From drsalists at gmail.com Sun Nov 1 00:16:47 2020 From: drsalists at gmail.com (Dan Stromberg) Date: Sat, 31 Oct 2020 21:16:47 -0700 Subject: Best way to determine user's screensize? In-Reply-To: <20201031231726.GC21877@hjp.at> References: <-4Od9L6qxZ_NGdTB72tL_Lewjt1MpvqqFbDKR0pYEE6Bn1D4GsCqCB2Q102p-O5KtGLJp_mCwEOtC61ceDUsD-PsQ8uw1dXch0Jh89iR6lg=@protonmail.com> <20201030235630.GC24901@hjp.at> <20201031120203.GC22631@hjp.at> <20201031125138.GB33753@scrozzle> <20201031133752.GA5683@hjp.at> <20201031165841.GC33753@scrozzle> <20201031182434.GB5897@hjp.at> <20201031221236.GD33753@scrozzle> <20201031231726.GC21877@hjp.at> Message-ID: On Sat, Oct 31, 2020 at 4:18 PM Peter J. Holzer wrote: > On 2020-10-31 17:12:36 -0500, 2QdxY4RzWzUUiLuE at potatochowder.com wrote: > > On 2020-10-31 at 19:24:34 +0100, > > "Peter J. Holzer" wrote: > > > On 2020-10-31 11:58:41 -0500, 2QdxY4RzWzUUiLuE at potatochowder.com > wrote: > > > > I never claimed it was easy. Yes, the author of an MUA has to make a > > > > guess and a bunch of decisions about a useful default setup (such a > set > > > > of defaults already appears elsewhere in this thread). > > > > > > Aha. And why would be better to "make a guess" than to use information > > > available at runtime? > > > > Some information, sure. Please don't assume that physical pixels or > > physical millimeters of display space relate to useful window sizes. > > It does. It's the upper bound. The window may be smaller, but not > larger. > Actually, I think Qt does this (base some parts of layout on the screen's physical size) at some fundamental level. Or so I suspect - I don't know for sure just yet. But if I run a Qt app in TigerVNC (EG keepassxc or an hello world), the app comes up as just a blank window, or it gives a SIGFPE in konsole while sizing the window. And concomitantly xdpyinfo believes that the physical dimensions of the TigerVNC screen are 0x0mm. If I do the same thing over plain ssh+X11 tunneling between the same two hosts, all 3 of those apps work fine, and the dimensions of the screen aren't 0x0. In TigerVNC's partial defense, I'm told that in newer versions of TigerVNC the screen dimensions are no longer 0x0mm. From torriem at gmail.com Sun Nov 1 00:43:17 2020 From: torriem at gmail.com (Michael Torrie) Date: Sat, 31 Oct 2020 22:43:17 -0600 Subject: GUI: I am also looking for a nudge into the best (GUI) direction. In-Reply-To: References: Message-ID: <14bd94dd-6467-1b52-6f90-8836e5f08c53@gmail.com> On 10/31/20 5:42 PM, Greg Ewing wrote: > On 1/11/20 9:44 am, Barry Scott wrote: > >> It does not appear to me that use native widgets is important for a tool kit. > > It's not strictly necessary. However, recreating the exact appearance > and behaviour of native widgets is a lot of work, and difficult to do > well -- most toolkits that attempt this don't manage to get all the > details exactly right. > > Moreover, a lot of maintenance effort is needed to keep up with > changes to the native widgets which frequently happen with OS updates. > And even if the toolkit is kept up to date, you need to install a > new version of the toolkit when changes occur. Maybe. However it seems like this is the route nearly everyone takes these days, include MS themselves. See below. > On the other hand, if the toolkit wraps the platform's native widgets, > it gets all the correct appearance and behaviour, and automatically > tracks changes. > > For these reasons I regard "uses native widgets" as a mark of quality > for a toolkit. In C# world, WinForms is often used, but it's not "native" win32 widgets. Widgets are implemented in managed code (according to Wikipedia) that draw themselves using the theming dll so they look native, or at least look somewhat consistent with regards to button styles, fonts, colors, etc. With the introduction of UWP apps, "native" has further lost meaning. Going forward, perhaps MS intends UWP to be the new native. I don't know and I'm not sure MS knows. MS Office hasn't used native win32 widgets for many years now (since Office 2000 I think, perhaps before). In fact I know of very few Windows applications that use exclusively the basic native widget set from win32. Nearly all apps use some kind of GUI framework, from MS or elsewhere, that implement their own widgets, often using the Theming system to draw them and get the colors right. Some apps don't even bother trying to look native--and yes those tend to be low-quality apps like antivirus programs. Shudder. I think notepad.exe, regedit.exe, etc, are probably the only apps I've used recently that actually use "native" win32 widgets. From Bischoop at vimart.net Sun Nov 1 08:38:22 2020 From: Bischoop at vimart.net (Bischoop) Date: Sun, 1 Nov 2020 13:38:22 -0000 (UTC) Subject: Find word by given characters References: Message-ID: On 2020-11-01, Bischoop wrote: > I'm working on a script i which user inputs letters and then a printed > words containing those letters. The scripts works however I can't solve > one problem , it prints also words in which these letters occur more > than once. > ------------------- > Fore example: > Letters: at > Output: auto, autobahn. > ------------------- > > I supposed to not print word: "autobahn" because I've given it only one > letter "a". > Problem's solved. ------------ for word in words: if all(word.count(x) == letters.count(x) for x in letters): print(word) ------------- Thanks for suggestions, I didn't had to use counter but going to look into as it seems useful and interesting. Thank You From bora at boramalper.org Sun Nov 1 04:56:46 2020 From: bora at boramalper.org (Bora) Date: Sun, 01 Nov 2020 09:56:46 +0000 Subject: Extending collections.Counter with top_n() to return elements by rank Message-ID: <73982c100acf8df6973fe64a4ec4a9de90f06ba5.camel@boramalper.org> collections.Counter has most_common([n]) method which returns the most common n elements of the counter, but in case of a tie the result is unspecified --- whereas in practice the order of insertion breaks the tie. For example: >>> Counter(["a","a","b","a","b","c","c","d"]).most_common(2) [('a', 3), ('b', 2)] >>> Counter(["a","a","c","a","b","b","c","d"]).most_common(2) [('a', 3), ('c', 2)] In some cases (which I believe are not rare) you would like to break the tie yourself or get the top elements by *rank*. Using our example: Rank Elements 0 {"a"} 1 {"b", "c"} 2 {"d"} I propose a new method top_n(n) that returns the top elements in the first n ranks. For example: >>> Counter(["a","a","b","a","b","c","c","d"]).top_n(0) [('a', 3)] >>> Counter(["a","a","b","a","b","c","c","d"]).top_n(1) [('a', 3), ('b', 2), ('c', 2)] >>> Counter(["a","a","b","a","b","c","c","d"]).top_n(2) [('a', 3), ('b', 2), ('c', 2), ('d', 1)] >>> Counter(["a","a","b","a","b","c","c","d"]).top_n(99) [('a', 3), ('b', 2), ('c', 2), ('d', 1)] >>> Counter(["a","a","b","a","b","c","c","d"]).top_n(-1) [] Some points to discuss: * What the return type should be? A list of tuples?like most_common() or List[Tuple[int, List[T]] that conveys the rank information too? Each tuple is a rank, whose first element is the frequency and second element is the list of elements. E.g. [(3, ['a']), (2, ['b', 'c']), (1, ['d'])] * Rank starts at 0 or 1? * Shall negative numbers raise an exception or return an empty list like most_common()? I would love to hear your opinion on this, and if there is interest, I am happy to implement it too. Regards, Bora M. Alper https://boramalper.org/ From songbird at anthive.com Sun Nov 1 09:47:13 2020 From: songbird at anthive.com (songbird) Date: Sun, 1 Nov 2020 09:47:13 -0500 Subject: Best way to determine user's screensize? References: <-4Od9L6qxZ_NGdTB72tL_Lewjt1MpvqqFbDKR0pYEE6Bn1D4GsCqCB2Q102p-O5KtGLJp_mCwEOtC61ceDUsD-PsQ8uw1dXch0Jh89iR6lg=@protonmail.com> Message-ID: Grant Edwards wrote: > On 2020-10-31, songbird wrote: ... >> do you object to a window being put in the approximate >> center of the screen? > > YES. I've configured my window manager so windows start up where I > want them to start up. It's none of the application's business where > it's window is. > > When developing an application, try to remember IT'S NOT YOUR > COMPUTER. certainly it isn't but it is my game and i kept it simple. if people don't like it then they can find something else to play. i'm good with that, but the next time i get back to making changes i'll see what i can figure out for saving the location where someone has moved it. songbird From songbird at anthive.com Sun Nov 1 09:40:44 2020 From: songbird at anthive.com (songbird) Date: Sun, 1 Nov 2020 09:40:44 -0500 Subject: Best way to determine user's screensize? References: <-4Od9L6qxZ_NGdTB72tL_Lewjt1MpvqqFbDKR0pYEE6Bn1D4GsCqCB2Q102p-O5KtGLJp_mCwEOtC61ceDUsD-PsQ8uw1dXch0Jh89iR6lg=@protonmail.com> Message-ID: Mats Wichmann wrote: > On 10/30/20 6:47 PM, songbird wrote: ... >> do you object to a window being put in the approximate >> center of the screen? > > Absolutely! I'm fighting that on a system which, after an update, > insists on opening new terminal windows centered - some recent policy > change is now doing that instead of where the same thing was placed the > last time it was open (I assume I'll find the knob for that eventually). > As others have said, there's no one-size-fits-all; on a big screen you > certainly don't want the same things as on a phone, where "take over the > whole screen" might indeed be the only thing that makes sense. to keep a program simple i made it to open in the center. if i ever get back to it i'll have to figure out how to ask the windowing system what it wants to do for placement and then store that location as part of the configuration if the person moves it. i don't use multiple screens yet nor do i mind moving an item once when i'm starting up, but i could see where if there are a lot of windows that it would be annoying to have to move all of them. songbird From duncan at invalid.invalid Sun Nov 1 13:23:25 2020 From: duncan at invalid.invalid (duncan smith) Date: Sun, 1 Nov 2020 18:23:25 +0000 Subject: Find word by given characters In-Reply-To: References: Message-ID: On 01/11/2020 13:38, Bischoop wrote: > On 2020-11-01, Bischoop wrote: >> I'm working on a script i which user inputs letters and then a printed >> words containing those letters. The scripts works however I can't solve >> one problem , it prints also words in which these letters occur more >> than once. >> ------------------- >> Fore example: >> Letters: at >> Output: auto, autobahn. >> ------------------- >> >> I supposed to not print word: "autobahn" because I've given it only one >> letter "a". >> > > Problem's solved. > > ------------ > for word in words: > if all(word.count(x) == letters.count(x) for x in letters): > print(word) > ------------- > > Thanks for suggestions, I didn't had to use counter but going to look > into as it seems useful and interesting. > > Thank You > But this generates the letters counts for each word. They only need to be generated once (outside the for loop). And using count requires iterating over the letters / words for each x in letters (rather than once). For a large enough collection of words you'd notice the difference. Duncan From greg.ewing at canterbury.ac.nz Sun Nov 1 17:36:06 2020 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Mon, 2 Nov 2020 11:36:06 +1300 Subject: GUI: I am also looking for a nudge into the best (GUI) direction. In-Reply-To: References: <14bd94dd-6467-1b52-6f90-8836e5f08c53@gmail.com> Message-ID: On 1/11/20 5:43 pm, Michael Torrie wrote: > In C# world, WinForms is often used, but it's not "native" win32 > widgets. Widgets are implemented in managed code (according to > Wikipedia) that draw themselves using the theming dll so they look > native, or at least look somewhat consistent with regards to button > styles, fonts, colors, etc. Well, Microsoft has a lot more resources than your typical third party GUI toolkit developer to spend on re-doing everything periodically. It still make sense to let them do the hard work instead of replicating it all yourself. > In fact I know of very few > Windows applications that use exclusively the basic native widget set > from win32. Which is understandable -- the raw Windows GUI API is pretty cruddy and doesn't do a lot of what one expects from a modern GUI toolkit. But I still think it's better to base your UI on one of the standard offerings from Microsoft such as WinForms rather than rolling your own. -- Greg From Bischoop at vimart.net Mon Nov 2 05:29:11 2020 From: Bischoop at vimart.net (Bischoop) Date: Mon, 2 Nov 2020 10:29:11 -0000 (UTC) Subject: Find word by given characters References: Message-ID: On 2020-11-01, duncan smith wrote: >> > > But this generates the letters counts for each word. They only need to > be generated once (outside the for loop). And using count requires > iterating over the letters / words for each x in letters (rather than > once). For a large enough collection of words you'd notice the difference. > You're pretty much right, it doesn't go too fast. I've done this years ago with Python2, had a bit free time now and wanted to ReLearn Python from starting old projects I've done in past but can't remember how I made it working lol. From grant.b.edwards at gmail.com Sun Nov 1 10:28:22 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Sun, 1 Nov 2020 15:28:22 -0000 (UTC) Subject: Best way to determine user's screensize? References: <-4Od9L6qxZ_NGdTB72tL_Lewjt1MpvqqFbDKR0pYEE6Bn1D4GsCqCB2Q102p-O5KtGLJp_mCwEOtC61ceDUsD-PsQ8uw1dXch0Jh89iR6lg=@protonmail.com> Message-ID: On 2020-11-01, songbird wrote: > to keep a program simple i made it to open in the center. That's not simple: it actually takes _extra_ work to do that. > if i ever get back to it i'll have to figure out how to ask > the windowing system what it wants to do for placement I've never heard of doing that before. I've written lots of desktop GUI apps in the past 30 years, and I've never written one line of code dealing with the location of the top-level window. I just let the toolkit and window manager handle it. From grant.b.edwards at gmail.com Sun Nov 1 10:31:57 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Sun, 1 Nov 2020 15:31:57 -0000 (UTC) Subject: Best way to determine user's screensize? References: <-4Od9L6qxZ_NGdTB72tL_Lewjt1MpvqqFbDKR0pYEE6Bn1D4GsCqCB2Q102p-O5KtGLJp_mCwEOtC61ceDUsD-PsQ8uw1dXch0Jh89iR6lg=@protonmail.com> Message-ID: On 2020-11-01, songbird wrote: > certainly it isn't but it is my game and i kept it simple. if > people don't like it then they can find something else to play. i'm > good with that, but the next time i get back to making changes i'll > see what i can figure out for saving the location where someone has > moved it. I have no objection to saving the most recent window size and using that on the next startup, but I hate applications that force the _location_ of the window. I've configured my window manager to open windows where I want them opened, please respect that. -- Grant From variablestarlight at gmail.com Mon Nov 2 04:06:10 2020 From: variablestarlight at gmail.com (=?UTF-8?Q?Hern=c3=a1n_De_Angelis?=) Date: Mon, 2 Nov 2020 10:06:10 +0100 Subject: Post request and encoding Message-ID: <2680c348-d274-783c-0023-0b0a7b349587@gmail.com> Hi everyone, I am writing a program that sends a post request to a server. The post request may include keywords with Swedish characters (???). I noticed that requests that include strings without those characters return a useful expected response. On the other hand, posts including those characters return an 'empty' response. However, if I save that same request to a file and send it using wget I do get a useful response. This suggests to me that the problem should be in how the post is sent or processed before being sent and not in how it is generated. My request has the form: header = {'Content-type':'application/xml', 'charset':'utf-8'} response = requests.post(server, data=request, headers=header) I have tried of course adding request.encode('utf-8') before sending the request but it has not lead to a different result. I have spent several hours trying to understand whats going on here. I thought at first that this had to do with an issue described here: https://github.com/psf/requests/issues/5560 but apparently that issue was closed as it was deemed to be unrelated to the requests library. Has anyone experienced this before? Is there something obvious I am missing here? I am not new to programming but relatively new to Python, so bear with me please. Thanks in advance /H. If it is of any use, I post the following too: python3 -m requests.help { "chardet": { "version": "3.0.4" }, "cryptography": { "version": "3.1.1" }, "idna": { "version": "2.10" }, "implementation": { "name": "CPython", "version": "3.8.5" }, "platform": { "release": "5.9.1-1-default", "system": "Linux" }, "pyOpenSSL": { "openssl_version": "1010108f", "version": "19.1.0" }, "requests": { "version": "2.24.0" }, "system_ssl": { "version": "1010108f" }, "urllib3": { "version": "1.25.10" }, "using_pyopenssl": true } From variablestarlight at gmail.com Mon Nov 2 12:21:15 2020 From: variablestarlight at gmail.com (=?UTF-8?Q?Hern=c3=a1n_De_Angelis?=) Date: Mon, 2 Nov 2020 18:21:15 +0100 Subject: Post request and encoding In-Reply-To: <2680c348-d274-783c-0023-0b0a7b349587@gmail.com> References: <2680c348-d274-783c-0023-0b0a7b349587@gmail.com> Message-ID: <1f841924-cffd-bad7-1349-ed87fb38c8dd@gmail.com> Just reply to myself and whoever might find this useful. encode() must be done within the request call: header = {'Content-type':'application/xml', 'charset':'UTF-8'} response = requests.post(server, data=request.encode('utf-8'), headers=header) not in a previous separate line as I did. Now it works. This wasn't an obvious way to proceed for me. /H. On 2020-11-02 10:06, Hern?n De Angelis wrote: > Hi everyone, > > I am writing a program that sends a post request to a server. The post > request may include keywords with Swedish characters (???). > > I noticed that requests that include strings without those characters > return a useful expected response. On the other hand, posts including > those characters return an 'empty' response. However, if I save that > same request to a file and send it using wget I do get a useful > response. This suggests to me that the problem should be in how the > post is sent or processed before being sent and not in how it is > generated. > > My request has the form: > > header = {'Content-type':'application/xml', 'charset':'utf-8'} > response = requests.post(server, data=request, headers=header) > > I have tried of course adding > > request.encode('utf-8') > > before sending the request but it has not lead to a different result. > > I have spent several hours trying to understand whats going on here. I > thought at first that this had to do with an issue described here: > https://github.com/psf/requests/issues/5560 but apparently that issue > was closed as it was deemed to be unrelated to the requests library. > > > Has anyone experienced this before? Is there something obvious I am > missing here? > > I am not new to programming but relatively new to Python, so bear with > me please. > > > Thanks in advance > > /H. > > > If it is of any use, I post the following too: > > python3 -m requests.help > { > "chardet": { > "version": "3.0.4" > }, > "cryptography": { > "version": "3.1.1" > }, > "idna": { > "version": "2.10" > }, > "implementation": { > "name": "CPython", > "version": "3.8.5" > }, > "platform": { > "release": "5.9.1-1-default", > "system": "Linux" > }, > "pyOpenSSL": { > "openssl_version": "1010108f", > "version": "19.1.0" > }, > "requests": { > "version": "2.24.0" > }, > "system_ssl": { > "version": "1010108f" > }, > "urllib3": { > "version": "1.25.10" > }, > "using_pyopenssl": true > } > From rosuav at gmail.com Mon Nov 2 12:29:00 2020 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 3 Nov 2020 04:29:00 +1100 Subject: Post request and encoding In-Reply-To: <1f841924-cffd-bad7-1349-ed87fb38c8dd@gmail.com> References: <2680c348-d274-783c-0023-0b0a7b349587@gmail.com> <1f841924-cffd-bad7-1349-ed87fb38c8dd@gmail.com> Message-ID: On Tue, Nov 3, 2020 at 4:22 AM Hern?n De Angelis wrote: > > Just reply to myself and whoever might find this useful. > > encode() must be done within the request call: > > header = {'Content-type':'application/xml', 'charset':'UTF-8'} > response = requests.post(server, data=request.encode('utf-8'), > headers=header) > > not in a previous separate line as I did. > > Now it works. This wasn't an obvious way to proceed for me. > I'm not sure of all the context here, but most likely, what you're seeing is that your data needs to be bytes and you had text. When you call the encode method, you don't change the data itself - what happens is that it returns an encoded form of the data. That's why just calling request.encode() won't do anything - it creates the encoded form but then does nothing with it. Hopefully that helps a bit. ChrisA From Karsten.Hilbert at gmx.net Mon Nov 2 12:32:09 2020 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Mon, 2 Nov 2020 18:32:09 +0100 Subject: Post request and encoding In-Reply-To: <1f841924-cffd-bad7-1349-ed87fb38c8dd@gmail.com> References: <2680c348-d274-783c-0023-0b0a7b349587@gmail.com> <1f841924-cffd-bad7-1349-ed87fb38c8dd@gmail.com> Message-ID: <20201102173209.GL26982@hermes.hilbert.loc> On Mon, Nov 02, 2020 at 06:21:15PM +0100, Hern?n De Angelis wrote: For the record: > Just reply to myself and whoever might find this useful. > > encode() must be done within the request call: Nope (but it can, as you showed). > header = {'Content-type':'application/xml', 'charset':'UTF-8'} > response = requests.post(server, data=request.encode('utf-8'), > headers=header) > > not in a previous separate line as I did. Your separate line was wrong as much as ayone can guess: > > I have tried of course adding > > > > request.encode('utf-8') > > > > before sending the request but it has not lead to a different result. You would have needed to do: request = request.encode('utf-8') because .encode() does not operate in-place. Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B From variablestarlight at gmail.com Mon Nov 2 12:43:20 2020 From: variablestarlight at gmail.com (=?UTF-8?Q?Hern=c3=a1n_De_Angelis?=) Date: Mon, 2 Nov 2020 18:43:20 +0100 Subject: Post request and encoding In-Reply-To: <20201102173209.GL26982@hermes.hilbert.loc> References: <2680c348-d274-783c-0023-0b0a7b349587@gmail.com> <1f841924-cffd-bad7-1349-ed87fb38c8dd@gmail.com> <20201102173209.GL26982@hermes.hilbert.loc> Message-ID: <038e3d90-e38a-825c-7d02-bf65717a4fd4@gmail.com> I see, my mistake was (tacitly) assuming that encode() could work in place. Now I see that it should work in a previous line as you wrote. Thank you! /H. On 2020-11-02 18:32, Karsten Hilbert wrote: > On Mon, Nov 02, 2020 at 06:21:15PM +0100, Hern?n De Angelis wrote: > > For the record: > >> Just reply to myself and whoever might find this useful. >> >> encode() must be done within the request call: > Nope (but it can, as you showed). > >> header = {'Content-type':'application/xml', 'charset':'UTF-8'} >> response = requests.post(server, data=request.encode('utf-8'), >> headers=header) >> >> not in a previous separate line as I did. > Your separate line was wrong as much as ayone can guess: > >>> I have tried of course adding >>> >>> request.encode('utf-8') >>> >>> before sending the request but it has not lead to a different result. > You would have needed to do: > > request = request.encode('utf-8') > > because .encode() does not operate in-place. > > Karsten > -- > GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B From ethan at stoneleaf.us Mon Nov 2 12:56:44 2020 From: ethan at stoneleaf.us (Ethan Furman) Date: Mon, 2 Nov 2020 09:56:44 -0800 Subject: Post request and encoding In-Reply-To: <20201102173209.GL26982@hermes.hilbert.loc> References: <2680c348-d274-783c-0023-0b0a7b349587@gmail.com> <1f841924-cffd-bad7-1349-ed87fb38c8dd@gmail.com> <20201102173209.GL26982@hermes.hilbert.loc> Message-ID: <39fed5b7-c660-f617-7e8c-c1df9715a08a@stoneleaf.us> On 11/2/20 9:32 AM, Karsten Hilbert wrote: > because .encode() does not operate in-place. Yeah, none of the string operations do, and it's embarrassing how many times that still bites me. :-/ -- ~Ethan~ From Karsten.Hilbert at gmx.net Mon Nov 2 13:03:54 2020 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Mon, 2 Nov 2020 19:03:54 +0100 Subject: Post request and encoding In-Reply-To: <038e3d90-e38a-825c-7d02-bf65717a4fd4@gmail.com> References: <2680c348-d274-783c-0023-0b0a7b349587@gmail.com> <1f841924-cffd-bad7-1349-ed87fb38c8dd@gmail.com> <20201102173209.GL26982@hermes.hilbert.loc> <038e3d90-e38a-825c-7d02-bf65717a4fd4@gmail.com> Message-ID: <20201102180354.GM26982@hermes.hilbert.loc> On Mon, Nov 02, 2020 at 06:43:20PM +0100, Hern?n De Angelis wrote: > I see, my mistake was (tacitly) assuming that encode() could work in place. > > Now I see that it should work in a previous line as you wrote. > > Thank you! Sure, and excuse my perhaps slightly terse tone in that earlier mail ... Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B From PythonList at DancesWithMice.info Mon Nov 2 14:09:24 2020 From: PythonList at DancesWithMice.info (dn) Date: Tue, 3 Nov 2020 08:09:24 +1300 Subject: Find word by given characters In-Reply-To: References: Message-ID: <36f4147e-6be4-4f26-f764-f50119046333@DancesWithMice.info> On 02/11/2020 23:29, Bischoop wrote: > On 2020-11-01, duncan smith wrote: >>> >> >> But this generates the letters counts for each word. They only need to >> be generated once (outside the for loop). And using count requires >> iterating over the letters / words for each x in letters (rather than >> once). For a large enough collection of words you'd notice the difference. >> > > You're pretty much right, it doesn't go too fast. > I've done this years ago with Python2, had a bit free time now and > wanted to ReLearn Python from starting old projects I've done in past > but can't remember how I made it working lol. If you have a working Py2 version, once print-statements were changed into functions, what errors were thrown-up? Multiple loops written in Python are likely to be slower than same in compiled code - which was probably part of the motivation for @Terry's response. Plus, "re-use" - why write something ourselves if someone else has already done the work? How about a change of tactics? - str.find() or .index() will locate a character within the string (starting from character[0]/the left-hand side) - if this fails, tears will fall... - repeat, from the right - if both results are the same character/position, it must be unique within the string - repeat for each character in "Letters" This process assumes that built-in functions are faster than exhaustive scans written in Python, and thus (presumably) also that the number of "Letters" is small in comparison with the lengths of words. Once the algorithms are proven, a speed comparison might be an interesting exercise... For extra credit: once you've solved both, and compared the alternatives on your machine; post the code (and test data), and ask various colleagues 'here' to repeat the speed/performance comparisons on other machines. Will/should the results be identical? -- Regards =dn From variablestarlight at gmail.com Mon Nov 2 14:49:31 2020 From: variablestarlight at gmail.com (Variable Starlight) Date: Mon, 2 Nov 2020 20:49:31 +0100 Subject: Post request and encoding In-Reply-To: <20201102180354.GM26982@hermes.hilbert.loc> References: <2680c348-d274-783c-0023-0b0a7b349587@gmail.com> <1f841924-cffd-bad7-1349-ed87fb38c8dd@gmail.com> <20201102173209.GL26982@hermes.hilbert.loc> <038e3d90-e38a-825c-7d02-bf65717a4fd4@gmail.com> <20201102180354.GM26982@hermes.hilbert.loc> Message-ID: No worries ? Den m?n 2 nov. 2020 19:05Karsten Hilbert skrev: > On Mon, Nov 02, 2020 at 06:43:20PM +0100, Hern?n De Angelis wrote: > > > I see, my mistake was (tacitly) assuming that encode() could work in > place. > > > > Now I see that it should work in a previous line as you wrote. > > > > Thank you! > > Sure, and excuse my perhaps slightly terse tone in that earlier mail ... > > Karsten > > -- > GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B > -- > https://mail.python.org/mailman/listinfo/python-list > From variablestarlight at gmail.com Mon Nov 2 14:50:28 2020 From: variablestarlight at gmail.com (Variable Starlight) Date: Mon, 2 Nov 2020 20:50:28 +0100 Subject: Post request and encoding In-Reply-To: <39fed5b7-c660-f617-7e8c-c1df9715a08a@stoneleaf.us> References: <2680c348-d274-783c-0023-0b0a7b349587@gmail.com> <1f841924-cffd-bad7-1349-ed87fb38c8dd@gmail.com> <20201102173209.GL26982@hermes.hilbert.loc> <39fed5b7-c660-f617-7e8c-c1df9715a08a@stoneleaf.us> Message-ID: Thanks, I now learned the lesson. ? Den m?n 2 nov. 2020 18:58Ethan Furman skrev: > On 11/2/20 9:32 AM, Karsten Hilbert wrote: > > > because .encode() does not operate in-place. > > Yeah, none of the string operations do, and it's embarrassing how many > times that still bites me. :-/ > > -- > ~Ethan~ > -- > https://mail.python.org/mailman/listinfo/python-list > From grant.b.edwards at gmail.com Mon Nov 2 13:54:18 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 2 Nov 2020 18:54:18 -0000 (UTC) Subject: Post request and encoding References: <2680c348-d274-783c-0023-0b0a7b349587@gmail.com> <1f841924-cffd-bad7-1349-ed87fb38c8dd@gmail.com> <20201102173209.GL26982@hermes.hilbert.loc> <39fed5b7-c660-f617-7e8c-c1df9715a08a@stoneleaf.us> Message-ID: On 2020-11-02, Ethan Furman wrote: > On 11/2/20 9:32 AM, Karsten Hilbert wrote: > >> because .encode() does not operate in-place. > > Yeah, none of the string operations do, and it's embarrassing how > many times that still bites me. :-/ I've been writing Python for a little over 20 years. In another 20 years, maybe I'll stop making that mistake. :) From jaybraun2.0 at gmail.com Mon Nov 2 16:53:52 2020 From: jaybraun2.0 at gmail.com (Jay Braun) Date: Mon, 2 Nov 2020 13:53:52 -0800 (PST) Subject: Solaris 11 GUI framework Message-ID: <4597a41c-a317-4b0f-be12-c6c165eb8feen@googlegroups.com> Looking for a GUI framework supported on Solaris 11. From ikorot01 at gmail.com Mon Nov 2 17:54:54 2020 From: ikorot01 at gmail.com (Igor Korot) Date: Mon, 2 Nov 2020 16:54:54 -0600 Subject: Solaris 11 GUI framework In-Reply-To: <4597a41c-a317-4b0f-be12-c6c165eb8feen@googlegroups.com> References: <4597a41c-a317-4b0f-be12-c6c165eb8feen@googlegroups.com> Message-ID: Hi, On Mon, Nov 2, 2020, 3:57 PM Jay Braun wrote: > Looking for a GUI framework supported on Solaris 11. > Wxpython, pygtk, Java. Take you poison. Thank you. -- > https://mail.python.org/mailman/listinfo/python-list > From jaybraun2.0 at gmail.com Mon Nov 2 17:57:56 2020 From: jaybraun2.0 at gmail.com (Jay Braun) Date: Mon, 2 Nov 2020 14:57:56 -0800 (PST) Subject: Solaris 11 GUI framework In-Reply-To: References: <4597a41c-a317-4b0f-be12-c6c165eb8feen@googlegroups.com> Message-ID: <60895db7-e013-4e37-85db-46d6742762b0n@googlegroups.com> Thank you. I should have mentioned that I am looking for a Python GUI framework. I neglected to mention that since this is a Python group. Sorry. From ikorot01 at gmail.com Mon Nov 2 18:04:32 2020 From: ikorot01 at gmail.com (Igor Korot) Date: Mon, 2 Nov 2020 17:04:32 -0600 Subject: Solaris 11 GUI framework In-Reply-To: <60895db7-e013-4e37-85db-46d6742762b0n@googlegroups.com> References: <4597a41c-a317-4b0f-be12-c6c165eb8feen@googlegroups.com> <60895db7-e013-4e37-85db-46d6742762b0n@googlegroups.com> Message-ID: Hi, On Mon, Nov 2, 2020, 5:02 PM Jay Braun wrote: > Thank you. I should have mentioned that I am looking for a Python GUI > framework. I neglected to mention that since this is a Python group. > Sorry. > Well, first 2 are python and base on gtk. Thank you. -- > https://mail.python.org/mailman/listinfo/python-list > From Bischoop at vimart.net Mon Nov 2 18:10:31 2020 From: Bischoop at vimart.net (Bischoop) Date: Mon, 2 Nov 2020 23:10:31 -0000 (UTC) Subject: Find word by given characters References: <36f4147e-6be4-4f26-f764-f50119046333@DancesWithMice.info> Message-ID: On 2020-11-02, dn wrote: > > > If you have a working Py2 version, once print-statements were changed > into functions, what errors were thrown-up? > > That was almost 15 if no more years ago when I was learning then had a long break beacause Life :-) Got married, working as Chef, now have some more time, working part time so a got back to old hobby and learning again, however I see now with age everything is going slower lol > Multiple loops written in Python are likely to be slower than same in > compiled code - which was probably part of the motivation for @Terry's > response. Plus, "re-use" - why write something ourselves if someone else > has already done the work? > For educating purposes? > > How about a change of tactics? > > - str.find() or .index() will locate a character within the string > (starting from character[0]/the left-hand side) > - if this fails, tears will fall... > - repeat, from the right > - if both results are the same character/position, it must be unique > within the string > - repeat for each character in "Letters" > > This process assumes that built-in functions are faster than exhaustive > scans written in Python, and thus (presumably) also that the number of > "Letters" is small in comparison with the lengths of words. > ha, everything seems easy only if you know that. Sorry mate, for you it's obvious for me: oh, OK. > > Once the algorithms are proven, a speed comparison might be an > interesting exercise... > > For extra credit: once you've solved both, and compared the alternatives > on your machine; post the code (and test data), and ask various > colleagues 'here' to repeat the speed/performance comparisons on other > machines. > > Will/should the results be identical? I'll look into that tomorrow, your sugestions guys and hopefully I've achieve these goals. Thanks again From songbird at anthive.com Mon Nov 2 17:38:28 2020 From: songbird at anthive.com (songbird) Date: Mon, 2 Nov 2020 17:38:28 -0500 Subject: Best way to determine user's screensize? References: <-4Od9L6qxZ_NGdTB72tL_Lewjt1MpvqqFbDKR0pYEE6Bn1D4GsCqCB2Q102p-O5KtGLJp_mCwEOtC61ceDUsD-PsQ8uw1dXch0Jh89iR6lg=@protonmail.com> Message-ID: <4ce67h-c33.ln1@anthive.com> Grant Edwards wrote: > On 2020-11-01, songbird wrote: > >> to keep a program simple i made it to open in the center. > > That's not simple: it actually takes _extra_ work to do that. this was the first python3 program i wrote, i certainly do not know python3 or desktop application standards or much of the other stuff i did, but the program does work and i'm fine with it as what it is. by no means is any program the final statement on any problem - they are all iterations. some fail, some go further. mayhaps, i'll get further, i can't say at the present, mainly because my time for programming is not that much during the spring/summer/fall. i'm only taking a look at this thread because it does touch on issues i'm curious about and i'm gradually getting more time so perhaps there's a chance it will get some updates and changes this winter. someone commented to me that if that is my attitude then perhaps nobody will play it. that's ok, i didn't write it for anything other a learning experience. that experience will perhaps continue... i may also perhaps get run over by a mad cow tomorrow and the future will then be left for someone else to determine. :) >> if i ever get back to it i'll have to figure out how to ask >> the windowing system what it wants to do for placement > > I've never heard of doing that before. I've written lots of desktop > GUI apps in the past 30 years, and I've never written one line of code > dealing with the location of the top-level window. I just let the > toolkit and window manager handle it. if there are answers to the following questions this would go in my file for future efforts. 1. i'm running Debian testing, lightdm and MATE desktop. 2. i don't know anything about how those things provide information to an application. pointers would be appreciated. 3. the application is written in python3, using gtk3 and pyglet. it is a very rotten first attempt, i admit that. :) but also, for what it is it does work. note, it does not work on Windows because i don't have a windows machine for development and testing nor do i have the inclination to do that right now (which is why that's not done yet). i've posted links to it here before but just so anyone doesn't have to search for it i'll put the link here too: https://github.com/flowerbug/ngfp have fun, cheers, etc. :) songbird From duncan at invalid.invalid Mon Nov 2 19:13:10 2020 From: duncan at invalid.invalid (duncan smith) Date: Tue, 3 Nov 2020 00:13:10 +0000 Subject: Find word by given characters In-Reply-To: References: <36f4147e-6be4-4f26-f764-f50119046333@DancesWithMice.info> Message-ID: On 02/11/2020 19:09, dn wrote: > On 02/11/2020 23:29, Bischoop wrote: >> On 2020-11-01, duncan smith wrote: >>>> >>> >>> But this generates the letters counts for each word. They only need to >>> be generated once (outside the for loop). And using count requires >>> iterating over the letters / words for each x in letters (rather than >>> once). For a large enough collection of words you'd notice the >>> difference. >>> >> >> You're pretty much right, it doesn't go too fast. >> I've done this years ago with Python2, had a bit free time now and >> wanted to ReLearn Python from starting old projects I've done in past >> but can't remember how I made it working lol. > > > If you have a working Py2 version, once print-statements were changed > into functions, what errors were thrown-up? > > > Multiple loops written in Python are likely to be slower than same in > compiled code - which was probably part of the motivation for @Terry's > response. Plus, "re-use" - why write something ourselves if someone else > has already done the work? > > > How about a change of tactics? > > - str.find() or .index() will locate a character within the string > (starting from character[0]/the left-hand side) > - if this fails, tears will fall... > - repeat, from the right > - if both results are the same character/position, it must be unique > within the string > - repeat for each character in "Letters" > [snip] But he appears to need the count in order to compare against the counts in letters. I assume letters could be something like 'att', in which case knowing a word contains more than one 't' doesn't cut it. He could try iterating over the characters in each word once, checking that no count from letters is exceeded, and that the number of remaining characters gives some chance that the relevant counts from letters could be achieved. In the worst case (e.g. a conforming word) this requires iterating over all the characters in a word once. That's not to say it would actually run quicker 'on average' than a solution using Counter. Duncan From PythonList at DancesWithMice.info Mon Nov 2 21:56:53 2020 From: PythonList at DancesWithMice.info (dn) Date: Tue, 3 Nov 2020 15:56:53 +1300 Subject: Find word by given characters In-Reply-To: References: <36f4147e-6be4-4f26-f764-f50119046333@DancesWithMice.info> Message-ID: On 03/11/2020 12:10, Bischoop wrote: > On 2020-11-02, dn wrote: >> If you have a working Py2 version, once print-statements were changed >> into functions, what errors were thrown-up? >> > That was almost 15 if no more years ago when I was learning then had a > long break beacause Life :-) Got married, working as Chef, now have some > more time, working part time so a got back to old hobby and learning > again, however I see now with age everything is going slower lol Apologies, I hoped that you had the Py2 code to-hand. >> Multiple loops written in Python are likely to be slower than same in >> compiled code - which was probably part of the motivation for @Terry's >> response. Plus, "re-use" - why write something ourselves if someone else >> has already done the work? > > For educating purposes? We are/should all be learning! >> How about a change of tactics? >> >> - str.find() or .index() will locate a character within the string >> (starting from character[0]/the left-hand side) >> - if this fails, tears will fall... >> - repeat, from the right >> - if both results are the same character/position, it must be unique >> within the string >> - repeat for each character in "Letters" >> >> This process assumes that built-in functions are faster than exhaustive >> scans written in Python, and thus (presumably) also that the number of >> "Letters" is small in comparison with the lengths of words. >> > ha, everything seems easy only if you know that. > Sorry mate, for you it's obvious for me: oh, OK. You are correct: "any sufficiently advanced technology is indistinguishable from magic" [Arthur C Clarke]. I'd like to think that characterisation correct (it would be more believable if you cataloged my debonair demeanor and devastatingly-good looks -maybe!). However, the reality is that I had to stop and think about it. That said, my 'catalog' of Python tactics may/should be wider than yours (and yet is probably 'not much' when compared with certain others!) No question: one must start with the basics, even whilst aspiring to 'the lofty peaks'. In a parallel response (to @Duncan's post) other approaches - which may be beyond your current reach, are discussed. The 'learning opportunity/ies' (if not for you/me, for the many others following this discussion on-list) are (at least) three-fold: - how to write loops and wrangle strings; - how sometimes not writing code can be 'faster' (at dev.time and/or in prod) because someone else has already coded a solution (or something I can 'improve'); and - there is often more than one way to look at the problem (do I search every letter of the candidate word, once for every letter in Letters, or vice-versa - or is there yet another way!) My suggestion: continue with the nested loops approach until you've cracked it. Then, working at your own pace, and at your own interest, consider implementing the counter() idea. Can you make it work? Can you make it meet the spec? Then, take a look at a str.index() alternative. Then, look-around for some other approach. Finally (which seems to imply an 'end' - hah!), look back, and reflect on both the acquiring of so many new skills; and how some solutions are 'faster', some more 'obvious', and some more "elegant". Hey, it all sounds like "learning" to me! >> Once the algorithms are proven, a speed comparison might be an >> interesting exercise... >> >> For extra credit: once you've solved both, and compared the alternatives >> on your machine; post the code (and test data), and ask various >> colleagues 'here' to repeat the speed/performance comparisons on other >> machines. >> >> Will/should the results be identical? > > I'll look into that tomorrow, your sugestions guys and hopefully I've > achieve these goals. You cast yourself as 'the learner', but if you (whenever) contribute something along these lines, there will be many who learn from you... -- Regards =dn From PythonList at DancesWithMice.info Mon Nov 2 22:10:39 2020 From: PythonList at DancesWithMice.info (dn) Date: Tue, 3 Nov 2020 16:10:39 +1300 Subject: Find word by given characters In-Reply-To: References: <36f4147e-6be4-4f26-f764-f50119046333@DancesWithMice.info> Message-ID: <61beed7c-a0c0-5885-40d1-b6c5de078722@DancesWithMice.info> On 03/11/2020 13:13, duncan smith wrote: > On 02/11/2020 19:09, dn wrote: >> On 02/11/2020 23:29, Bischoop wrote: >>> On 2020-11-01, duncan smith wrote: >>>> But this generates the letters counts for each word. They only need to >>>> be generated once (outside the for loop). And using count requires >>>> iterating over the letters / words for each x in letters (rather than >>>> once). For a large enough collection of words you'd notice the >>>> difference. >> Multiple loops written in Python are likely to be slower than same in >> compiled code - which was probably part of the motivation for @Terry's >> response. Plus, "re-use" - why write something ourselves if someone else >> has already done the work? ... >> - str.find() or .index() will locate a character within the string... > But he appears to need the count in order to compare against the counts > in letters. I assume letters could be something like 'att', in which > case knowing a word contains more than one 't' doesn't cut it. He could > try iterating over the characters in each word once, checking that no > count from letters is exceeded, and that the number of remaining > characters gives some chance that the relevant counts from letters could > be achieved. In the worst case (e.g. a conforming word) this requires > iterating over all the characters in a word once. That's not to say it > would actually run quicker 'on average' than a solution using Counter. The str.index() idea solves both (ie "all") examples given, but beyond that, no guarantees! The (full) specs are not clear. There's certainly room for misunderstanding. I'd be happier if I could 'see' a full spec or recognise a practical application, because then we'd be better able to discuss facts. Meantime, we try to help with what we have been given... The OP's sample code only realises "conforming word[s]" (good term BTW!). The snippet does not report any "count". Similarly, there's no facts to avoid ("I assume") an assumption about whether "Letters" may include duplication - indeed: whether duplication has meaning or should be regarded as user-error. The point has been made that finding multiple instances of "Letters" disqualifies that word. Does that (also) disqualify having repetition of a letter within Letters? (or not?) What does "att" imply? That there must be one and only one "a" in the word, plus a "t", and only one *other* "t"? Can't see it in 'the specs' to be able to say "right" or "wrong"! (Nor is it my spec!) Whereas the OP indicates (first example) that the two characters "a" and "t" must appear, there was no apparent, required, linkage (or separation) between them, eg "auto" doesn't include the two letters consecutively (one of my first (mistaken) thoughts when looking at the OP). Accordingly, I (again, rightly or wrongly), assumed that the lack of linkage between characters in "Letters" reasonably suggested (if not, implied) that if "auto" matches "at", it would also match "ta". Similarly, and without further detail, I couldn't see good reason why Letters itself would contain repetition, eg "att". (or not!) Aside: that idea might make for a good second-level challenge! (complicating both the nested-loops and the str.index() ideas - but possibly not when using counter()...) When counter() was suggested, it was necessary to 'count' the characters in both the candidate-word and "Letters". Isn't that 'requirement' necessary only to be able to perform the final comparison/validation step? (there is no equivalent in the .index() algorithm) Whereas counter() was mentioned as a potential solution, it didn't seem to fit. So, I sought another... Moving to the suggested speed-comparison (and lesson in drawing from Python's rich collection of resources) was originally aimed at putting a native-Python nested list string manipulation solution, alongside an embedded function alternative. (cf anything involving Counter) - but hey, "the more the merrier..."! Performing this sort of experiment, and making such an observation (for oneself) is a great motivator (should one be needed) to learn Python's built-in functions, what is available in the PSL, and locating other similar 'riches' offered within the Python 'eco-system'! -- Regards =dn From arj.python at gmail.com Tue Nov 3 00:34:26 2020 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Tue, 3 Nov 2020 09:34:26 +0400 Subject: Documenting the Python Community Message-ID: Greetings list, I have a project in mind to help document the Python community. It involves among others keeping a within reach info of user groups (name, location, contact) and checking activity status. Sending the mail to this list since i could not find a community workgroup. I know Mr Chris is in the Wiki team and that Mrs McKellar once toured Python usergroup spaces for a PSF community-related initiative many years ago. Besides those i don't know any specific person who might be interested This occurs after we organised FlaskCon . It was an ugly experience contacting user groups around the world. The wiki is outdated. Many user groups are no longer active, some websites are down, others have weird ways of communicating. This mail is basically to gather interested folks together with the hope of hatching a minimum viable plan d'action. Being myself a usergroup organiser , we'd like to find a way to 1. make user groups compliant to a minimum standard 2. put the appropriate mechanism in place so that the PSF can easily have a watch over user groups and give them some bumps from time to time 3. some kind of onboarding and advices for new user groups In parallel I am also thinking of documenting user groups histories, starting with those I have some sort of relationship with. The idea behind is to reinforce the community touch. The draft might seem a tedious task for the expected benefits but with the right approach it will be smooth. Feel free to continue the conversation! Kind Regards, Abdur-Rahmaan Janhangeer about | blog github Mauritius From frank at chagford.com Tue Nov 3 03:27:07 2020 From: frank at chagford.com (Frank Millman) Date: Tue, 3 Nov 2020 10:27:07 +0200 Subject: asyncio question Message-ID: Hi all My app runs an HTTP server using asyncio. A lot of the code dates back to Python 3.4, and I am trying to bring it up to date. There is one aspect I do not understand. The 'old' way looks like this - import asyncio def main(): loop = asyncio.get_event_loop() server = loop.run_until_complete( asyncio.start_server(handle_client, host, port)) loop.run_forever() if __name__ == '__main__': main() According to the docs, the preferred way is now like this - import asyncio async def main(): loop = asyncio.get_running_loop() server = await asyncio.start_server( handle_client, host, port) async with server: server.serve_forever() if __name__ == '__main__': asyncio.run(main()) It works, and it does look neater. But I want to start some background tasks before starting the server, and cancel them on Ctrl+C. Using the 'old' method, I can wrap 'loop.run_forever()' in a try/except/finally, check for KeyboardInterrupt, and run my cleanup in the 'finally' block. Using the 'new' method, KeyboardInterrupt is not caught by 'server.serve_forever()' but by 'asyncio.run()'. It is too late to do any cleanup at this point, as the loop has already been stopped. Is it ok to stick to the 'old' method, or is there a better way to do this. Thanks Frank Millman From Bischoop at vimart.net Tue Nov 3 09:06:40 2020 From: Bischoop at vimart.net (Bischoop) Date: Tue, 3 Nov 2020 14:06:40 -0000 (UTC) Subject: Find word by given characters References: <36f4147e-6be4-4f26-f764-f50119046333@DancesWithMice.info> <61beed7c-a0c0-5885-40d1-b6c5de078722@DancesWithMice.info> Message-ID: On 2020-11-03, dn wrote: > > > The (full) specs are not clear. There's certainly room for > misunderstanding. I'd be happier if I could 'see' a full spec or > recognise a practical application, because then we'd be better able to > discuss facts. Meantime, we try to help with what we have been given... > > > The OP's sample code only realises "conforming word[s]" (good term > BTW!). The snippet does not report any "count". Similarly, there's no > facts to avoid ("I assume") an assumption about whether "Letters" may > include duplication - indeed: whether duplication has meaning or should > be regarded as user-error. > Let me clarify what I want to do: We all know Scrabble game. there's a file with Dictionary containing word in each line, the idea is to input some letters for example mentioned earlier: att, the script supposed to find all words in which letters: 'a','t','t' occur and print these words. It supposed not to print word: 'auto' because there's only one 't' but words such as: 'toast', 'toasty', 'tolerant' are meeting the criteria becase we have in these words one 'a' and two 't' as user has input. I've checked collections counter but seems to complicated for me at this stage yet and I'm struggling with applying it. From ben.usenet at bsb.me.uk Tue Nov 3 09:41:39 2020 From: ben.usenet at bsb.me.uk (Ben Bacarisse) Date: Tue, 03 Nov 2020 14:41:39 +0000 Subject: Find word by given characters References: <36f4147e-6be4-4f26-f764-f50119046333@DancesWithMice.info> <61beed7c-a0c0-5885-40d1-b6c5de078722@DancesWithMice.info> Message-ID: <878sbi8puk.fsf@bsb.me.uk> Bischoop writes: > Let me clarify what I want to do: > We all know Scrabble game. > there's a file with Dictionary containing word in each line, the idea is > to input some letters for example mentioned earlier: att, the script > supposed to find all words in which letters: 'a','t','t' occur and print > these words. It supposed not to print word: 'auto' because there's only > one 't' but words such as: 'toast', 'toasty', 'tolerant' are meeting the > criteria becase we have in these words one 'a' and two 't' as user has > input. In Scrabble, you will usually know the order you want for the known letters, so you could just make a regular expression: t.*a.*t In fact, you often know the gaps, so you might even be able to match something more specific like t.a..t instead. If you don't know the order, you can still make a chain of matches. For example, matching for t.*t and then also a. Every distinct letter needs a match, and repeated letters need a single match with .* between them. And since Python REs have (?=...) look ahead syntax you could even make a single pattern like this: (?=.*t.*t)(?=.*a) While there are probably better ways in Python, this is what I'd do on the command line. For example $ grep -P '(?=.*t.*t)(?=.*a)' word-list | wc -l 45677 $ grep 't.*t' word-list | grep a | wc -l 45677 -- Ben. From tjreedy at udel.edu Mon Nov 2 22:04:17 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Mon, 2 Nov 2020 22:04:17 -0500 Subject: Please help test astral char display in tkinter Text (especially *nix) Message-ID: tcl/tk supports unicode chars in the BMP (Basic Multilingual Plane, utf-8 encoded with 1-3 bytes). The presence of chars in other plains ('astral', utf-8 encoded with 4 bytes, I believe) in a tkinter Text widget messages up *editing*, but they can sometimes be displayed with appropriate glyphs. On my Windows 10 64-bit 2004 update, astral code points print as unassigned [X], replaced [], or proper glyphs (see below). On my up-to-date macOS Mohave, as far as I know, no glyphs are actually printed and some hang, freezing IDLE's Shell (and making extensive testing difficult). On Linux, behavior is mixed, including 'crashes', with the use of multicolor rather than black/white fonts apparently an issue. https://bugs.python.org/issue42225. I would like more information about behavior on other systems, especially *nix. The following runs to completion for me, without errors, in about 1 second. tk = True if tk: from tkinter import Tk from tkinter.scrolledtext import ScrolledText root = Tk() text = ScrolledText(root, width=80, height=40) text.pack() def print(txt): text.insert('insert', txt+'\n') errors = [] for i in range(0x10000, 0x40000, 32): chars = ''.join(chr(i+j) for j in range(32)) try: print(f"{hex(i)} {chars}") except Exception as e: errors.append(f"{hex(i)} {e}") print("ERRORS:") for line in errors: print(line) Perhaps half of the assigned chars in the first plane are printed instead of being replaced with a narrow box. This includes emoticons as foreground color outlines on background color. Maybe all of the second plane of extended CJK chars are printed. The third plane is unassigned and prints as unassigned boxes (with an X). If you get errors, how many. If you get a hang or crash, how far did the program get? -- Terry Jan Reedy From pkpearson at nowhere.invalid Tue Nov 3 10:31:44 2020 From: pkpearson at nowhere.invalid (Peter Pearson) Date: 3 Nov 2020 15:31:44 GMT Subject: Best way to determine user's screensize? References: <-4Od9L6qxZ_NGdTB72tL_Lewjt1MpvqqFbDKR0pYEE6Bn1D4GsCqCB2Q102p-O5KtGLJp_mCwEOtC61ceDUsD-PsQ8uw1dXch0Jh89iR6lg=@protonmail.com> Message-ID: On Sun, 1 Nov 2020 15:31:57 -0000 (UTC), Grant Edwards wrote: > > I have no objection to saving the most recent window size and using > that on the next startup, but I hate applications that force the > _location_ of the window. I've configured my window manager to open > windows where I want them opened, please respect that. Hear, hear! This user has invested a lot of time learning how to live comfortably with his window manager. When some upstart app invalidates that knowledge and the corresponding deeply ingrained habits, it's a big annoyance. -- To email me, substitute nowhere->runbox, invalid->com. From duncan at invalid.invalid Tue Nov 3 12:10:23 2020 From: duncan at invalid.invalid (duncan smith) Date: Tue, 3 Nov 2020 17:10:23 +0000 Subject: Find word by given characters In-Reply-To: References: <36f4147e-6be4-4f26-f764-f50119046333@DancesWithMice.info> <61beed7c-a0c0-5885-40d1-b6c5de078722@DancesWithMice.info> Message-ID: <5agoH.205450$6w2.27880@fx44.iad> On 03/11/2020 14:06, Bischoop wrote: > On 2020-11-03, dn wrote: >> >> >> The (full) specs are not clear. There's certainly room for >> misunderstanding. I'd be happier if I could 'see' a full spec or >> recognise a practical application, because then we'd be better able to >> discuss facts. Meantime, we try to help with what we have been given... >> >> >> The OP's sample code only realises "conforming word[s]" (good term >> BTW!). The snippet does not report any "count". Similarly, there's no >> facts to avoid ("I assume") an assumption about whether "Letters" may >> include duplication - indeed: whether duplication has meaning or should >> be regarded as user-error. >> > > Let me clarify what I want to do: > We all know Scrabble game. > there's a file with Dictionary containing word in each line, the idea is > to input some letters for example mentioned earlier: att, the script > supposed to find all words in which letters: 'a','t','t' occur and print > these words. It supposed not to print word: 'auto' because there's only > one 't' but words such as: 'toast', 'toasty', 'tolerant' are meeting the > criteria becase we have in these words one 'a' and two 't' as user has > input. > I've checked collections counter but seems to complicated for me at this > stage yet and I'm struggling with applying it. > >>> from collections import Counter >>> letters = 'att' >>> letter_counts = Counter(letters) >>> word = 'tolerate' >>> wd_counts = Counter(word) >>> for char, cnt in letter_counts.items(): print (cnt == wd_counts[char]) True True >>> word = 'auto' >>> wd_counts = Counter(word) >>> for char, cnt in letter_counts.items(): print (cnt == wd_counts[char]) True False >>> or, equivalent to the above loop, but breaking when the first False is generated and returning the single Boolean that you're after, >>> all(cnt == wd_counts[char] for char, cnt in letter_counts.items()) False >>> There's still a lot of scope for improvement, but possibly not by doing simple things. Duncan From rosuav at gmail.com Tue Nov 3 12:34:51 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 4 Nov 2020 04:34:51 +1100 Subject: Find word by given characters In-Reply-To: References: <36f4147e-6be4-4f26-f764-f50119046333@DancesWithMice.info> <61beed7c-a0c0-5885-40d1-b6c5de078722@DancesWithMice.info> Message-ID: On Wed, Nov 4, 2020 at 1:11 AM Bischoop wrote: > Let me clarify what I want to do: > We all know Scrabble game. > there's a file with Dictionary containing word in each line, the idea is > to input some letters for example mentioned earlier: att, the script > supposed to find all words in which letters: 'a','t','t' occur and print > these words. It supposed not to print word: 'auto' because there's only > one 't' but words such as: 'toast', 'toasty', 'tolerant' are meeting the > criteria becase we have in these words one 'a' and two 't' as user has > input. > I've checked collections counter but seems to complicated for me at this > stage yet and I'm struggling with applying it. This seems strangely backwards for a Scrabble game. Normally you would have a set of available tiles, and you have to form a word using only those tiles, but it doesn't necessarily have to use them all. You seem to have something where you must use all the tiles you have, and may use any number of others. But, no matter; it can be done either way. >>> from collections import Counter >>> Counter("att") <= Counter("toast") True >>> Counter("att") <= Counter("toasty") True >>> Counter("att") <= Counter("tolerant") True >>> Counter("att") <= Counter("auto") False A Counter can behave like a multiset. If you picture the <= operator as being "is a subset of", and then squint a little, irritate your math teacher, and pretend that a set can have more than one of the same thing in it, then a Counter's less-than-or-equal operator will tell you if one multiset is a subset of another. (The normal way to play Scrabble would simply reverse the operands, so you'd ask if the word is <= the tiles you have. It's otherwise exactly the same check.) ChrisA From grant.b.edwards at gmail.com Tue Nov 3 11:38:36 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Tue, 3 Nov 2020 16:38:36 -0000 (UTC) Subject: Solaris 11 GUI framework References: <4597a41c-a317-4b0f-be12-c6c165eb8feen@googlegroups.com> Message-ID: On 2020-11-02, Igor Korot wrote: > On Mon, Nov 2, 2020, 3:57 PM Jay Braun wrote: > >> Looking for a GUI framework supported on Solaris 11. > > Wxpython, pygtk, Java. I wouldn't start a new project with pygtk. It's obsolete (Python2 only) and is no longer supported/available on some platforms. It's been replace by PyGObject https://pygobject.readthedocs.io/en/latest/ Porting from PyGtk to PyGObject is pretty straight-forward, but PyGObject is definitely less "Pythonic". While PyGtk was a hand-crafted set of python bindings for GTK2, PyGObject is sort-of automated based on the standard introspection features of GObject libraries. I've heard this requires a lot less maintenance than the old PyGTK bindings. -- Grant From pablogsal at gmail.com Tue Nov 3 12:46:00 2020 From: pablogsal at gmail.com (Pablo Galindo Salgado) Date: Tue, 3 Nov 2020 17:46:00 +0000 Subject: Fwd: [RELEASE] Python 3.10.0a2 available for testing In-Reply-To: References: Message-ID: The engines of the secret release manager machine have finished producing a new pre-release. Go get it here: https://www.python.org/downloads/release/python-3100a2/ *Major new features of the 3.10 series, compared to 3.9* Python 3.10 is still in development. This releasee, 3.10.0a2 is the second of six planned alpha releases. Alpha releases are intended to make it easier to test the current state of new features and bug fixes and to test the release process. During the alpha phase, features may be added up until the start of the beta phase (2021-05-03) and, if necessary, may be modified or deleted up until the release candidate phase (2021-10-04). Please keep in mind that this is a preview release and its use is not recommended for production environments. Many new features for Python 3.10 are still being planned and written. Among the new major new features and changes so far: PEP 623 -- Remove wstr from Unicode PEP 604 -- Allow writing union types as X | Y PEP 612 -- Parameter Specification Variables PEP 626 -- Precise line numbers for debugging and other tools. (Hey, fellow core developer, if a feature you find important is missing from this list, let Pablo know.) The next pre-release of Python 3.10 will be 3.10.0a3, currently scheduled for 2020-12-07. *And now for something completely different * The cardinality (the number of elements) of infinite sets can be one of the most surprising results of set theory. For example, there are the same amount of even natural numbers than natural numbers (which can be even or odd). There is also the same amount of rational numbers than natural numbers. But on the other hand, there are more real numbers between 0 and 1 than natural numbers! All these sets have infinite cardinality but turn out that some of these infinities are bigger than others. These infinite cardinalities normally are represented using aleph numbers. Infinite sets are strange beasts indeed. Regards from cold London, Pablo Galindo Salgado From dieter at handshake.de Tue Nov 3 13:30:55 2020 From: dieter at handshake.de (Dieter Maurer) Date: Tue, 3 Nov 2020 19:30:55 +0100 Subject: Post request and encoding In-Reply-To: <2680c348-d274-783c-0023-0b0a7b349587@gmail.com> References: <2680c348-d274-783c-0023-0b0a7b349587@gmail.com> Message-ID: <24481.41439.675854.964236@ixdm.fritz.box> Hern?n De Angelis wrote at 2020-11-2 10:06 +0100: > ... >My request has the form: > >header = {'Content-type':'application/xml', 'charset':'utf-8'} Not your problem (which you have already resolved) but: `charset` is not an individual header but a parameter for the `Content-Type` header. For `xml` `utf-8` is the default charset. From david_burnette at mentor.com Tue Nov 3 15:11:29 2020 From: david_burnette at mentor.com (David Burnette) Date: Tue, 3 Nov 2020 12:11:29 -0800 (PST) Subject: Strange terminal behavior after quitting Tkinter application In-Reply-To: <1176881604.574369.77230@b58g2000hsg.googlegroups.com> References: <1176881604.574369.77230@b58g2000hsg.googlegroups.com> Message-ID: <871fd9d2-a00c-4263-b43b-ef8276040748n@googlegroups.com> On Wednesday, April 18, 2007 at 12:33:24 AM UTC-7, Chris wrote: > Hi, > I'm puzzled by some strange behavior when my Python/Tkinter > application quits (on linux): the terminal from which I started Python > is messed up. > If start up python, then import the code below, then start the program > with Application(), then click the Quit button, my terminal never > prints anything again (such as commands I type). > > import Tkinter > import sys > class Application(Tkinter.Tk): > def __init__(self,**config): > Tkinter.Tk.__init__(self,**config) > > Tkinter.Button(self,text="Quit",command=self.quit_application).pack() > def quit_application(self): > sys.exit() > > > Can anyone tell me what I'm doing wrong? > Thanks for your help. > Chris I notice this same behavior with other tk applications like "tkdiff". So what is the correct cleanup for a proper exit from a plain Tk application? From avigross at verizon.net Tue Nov 3 17:14:22 2020 From: avigross at verizon.net (Avi Gross) Date: Tue, 3 Nov 2020 17:14:22 -0500 Subject: Find word by given characters In-Reply-To: References: <36f4147e-6be4-4f26-f764-f50119046333@DancesWithMice.info> <61beed7c-a0c0-5885-40d1-b6c5de078722@DancesWithMice.info> Message-ID: <04c701d6b22e$af0f65f0$0d2e31d0$@verizon.net> I, too, have wondered what exactly the point was of the required functionality for SCRABBLE but note you can extend a current word so additional letters may be available in a game but only if they are an exact fit to put before, after, or in middle of your word. But this seems to be a fairly simple problem to solve unless I misunderstand it. Elegance aside, what would be wrong with this approach. - Read a word at a time in a loop from the file of dictionary words (non-Python meaning of dictionary.) For each one do the following, perhaps using a function: Break the current word into a list of individual letters. Loop over the letters you want and: If the letter is in the list, remove it and continue Else skip the current word as it is not a match. At the end of each of the above loops, you only reached here if all the letters were found and removed. If the list is now empty, fine. If it has extra remaining letters, also fine by the requirements stated. Letters in the list multiple times are removed multiple times. The above need not use list of letters and can be done many other ways but seems conceptually simple. Each word is processed once. It can be converted to using a list comprehension or something similar by using "all" and so on. Or am I missing something about other approaches being better or more efficient or ... And, yes, counting may have an advantage as the list does not need to be modified repeatedly but creating an object or three also has overhead. -----Original Message----- From: Python-list On Behalf Of Chris Angelico Sent: Tuesday, November 3, 2020 12:35 PM To: Python Subject: Re: Find word by given characters On Wed, Nov 4, 2020 at 1:11 AM Bischoop wrote: > Let me clarify what I want to do: > We all know Scrabble game. > there's a file with Dictionary containing word in each line, the idea > is to input some letters for example mentioned earlier: att, the > script supposed to find all words in which letters: 'a','t','t' occur > and print these words. It supposed not to print word: 'auto' because > there's only one 't' but words such as: 'toast', 'toasty', 'tolerant' > are meeting the criteria becase we have in these words one 'a' and two > 't' as user has input. > I've checked collections counter but seems to complicated for me at > this stage yet and I'm struggling with applying it. This seems strangely backwards for a Scrabble game. Normally you would have a set of available tiles, and you have to form a word using only those tiles, but it doesn't necessarily have to use them all. You seem to have something where you must use all the tiles you have, and may use any number of others. But, no matter; it can be done either way. >>> from collections import Counter >>> Counter("att") <= Counter("toast") True >>> Counter("att") <= Counter("toasty") True >>> Counter("att") <= Counter("tolerant") True >>> Counter("att") <= Counter("auto") False A Counter can behave like a multiset. If you picture the <= operator as being "is a subset of", and then squint a little, irritate your math teacher, and pretend that a set can have more than one of the same thing in it, then a Counter's less-than-or-equal operator will tell you if one multiset is a subset of another. (The normal way to play Scrabble would simply reverse the operands, so you'd ask if the word is <= the tiles you have. It's otherwise exactly the same check.) ChrisA -- https://mail.python.org/mailman/listinfo/python-list From Bischoop at vimart.net Tue Nov 3 18:27:42 2020 From: Bischoop at vimart.net (Bischoop) Date: Tue, 3 Nov 2020 23:27:42 -0000 (UTC) Subject: Find word by given characters References: <36f4147e-6be4-4f26-f764-f50119046333@DancesWithMice.info> <61beed7c-a0c0-5885-40d1-b6c5de078722@DancesWithMice.info> Message-ID: On 2020-11-03, Chris Angelico wrote: > > This seems strangely backwards for a Scrabble game. Normally you would > have a set of available tiles, and you have to form a word using only > those tiles, but it doesn't necessarily have to use them all. You seem > to have something where you must use all the tiles you have, and may > use any number of others. But, no matter; it can be done either way. > I know, it's useless I just came to idea to do something when was learning, now I remembered long time ago I've done it somehow with list and len() probably, this time I came to idea to rewrite using count. But it seems I'm crap and takes me hell a lot of time to get on it. From Bischoop at vimart.net Tue Nov 3 18:35:44 2020 From: Bischoop at vimart.net (Bischoop) Date: Tue, 3 Nov 2020 23:35:44 -0000 (UTC) Subject: Find word by given characters References: <36f4147e-6be4-4f26-f764-f50119046333@DancesWithMice.info> <61beed7c-a0c0-5885-40d1-b6c5de078722@DancesWithMice.info> <5agoH.205450$6w2.27880@fx44.iad> Message-ID: On 2020-11-03, duncan smith wrote: >> > >>>> from collections import Counter >>>> letters = 'att' >>>> letter_counts = Counter(letters) >>>> word = 'tolerate' >>>> wd_counts = Counter(word) >>>> for char, cnt in letter_counts.items(): > print (cnt == wd_counts[char]) > > > True > True >>>> word = 'auto' >>>> wd_counts = Counter(word) >>>> for char, cnt in letter_counts.items(): > print (cnt == wd_counts[char]) > > > True > False >>>> > > or, equivalent to the above loop, but breaking when the first False is > generated and returning the single Boolean that you're after, > >>>> all(cnt == wd_counts[char] for char, cnt in letter_counts.items()) > False >>>> > > There's still a lot of scope for improvement, but possibly not by doing > simple things lol I'm thinking about it for a couple days and you guys coming with few ideas to it like it's nothing. Pity I've wasted a decade with woman, now probably to old to learn anything new. From PythonList at DancesWithMice.info Tue Nov 3 18:48:47 2020 From: PythonList at DancesWithMice.info (dn) Date: Wed, 4 Nov 2020 12:48:47 +1300 Subject: Find word by given characters In-Reply-To: References: <36f4147e-6be4-4f26-f764-f50119046333@DancesWithMice.info> <61beed7c-a0c0-5885-40d1-b6c5de078722@DancesWithMice.info> Message-ID: <798e9903-2996-94c1-38e8-68dc01534769@DancesWithMice.info> On 04/11/2020 12:27, Bischoop wrote: > On 2020-11-03, Chris Angelico wrote: >> >> This seems strangely backwards for a Scrabble game. Normally you would >> have a set of available tiles, and you have to form a word using only >> those tiles, but it doesn't necessarily have to use them all. You seem >> to have something where you must use all the tiles you have, and may >> use any number of others. But, no matter; it can be done either way. >> > > I know, it's useless I just came to idea to do something when was > learning, now I remembered long time ago I've done it somehow with list > and len() probably, this time I came to idea to rewrite using count. But > it seems I'm crap and takes me hell a lot of time to get on it. Don't beat yourself up about it. As you have already noted, it is difficult for an 'apprentice' to know things (s)he has yet to learn - and that was related to Python-language features. On top of that, it is another difficult and quite different skill to write a specification which is accurate, complete, and meaningful to coders... Do I recall that you are 'coming back' to Python, and as an hobbyist? Rather than setting your own specs, why not work from those set by others? If you want to learn the Python language, and especially if you also mean 'programming' as an art?science, why not add some structure and follow a text-book or an on-line course? For example, Dr Chuck's (famous and long-standing) courses and other U.Mich offerings are available from https://www.coursera.org/search?query=python& (624 'hits'!). You will find similar (perhaps I notice a DataScience/ML bias?) on edx.org (https://www.edx.org/search?q=python&tab=course) Your thoughts? Disclaimer: I train from the edX platform - but not in Python. -- Regards =dn From python at mrabarnett.plus.com Tue Nov 3 19:51:00 2020 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 4 Nov 2020 00:51:00 +0000 Subject: Strange terminal behavior after quitting Tkinter application In-Reply-To: <871fd9d2-a00c-4263-b43b-ef8276040748n@googlegroups.com> References: <1176881604.574369.77230@b58g2000hsg.googlegroups.com> <871fd9d2-a00c-4263-b43b-ef8276040748n@googlegroups.com> Message-ID: On 2020-11-03 20:11, David Burnette wrote: > On Wednesday, April 18, 2007 at 12:33:24 AM UTC-7, Chris wrote: >> Hi, >> I'm puzzled by some strange behavior when my Python/Tkinter >> application quits (on linux): the terminal from which I started Python >> is messed up. >> If start up python, then import the code below, then start the program >> with Application(), then click the Quit button, my terminal never >> prints anything again (such as commands I type). >> >> import Tkinter >> import sys >> class Application(Tkinter.Tk): >> def __init__(self,**config): >> Tkinter.Tk.__init__(self,**config) >> >> Tkinter.Button(self,text="Quit",command=self.quit_application).pack() >> def quit_application(self): >> sys.exit() >> >> >> Can anyone tell me what I'm doing wrong? >> Thanks for your help. >> Chris > > I notice this same behavior with other tk applications like "tkdiff". > So what is the correct cleanup for a proper exit from a plain Tk application? > Updated to Python 3, it should be more like this: import tkinter import sys class Application(tkinter.Tk): def __init__(self,**config): tkinter.Tk.__init__(self, **config) tkinter.Button(self, text="Quit", command=self.quit_application).pack() def quit_application(self): self.destroy() Application().mainloop() From duncan at invalid.invalid Tue Nov 3 20:34:43 2020 From: duncan at invalid.invalid (duncan smith) Date: Wed, 4 Nov 2020 01:34:43 +0000 Subject: Find word by given characters In-Reply-To: References: <36f4147e-6be4-4f26-f764-f50119046333@DancesWithMice.info> <61beed7c-a0c0-5885-40d1-b6c5de078722@DancesWithMice.info> <5agoH.205450$6w2.27880@fx44.iad> Message-ID: On 03/11/2020 23:35, Bischoop wrote: > On 2020-11-03, duncan smith wrote: >>> >> >>>>> from collections import Counter >>>>> letters = 'att' >>>>> letter_counts = Counter(letters) >>>>> word = 'tolerate' >>>>> wd_counts = Counter(word) >>>>> for char, cnt in letter_counts.items(): >> print (cnt == wd_counts[char]) >> >> >> True >> True >>>>> word = 'auto' >>>>> wd_counts = Counter(word) >>>>> for char, cnt in letter_counts.items(): >> print (cnt == wd_counts[char]) >> >> >> True >> False >>>>> >> >> or, equivalent to the above loop, but breaking when the first False is >> generated and returning the single Boolean that you're after, >> >>>>> all(cnt == wd_counts[char] for char, cnt in letter_counts.items()) >> False >>>>> >> >> There's still a lot of scope for improvement, but possibly not by doing >> simple things > > > lol > > I'm thinking about it for a couple days and you guys coming with few > ideas to it like it's nothing. > Pity I've wasted a decade with woman, now probably to old to learn > anything new. > It looks like you've learnt something about wasting time with women ;-). Keep tinkering as long as you're enjoying it (or getting paid for it) and pick up knowledge of relevant data structures and algorithms as you go. (That's what I've done. I'm actually a statistician.) The above solution uses bags (implemented in Python as Counter instances), and the (repeated) generation of the letters bag was hoisted outside the for loop. (If the dictionary was going to be searched for multiple sets of letters the generation of the word bags would also be hoisted.) There's also the idea of breaking out of the loop once the first False is generated (implemented most neatly by using all). So there might be something useful to take from it. A bag was the obvious data structure because the solution depends only on the unique characters in a string and their frequencies. But that's thinking about the problem word by word. We actually have a dictionary of words, and a dictionary can be structured so that it can be searched much more efficiently than 'word by word'. The particular data structure I have in mind is not (yet) in the standard Python library. That's maybe worth looking at when you've got the word by word approach grokked. Duncan From qberz2005 at gmail.com Tue Nov 3 20:32:53 2020 From: qberz2005 at gmail.com (Quentin Bock) Date: Tue, 3 Nov 2020 20:32:53 -0500 Subject: Help Message-ID: So, I'm newer to Python and I'm messing around with math functions and multiplication, etc. here is my line of code: def multiply(numbers): total = 1 for x in numbers: total *= x return total print(multiply((8, 2, 3, -1, 7))) When I run this, my answer is 8 but it should be 336 can some help ._. From skip.montanaro at gmail.com Tue Nov 3 20:57:16 2020 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Tue, 3 Nov 2020 19:57:16 -0600 Subject: Help In-Reply-To: References: Message-ID: > > When I run this, my answer is 8 but it should be 336 can some help ._. > Looks like you are returning from inside the loop. Skip > From grant.b.edwards at gmail.com Tue Nov 3 21:29:56 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Wed, 4 Nov 2020 02:29:56 -0000 (UTC) Subject: Help References: Message-ID: On 2020-11-04, Quentin Bock wrote: > So, I'm newer to Python and I'm messing around with math functions and > multiplication, etc. here is my line of code: > > def multiply(numbers): > total = 1 > for x in numbers: > total *= x > return total > print(multiply((8, 2, 3, -1, 7))) > > When I run this, my answer is 8 but it should be 336 can some help ._. 1. If you're using tabs to indent; don't. It results in hard-to diagnose problems. Use spaces to indent. 2. Cut/past the exact code when asking questions. The code you posted does not print 8. It doesn't run at all: $ cat bar.py def multiply(numbers): total = 1 for x in numbers: total *= x return total print(multiply((8, 2, 3, -1, 7))) $ python bar.py File "bar.py", line 3 for x in numbers: ^ IndentationError: unexpected indent 3. The answer you want is not 336, it's -336: $ cat foo.py def multiply(numbers): total = 1 for x in numbers: total *= x return total print(multiply((8,2,3,-1,7))) $ python foo.py -336 4. I suspect that your actual code looks like this: $ cat foo.py def multiply(numbers): total = 1 for x in numbers: total *= x return total print(multiply((8,2,3,-1,7))) $ python foo.py 8 See the difference between #3 and #4? From duncan at invalid.invalid Tue Nov 3 21:33:09 2020 From: duncan at invalid.invalid (duncan smith) Date: Wed, 4 Nov 2020 02:33:09 +0000 Subject: Find word by given characters In-Reply-To: References: <36f4147e-6be4-4f26-f764-f50119046333@DancesWithMice.info> <61beed7c-a0c0-5885-40d1-b6c5de078722@DancesWithMice.info> <04c701d6b22e$af0f65f0$0d2e31d0$@verizon.net> Message-ID: On 03/11/2020 22:14, Avi Gross wrote: > I, too, have wondered what exactly the point was of the required > functionality for SCRABBLE but note you can extend a current word so > additional letters may be available in a game but only if they are an exact > fit to put before, after, or in middle of your word. > > But this seems to be a fairly simple problem to solve unless I misunderstand > it. Elegance aside, what would be wrong with this approach. > > - Read a word at a time in a loop from the file of dictionary words > (non-Python meaning of dictionary.) For each one do the following, perhaps > using a function: > > Break the current word into a list of individual letters. > Loop over the letters you want and: > If the letter is in the list, remove it and continue > Else skip the current word as it is not a match. > > At the end of each of the above loops, you only reached here if all the > letters were found and removed. If the list is now empty, fine. If it has > extra remaining letters, also fine by the requirements stated. Letters in > the list multiple times are removed multiple times. > > The above need not use list of letters and can be done many other ways but > seems conceptually simple. Each word is processed once. It can be converted > to using a list comprehension or something similar by using "all" and so on. > > Or am I missing something about other approaches being better or more > efficient or ... And, yes, counting may have an advantage as the list does > not need to be modified repeatedly but creating an object or three also has > overhead. [snip] The Counter approach only requires iterating over the letters once to construct the letters bag, then each word once to create the relevant word bag. After that it's (at worst) a couple of lookups and a comparison for each unique character in letters (for each word). Your approach requires iteration over the words to create the lists of characters. Then they are (potentially) iterated over multiple times looking for the characters in letters. There's also the cost of removing items from arbitrary positions in the lists. Also, it seems that the character frequencies must be equal, and your approach only ensures that the words contain at least the required numbers of characters. In computational terms, if the first approach is something like O(n+m) for n letters and words of length m, your algorithm is more like O(nm). Not to say that it will be slower for all possible letters and dictionaries, but probably for any realistic cases and a lot slower for large enough dictionaries. Duncan From avigross at verizon.net Tue Nov 3 23:21:43 2020 From: avigross at verizon.net (Avi Gross) Date: Tue, 3 Nov 2020 23:21:43 -0500 Subject: Find word by given characters In-Reply-To: References: <36f4147e-6be4-4f26-f764-f50119046333@DancesWithMice.info> <61beed7c-a0c0-5885-40d1-b6c5de078722@DancesWithMice.info> <04c701d6b22e$af0f65f0$0d2e31d0$@verizon.net> Message-ID: <088301d6b262$00d1b1d0$02751570$@verizon.net> Duncan, my comments below yours at end. ---YOURS--- The Counter approach only requires iterating over the letters once to construct the letters bag, then each word once to create the relevant word bag. After that it's (at worst) a couple of lookups and a comparison for each unique character in letters (for each word). Your approach requires iteration over the words to create the lists of characters. Then they are (potentially) iterated over multiple times looking for the characters in letters. There's also the cost of removing items from arbitrary positions in the lists. Also, it seems that the character frequencies must be equal, and your approach only ensures that the words contain at least the required numbers of characters. In computational terms, if the first approach is something like O(n+m) for n letters and words of length m, your algorithm is more like O(nm). Not to say that it will be slower for all possible letters and dictionaries, but probably for any realistic cases and a lot slower for large enough dictionaries. Duncan --MINE--- I appreciate your analysis. I have not looked at the "counter" implementation and suspect it does some similar loops within, albeit it may be implemented in a compiled language like C++. I did not write out my algorithm in Python but have done it for myself. It runs fast enough with most of the time spent in the slow I/O part. We can agree all algorithms have to read in all the words in a data file. There may be ways to store the data such as in a binary tree and even ways to thus prune the search as once a node is reached where all required letters have been found, all further words qualify below that point. If you match say "instant" then instants and instantiation would be deeper in the tree and also qualify assuming extra letters are allowed. We may differ on the requirement as I think that the number of repeats for something like a,t,t require to be at least as big as in "attend" but that "attention" with yet another "t" would also be OK. If I am wrong, fine, but I note the person requesting this has admitted a certain lack of credentials while also claiming he made up a scenario just for fun. So this is not actually a particularly worthy challenge let alone with a purpose. My impression is that the average word length would be something small like 5-7. The number of words in a dictionary might be 100,000 or more. So if you want efficiency, where do you get the bang for the buck? I would argue that a simple test run on all the words might often narrow the field to a much smaller number of answers like just a few thousand or even much less. Say you test for the presence of "aeiou" in words, in whatever order. That might be done from reading a file and filtering out a relatively few potential answers. You can save those for second round to determine if they are fully qualified by any additional rules that may involve more expensive operations. How fast (or slow) are regular expressions for this purpose? Obviously it depends on complexity and something like "^[^aeiou]*[aeiou] [^aeiou]*[aeiou] [^aeiou]*[aeiou] [^aeiou]*[aeiou] [^aeiou]*[aeiou] [^aeiou]*$" would be easy to construct once but likely horribly inefficient in searching and a bit of overkill here. I suspect there is already some simple C function that could be used from within python that looks like findall(choices, word) that might return how many of the letters in choices were found in word and you simply comparer that to length(word) perhaps more efficiently. It looks easier to check if a character exists in one of the ways already discussed within python using a loop as discussed. Something as simple as this: needed = "aeiou" trying = "education" found = all([trying.find(each) >= 0 for each in needed ]) print(found) trying = "educated" found = all([trying.find(each) >= 0 for each in needed ]) print(found) The above prints My point is you can use the above to winnow down possible answers and only subject that smaller number to one of many tests including using a counter, making a dictionary you can query (albeit probably slower for fairly short words) and so on. Back to your other point, you suggest iterating over characters ( I happened to do it in a list) multiple times can result in duplication as the same characters are searched repeatedly. Sure. I simply note most words are short. How much overhead is there searching for say nine characters five times? Compare that to say creating a dictionary or other data structure once, and then making a hash out of each letter being searched for? I can envision many possible ways to speed this up but many involve more use of memory or all other kinds of overhead such as initializing an object and calling various member functions and then deleting it or re-initializing it. My suggestion of removing items from a short list is not ideal and depending on how a bag was otherwise implemented, I could see it being better but again, how much is saved if you have a nine letter word that may contain nine unique letters or even have repeated letters as in banana? You end up saving a copy of the letter (or a hashed version) plus some integer value (perhaps just a byte) for the count. I would need to see the implementation and do some speed tests, ... In real programming, there are many choices. This is a bit of a hypothetical but a part of me suggests the best answer for a quick prototype is something simple and not necessarily tuned for speed, just to show it can be done. Then, if the code is used often and is slow, sure, enhance it. Back in my UNIX days, I might have started with a rather inefficient pipeline for my example like: grep 'a' filename | grep 'e' | grep 'i' | grep 'o' | grep 'u' | ... That would produce a list of candidates, again not efficiently. I might have switched to using better regular expressions, perhaps using sed instead, or AWK or even PERL. But if it had to be fast production code, I might have used C then C++ or whatever latest tool I had. These days, some things run so fast that we get lazy. When doing a pipelined approach in R or Python that analyzes data, I often effectively have to apply a set of conditions to lots of data, one after another. Do you trim the number of columns in a data frame first or do you apply a condition that trims the number of rows first? Clearly if you need 5 columns out of 666, then chances are you narrow the columns so there is less useless copying in later parts of the pipeline. . But what if you have multiple conditions that each remove some rows and it depends on what the data looks like? For example, remove all rows in which one variable is NA and also all rows where another two variables are not equal to each other and so on. Isn't part of the consideration how expensive each comparison is? Imagine if you want to remove rows where a word in one column is not in the scrabble dictionary and your stupid function has to read it in each and every time! I would want that to be done last after cheaper methods removed say all words longer than 10 characters or that had uppercase or numeric parts or spaces or were NA. So if the functionality in the topic above was really being built, and the functionality was being called repeatedly as some game progressed, you definitely might want to speed it up, if nothing else, by reading the dictionary file into memory once, perhaps into a data structure like a modified binary tree which could be searched with tail recursion or short-cuts. And in some cases, you might even want odd things like to cache the results of earlier queries in a dictionary and skip a full repeat search entirely. You might argue this situation always gets called with different arguments. Perhaps but imagine writing a program where the computer plays against a human. The computer might look at every open region of a scrabble board and take the tiles already in their "hand" and add zero or more tiles indicating characters already on the game board that it wanted to extend into or beyond. Say it sees the letter "r" and wonders if it could place all letters immediately to the left of that "r" and then to see if the "r" could be in multiple places within the word formed and finally if it could make a word starting with "r". That could be multiple identical calls, perhaps only differing in the order of the characters it is searching for. And it might repeat similar calls in another part of the board that has a dangling "r", perhaps the same one it did not use before. Obviously, the goal here would be to find all potentially possible words it could actually fit into that slot so further analysis would happen and it would investigate which method provided more points. It may even look ahead to see if that move allowed the opponent a better-countermove and so on into deeper analyses. Much of the expense of deciding what to actually do would be outside the functionality described. Admittedly, I see no reason for it to actually ask for these words as described that could be longer, but only proper permutations of the letters. My point is I can envision places where caching earlier results would be potentially a great speedup. Heck, I suggest the problem could be turned around as the number of combinations might be computed and simply tested to see if they exist in a Python dictionary made from the external dictionary. Heck, why even write the main routine in an interpreted language when you can link in a function written to be even more efficient? But enhancements like that come with a cost. Would you pay a programmer an extra month to speed something like that up 5%? Maybe, but often not. And if you add in the typical costs in a large organization of various kinds of testing needed for a more complex or subtle approach, ... Avi From auriocus at gmx.de Wed Nov 4 01:34:24 2020 From: auriocus at gmx.de (Christian Gollwitzer) Date: Wed, 4 Nov 2020 07:34:24 +0100 Subject: Strange terminal behavior after quitting Tkinter application In-Reply-To: References: <1176881604.574369.77230@b58g2000hsg.googlegroups.com> <871fd9d2-a00c-4263-b43b-ef8276040748n@googlegroups.com> <7mm3qflnt9citn98gab0aihfr68qrl6m0l@4ax.com> Message-ID: Am 03.11.20 um 23:34 schrieb Dennis Lee Bieber: > > Out of curiosity, does Python on Linux honor the .pyw extension? > > On Windows, .pyw indicates a Python program that implements a GUI and > will NOT make use of console (stdin/stdout/stderr). On Linux, there is no such distinction. On Windows it is only needed because, if you connect stdin/out, a terminal window pops up. >For a true GUI program that is notr acceptable, the user will be puzzled what this ugly useless window wants to do, and therefore a flag in the EXE file format indicates to Windows if it should pop up the console or not. On Linux, stdin/out is always connected. You must run your program from a terminal window to see it, otherwise it is silently connected to some channel in the background by the desktop environment. It can happen that the standard channels are closed, if you run a program in the terminal and then close the terminal (which sends SIGHUP to the program). In this case the program might later on throw I/O errors, when printing to stdout. Christian From aeros167 at gmail.com Wed Nov 4 01:36:53 2020 From: aeros167 at gmail.com (Kyle Stanley) Date: Wed, 4 Nov 2020 01:36:53 -0500 Subject: asyncio question In-Reply-To: References: Message-ID: On Tue, Nov 3, 2020 at 3:27 AM Frank Millman wrote: > It works, and it does look neater. But I want to start some background > tasks before starting the server, and cancel them on Ctrl+C. > > Using the 'old' method, I can wrap 'loop.run_forever()' in a > try/except/finally, check for KeyboardInterrupt, and run my cleanup in > the 'finally' block. > > Using the 'new' method, KeyboardInterrupt is not caught by > 'server.serve_forever()' but by 'asyncio.run()'. It is too late to do > any cleanup at this point, as the loop has already been stopped. > > Is it ok to stick to the 'old' method, or is there a better way to do this. > It's fine to stick with the older method in your case, as there's nothing inherently wrong with continuing to use it. `asyncio.run()` is largely a convenience function that takes care of some finalization/cleanup steps that are often forgotten (cancelling remaining tasks, closing event loop's default ThreadPoolExecutor, closing async generators, etc). If you want to use custom KeyboardInterrupt handling and still use asyncio.run(), you can either (a) use `loop.add_signal_handler()` or (b) make a slightly modified local version of `asyncio.run()` that has your desired KeyboardInterrupt behavior, based roughly on https://github.com/python/cpython/blob/master/Lib/asyncio/runners.py. However, using `loop.run_until_complete()` instead of `asyncio.run()` is also perfectly fine, especially in existing code that still works without issue. It just leaves the author with a bit more responsibility when it comes to resource finalization and dealing with the event loop in general (which can add some extra cognitive burden and room for error, particularly when dealing with multiple event loops or threads). But it's reasonably common to continue using `loop.run_until_complete()` in situations where the default `asyncio.run()` behavior isn't what you need/want, such as your case. From variablestarlight at gmail.com Wed Nov 4 02:46:01 2020 From: variablestarlight at gmail.com (=?UTF-8?Q?Hern=c3=a1n_De_Angelis?=) Date: Wed, 4 Nov 2020 08:46:01 +0100 Subject: Post request and encoding In-Reply-To: <24481.41439.675854.964236@ixdm.fritz.box> References: <2680c348-d274-783c-0023-0b0a7b349587@gmail.com> <24481.41439.675854.964236@ixdm.fritz.box> Message-ID: <80ffb913-951a-a4f2-3053-4c311c1294cc@gmail.com> I see. Should be "encoding". Thanks. /H. On 2020-11-03 19:30, Dieter Maurer wrote: > Hern?n De Angelis wrote at 2020-11-2 10:06 +0100: >> ... >> My request has the form: >> >> header = {'Content-type':'application/xml', 'charset':'utf-8'} > Not your problem (which you have already resolved) but: > `charset` is not an individual header but a parameter > for the `Content-Type` header. For `xml` `utf-8` is the default charset. From ankurimt01 at gmail.com Tue Nov 3 22:55:47 2020 From: ankurimt01 at gmail.com (ankur gupta) Date: Wed, 4 Nov 2020 09:25:47 +0530 Subject: Seeking guidance to start a career in python programming Message-ID: Good Morning to All, My name is Ankur Gupta and I wish to seek guidance from you. I belong to a non-computer science background but have always been attracted to this field. I had computer science in class 12th (Where I learned C++ and Python) but I did Mechanical Engineering instead in college. I wish to pursue a career in Python programming and therefore undertook 2 online certification courses in python but besides this, my progress is almost stalled. Request you all to please guide how I can move forward with my current learning of the language and also steps that I can take to pursue a career in this field. Once again thanks to you all for your time and consideration and I look forward to your response Regards Ankur Gupta From info at cmcc.it Wed Nov 4 02:06:00 2020 From: info at cmcc.it (info cmcc) Date: Wed, 4 Nov 2020 08:06:00 +0100 Subject: Frontend Developer | Job position at CMCC Foundation, Italy In-Reply-To: References: Message-ID: *Please, feel free to circulate **to anyone you think may be interested.* -- *Frontend Developer (code 12294)* *Deadline: 10/11/2020* The CMCC is taking into consideration the possibility to hire a talented, motivated and proactive Frontend Developer to support the digital ocean applications. This job announcement is a public invitation to express interest for the above mentioned CMCC Position. The location is *CMCC Headquarters in Lecce, Italy*. The primary purpose for this position is to support both the research and operational activities of the OPA division. The desired, mandatory qualifications are: - M.Sc. degree (or candidate for graduation in the next couple of months) or equivalent working experience in Computer Science, Engineering; - web services and web application development; - REST api; - HTML and CSS (with cross-browser development); - JavaScript frameworks (jQuery, ReactJS); - Modern authorization mechanisms, such as JSON Web Token; - Programming languages (such as Python or Java) - Version Control Management Systems - Fluency in the English language Furthermore, it is welcome to have as much as possible of the following experience: - UNIX/Linux operating systems and script; - authorization mechanisms, such as JSON Web TokenFds; - Web Feature Service (WFS), Web Map Service (WMS), Web GIS; - DBMS (mySQL); - mobile applications languages; - Object-oriented design and developmental skills; - Platforms for publishing spatial data and interactive mapping applications to the web (i.e. MapServer); - experience in managing/manipulating NetCDF data. Belonging to legally protected categories (ex L. 68/99) will constitute a preferential condition. The initial appointment is for 24 months starting as soon as possible at an annual salary ranging from 24 to 36K Euros for Junior Research Associates and from 32 to 50K Euros for Senior Research Associates, comprehensive of benefits, depending on qualification and experience. *APPLY NOW: **https://cmccfoundation.applytojob.com/apply/ABzlrQovtP/Frontend-Developer * -- Fondazione CMCCCentro Euro-Mediterraneo sui Cambiamenti Climatici Via Augusto Imperatore, 16 - 73100 Lecce info at cmcc.it - www.cmcc.it From mennoholscher at gmail.com Wed Nov 4 07:47:59 2020 From: mennoholscher at gmail.com (Menno Holscher) Date: Wed, 4 Nov 2020 13:47:59 +0100 Subject: Please help test astral char display in tkinter Text (especially *nix) In-Reply-To: References: Message-ID: Op 03-11-2020 om 04:04 schreef Terry Reedy: > Perhaps half of the assigned chars in the first plane are printed > instead of being replaced with a narrow box. This includes emoticons as > foreground color outlines on background color.? Maybe all of the second > plane of extended CJK chars are printed.? The third plane is unassigned > and prints as unassigned boxes (with an X). > > If you get errors, how many.? If you get a hang or crash, how far did > the program get? > openSuse Linux 15.2 Leap, Python 3.6.10, tcl and tk 8.6.7 The program runs fine, but complains in the text scrollbox: 0x10000 character U+10000 is above the range (U+0000-U+FFFF) allowed by Tcl until 0x3ffe0 character U+3ffe0 is above the range (U+0000-U+FFFF) allowed by Tcl Menno H?lscher From duncan at invalid.invalid Wed Nov 4 13:09:19 2020 From: duncan at invalid.invalid (duncan smith) Date: Wed, 4 Nov 2020 18:09:19 +0000 Subject: Find word by given characters In-Reply-To: References: <36f4147e-6be4-4f26-f764-f50119046333@DancesWithMice.info> <61beed7c-a0c0-5885-40d1-b6c5de078722@DancesWithMice.info> <04c701d6b22e$af0f65f0$0d2e31d0$@verizon.net> <088301d6b262$00d1b1d0$02751570$@verizon.net> Message-ID: On 04/11/2020 04:21, Avi Gross wrote: > Duncan, my comments below yours at end. > > ---YOURS--- > The Counter approach only requires iterating over the letters once to > construct the letters bag, then each word once to create the relevant word > bag. After that it's (at worst) a couple of lookups and a comparison for > each unique character in letters (for each word). > > Your approach requires iteration over the words to create the lists of > characters. Then they are (potentially) iterated over multiple times looking > for the characters in letters. There's also the cost of removing items from > arbitrary positions in the lists. Also, it seems that the character > frequencies must be equal, and your approach only ensures that the words > contain at least the required numbers of characters. > > In computational terms, if the first approach is something like O(n+m) for n > letters and words of length m, your algorithm is more like O(nm). > Not to say that it will be slower for all possible letters and dictionaries, > but probably for any realistic cases and a lot slower for large enough > dictionaries. > > Duncan > > --MINE--- > > I appreciate your analysis. I have not looked at the "counter" > implementation and suspect it does some similar loops within, albeit it may > be implemented in a compiled language like C++. > Before the introduction of counters I would have used a dict to create a mapping of characters to counts. That would require iterating over the characters in a string only once to create / update the dict entries, and I doubt counters are implemented less efficiently than that. > I did not write out my algorithm in Python but have done it for myself. It > runs fast enough with most of the time spent in the slow I/O part. > > We can agree all algorithms have to read in all the words in a data file. > There may be ways to store the data such as in a binary tree and even ways > to thus prune the search as once a node is reached where all required > letters have been found, all further words qualify below that point. If you > match say "instant" then instants and instantiation would be deeper in the > tree and also qualify assuming extra letters are allowed. I don't see how a binary tree would be useful. As I've pointed out in another post, there are other data structures that could be useful. What I had in mind was a trie (prefix tree). But it's only the distinct characters and frequencies that are relevant and so I'd exploit that (and one or two other things) to reduce space and improve search. We may differ on > the requirement as I think that the number of repeats for something like > a,t,t require to be at least as big as in "attend" but that "attention" with > yet another "t" would also be OK. If I am wrong, fine, but I note the person > requesting this has admitted a certain lack of credentials while also > claiming he made up a scenario just for fun. So this is not actually a > particularly worthy challenge let alone with a purpose. > > My impression is that the average word length would be something small like > 5-7. The number of words in a dictionary might be 100,000 or more. So if you > want efficiency, where do you get the bang for the buck? > > I would argue that a simple test run on all the words might often narrow the > field to a much smaller number of answers like just a few thousand or even > much less. Say you test for the presence of "aeiou" in words, in whatever > order. That might be done from reading a file and filtering out a relatively > few potential answers. You can save those for second round to determine if > they are fully qualified by any additional rules that may involve more > expensive operations. > Your proposed approach didn't involve any trees (or tries) or filtering of words. So I don't see how any of this justifies it. > How fast (or slow) are regular expressions for this purpose? Obviously it > depends on complexity and something like > "^[^aeiou]*[aeiou] [^aeiou]*[aeiou] [^aeiou]*[aeiou] [^aeiou]*[aeiou] > [^aeiou]*[aeiou] [^aeiou]*$" > > would be easy to construct once but likely horribly inefficient in searching > and a bit of overkill here. I suspect there is already some simple C > function that could be used from within python that looks like > findall(choices, word) that might return how many of the letters in choices > were found in word and you simply comparer that to length(word) perhaps more > efficiently. > > It looks easier to check if a character exists in one of the ways already > discussed within python using a loop as discussed. Something as simple as > this: > > needed = "aeiou" > trying = "education" > found = all([trying.find(each) >= 0 for each in needed ]) > print(found) > > trying = "educated" > found = all([trying.find(each) >= 0 for each in needed ]) > print(found) > The above prints > > My point is you can use the above to winnow down possible answers and only > subject that smaller number to one of many tests including using a counter, > making a dictionary you can query (albeit probably slower for fairly short > words) and so on. > That still involves iterating over a word's characters repeatedly. And that's just to identify if a word is a possible match. > Back to your other point, you suggest iterating over characters ( I happened > to do it in a list) multiple times can result in duplication as the same > characters are searched repeatedly. Sure. I simply note most words are > short. How much overhead is there searching for say nine characters five > times? Compare that to say creating a dictionary or other data structure > once, and then making a hash out of each letter being searched for? Exactly. If the words are short enough, and removing items from arbitrary positions in lists is quick enough, and dict creation and lookups are sufficiently expensive - then it might be quicker. But we have a reasonable idea which of these things are expensive and which are quick. If in doubt we can time it. I can > envision many possible ways to speed this up but many involve more use of > memory or all other kinds of overhead such as initializing an object and > calling various member functions and then deleting it or re-initializing it. > My suggestion of removing items from a short list is not ideal and depending > on how a bag was otherwise implemented, I could see it being better but > again, how much is saved if you have a nine letter word that may contain > nine unique letters or even have repeated letters as in banana? You end up > saving a copy of the letter (or a hashed version) plus some integer value > (perhaps just a byte) for the count. I would need to see the implementation > and do some speed tests, ... > > In real programming, there are many choices. This is a bit of a hypothetical > but a part of me suggests the best answer for a quick prototype is something > simple and not necessarily tuned for speed, just to show it can be done. > Then, if the code is used often and is slow, sure, enhance it. Back in my > UNIX days, I might have started with a rather inefficient pipeline for my > example like: > > grep 'a' filename | grep 'e' | grep 'i' | grep 'o' | grep 'u' | ... > > That would produce a list of candidates, again not efficiently. I might have > switched to using better regular expressions, perhaps using sed instead, or > AWK or even PERL. But if it had to be fast production code, I might have > used C then C++ or whatever latest tool I had. > > These days, some things run so fast that we get lazy. When doing a pipelined > approach in R or Python that analyzes data, I often effectively have to > apply a set of conditions to lots of data, one after another. Do you trim > the number of columns in a data frame first or do you apply a condition that > trims the number of rows first? Clearly if you need 5 columns out of 666, > then chances are you narrow the columns so there is less useless copying in > later parts of the pipeline. . But what if you have multiple conditions that > each remove some rows and it depends on what the data looks like? For > example, remove all rows in which one variable is NA and also all rows where > another two variables are not equal to each other and so on. Isn't part of > the consideration how expensive each comparison is? Imagine if you want to > remove rows where a word in one column is not in the scrabble dictionary and > your stupid function has to read it in each and every time! I would want > that to be done last after cheaper methods removed say all words longer than > 10 characters or that had uppercase or numeric parts or spaces or were NA. > > So if the functionality in the topic above was really being built, and the > functionality was being called repeatedly as some game progressed, you > definitely might want to speed it up, if nothing else, by reading the > dictionary file into memory once, perhaps into a data structure like a > modified binary tree which could be searched with tail recursion or > short-cuts. And in some cases, you might even want odd things like to cache > the results of earlier queries in a dictionary and skip a full repeat > search entirely. > > You might argue this situation always gets called with different arguments. > Perhaps but imagine writing a program where the computer plays against a > human. The computer might look at every open region of a scrabble board and > take the tiles already in their "hand" and add zero or more tiles indicating > characters already on the game board that it wanted to extend into or > beyond. Say it sees the letter "r" and wonders if it could place all letters > immediately to the left of that "r" and then to see if the "r" could be in > multiple places within the word formed and finally if it could make a word > starting with "r". That could be multiple identical calls, perhaps only > differing in the order of the characters it is searching for. And it might > repeat similar calls in another part of the board that has a dangling "r", > perhaps the same one it did not use before. Obviously, the goal here would > be to find all potentially possible words it could actually fit into that > slot so further analysis would happen and it would investigate which method > provided more points. It may even look ahead to see if that move allowed the > opponent a better-countermove and so on into deeper analyses. Much of the > expense of deciding what to actually do would be outside the functionality > described. > > Admittedly, I see no reason for it to actually ask for these words as > described that could be longer, but only proper permutations of the letters. > My point is I can envision places where caching earlier results would be > potentially a great speedup. Heck, I suggest the problem could be turned > around as the number of combinations might be computed and simply tested to > see if they exist in a Python dictionary made from the external dictionary. > > Heck, why even write the main routine in an interpreted language when you > can link in a function written to be even more efficient? > > But enhancements like that come with a cost. Would you pay a programmer an > extra month to speed something like that up 5%? Maybe, but often not. And if > you add in the typical costs in a large organization of various kinds of > testing needed for a more complex or subtle approach, ... > > Avi > So the upshot of this is that the use of counters is premature optimisation? I don't agree. I'm not even convinced that your proposed approach is simpler. We need to compare the frequencies of characters, and counters give us those frequencies directly. Then we compare them. Premature optimisation might be "write a trie class, then ...". I like to start with clean code that's not obviously inefficient and that I might not have to revisit later (to tidy up or optimise). For me, that would be the approach using counters. Duncan From avigross at verizon.net Wed Nov 4 14:12:59 2020 From: avigross at verizon.net (Avi Gross) Date: Wed, 4 Nov 2020 14:12:59 -0500 Subject: Find word by given characters In-Reply-To: References: <36f4147e-6be4-4f26-f764-f50119046333@DancesWithMice.info> <61beed7c-a0c0-5885-40d1-b6c5de078722@DancesWithMice.info> <04c701d6b22e$af0f65f0$0d2e31d0$@verizon.net> <088301d6b262$00d1b1d0$02751570$@verizon.net> Message-ID: <0a0d01d6b2de$82a5b4f0$87f11ed0$@verizon.net> My comments at end: -----Original Message----- From: Python-list On Behalf Of duncan smith Sent: Wednesday, November 4, 2020 1:09 PM To: python-list at python.org Subject: Re: Find word by given characters On 04/11/2020 04:21, Avi Gross wrote: > Duncan, my comments below yours at end. > > ---YOURS--- > The Counter approach only requires iterating over the letters once to > construct the letters bag, then each word once to create the relevant > word bag. After that it's (at worst) a couple of lookups and a > comparison for each unique character in letters (for each word). > > Your approach requires iteration over the words to create the lists of > characters. Then they are (potentially) iterated over multiple times > looking for the characters in letters. There's also the cost of > removing items from arbitrary positions in the lists. Also, it seems > that the character frequencies must be equal, and your approach only > ensures that the words contain at least the required numbers of characters. > > In computational terms, if the first approach is something like O(n+m) > for n letters and words of length m, your algorithm is more like O(nm). > Not to say that it will be slower for all possible letters and > dictionaries, but probably for any realistic cases and a lot slower > for large enough dictionaries. > > Duncan > > --MINE--- > > I appreciate your analysis. I have not looked at the "counter" > implementation and suspect it does some similar loops within, albeit > it may be implemented in a compiled language like C++. > Before the introduction of counters I would have used a dict to create a mapping of characters to counts. That would require iterating over the characters in a string only once to create / update the dict entries, and I doubt counters are implemented less efficiently than that. > I did not write out my algorithm in Python but have done it for > myself. It runs fast enough with most of the time spent in the slow I/O part. > > We can agree all algorithms have to read in all the words in a data file. > There may be ways to store the data such as in a binary tree and even > ways to thus prune the search as once a node is reached where all > required letters have been found, all further words qualify below that > point. If you match say "instant" then instants and instantiation > would be deeper in the tree and also qualify assuming extra letters are allowed. I don't see how a binary tree would be useful. As I've pointed out in another post, there are other data structures that could be useful. What I had in mind was a trie (prefix tree). But it's only the distinct characters and frequencies that are relevant and so I'd exploit that (and one or two other things) to reduce space and improve search. We may differ on > the requirement as I think that the number of repeats for something > like a,t,t require to be at least as big as in "attend" but that > "attention" with yet another "t" would also be OK. If I am wrong, > fine, but I note the person requesting this has admitted a certain > lack of credentials while also claiming he made up a scenario just for > fun. So this is not actually a particularly worthy challenge let alone with a purpose. > > My impression is that the average word length would be something small > like 5-7. The number of words in a dictionary might be 100,000 or > more. So if you want efficiency, where do you get the bang for the buck? > > I would argue that a simple test run on all the words might often > narrow the field to a much smaller number of answers like just a few > thousand or even much less. Say you test for the presence of "aeiou" > in words, in whatever order. That might be done from reading a file > and filtering out a relatively few potential answers. You can save > those for second round to determine if they are fully qualified by > any additional rules that may involve more expensive operations. > Your proposed approach didn't involve any trees (or tries) or filtering of words. So I don't see how any of this justifies it. > How fast (or slow) are regular expressions for this purpose? Obviously > it depends on complexity and something like "^[^aeiou]*[aeiou] > [^aeiou]*[aeiou] [^aeiou]*[aeiou] [^aeiou]*[aeiou] [^aeiou]*[aeiou] > [^aeiou]*$" > > would be easy to construct once but likely horribly inefficient in > searching and a bit of overkill here. I suspect there is already some > simple C function that could be used from within python that looks > like findall(choices, word) that might return how many of the letters > in choices were found in word and you simply comparer that to > length(word) perhaps more efficiently. > > It looks easier to check if a character exists in one of the ways > already discussed within python using a loop as discussed. Something > as simple as > this: > > needed = "aeiou" > trying = "education" > found = all([trying.find(each) >= 0 for each in needed ]) > print(found) > > trying = "educated" > found = all([trying.find(each) >= 0 for each in needed ]) > print(found) > The above prints > > My point is you can use the above to winnow down possible answers and > only subject that smaller number to one of many tests including using > a counter, making a dictionary you can query (albeit probably slower > for fairly short > words) and so on. > That still involves iterating over a word's characters repeatedly. And that's just to identify if a word is a possible match. > Back to your other point, you suggest iterating over characters ( I > happened to do it in a list) multiple times can result in duplication > as the same characters are searched repeatedly. Sure. I simply note > most words are short. How much overhead is there searching for say > nine characters five times? Compare that to say creating a dictionary > or other data structure once, and then making a hash out of each letter being searched for? Exactly. If the words are short enough, and removing items from arbitrary positions in lists is quick enough, and dict creation and lookups are sufficiently expensive - then it might be quicker. But we have a reasonable idea which of these things are expensive and which are quick. If in doubt we can time it. I can > envision many possible ways to speed this up but many involve more use > of memory or all other kinds of overhead such as initializing an > object and calling various member functions and then deleting it or re-initializing it. > My suggestion of removing items from a short list is not ideal and > depending on how a bag was otherwise implemented, I could see it being > better but again, how much is saved if you have a nine letter word > that may contain nine unique letters or even have repeated letters as > in banana? You end up saving a copy of the letter (or a hashed > version) plus some integer value (perhaps just a byte) for the count. > I would need to see the implementation and do some speed tests, ... > > In real programming, there are many choices. This is a bit of a > hypothetical but a part of me suggests the best answer for a quick > prototype is something simple and not necessarily tuned for speed, just to show it can be done. > Then, if the code is used often and is slow, sure, enhance it. Back in > my UNIX days, I might have started with a rather inefficient pipeline > for my example like: > > grep 'a' filename | grep 'e' | grep 'i' | grep 'o' | grep 'u' | ... > > That would produce a list of candidates, again not efficiently. I > might have switched to using better regular expressions, perhaps using > sed instead, or AWK or even PERL. But if it had to be fast production > code, I might have used C then C++ or whatever latest tool I had. > > These days, some things run so fast that we get lazy. When doing a > pipelined approach in R or Python that analyzes data, I often > effectively have to apply a set of conditions to lots of data, one > after another. Do you trim the number of columns in a data frame first > or do you apply a condition that trims the number of rows first? > Clearly if you need 5 columns out of 666, then chances are you narrow > the columns so there is less useless copying in later parts of the > pipeline. . But what if you have multiple conditions that each remove > some rows and it depends on what the data looks like? For example, > remove all rows in which one variable is NA and also all rows where > another two variables are not equal to each other and so on. Isn't > part of the consideration how expensive each comparison is? Imagine if > you want to remove rows where a word in one column is not in the > scrabble dictionary and your stupid function has to read it in each > and every time! I would want that to be done last after cheaper > methods removed say all words longer than > 10 characters or that had uppercase or numeric parts or spaces or were NA. > > So if the functionality in the topic above was really being built, > and the functionality was being called repeatedly as some game > progressed, you definitely might want to speed it up, if nothing else, > by reading the dictionary file into memory once, perhaps into a data > structure like a modified binary tree which could be searched with > tail recursion or short-cuts. And in some cases, you might even want > odd things like to cache the results of earlier queries in a > dictionary and skip a full repeat search entirely. > > You might argue this situation always gets called with different arguments. > Perhaps but imagine writing a program where the computer plays against > a human. The computer might look at every open region of a scrabble > board and take the tiles already in their "hand" and add zero or more > tiles indicating characters already on the game board that it wanted > to extend into or beyond. Say it sees the letter "r" and wonders if it > could place all letters immediately to the left of that "r" and then > to see if the "r" could be in multiple places within the word formed > and finally if it could make a word starting with "r". That could be > multiple identical calls, perhaps only differing in the order of the > characters it is searching for. And it might repeat similar calls in > another part of the board that has a dangling "r", perhaps the same > one it did not use before. Obviously, the goal here would be to find > all potentially possible words it could actually fit into that slot so > further analysis would happen and it would investigate which method > provided more points. It may even look ahead to see if that move > allowed the opponent a better-countermove and so on into deeper > analyses. Much of the expense of deciding what to actually do would be outside the functionality described. > > Admittedly, I see no reason for it to actually ask for these words as > described that could be longer, but only proper permutations of the letters. > My point is I can envision places where caching earlier results would > be potentially a great speedup. Heck, I suggest the problem could be > turned around as the number of combinations might be computed and > simply tested to see if they exist in a Python dictionary made from the external dictionary. > > Heck, why even write the main routine in an interpreted language when > you can link in a function written to be even more efficient? > > But enhancements like that come with a cost. Would you pay a > programmer an extra month to speed something like that up 5%? Maybe, > but often not. And if you add in the typical costs in a large > organization of various kinds of testing needed for a more complex or subtle approach, ... > > Avi > So the upshot of this is that the use of counters is premature optimisation? I don't agree. I'm not even convinced that your proposed approach is simpler. We need to compare the frequencies of characters, and counters give us those frequencies directly. Then we compare them. Premature optimisation might be "write a trie class, then ...". I like to start with clean code that's not obviously inefficient and that I might not have to revisit later (to tidy up or optimise). For me, that would be the approach using counters. Duncan ----MY COMMENTS on 11/02/2020--- Duncan, my main point is an academic discussion and I have no experience or complaints about using the excellent suggestions of solving a problem using a counter. Once a good implementation of something is available and reliable and efficient, anyone who knows how to use it can use it to write decent code. The person posting this "problem"' seems to be learning by making up vague projects for themselves. When I have taught programming, the emphasis has been to learn the LANGUAGE first and how to do things in the core language and perhaps standard additions. Aspects like loops and lists are fairly standard in Python. Arguably you could suggest so are many aspects of object-oriented and functional programming these days. But generally (and perhaps wrongly) we often are expected to learn how to solve problems using the basics, often partially to learn how to compose a logical set of steps as an algorithm. Later we may learn that much of what we need has already been taken care of and you have modules or packages or libraries that often let you work at a higher level. So an approach that effectively uses an abstraction that counts everything in one logical step and allows you to ask if one thing is a subset of another is probably even better from a programming perspective. I am not saying it is a premature optimization. It may turn out to not be optimal though given the scenario where small enough words dominate. It is like with dictionaries in Python where the inner method has to allocate space for a hash table of some size that can grow. Given the nature of this problem, there is an obvious way to make a data structure that is more compact and probably faster. Again, just as an academic thought experiment, what we require is the ability to store info about no more than 26 lower-case letters of the alphabet and count how many. I mean, for now, assume we are limited to ASCII, not all Unicode characters. So something as simple as a vector of fixed length 26 would be enough and the hash function would simply subtract a fixed number offset from the value of the character as a byte of 8 bits. The count value is very limited as the longest scrabble word might be on the order of length 20 and no word is likely to have more than 5 or so repetitions of any one character. So having a "counter" bag/dictionary may be overkill in this scenario. As for the subset methodology, it can be a simple vectorized operation as something that acts like a vector (perhaps using numpy) can be used to do something like A >= B to get a vector of True/False and require them all to be True if it is a subset. So, to be clear, I see lots of ways to program most things. Some are arguably better for instructional purposes in a particular language and some are easier on the programmer and some are more efficient and some are easier/harder to debug and so on. When I, or others, present an alternative, it often does not mean existing proposals are wrong or even bad. Your points about how often characters or list items are scanned are valid. But O(N) type arguments must also consider the cost of such access not just how many times. Also valid are your concerns of costs in removing list items in random locations. And, no, my original example did not use exotic things like trees. But I have had many years of experience in many languages and in each I develop a toolbag to work with. For longer lists where I wanted to be able to insert or delete at random, I might use something like linked lists that allow efficient changes without copying the entire list repeatedly. Of course, that works better in languages that support something like pointers. For short lists like in this example, the overhead may be not worth it and a bit of copying may be as fast or faster and not worth worrying about. I think I have said more than enough and won't continue this thread. There are many fairly decent ways of doing things and this particular problem is not particularly interesting as I see little actual reason to build it. But having said that, I note lots of apps for my phone and elsewhere that are games for making words in many different ways, often by permuting a set of letters you can use. Underneath the hood, I suspect they have a dictionary they have to consult, and wonder how they implement their searches. -- https://mail.python.org/mailman/listinfo/python-list From duncan at invalid.invalid Wed Nov 4 15:03:31 2020 From: duncan at invalid.invalid (duncan smith) Date: Wed, 4 Nov 2020 20:03:31 +0000 Subject: Find word by given characters In-Reply-To: References: <36f4147e-6be4-4f26-f764-f50119046333@DancesWithMice.info> <61beed7c-a0c0-5885-40d1-b6c5de078722@DancesWithMice.info> <04c701d6b22e$af0f65f0$0d2e31d0$@verizon.net> <088301d6b262$00d1b1d0$02751570$@verizon.net> <0a0d01d6b2de$82a5b4f0$87f11ed0$@verizon.net> Message-ID: On 04/11/2020 19:12, Avi Gross wrote: > My comments at end: > > -----Original Message----- > From: Python-list On > Behalf Of duncan smith > Sent: Wednesday, November 4, 2020 1:09 PM > To: python-list at python.org > Subject: Re: Find word by given characters > > On 04/11/2020 04:21, Avi Gross wrote: >> Duncan, my comments below yours at end. >> >> ---YOURS--- >> The Counter approach only requires iterating over the letters once to >> construct the letters bag, then each word once to create the relevant >> word bag. After that it's (at worst) a couple of lookups and a >> comparison for each unique character in letters (for each word). >> >> Your approach requires iteration over the words to create the lists of >> characters. Then they are (potentially) iterated over multiple times >> looking for the characters in letters. There's also the cost of >> removing items from arbitrary positions in the lists. Also, it seems >> that the character frequencies must be equal, and your approach only >> ensures that the words contain at least the required numbers of > characters. >> >> In computational terms, if the first approach is something like O(n+m) >> for n letters and words of length m, your algorithm is more like O(nm). >> Not to say that it will be slower for all possible letters and >> dictionaries, but probably for any realistic cases and a lot slower >> for large enough dictionaries. >> >> Duncan >> >> --MINE--- >> >> I appreciate your analysis. I have not looked at the "counter" >> implementation and suspect it does some similar loops within, albeit >> it may be implemented in a compiled language like C++. >> > > Before the introduction of counters I would have used a dict to create a > mapping of characters to counts. That would require iterating over the > characters in a string only once to create / update the dict entries, and I > doubt counters are implemented less efficiently than that. > >> I did not write out my algorithm in Python but have done it for >> myself. It runs fast enough with most of the time spent in the slow I/O > part. >> >> We can agree all algorithms have to read in all the words in a data file. >> There may be ways to store the data such as in a binary tree and even >> ways to thus prune the search as once a node is reached where all >> required letters have been found, all further words qualify below that >> point. If you match say "instant" then instants and instantiation >> would be deeper in the tree and also qualify assuming extra letters are > allowed. > > I don't see how a binary tree would be useful. As I've pointed out in > another post, there are other data structures that could be useful. What I > had in mind was a trie (prefix tree). But it's only the distinct characters > and frequencies that are relevant and so I'd exploit that (and one or two > other things) to reduce space and improve search. > > We may differ on >> the requirement as I think that the number of repeats for something >> like a,t,t require to be at least as big as in "attend" but that >> "attention" with yet another "t" would also be OK. If I am wrong, >> fine, but I note the person requesting this has admitted a certain >> lack of credentials while also claiming he made up a scenario just for >> fun. So this is not actually a particularly worthy challenge let alone > with a purpose. >> >> My impression is that the average word length would be something small >> like 5-7. The number of words in a dictionary might be 100,000 or >> more. So if you want efficiency, where do you get the bang for the buck? >> >> I would argue that a simple test run on all the words might often >> narrow the field to a much smaller number of answers like just a few >> thousand or even much less. Say you test for the presence of "aeiou" >> in words, in whatever order. That might be done from reading a file >> and filtering out a relatively few potential answers. You can save >> those for second round to determine if they are fully qualified by >> any additional rules that may involve more expensive operations. >> > > Your proposed approach didn't involve any trees (or tries) or filtering of > words. So I don't see how any of this justifies it. > >> How fast (or slow) are regular expressions for this purpose? Obviously >> it depends on complexity and something like "^[^aeiou]*[aeiou] >> [^aeiou]*[aeiou] [^aeiou]*[aeiou] [^aeiou]*[aeiou] [^aeiou]*[aeiou] >> [^aeiou]*$" >> >> would be easy to construct once but likely horribly inefficient in >> searching and a bit of overkill here. I suspect there is already some >> simple C function that could be used from within python that looks >> like findall(choices, word) that might return how many of the letters >> in choices were found in word and you simply comparer that to >> length(word) perhaps more efficiently. >> >> It looks easier to check if a character exists in one of the ways >> already discussed within python using a loop as discussed. Something >> as simple as >> this: >> >> needed = "aeiou" >> trying = "education" >> found = all([trying.find(each) >= 0 for each in needed ]) >> print(found) >> >> trying = "educated" >> found = all([trying.find(each) >= 0 for each in needed ]) >> print(found) >> The above prints >> >> My point is you can use the above to winnow down possible answers and >> only subject that smaller number to one of many tests including using >> a counter, making a dictionary you can query (albeit probably slower >> for fairly short >> words) and so on. >> > > That still involves iterating over a word's characters repeatedly. And > that's just to identify if a word is a possible match. > >> Back to your other point, you suggest iterating over characters ( I >> happened to do it in a list) multiple times can result in duplication >> as the same characters are searched repeatedly. Sure. I simply note >> most words are short. How much overhead is there searching for say >> nine characters five times? Compare that to say creating a dictionary >> or other data structure once, and then making a hash out of each letter > being searched for? > > Exactly. If the words are short enough, and removing items from arbitrary > positions in lists is quick enough, and dict creation and lookups are > sufficiently expensive - then it might be quicker. But we have a reasonable > idea which of these things are expensive and which are quick. If in doubt we > can time it. > > I can >> envision many possible ways to speed this up but many involve more use >> of memory or all other kinds of overhead such as initializing an >> object and calling various member functions and then deleting it or > re-initializing it. >> My suggestion of removing items from a short list is not ideal and >> depending on how a bag was otherwise implemented, I could see it being >> better but again, how much is saved if you have a nine letter word >> that may contain nine unique letters or even have repeated letters as >> in banana? You end up saving a copy of the letter (or a hashed >> version) plus some integer value (perhaps just a byte) for the count. >> I would need to see the implementation and do some speed tests, ... >> >> In real programming, there are many choices. This is a bit of a >> hypothetical but a part of me suggests the best answer for a quick >> prototype is something simple and not necessarily tuned for speed, just to > show it can be done. >> Then, if the code is used often and is slow, sure, enhance it. Back in >> my UNIX days, I might have started with a rather inefficient pipeline >> for my example like: >> >> grep 'a' filename | grep 'e' | grep 'i' | grep 'o' | grep 'u' | ... >> >> That would produce a list of candidates, again not efficiently. I >> might have switched to using better regular expressions, perhaps using >> sed instead, or AWK or even PERL. But if it had to be fast production >> code, I might have used C then C++ or whatever latest tool I had. >> >> These days, some things run so fast that we get lazy. When doing a >> pipelined approach in R or Python that analyzes data, I often >> effectively have to apply a set of conditions to lots of data, one >> after another. Do you trim the number of columns in a data frame first >> or do you apply a condition that trims the number of rows first? >> Clearly if you need 5 columns out of 666, then chances are you narrow >> the columns so there is less useless copying in later parts of the >> pipeline. . But what if you have multiple conditions that each remove >> some rows and it depends on what the data looks like? For example, >> remove all rows in which one variable is NA and also all rows where >> another two variables are not equal to each other and so on. Isn't >> part of the consideration how expensive each comparison is? Imagine if >> you want to remove rows where a word in one column is not in the >> scrabble dictionary and your stupid function has to read it in each >> and every time! I would want that to be done last after cheaper >> methods removed say all words longer than >> 10 characters or that had uppercase or numeric parts or spaces or were NA. >> >> So if the functionality in the topic above was really being built, >> and the functionality was being called repeatedly as some game >> progressed, you definitely might want to speed it up, if nothing else, >> by reading the dictionary file into memory once, perhaps into a data >> structure like a modified binary tree which could be searched with >> tail recursion or short-cuts. And in some cases, you might even want >> odd things like to cache the results of earlier queries in a >> dictionary and skip a full repeat search entirely. >> >> You might argue this situation always gets called with different > arguments. >> Perhaps but imagine writing a program where the computer plays against >> a human. The computer might look at every open region of a scrabble >> board and take the tiles already in their "hand" and add zero or more >> tiles indicating characters already on the game board that it wanted >> to extend into or beyond. Say it sees the letter "r" and wonders if it >> could place all letters immediately to the left of that "r" and then >> to see if the "r" could be in multiple places within the word formed >> and finally if it could make a word starting with "r". That could be >> multiple identical calls, perhaps only differing in the order of the >> characters it is searching for. And it might repeat similar calls in >> another part of the board that has a dangling "r", perhaps the same >> one it did not use before. Obviously, the goal here would be to find >> all potentially possible words it could actually fit into that slot so >> further analysis would happen and it would investigate which method >> provided more points. It may even look ahead to see if that move >> allowed the opponent a better-countermove and so on into deeper >> analyses. Much of the expense of deciding what to actually do would be > outside the functionality described. >> >> Admittedly, I see no reason for it to actually ask for these words as >> described that could be longer, but only proper permutations of the > letters. >> My point is I can envision places where caching earlier results would >> be potentially a great speedup. Heck, I suggest the problem could be >> turned around as the number of combinations might be computed and >> simply tested to see if they exist in a Python dictionary made from the > external dictionary. >> >> Heck, why even write the main routine in an interpreted language when >> you can link in a function written to be even more efficient? >> >> But enhancements like that come with a cost. Would you pay a >> programmer an extra month to speed something like that up 5%? Maybe, >> but often not. And if you add in the typical costs in a large >> organization of various kinds of testing needed for a more complex or > subtle approach, ... >> >> Avi >> > > So the upshot of this is that the use of counters is premature optimisation? > I don't agree. I'm not even convinced that your proposed approach is > simpler. We need to compare the frequencies of characters, and counters give > us those frequencies directly. Then we compare them. > Premature optimisation might be "write a trie class, then ...". > > I like to start with clean code that's not obviously inefficient and that I > might not have to revisit later (to tidy up or optimise). For me, that would > be the approach using counters. > > Duncan > > ----MY COMMENTS on 11/02/2020--- > > Duncan, my main point is an academic discussion and I have no experience or > complaints about using the excellent suggestions of solving a problem using > a counter. Once a good implementation of something is available and reliable > and efficient, anyone who knows how to use it can use it to write decent > code. > > The person posting this "problem"' seems to be learning by making up vague > projects for themselves. When I have taught programming, the emphasis has > been to learn the LANGUAGE first and how to do things in the core language > and perhaps standard additions. Aspects like loops and lists are fairly > standard in Python. Arguably you could suggest so are many aspects of > object-oriented and functional programming these days. But generally (and > perhaps wrongly) we often are expected to learn how to solve problems using > the basics, often partially to learn how to compose a logical set of steps > as an algorithm. Later we may learn that much of what we need has already > been taken care of and you have modules or packages or libraries that often > let you work at a higher level. > > So an approach that effectively uses an abstraction that counts everything > in one logical step and allows you to ask if one thing is a subset of > another is probably even better from a programming perspective. I am not > saying it is a premature optimization. It may turn out to not be optimal > though given the scenario where small enough words dominate. It is like with > dictionaries in Python where the inner method has to allocate space for a > hash table of some size that can grow. Given the nature of this problem, > there is an obvious way to make a data structure that is more compact and > probably faster. > > Again, just as an academic thought experiment, what we require is the > ability to store info about no more than 26 lower-case letters of the > alphabet and count how many. I mean, for now, assume we are limited to > ASCII, not all Unicode characters. So something as simple as a vector of > fixed length 26 would be enough and the hash function would simply subtract > a fixed number offset from the value of the character as a byte of 8 bits. > The count value is very limited as the longest scrabble word might be on the > order of length 20 and no word is likely to have more than 5 or so > repetitions of any one character. So having a "counter" bag/dictionary may > be overkill in this scenario. As for the subset methodology, it can be a > simple vectorized operation as something that acts like a vector (perhaps > using numpy) can be used to do something like A >= B to get a vector of > True/False and require them all to be True if it is a subset. > > So, to be clear, I see lots of ways to program most things. Some are > arguably better for instructional purposes in a particular language and some > are easier on the programmer and some are more efficient and some are > easier/harder to debug and so on. When I, or others, present an alternative, > it often does not mean existing proposals are wrong or even bad. > > Your points about how often characters or list items are scanned are valid. > But O(N) type arguments must also consider the cost of such access not just > how many times. Also valid are your concerns of costs in removing list > items in random locations. And, no, my original example did not use exotic > things like trees. But I have had many years of experience in many > languages and in each I develop a toolbag to work with. For longer lists > where I wanted to be able to insert or delete at random, I might use > something like linked lists that allow efficient changes without copying the > entire list repeatedly. Of course, that works better in languages that > support something like pointers. For short lists like in this example, the > overhead may be not worth it and a bit of copying may be as fast or faster > and not worth worrying about. > > I think I have said more than enough and won't continue this thread. There > are many fairly decent ways of doing things and this particular problem is > not particularly interesting as I see little actual reason to build it. But > having said that, I note lots of apps for my phone and elsewhere that are > games for making words in many different ways, often by permuting a set of > letters you can use. Underneath the hood, I suspect they have a dictionary > they have to consult, and wonder how they implement their searches. > -- > https://mail.python.org/mailman/listinfo/python-list > You asked, "what would be wrong with this approach" and "am I missing something about other approaches being better or more efficient". Those are the questions I answered. I explained why I thought your approach would be likely to be comparatively slow for realistic use cases. The OP says he is coming back to Python after a lay off (having used Python2 before). So I didn't see this as a teaching exercise. Rather, I showed how I would do it in Python3. Duncan From davidrd2228 at gmail.com Wed Nov 4 15:37:38 2020 From: davidrd2228 at gmail.com (=?utf-8?Q?David_Ru=C3=ADz_Dom=C3=ADnguez?=) Date: Wed, 4 Nov 2020 14:37:38 -0600 Subject: IDEL from Windows It does not work Message-ID: <32887439-5040-470D-AAA4-DC59682BB91F@hxcore.ol> IDEL from Windows It does not work, started the program and won?t open it. I already uninstalled and reinstalled it and it still does not open thanks for your service ? Enviado desde [1]Correo para Windows 10 ? References Visible links 1. https://go.microsoft.com/fwlink/?LinkId=550986 From ikorot01 at gmail.com Wed Nov 4 16:38:13 2020 From: ikorot01 at gmail.com (Igor Korot) Date: Wed, 4 Nov 2020 15:38:13 -0600 Subject: IDEL from Windows It does not work In-Reply-To: <32887439-5040-470D-AAA4-DC59682BB91F@hxcore.ol> References: <32887439-5040-470D-AAA4-DC59682BB91F@hxcore.ol> Message-ID: Hi, On Wed, Nov 4, 2020 at 2:47 PM David Ru?z Dom?nguez wrote: > > IDEL from Windows It does not work, started the program and won?t open it. > I already uninstalled and reinstalled it and it still does not open Do you mean IDLE? If yes - please define "does not work". Are you trying to start it from the Desktop? Start Menu? Does it give you any error? Which one? Are you trying to execute some script with it? Please five us more info... I also presume you are working under Windows 10. Thank you. > > thanks for your service > > > > Enviado desde [1]Correo para Windows 10 > > > > References > > Visible links > 1. https://go.microsoft.com/fwlink/?LinkId=550986 > -- > https://mail.python.org/mailman/listinfo/python-list From Gronicus at SGA.Ninja Wed Nov 4 18:02:16 2020 From: Gronicus at SGA.Ninja (Steve) Date: Wed, 4 Nov 2020 18:02:16 -0500 Subject: Time Date Conversion? Message-ID: <01e401d6b2fe$8aadc690$a00953b0$@SGA.Ninja> The text File entry is: BPd 2020-11-04 17:28:03.352027 66 I bring it into the program using: with open("_TIME-DATE.txt" , 'r') as infile: for lineEQN in infile: # loop to find each line in the file for that dose and set it in a variable as follows: ItemDateTime = lineEQN[7:36].strip() When I print ItemDateTime, it looks like: 2020-11-04 17:28:03.352027 How do I display it as "Wednesday, November 4, 2020 5:28pm" ? Steve ------------------------------------------------------------------------- Footnote: Seatbelts are very dangerous. I cannot tell you how many times I almost got into an accident trying to buckle one. From larry.martell at gmail.com Wed Nov 4 18:47:18 2020 From: larry.martell at gmail.com (Larry Martell) Date: Wed, 4 Nov 2020 18:47:18 -0500 Subject: Time Date Conversion? In-Reply-To: <01e401d6b2fe$8aadc690$a00953b0$@SGA.Ninja> References: <01e401d6b2fe$8aadc690$a00953b0$@SGA.Ninja> Message-ID: On Wed, Nov 4, 2020 at 6:21 PM Steve wrote: > > The text File entry is: > BPd 2020-11-04 17:28:03.352027 66 > > I bring it into the program using: > with open("_TIME-DATE.txt" , 'r') as infile: > for lineEQN in infile: # loop to find each line in the file for that > dose > and set it in a variable as follows: > ItemDateTime = lineEQN[7:36].strip() > > When I print ItemDateTime, it looks like: > 2020-11-04 17:28:03.352027 > > How do I display it as "Wednesday, November 4, 2020 5:28pm" ? Look at strptime/strftime From python at mrabarnett.plus.com Wed Nov 4 20:01:28 2020 From: python at mrabarnett.plus.com (MRAB) Date: Thu, 5 Nov 2020 01:01:28 +0000 Subject: Time Date Conversion? In-Reply-To: <01e401d6b2fe$8aadc690$a00953b0$@SGA.Ninja> References: <01e401d6b2fe$8aadc690$a00953b0$@SGA.Ninja> Message-ID: On 2020-11-04 23:02, Steve wrote: > The text File entry is: > BPd 2020-11-04 17:28:03.352027 66 > > I bring it into the program using: > with open("_TIME-DATE.txt" , 'r') as infile: > for lineEQN in infile: # loop to find each line in the file for that > dose > and set it in a variable as follows: > ItemDateTime = lineEQN[7:36].strip() > > When I print ItemDateTime, it looks like: > 2020-11-04 17:28:03.352027 > > How do I display it as "Wednesday, November 4, 2020 5:28pm" ? > Use the datetime module. Parse it with datetime.strptime and then format it with the .strftime method of the resultant datetime object. From cs at cskk.id.au Wed Nov 4 20:01:37 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 5 Nov 2020 12:01:37 +1100 Subject: Time Date Conversion? In-Reply-To: <01e401d6b2fe$8aadc690$a00953b0$@SGA.Ninja> References: <01e401d6b2fe$8aadc690$a00953b0$@SGA.Ninja> Message-ID: <20201105010137.GA5028@cskk.homeip.net> On 04Nov2020 18:02, Steve wrote: >The text File entry is: > BPd 2020-11-04 17:28:03.352027 66 > >I bring it into the program using: >with open("_TIME-DATE.txt" , 'r') as infile: > for lineEQN in infile: # loop to find each line in the file for that >dose >and set it in a variable as follows: >ItemDateTime = lineEQN[7:36].strip() > >When I print ItemDateTime, it looks like: > 2020-11-04 17:28:03.352027 > >How do I display it as "Wednesday, November 4, 2020 5:28pm" ? Larry has pointed you at strptime and strftime, which read ("parse") a string for date information and write ("format") a string for presentation. The intermediate form is usually either a timestamp (an offset from some point in time, in seconds) or a datetime object (see the datetime module). I'd also point out that your source format looks like a nice ISO8601 format time, and the datetime module has a handy fromisoformat function to the basic forms of that. As programmers we like the ISO8601 presentation because it has the most significant values first and also naively sorts lexically into the time ordering. A less fragile way to parse your example line is to use split() to break it into whitepsace separated fields and then parse field[1]+" "+field[2]. That also gets you the first word as field[0], which might be useful - it likely helps classify the input lines in some way. Cheers, Cameron Simpson From marek.mosiewicz at jotel.com.pl Thu Nov 5 05:10:03 2020 From: marek.mosiewicz at jotel.com.pl (Marek Mosiewicz) Date: Thu, 05 Nov 2020 11:10:03 +0100 Subject: Any experience with Python for GraalVM ? Message-ID: Hello, Does somebody have any experience with GraalVM [1] It is new VM from Oracle which is said to have ability to run Python 3 I have idea to try to run Odoo [2] on it [3]. Odoo is ERP system written in Python. Odoo is big piece of software with many dependencies, but from my understanding of it most important to have something working on Graal would by werkzung and have some working implementation of psycopg2 (Postgresql API) Any ideas ? [1] http://www.graal.org [2] http://odoo.com [2] https://github.com/marekmosiewicz/goblet ---- Marek Mosiewicz http://marekmosiewicz.pl From cousinstanley at gmail.com Thu Nov 5 10:42:25 2020 From: cousinstanley at gmail.com (Cousin Stanley) Date: Thu, 05 Nov 2020 08:42:25 -0700 Subject: Seeking guidance to start a career in python programming References: Message-ID: ankur gupta wrote: > Good Morning to All, > My name is Ankur Gupta and I wish to seek guidance from you. > > I belong to a non-computer science background > but have always been attracted to this field. > > I had computer science in class 12th ( Where I learned C++ > and Python ) but I did Mechanical Engineering instead in college. > > I wish to pursue a career in Python programming > and therefore undertook 2 online certification courses > in python but besides this, my progress is almost stalled. > > Request you all to please guide how I can move forward > with my current learning of the language and also steps > that I can take to pursue a career in this field. Mechanical Engineers are needed in an almost endlessly wide array of applications ... from nano-bots in bio-engineering to space-bots sampling soil samples on asteroids You might consider applying the Python knowledge that you have acquired to endeavors in the field that you are most familar with. -- Stanley C. Kitching Human Being Phoenix, Arizona From flaskee at protonmail.com Thu Nov 5 10:54:29 2020 From: flaskee at protonmail.com (flaskee) Date: Thu, 05 Nov 2020 15:54:29 +0000 Subject: songbird's ngfp Message-ID: Hey songbird, Just the tiniest of tips. You might want to add the full venv setup link: https://packaging.python.org/guides/installing-using-pip-and-virtual-environments/ somewhere in https://github.com/flowerbug/ngfp/blob/master/README.md ~~~~~~~~~~~~~~~~~~~~~ ngfp did not install for me: (python 3.7 | debian 10.6 | venv) But, it could be me. I'll try it again. I look forward to seeing your game. Thanks! From tjreedy at udel.edu Wed Nov 4 22:15:03 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Wed, 4 Nov 2020 22:15:03 -0500 Subject: Please help test astral char display in tkinter Text (especially *nix) In-Reply-To: References: Message-ID: On 11/4/2020 7:47 AM, Menno Holscher wrote: > Op 03-11-2020 om 04:04 schreef Terry Reedy: >> Perhaps half of the assigned chars in the first plane are printed >> instead of being replaced with a narrow box. This includes emoticons >> as foreground color outlines on background color.? Maybe all of the >> second plane of extended CJK chars are printed.? The third plane is >> unassigned and prints as unassigned boxes (with an X). >> >> If you get errors, how many.? If you get a hang or crash, how far did >> the program get? >> > openSuse Linux 15.2 Leap, Python 3.6.10, tcl and tk 8.6.7 > > The program runs fine, but complains in the text scrollbox: > 0x10000 character U+10000 is above the range (U+0000-U+FFFF) allowed by Tcl > > until > > 0x3ffe0 character U+3ffe0 is above the range (U+0000-U+FFFF) allowed by Tcl Thank you. I assume that this message replaces the line of 32, which tcl did not attempt to print. Much better than crashing. I should have specified that not printing is likely for any python older than about year. I have no idea what would happen with current Python and tcl/tk older than the 8.6.8 provided with the Windows installer. -- Terry Jan Reedy From tjreedy at udel.edu Wed Nov 4 22:19:54 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Wed, 4 Nov 2020 22:19:54 -0500 Subject: IDEL from Windows It does not work In-Reply-To: References: <32887439-5040-470D-AAA4-DC59682BB91F@hxcore.ol> Message-ID: On 11/4/2020 4:38 PM, Igor Korot wrote: > Hi, > > On Wed, Nov 4, 2020 at 2:47 PM David Ru?z Dom?nguez > wrote: >> >> IDEL from Windows It does not work, started the program and won?t open it. >> I already uninstalled and reinstalled it and it still does not open When you installed, did you ask for tcl/tk to be installed so tkinter and IDLE would work? Does python run? If so, does "import tkinter" run? > Do you mean IDLE? > If yes - please define "does not work". Are you trying to start it > from the Desktop? Start Menu? In particular, try starting from CommandPrompt with C:...> python -m idlelib > Does it give you any error? Which one? > Are you trying to execute some script with it? Try starting first without a script (python program). > > Please five us more info... > > I also presume you are working under Windows 10. -- Terry Jan Reedy From marek.mosiewicz at jotel.com.pl Thu Nov 5 15:25:31 2020 From: marek.mosiewicz at jotel.com.pl (Marek Mosiewicz) Date: Thu, 05 Nov 2020 21:25:31 +0100 Subject: Any experience with Python for GraalVM ? In-Reply-To: References: Message-ID: <84d391b364ed12d89cb49768cbe7332a92b686a6.camel@jotel.com.pl> W?dniu czw, 05.11.2020 o?godzinie 11?02?-0500, u?ytkownik Dennis Lee Bieber napisa?: > On Thu, 05 Nov 2020 11:10:03 +0100, Marek Mosiewicz > declaimed the following: > > > Does somebody have any experience with GraalVM [1] > > It is new VM from Oracle which is said to have > > ability to run Python 3 > > > ????????Based upon https://www.graalvm.org/reference- > manual/python/?that > capability is rather minimum... I just downloaded GraalVM and Werkzeug is being installed successfully. Maybe it is worth to try. > > -- > ????????Wulfraed???????????????? Dennis Lee Bieber???????? AF6VN > ????????wlfraed at ix.netcom.com??? > http://wlfraed.microdiversity.freeddns.org/ > -- Marek Mosiewicz http://marekmosiewicz.pl From Gronicus at SGA.Ninja Fri Nov 6 02:25:25 2020 From: Gronicus at SGA.Ninja (Steve) Date: Fri, 6 Nov 2020 02:25:25 -0500 Subject: Is there a conflict of libraries here? Message-ID: <02ce01d6b40d$ff230cf0$fd6926d0$@SGA.Ninja> In my program, I have the following lines of code: import random import re import time import datetime from datetime import timedelta from time import gmtime, strftime ##define strftime as time/date right now import winsound as ws import sys These may or may not affect my new program code but here is the issue: If I add the code: from datetime import datetime these new lines work: dt = datetime.fromisoformat(ItemDateTime) dt_string = dt.strftime(' at %H:%M on %A %d %B %Y') and will fail without that "datetime import datetime" line however; With that "datetime import datetime" line included, all of the lines of code throughout the program that contain "datetime.datetime" fail. These have been in use for over three years and there are at least a dozen of them. The error produced is: time1 = datetime.datetime.strptime(T1, date_format) AttributeError: type object 'datetime.datetime' has no attribute 'datetime' How do I have my cake and eat it too? Steve Footnote: Some mornings it just isn't worth chewing through the leather straps. From frank at chagford.com Fri Nov 6 02:36:02 2020 From: frank at chagford.com (Frank Millman) Date: Fri, 6 Nov 2020 09:36:02 +0200 Subject: Is there a conflict of libraries here? In-Reply-To: <02ce01d6b40d$ff230cf0$fd6926d0$@SGA.Ninja> References: <02ce01d6b40d$ff230cf0$fd6926d0$@SGA.Ninja> Message-ID: <6a3289a4-112f-0724-c6e6-151e5a9f7666@chagford.com> On 2020-11-06 9:25 AM, Steve wrote: > In my program, I have the following lines of code: > > import random > > import re > > import time > > import datetime > > from datetime import timedelta > > from time import gmtime, strftime ##define strftime as time/date right > now > > import winsound as ws > > import sys > > These may or may not affect my new program code but here is the issue: > > > > If I add the code: > > from datetime import datetime > > these new lines work: > > dt = datetime.fromisoformat(ItemDateTime) > > dt_string = dt.strftime(' at %H:%M on %A %d %B %Y') > > and will fail without that "datetime import datetime" line > > > > however; > > > > With that "datetime import datetime" line included, > > all of the lines of code throughout the program that contain > "datetime.datetime" fail. > These have been in use for over three years and there are at least a dozen > of them. > > The error produced is: > > > time1 = datetime.datetime.strptime(T1, date_format) > > AttributeError: type object 'datetime.datetime' has no attribute > 'datetime' > I think all you have to do is - 1. Remove the line 'from datetime import datetime'. 2. Change dt = datetime.fromisoformat(ItemDateTime) to dt = datetime.datetime.fromisoformat(ItemDateTime) Unless I have missed something, that should work. Frank Millman From frank at chagford.com Fri Nov 6 02:36:02 2020 From: frank at chagford.com (Frank Millman) Date: Fri, 6 Nov 2020 09:36:02 +0200 Subject: Is there a conflict of libraries here? In-Reply-To: <02ce01d6b40d$ff230cf0$fd6926d0$@SGA.Ninja> References: <02ce01d6b40d$ff230cf0$fd6926d0$@SGA.Ninja> Message-ID: <6a3289a4-112f-0724-c6e6-151e5a9f7666@chagford.com> On 2020-11-06 9:25 AM, Steve wrote: > In my program, I have the following lines of code: > > import random > > import re > > import time > > import datetime > > from datetime import timedelta > > from time import gmtime, strftime ##define strftime as time/date right > now > > import winsound as ws > > import sys > > These may or may not affect my new program code but here is the issue: > > > > If I add the code: > > from datetime import datetime > > these new lines work: > > dt = datetime.fromisoformat(ItemDateTime) > > dt_string = dt.strftime(' at %H:%M on %A %d %B %Y') > > and will fail without that "datetime import datetime" line > > > > however; > > > > With that "datetime import datetime" line included, > > all of the lines of code throughout the program that contain > "datetime.datetime" fail. > These have been in use for over three years and there are at least a dozen > of them. > > The error produced is: > > > time1 = datetime.datetime.strptime(T1, date_format) > > AttributeError: type object 'datetime.datetime' has no attribute > 'datetime' > I think all you have to do is - 1. Remove the line 'from datetime import datetime'. 2. Change dt = datetime.fromisoformat(ItemDateTime) to dt = datetime.datetime.fromisoformat(ItemDateTime) Unless I have missed something, that should work. Frank Millman From songbird at anthive.com Fri Nov 6 02:14:04 2020 From: songbird at anthive.com (songbird) Date: Fri, 6 Nov 2020 02:14:04 -0500 Subject: songbird's ngfp References: Message-ID: flaskee wrote: ... > I look forward to seeing your game. > > Thanks! unfortunately the system needs a bit more complicated things to be installed for ngfp to also be installed. pkg-config and the cairo/pycairo stuff and a compiler... note, i have not had any chance to look into this further. some time ago i did see mention of wheels provided by the cairo/pycairo github project, but since it is still gardening season i've been a bit too busy to poke at this more to find out what has happened and how that might change the installation of ngfp. still, thank you again for trying and for the feedback. :) songbird From cs at cskk.id.au Fri Nov 6 04:30:47 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Fri, 6 Nov 2020 20:30:47 +1100 Subject: Is there a conflict of libraries here? In-Reply-To: <6a3289a4-112f-0724-c6e6-151e5a9f7666@chagford.com> References: <6a3289a4-112f-0724-c6e6-151e5a9f7666@chagford.com> Message-ID: <20201106093047.GA63836@cskk.homeip.net> On 06Nov2020 09:36, Frank Millman wrote: >On 2020-11-06 9:25 AM, Steve wrote: >>In my program, I have the following lines of code: >> import datetime >> from datetime import timedelta >> >> from time import gmtime, strftime ##define strftime as time/date right >>now >>If I add the code: >> >> from datetime import datetime >> >>these new lines work: >> >> dt = datetime.fromisoformat(ItemDateTime) >> >> dt_string = dt.strftime(' at %H:%M on %A %d %B %Y') >> >>and will fail without that "datetime import datetime" line Right, because you're using the datetime _class_ to get the fromisoformat factory function. >>however; >> >> >>With that "datetime import datetime" line included, >> >>all of the lines of code throughout the program that contain >>"datetime.datetime" fail. >>These have been in use for over three years and there are at least a dozen >>of them. Yeah. because _those_ lines are using the name "datetime" as the module name. Just replace "datetime.datetime" throughout with "datetime". Your code will be more readable anyway. >>The error produced is: >> >> time1 = datetime.datetime.strptime(T1, date_format) >> >> AttributeError: type object 'datetime.datetime' has no attribute >>'datetime' That is because "datetime" is currently the class, not the module. >1. Remove the line 'from datetime import datetime'. > >2. Change dt = datetime.fromisoformat(ItemDateTime) to > dt = datetime.datetime.fromisoformat(ItemDateTime) > >Unless I have missed something, that should work. That will work, but produces verbose code. I prefer to import things _from_ the datetime module, letting me drop the 'datetime." module prefix across the code. Cheers, Cameron Simpson From Bischoop at vimart.net Fri Nov 6 07:23:05 2020 From: Bischoop at vimart.net (Bischoop) Date: Fri, 6 Nov 2020 12:23:05 -0000 (UTC) Subject: Incoming datas difficult to read "\r\n" and "\n" Message-ID: I'm experimenting with irc bot. I've made it connecting, reading etc but everything is difficult to read. It's coming like one long string without breaking lines. How to mace it printing in new line after: \r\n or \n in data? ------ b':weber.freenode.net 001 saaaki :Welcome to the freenode Internet Relay Chat Network saaaki\r\n:weber.freenode.net 002 saaaki :Your host is weber.freenode.net[162.213.39.42/6667], running version ircd-seven-1.1.9\r\n:weber.freenode.net 003 saaaki :This server was created Wed Dec 18 2019 at 21:37:52 UTC\r\n:weber.freenode.net 004 saaaki weber.freenode.net ircd-seven-1.1.9 DOQRSZaghilopsuwz CFILMPQSbcefgijklmnopqrstuvz bkloveqjfI\r\n:weber.freenode.net 005 saaaki CHANTYPES=# EXCEPTS INVEX CHANMODES=eIbq,k,flj,CFLMPQScgimnprstuz CHANLIMIT=#:120 PREFIX=(ov)@+ MAXLIST=bqeI:100 MODES=4 NETWORK=freenode STATUSMSG=@+ CALLERID=g CASEMAPPING=rfc1459 :are supported by this server\r\n:weber.freenode.net 005 saaaki CHARSET=ascii NICKLEN=16 CHANNELLEN=50 TOPICLEN=390 DEAF=D FNC TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:4,NOTICE:4,ACCEPT:,MONITOR: EXTBAN=$,ajrxz CLIENTVER=3.0 SAFELIST ELIST=CTU KNOCK :are supported by this server\r\n:weber.freenode.net 005 saaaki CP ------------------------------------------ My code: -------------- while 1: time.sleep(2) data=s.recv(2040) print(data) if data.find(b"PING"): s.send(b"PONG :pingis") ----------------- From rosuav at gmail.com Fri Nov 6 07:31:58 2020 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 6 Nov 2020 23:31:58 +1100 Subject: Incoming datas difficult to read "\r\n" and "\n" In-Reply-To: References: Message-ID: On Fri, Nov 6, 2020 at 11:26 PM Bischoop wrote: > > > I'm experimenting with irc bot. I've made it connecting, reading etc but > everything is difficult to read. > > It's coming like one long string without breaking lines. > How to mace it printing in new line after: \r\n or \n in data? > ------ > > b':weber.freenode.net 001 saaaki :Welcome to the freenode Internet Relay > Chat Network saaaki\r\n:weber.freenode.net 002 saaaki :Your host is > weber.freenode.net[162.213.39.42/6667], running version > ircd-seven-1.1.9\r\n:weber.freenode.net 003 saaaki :This server was > created Wed Dec 18 2019 at 21:37:52 UTC\r\n:weber.freenode.net 004 > saaaki weber.freenode.net ircd-seven-1.1.9 DOQRSZaghilopsuwz > CFILMPQSbcefgijklmnopqrstuvz bkloveqjfI\r\n:weber.freenode.net 005 > saaaki CHANTYPES=# EXCEPTS INVEX CHANMODES=eIbq,k,flj,CFLMPQScgimnprstuz > CHANLIMIT=#:120 PREFIX=(ov)@+ MAXLIST=bqeI:100 MODES=4 NETWORK=freenode > STATUSMSG=@+ CALLERID=g CASEMAPPING=rfc1459 :are supported by this > server\r\n:weber.freenode.net 005 saaaki CHARSET=ascii NICKLEN=16 > CHANNELLEN=50 TOPICLEN=390 DEAF=D FNC > TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:4,NOTICE:4,ACCEPT:,MONITOR: > EXTBAN=$,ajrxz CLIENTVER=3.0 SAFELIST ELIST=CTU KNOCK :are supported by > this server\r\n:weber.freenode.net 005 saaaki CP > ------------------------------------------ > > My code: > -------------- > while 1: > time.sleep(2) > data=s.recv(2040) > print(data) > if data.find(b"PING"): > s.send(b"PONG :pingis") > You're currently dumping out the raw bytes. Not very interesting, and that's why it's not easy to read. I would recommend (a) decoding the bytes to text, and (b) splitting it on "\r\n", thus getting it line-by-line. What you may want to consider, though, is using an actual IRC library. It'll handle all kinds of details for you :) ChrisA From Bischoop at vimart.net Fri Nov 6 07:46:01 2020 From: Bischoop at vimart.net (Bischoop) Date: Fri, 6 Nov 2020 12:46:01 -0000 (UTC) Subject: Incoming datas difficult to read "\r\n" and "\n" References: Message-ID: On 2020-11-06, Chris Angelico wrote: > You're currently dumping out the raw bytes. Not very interesting, and > that's why it's not easy to read. I would recommend (a) decoding the > bytes to text, and (b) splitting it on "\r\n", thus getting it > line-by-line. > > What you may want to consider, though, is using an actual IRC library. > It'll handle all kinds of details for you :) > right I've changed the line to: print(data.decode('utf8')) and prints it now nice but not sure how to apply yet: print (string.splitlines( )) and PING PONG matter. From rosuav at gmail.com Fri Nov 6 07:54:38 2020 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 6 Nov 2020 23:54:38 +1100 Subject: Incoming datas difficult to read "\r\n" and "\n" In-Reply-To: References: Message-ID: On Fri, Nov 6, 2020 at 11:51 PM Bischoop wrote: > > On 2020-11-06, Chris Angelico wrote: > > > You're currently dumping out the raw bytes. Not very interesting, and > > that's why it's not easy to read. I would recommend (a) decoding the > > bytes to text, and (b) splitting it on "\r\n", thus getting it > > line-by-line. > > > > What you may want to consider, though, is using an actual IRC library. > > It'll handle all kinds of details for you :) > > > > right > > I've changed the line to: > print(data.decode('utf8')) > > and prints it now nice but not sure how to apply yet: > > print (string.splitlines( )) > > and PING PONG matter. Cool. You're going to have to iterate over the lines and process each one individually. IRC is a line-based protocol and every line has its own meaning. But, again, this is where an IRC library would help enormously; it'll do all of that parsing (including taking care of edge cases that you might not have thought of), and let you just handle the parts that are interesting, like responding to specific messages from people. ChrisA From Bischoop at vimart.net Fri Nov 6 08:13:54 2020 From: Bischoop at vimart.net (Bischoop) Date: Fri, 6 Nov 2020 13:13:54 -0000 (UTC) Subject: Incoming datas difficult to read "\r\n" and "\n" References: Message-ID: On 2020-11-06, Chris Angelico wrote: > On Fri, Nov 6, 2020 at 11:51 PM Bischoop wrote: >> >> On 2020-11-06, Chris Angelico wrote: >> >> > You're currently dumping out the raw bytes. Not very interesting, and >> > that's why it's not easy to read. I would recommend (a) decoding the >> > bytes to text, and (b) splitting it on "\r\n", thus getting it >> > line-by-line. >> > >> > What you may want to consider, though, is using an actual IRC library. >> > It'll handle all kinds of details for you :) >> > >> >> right >> >> I've changed the line to: >> print(data.decode('utf8')) >> >> and prints it now nice but not sure how to apply yet: >> >> print (string.splitlines( )) >> >> and PING PONG matter. > > Cool. You're going to have to iterate over the lines and process each > one individually. IRC is a line-based protocol and every line has its > own meaning. But, again, this is where an IRC library would help > enormously; it'll do all of that parsing (including taking care of > edge cases that you might not have thought of), and let you just > handle the parts that are interesting, like responding to specific > messages from people. Yes, I know about irc libraries but I do it for educational purposes, when wrtiting it myself I do learn all the time new things. From as at sci.fi Fri Nov 6 02:37:27 2020 From: as at sci.fi (Anssi Saari) Date: Fri, 06 Nov 2020 09:37:27 +0200 Subject: Please help test astral char display in tkinter Text (especially *nix) References: Message-ID: Terry Reedy writes: > Perhaps half of the assigned chars in the first plane are printed > instead of being replaced with a narrow box. This includes emoticons > as foreground color outlines on background color. Maybe all of the > second plane of extended CJK chars are printed. The third plane is > unassigned and prints as unassigned boxes (with an X). I get the same as Menno Holscher (i.e. messages with "character is above the range blah blah") in Debian 10 with the system provided Python 3.7.3. Tcl and tk are 8.6.9. With Python 3.9.0 I get something like what you described above. Some chars print, lots of empty boxes too and lots of just empty space. No boxes with an X and no errors. From nkopteng at gmail.com Fri Nov 6 02:41:18 2020 From: nkopteng at gmail.com (J.J. E.) Date: Fri, 6 Nov 2020 08:41:18 +0100 Subject: I have no clue figuring out how to check dates in workholidays Message-ID: Hi, Thank you for allowing me in this support mailing list. My experience with Python is short due to my new job. My boss told me that I need to create a code that checks yesterday's date. The conditions for returning none are that: - Yesterday happens to be a holiday, - Yesterday turns out to be a Saturday or a Sunday. For both reasons, it needs to return None. Now I have learned to scan a text file, and I have learned (ROUGHLY) the structure of what seems to scan for specific words in "Indented Comments". The file "gwd.py" that I have joined stands for getWorkingDate. It is the rough draft that I am creating. So what I wish is you to help me get a basic structure of what I need to edit and get gwd.py to scan cameroon.py; once everyday the gwd.py checks yesterday's date and if it fills the above conditions, it returns none. That is all. Please note that creating a separate file with the list of national holidays is ok but then I prefer using the holidays library because it evolves with the years, if you know what I mean. Please forgive my lack of proper expression as well as I have been going through Python for exactly five weeks only. Jean Jacques ECKEBIL From pkpearson at nowhere.invalid Fri Nov 6 10:35:55 2020 From: pkpearson at nowhere.invalid (Peter Pearson) Date: 6 Nov 2020 15:35:55 GMT Subject: Is there a conflict of libraries here? References: <02ce01d6b40d$ff230cf0$fd6926d0$@SGA.Ninja> Message-ID: On Fri, 6 Nov 2020 02:25:25 -0500, Steve wrote: > In my program, I have the following lines of code: > import random > import re > import time > import datetime At this point, the name "datetime" points to a module. > from datetime import timedelta > from time import gmtime, strftime > import winsound as ws > import sys > [snip] > > from datetime import datetime By that, you have reassigned the name "datetime" to point to a class defined in the datetime module. [snip] > > AttributeError: type object 'datetime.datetime' has no attribute > 'datetime' Right, because the name "datetime" points to the class datetime in the module datetime. The class, unlike the module, has no "datetime" attribute. Apologies if you already knew this. I wasn't sure. -- To email me, substitute nowhere->runbox, invalid->com. From variablestarlight at gmail.com Fri Nov 6 11:17:50 2020 From: variablestarlight at gmail.com (=?UTF-8?Q?Hern=c3=a1n_De_Angelis?=) Date: Fri, 6 Nov 2020 17:17:50 +0100 Subject: Questions about XML processing? Message-ID: <519d01c1-d584-2c22-f82e-859a6a634367@gmail.com> Hi everyone I am confronting some XML parsing challenges and would like to ask some questions to more knowledgeable Python users. Apparently there exists a group for such questions but that list (xml-sig) has apparently not received (or archived) posts since May 2018(!). I wonder if there are other list or forum for Python XML questions, or if this list would be fine for that. Thanks in advance /H. From tjreedy at udel.edu Fri Nov 6 14:10:04 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Fri, 6 Nov 2020 14:10:04 -0500 Subject: Questions about XML processing? In-Reply-To: <519d01c1-d584-2c22-f82e-859a6a634367@gmail.com> References: <519d01c1-d584-2c22-f82e-859a6a634367@gmail.com> Message-ID: On 11/6/2020 11:17 AM, Hern?n De Angelis wrote: > I am confronting some XML parsing challenges and would like to ask some > questions to more knowledgeable Python users. Apparently there exists a > group for such questions but that list (xml-sig) has apparently not > received (or archived) posts since May 2018(!). I wonder if there are > other list or forum for Python XML questions, or if this list would be > fine for that. If you don't hear otherwise, try here. Or try stackoverflow.com and tag questions with python and xml. -- Terry Jan Reedy From variablestarlight at gmail.com Fri Nov 6 15:54:24 2020 From: variablestarlight at gmail.com (=?UTF-8?Q?Hern=c3=a1n_De_Angelis?=) Date: Fri, 6 Nov 2020 21:54:24 +0100 Subject: Questions about XML processing? In-Reply-To: References: <519d01c1-d584-2c22-f82e-859a6a634367@gmail.com> Message-ID: <5bab621e-6811-4296-d1d5-3649f9688362@gmail.com> Thank you Terry, Dan and Dieter for encouraging me to post here. I have already solved the problem albeit with a not so efficient solution. Perhaps, it is useful to present it here anyway in case some light can be added to this. My job is to parse a complicated XML (iso metadata) and pick up values of certain fields in certain conditions. This goes for the most part well. I am working with xml.etree.elementtree, which proved sufficient for the most part and the rest of the project. JSON is not an option within this project. The specific trouble was in this section, itself the child of a more complicated parent: (for simplicity tags are renamed and namespaces removed) ????????? ??????????? ????????????? ??????????????? Something ????????????? ????????????? ??????????????? Something else ????????????? ????????????? ??????????????? ????????????????? ??????????????????? <string>value</string> ????????????????? ????????????????? ??????????????????? ????????????????????? 2020-11-06 ????????????????????? ????????????????????? ??????????????????????? ????????????????????? ??????????????????? ????????????????? ??????????????? ????????????? ??????????? ????????? Basically, I have to get what is in tagC/string but only if the value of tagC/note/title/string is "value". As you see, there are several tagC, all children of tagB, but tagC can have different meanings(!). And no, I have no control over how these XML fields are constructed. In principle it is easy to make a "findall" and get strings for tagC, using: elem.findall("./tagA/tagB/tagC/string") and then get the content and append in case there is more than one tagC/string like: "Something, Something else". However, the hard thing to do here is to get those only when tagC/note/title/string='value'. I was expecting to find a way of specifying a certain construction in square brackets, like [@string='value'] or [@/tagC/note/title/string='value'], as is usual in XML and possible in xml.etree. However this proved difficult (at least for me). So this is the "brute" solution I implemented: - find all children of tagA/tagB - check if /tagA/tagB/tagC/note/title/string has "value" - if yes find all tagA/tagB/tagC/string In quasi-Python: string = [] element0 = elem.findall("./tagA/tagB/") ??? for element1 in element0: ??????? element2 = element1.find("./tagA/tagB/tagC/note/title/string") ??????????? if element2.text == 'value' ??????????????? element3 = element1.findall("./tagA/tagB/tagC/string) ??????????????? for element4 in element3: ??????????????????? string.append(element4.text) Crude, but works. As I wrote above, I was wishing that a bracketed clause of the type [@ ...] already in the first "findall" would do a more efficient job but alas my knowledge of xml is too rudimentary. Perhaps something to tinker on in the coming weeks. Have a nice weekend! On 2020-11-06 20:10, Terry Reedy wrote: > On 11/6/2020 11:17 AM, Hern?n De Angelis wrote: >> I am confronting some XML parsing challenges and would like to ask >> some questions to more knowledgeable Python users. Apparently there >> exists a group for such questions but that list (xml-sig) has >> apparently not received (or archived) posts since May 2018(!). I >> wonder if there are other list or forum for Python XML questions, or >> if this list would be fine for that. > > If you don't hear otherwise, try here.? Or try stackoverflow.com and > tag questions with python and xml. > > From Gronicus at SGA.Ninja Fri Nov 6 17:05:53 2020 From: Gronicus at SGA.Ninja (Steve) Date: Fri, 6 Nov 2020 17:05:53 -0500 Subject: Is there a conflict of libraries here? In-Reply-To: References: <02ce01d6b40d$ff230cf0$fd6926d0$@SGA.Ninja> Message-ID: <006301d6b489$001b0ba0$005122e0$@SGA.Ninja> "Right, because the name "datetime" points to the class datetime in the module datetime. The class, unlike the module, has no "datetime" attribute." Ok, how do I unpoint/repoint a "datetime" to let the two locations work? "Apologies if you already knew this. I wasn't sure." Absolutely did not know any of this. Libraries are a slow learning process for me.... Footnote Patient in the hospital: "What happens after I die?" Doctor: "We clean up the bed and bring in a new patient." -----Original Message----- From: Python-list On Behalf Of Peter Pearson Sent: Friday, November 6, 2020 10:36 AM To: python-list at python.org Subject: Re: Is there a conflict of libraries here? On Fri, 6 Nov 2020 02:25:25 -0500, Steve wrote: > In my program, I have the following lines of code: > import random > import re > import time > import datetime At this point, the name "datetime" points to a module. > from datetime import timedelta > from time import gmtime, strftime > import winsound as ws > import sys > [snip] > > from datetime import datetime By that, you have reassigned the name "datetime" to point to a class defined in the datetime module. [snip] > > AttributeError: type object 'datetime.datetime' has no attribute > 'datetime' Right, because the name "datetime" points to the class datetime in the module datetime. The class, unlike the module, has no "datetime" attribute. Apologies if you already knew this. I wasn't sure. -- To email me, substitute nowhere->runbox, invalid->com. -- https://mail.python.org/mailman/listinfo/python-list From mats at wichmann.us Fri Nov 6 17:57:00 2020 From: mats at wichmann.us (Mats Wichmann) Date: Fri, 6 Nov 2020 15:57:00 -0700 Subject: Is there a conflict of libraries here? In-Reply-To: <006301d6b489$001b0ba0$005122e0$@SGA.Ninja> References: <02ce01d6b40d$ff230cf0$fd6926d0$@SGA.Ninja> <006301d6b489$001b0ba0$005122e0$@SGA.Ninja> Message-ID: <58689f34-0961-e65e-b473-a3fb596d6e39@wichmann.us> On 11/6/20 3:05 PM, Steve wrote: > "Right, because the name "datetime" points to the class datetime in the > module datetime. > The class, unlike the module, has no "datetime" attribute." > > > > Ok, how do I unpoint/repoint a "datetime" to let the two locations work? > > > > "Apologies if you already knew this. I wasn't sure." > > > > Absolutely did not know any of this. > Libraries are a slow learning process for me.... > The Python import command does some stuff behind the scenes, but from the programmer viewpoint, you're just manipulating names in namespaces - making a mapping of a name to the relevant object. import boo gives you a name 'boo' in the relevant namespace, which refers to the module object made for boo when it was imported (that's some of the behind the scenes stuff). A quick interactive sample showing this in action: >>> globals() {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': , '__spec__': None, '__annotations__': {}, '__builtins__': } >>> import sys >>> globals() {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': , '__spec__': None, '__annotations__': {}, '__builtins__': , 'sys': } here's the case you are running into: >>> import datetime >>> globals() {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': , '__spec__': None, '__annotations__': {}, '__builtins__': , 'datetime': } >>> from datetime import datetime >>> globals() {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': , '__spec__': None, '__annotations__': {}, '__builtins__': , 'datetime': } If you want to import the datetime class and still have the full datetime module available, you can for example import as a different name - here's a sample of that: >>> import datetime as dt >>> from datetime import datetime >>> globals() {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': , '__spec__': None, '__annotations__': {}, '__builtins__': , 'dt': , 'datetime': } Does this make it clearer? From cs at cskk.id.au Fri Nov 6 18:06:15 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Sat, 7 Nov 2020 10:06:15 +1100 Subject: I have no clue figuring out how to check dates in workholidays In-Reply-To: References: Message-ID: <20201106230615.GA29337@cskk.homeip.net> On 06Nov2020 08:41, J.J. E. wrote: >Thank you for allowing me in this support mailing list. Anyone may join. Welcome! >My experience with >Python is short due to my new job. My boss told me that I need to create a >code that checks yesterday's date. The conditions for returning none are >that: > - Yesterday happens to be a holiday, > - Yesterday turns out to be a Saturday or a Sunday. >For both reasons, it needs to return None. A remark: that is unusual. Normally this would be a "logical" test: is yesterday a workholiday or not, returning True or False accordingly. Returning None will "test" as false, but it is not a normal value for false situations. What does your function return when neither situation applies? >Now I have learned to scan a >text file, and I have learned (ROUGHLY) the structure of what seems to scan >for specific words in "Indented Comments". > >The file "gwd.py" that I have joined stands for getWorkingDate. This is a text only list, and the list software discards most, if not all, attachments. Your sample file is not present in the email I received. Please paste the contents of gwd.py directly into your email (which itself should be a _reply_ to this email or your original email). Then we can see your code. Thanks, Cameron Simpson From nickli.1540489 at gmail.com Sat Nov 7 01:51:59 2020 From: nickli.1540489 at gmail.com (Nick Li) Date: Fri, 6 Nov 2020 22:51:59 -0800 (PST) Subject: Python 3 Message-ID: <1e99d306-994f-4b90-a016-9ae237afed35n@googlegroups.com> Does anyone know how to turn a decimal number into duodecimal or if there is a function built-in for it? From barry at barrys-emacs.org Sat Nov 7 05:16:57 2020 From: barry at barrys-emacs.org (Barry Scott) Date: Sat, 7 Nov 2020 10:16:57 +0000 Subject: Python 3 In-Reply-To: <1e99d306-994f-4b90-a016-9ae237afed35n@googlegroups.com> References: <1e99d306-994f-4b90-a016-9ae237afed35n@googlegroups.com> Message-ID: <06B39E9A-7BCB-4BD2-AC2E-A5D6E0D23B65@barrys-emacs.org> > On 7 Nov 2020, at 06:51, Nick Li wrote: > > Does anyone know how to turn a decimal number into duodecimal or if there is a function built-in for it? I see lots of interesting answer in here: https://stackoverflow.com/questions/2267362/how-to-convert-an-integer-to-a-string-in-any-base > -- > https://mail.python.org/mailman/listinfo/python-list > From variablestarlight at gmail.com Sat Nov 7 05:19:29 2020 From: variablestarlight at gmail.com (=?UTF-8?Q?Hern=C3=A1n_De_Angelis?=) Date: Sat, 7 Nov 2020 11:19:29 +0100 Subject: Python 3 In-Reply-To: <1e99d306-994f-4b90-a016-9ae237afed35n@googlegroups.com> References: <1e99d306-994f-4b90-a016-9ae237afed35n@googlegroups.com> Message-ID: Hi, Wikipedia has an article on the duodecimal system, that includes an explanation of how to convert from decimal and the other way around. https://en.wikipedia.org/wiki/Duodecimal?wprov=sfla1 Peerrhaps it can be easily implemented as a function. Good luck. H. Den l?r 7 nov. 2020 07:55Nick Li skrev: > Does anyone know how to turn a decimal number into duodecimal or if there > is a function built-in for it? > -- > https://mail.python.org/mailman/listinfo/python-list > From Bischoop at vimart.net Sat Nov 7 06:03:50 2020 From: Bischoop at vimart.net (Bischoop) Date: Sat, 7 Nov 2020 11:03:50 -0000 (UTC) Subject: strip() method makes me confused Message-ID: According to documentation strip method removes heading and trailing characters. Why then: txt = ",,,,,rrttggs...,..s,bananas...s.rrr" x = txt.strip(",s.grt") print(x) output: banana another example: text = "this is text, there should be not commas, but as you see there are still" y = txt.strip(",") print(text) output: this is text, there should be not commas, but as you see there are still From alexander at neilson.net.nz Sat Nov 7 06:21:31 2020 From: alexander at neilson.net.nz (Alexander Neilson) Date: Sun, 8 Nov 2020 00:21:31 +1300 Subject: strip() method makes me confused In-Reply-To: References: Message-ID: <469D4989-7FD3-4A6E-B5BF-7BA293B3F72A@neilson.net.nz> Because the strip methods argument is the set of characters to remove from either end. So it checks from the ends character by character until it finds a character that isn?t in the set. Then it removes everything prior to that (or after that at end of the string) and then returns the result. So your first example leaves ?banana? as the string because all characters after and before that string in the original string were found in the set. However in your second example the set only contains the comma and the string neither begins nor ends with commas so if (first character) in (set containing comma) returns false so it stops searching from that end and does the same at the other end. https://www.programiz.com/python-programming/methods/string/strip Hope that helps. Regards Alexander Alexander Neilson Neilson Productions Limited 021 329 681 alexander at neilson.net.nz > On 8/11/2020, at 00:06, Bischoop wrote: > > ? > According to documentation strip method removes heading and trailing > characters. > > Why then: > > txt = ",,,,,rrttggs...,..s,bananas...s.rrr" > > x = txt.strip(",s.grt") > > print(x) > > output: banana > > another example: > > text = "this is text, there should be not commas, but as you see there > are still" > y = txt.strip(",") > print(text) > > output: > this is text, there should be not commas, but as you see there are still > > > > -- > https://mail.python.org/mailman/listinfo/python-list From frank at chagford.com Sat Nov 7 06:28:40 2020 From: frank at chagford.com (Frank Millman) Date: Sat, 7 Nov 2020 13:28:40 +0200 Subject: strip() method makes me confused In-Reply-To: References: Message-ID: On 2020-11-07 1:03 PM, Bischoop wrote: > > According to documentation strip method removes heading and trailing > characters. Both are explained in the docs - > > Why then: > > txt = ",,,,,rrttggs...,..s,bananas...s.rrr" > > x = txt.strip(",s.grt") > > print(x) > > output: banana "The chars argument is not a prefix or suffix; rather, all combinations of its values are stripped" As you can see, it has removed every leading or trailing ',', 's', '.', 'g', 'r', and 't'. It starts at the beginning and removes characters until it finds a character that is not in the chars arguments. Then it starts at the end and, working backwards, removes characters until it finds a character that is not in the chars arguments. > > another example: > > text = "this is text, there should be not commas, but as you see there > are still" > y = txt.strip(",") > print(text) > > output: > this is text, there should be not commas, but as you see there are still > As you yourself said above, it removes 'leading and trailing characters'. In your example, the commas are all embedded in the string. They are not leading or trailing, so they are not removed. Note that in Python 3.9, 2 new string methods have been added - str.removeprefix(prefix, /) If the string starts with the prefix string, return string[len(prefix):]. Otherwise, return a copy of the original string str.removesuffix(suffix, /) If the string ends with the suffix string and that suffix is not empty, return string[:-len(suffix)]. Otherwise, return a copy of the original string HTH Frank Millman From frank at chagford.com Sat Nov 7 06:28:40 2020 From: frank at chagford.com (Frank Millman) Date: Sat, 7 Nov 2020 13:28:40 +0200 Subject: strip() method makes me confused In-Reply-To: References: Message-ID: On 2020-11-07 1:03 PM, Bischoop wrote: > > According to documentation strip method removes heading and trailing > characters. Both are explained in the docs - > > Why then: > > txt = ",,,,,rrttggs...,..s,bananas...s.rrr" > > x = txt.strip(",s.grt") > > print(x) > > output: banana "The chars argument is not a prefix or suffix; rather, all combinations of its values are stripped" As you can see, it has removed every leading or trailing ',', 's', '.', 'g', 'r', and 't'. It starts at the beginning and removes characters until it finds a character that is not in the chars arguments. Then it starts at the end and, working backwards, removes characters until it finds a character that is not in the chars arguments. > > another example: > > text = "this is text, there should be not commas, but as you see there > are still" > y = txt.strip(",") > print(text) > > output: > this is text, there should be not commas, but as you see there are still > As you yourself said above, it removes 'leading and trailing characters'. In your example, the commas are all embedded in the string. They are not leading or trailing, so they are not removed. Note that in Python 3.9, 2 new string methods have been added - str.removeprefix(prefix, /) If the string starts with the prefix string, return string[len(prefix):]. Otherwise, return a copy of the original string str.removesuffix(suffix, /) If the string ends with the suffix string and that suffix is not empty, return string[:-len(suffix)]. Otherwise, return a copy of the original string HTH Frank Millman From frank at chagford.com Sat Nov 7 06:34:29 2020 From: frank at chagford.com (Frank Millman) Date: Sat, 7 Nov 2020 13:34:29 +0200 Subject: strip() method makes me confused In-Reply-To: References: Message-ID: <07e913f5-8e50-8f5b-e7de-c43ebc740f01@chagford.com> On 2020-11-07 1:28 PM, Frank Millman wrote: > On 2020-11-07 1:03 PM, Bischoop wrote: >> [...] >> >> another example: >> >> text = "this is text, there should be not commas, but as you see there >> are still" >> y = txt.strip(",") >> print(text) >> >> output: >> this is text, there should be not commas, but as you see there are still >> > P.S. If you wanted to remove all the commas, you could do it like this - y = txt.replace(',', '') Frank From frank at chagford.com Sat Nov 7 06:34:29 2020 From: frank at chagford.com (Frank Millman) Date: Sat, 7 Nov 2020 13:34:29 +0200 Subject: strip() method makes me confused In-Reply-To: References: Message-ID: <07e913f5-8e50-8f5b-e7de-c43ebc740f01@chagford.com> On 2020-11-07 1:28 PM, Frank Millman wrote: > On 2020-11-07 1:03 PM, Bischoop wrote: >> [...] >> >> another example: >> >> text = "this is text, there should be not commas, but as you see there >> are still" >> y = txt.strip(",") >> print(text) >> >> output: >> this is text, there should be not commas, but as you see there are still >> > P.S. If you wanted to remove all the commas, you could do it like this - y = txt.replace(',', '') Frank From shishaozhong at gmail.com Sat Nov 7 07:14:32 2020 From: shishaozhong at gmail.com (Shaozhong SHI) Date: Sat, 7 Nov 2020 12:14:32 +0000 Subject: Questions about XML processing? In-Reply-To: <5bab621e-6811-4296-d1d5-3649f9688362@gmail.com> References: <519d01c1-d584-2c22-f82e-859a6a634367@gmail.com> <5bab621e-6811-4296-d1d5-3649f9688362@gmail.com> Message-ID: Hi, Hernan, Did you try to parse GML? Surely, there can be very concise and smart ways to do these things. Regards, David On Fri, 6 Nov 2020 at 20:57, Hern?n De Angelis wrote: > Thank you Terry, Dan and Dieter for encouraging me to post here. I have > already solved the problem albeit with a not so efficient solution. > Perhaps, it is useful to present it here anyway in case some light can > be added to this. > > My job is to parse a complicated XML (iso metadata) and pick up values > of certain fields in certain conditions. This goes for the most part > well. I am working with xml.etree.elementtree, which proved sufficient > for the most part and the rest of the project. JSON is not an option > within this project. > > The specific trouble was in this section, itself the child of a more > complicated parent: (for simplicity tags are renamed and namespaces > removed) > > > > > Something > > > Something else > > > > > <string>value</string> > > > > > 2020-11-06 > > > > > > > > > > > > Basically, I have to get what is in tagC/string but only if the value of > tagC/note/title/string is "value". As you see, there are several tagC, > all children of tagB, but tagC can have different meanings(!). And no, I > have no control over how these XML fields are constructed. > > In principle it is easy to make a "findall" and get strings for tagC, > using: > > elem.findall("./tagA/tagB/tagC/string") > > and then get the content and append in case there is more than one > tagC/string like: "Something, Something else". > > However, the hard thing to do here is to get those only when > tagC/note/title/string='value'. I was expecting to find a way of > specifying a certain construction in square brackets, like > [@string='value'] or [@/tagC/note/title/string='value'], as is usual in > XML and possible in xml.etree. However this proved difficult (at least > for me). So this is the "brute" solution I implemented: > > - find all children of tagA/tagB > - check if /tagA/tagB/tagC/note/title/string has "value" > - if yes find all tagA/tagB/tagC/string > > In quasi-Python: > > string = [] > element0 = elem.findall("./tagA/tagB/") > for element1 in element0: > element2 = element1.find("./tagA/tagB/tagC/note/title/string") > if element2.text == 'value' > element3 = element1.findall("./tagA/tagB/tagC/string) > for element4 in element3: > string.append(element4.text) > > > Crude, but works. As I wrote above, I was wishing that a bracketed > clause of the type [@ ...] already in the first "findall" would do a > more efficient job but alas my knowledge of xml is too rudimentary. > Perhaps something to tinker on in the coming weeks. > > Have a nice weekend! > > > > > > On 2020-11-06 20:10, Terry Reedy wrote: > > On 11/6/2020 11:17 AM, Hern?n De Angelis wrote: > >> I am confronting some XML parsing challenges and would like to ask > >> some questions to more knowledgeable Python users. Apparently there > >> exists a group for such questions but that list (xml-sig) has > >> apparently not received (or archived) posts since May 2018(!). I > >> wonder if there are other list or forum for Python XML questions, or > >> if this list would be fine for that. > > > > If you don't hear otherwise, try here. Or try stackoverflow.com and > > tag questions with python and xml. > > > > > -- > https://mail.python.org/mailman/listinfo/python-list > From variablestarlight at gmail.com Sat Nov 7 07:24:01 2020 From: variablestarlight at gmail.com (=?UTF-8?Q?Hern=C3=A1n_De_Angelis?=) Date: Sat, 7 Nov 2020 13:24:01 +0100 Subject: Questions about XML processing? In-Reply-To: References: <519d01c1-d584-2c22-f82e-859a6a634367@gmail.com> <5bab621e-6811-4296-d1d5-3649f9688362@gmail.com> Message-ID: No, it is XML metadata. I also believe there should be a better way using [@...] expressions in the path. H. Den l?r 7 nov. 2020 13:14Shaozhong SHI skrev: > Hi, Hernan, > > Did you try to parse GML? > > Surely, there can be very concise and smart ways to do these things. > > Regards, > > David > > On Fri, 6 Nov 2020 at 20:57, Hern?n De Angelis < > variablestarlight at gmail.com> wrote: > >> Thank you Terry, Dan and Dieter for encouraging me to post here. I have >> already solved the problem albeit with a not so efficient solution. >> Perhaps, it is useful to present it here anyway in case some light can >> be added to this. >> >> My job is to parse a complicated XML (iso metadata) and pick up values >> of certain fields in certain conditions. This goes for the most part >> well. I am working with xml.etree.elementtree, which proved sufficient >> for the most part and the rest of the project. JSON is not an option >> within this project. >> >> The specific trouble was in this section, itself the child of a more >> complicated parent: (for simplicity tags are renamed and namespaces >> removed) >> >> >> >> >> Something >> >> >> Something else >> >> >> >> >> <string>value</string> >> >> >> >> >> 2020-11-06 >> >> >> >> >> >> >> >> >> >> >> >> Basically, I have to get what is in tagC/string but only if the value of >> tagC/note/title/string is "value". As you see, there are several tagC, >> all children of tagB, but tagC can have different meanings(!). And no, I >> have no control over how these XML fields are constructed. >> >> In principle it is easy to make a "findall" and get strings for tagC, >> using: >> >> elem.findall("./tagA/tagB/tagC/string") >> >> and then get the content and append in case there is more than one >> tagC/string like: "Something, Something else". >> >> However, the hard thing to do here is to get those only when >> tagC/note/title/string='value'. I was expecting to find a way of >> specifying a certain construction in square brackets, like >> [@string='value'] or [@/tagC/note/title/string='value'], as is usual in >> XML and possible in xml.etree. However this proved difficult (at least >> for me). So this is the "brute" solution I implemented: >> >> - find all children of tagA/tagB >> - check if /tagA/tagB/tagC/note/title/string has "value" >> - if yes find all tagA/tagB/tagC/string >> >> In quasi-Python: >> >> string = [] >> element0 = elem.findall("./tagA/tagB/") >> for element1 in element0: >> element2 = element1.find("./tagA/tagB/tagC/note/title/string") >> if element2.text == 'value' >> element3 = element1.findall("./tagA/tagB/tagC/string) >> for element4 in element3: >> string.append(element4.text) >> >> >> Crude, but works. As I wrote above, I was wishing that a bracketed >> clause of the type [@ ...] already in the first "findall" would do a >> more efficient job but alas my knowledge of xml is too rudimentary. >> Perhaps something to tinker on in the coming weeks. >> >> Have a nice weekend! >> >> >> >> >> >> On 2020-11-06 20:10, Terry Reedy wrote: >> > On 11/6/2020 11:17 AM, Hern?n De Angelis wrote: >> >> I am confronting some XML parsing challenges and would like to ask >> >> some questions to more knowledgeable Python users. Apparently there >> >> exists a group for such questions but that list (xml-sig) has >> >> apparently not received (or archived) posts since May 2018(!). I >> >> wonder if there are other list or forum for Python XML questions, or >> >> if this list would be fine for that. >> > >> > If you don't hear otherwise, try here. Or try stackoverflow.com and >> > tag questions with python and xml. >> > >> > >> -- >> https://mail.python.org/mailman/listinfo/python-list >> > From Bischoop at vimart.net Sat Nov 7 08:40:59 2020 From: Bischoop at vimart.net (Bischoop) Date: Sat, 7 Nov 2020 13:40:59 -0000 (UTC) Subject: strip() method makes me confused References: <07e913f5-8e50-8f5b-e7de-c43ebc740f01@chagford.com> Message-ID: On 2020-11-07, Frank Millman wrote: > On 2020-11-07 1:28 PM, Frank Millman wrote: >> On 2020-11-07 1:03 PM, Bischoop wrote: >>> > [...] >>> >>> another example: >>> >>> text = "this is text, there should be not commas, but as you see there >>> are still" >>> y = txt.strip(",") >>> print(text) >>> >>> output: >>> this is text, there should be not commas, but as you see there are still >>> >> > > P.S. If you wanted to remove all the commas, you could do it like this - > > y = txt.replace(',', '') > > I understand now what is happening thanks. Yes, I know about replace, it just was bothering me about those examples I've gave earlier. Thanks From Bischoop at vimart.net Sat Nov 7 08:42:12 2020 From: Bischoop at vimart.net (Bischoop) Date: Sat, 7 Nov 2020 13:42:12 -0000 (UTC) Subject: strip() method makes me confused References: <469D4989-7FD3-4A6E-B5BF-7BA293B3F72A@neilson.net.nz> Message-ID: On 2020-11-07, Alexander Neilson wrote: > Because the strip methods argument is the set of characters to remove from either end. So it checks from the ends character by character until it finds a character that isn?t in the set. Then it removes everything prior to that (or after that at end of the string) and then returns the result. > > So your first example leaves ?banana? as the string because all characters after and before that string in the original string were found in the set. > > However in your second example the set only contains the comma and the string neither begins nor ends with commas so if (first character) in (set containing comma) returns false so it stops searching from that end and does the same at the other end. > > https://www.programiz.com/python-programming/methods/string/strip > Yes, I got it know. Thanks From Bischoop at vimart.net Sat Nov 7 08:46:17 2020 From: Bischoop at vimart.net (Bischoop) Date: Sat, 7 Nov 2020 13:46:17 -0000 (UTC) Subject: Any better way for this removal? Message-ID: So I was training with slicing. Came to idea to remove text after second occurence of character, below is how I've figured it out, I know if it works it good but.... how you guys would made it in more pythonic way? text = "This is string, remove text after second comma, to be removed." k= (text.find(",")) #find "," in a string m = (text.find(",", k+1)) #Find second "," in a string new_string = text[:m] print(new_string) From inhahe at gmail.com Sat Nov 7 09:39:40 2020 From: inhahe at gmail.com (inhahe) Date: Sat, 7 Nov 2020 09:39:40 -0500 Subject: Any better way for this removal? In-Reply-To: References: Message-ID: > > > On Sat, Nov 7, 2020 at 8:51 AM Bischoop wrote: > >> >> >> So I was training with slicing. >> Came to idea to remove text after second occurence of character, below >> is how I've figured it out, I know if it works it good but.... how you >> guys would made it in more pythonic way? >> >> text = "This is string, remove text after second comma, to be removed." >> >> k= (text.find(",")) #find "," in a string >> m = (text.find(",", k+1)) #Find second "," in a string >> new_string = text[:m] >> >> print(new_string) >> >> >> -- >> https://mail.python.org/mailman/listinfo/python-list > > Not sure what's more Pythonic, but another way of doing it would be to use `m = text.split(",", 2)`, then rejoin the string via `",".join(m[:2])`, and I guess you'd also have to add a comma at the end if you want that, `+","` Another way to do it would be with regex with capturing. `m = re.find("^(.*?,.*?,).*", text)` or something like that. Sorry, my Python is a little rusty. From dsp.tanmay at gmail.com Sat Nov 7 09:03:57 2020 From: dsp.tanmay at gmail.com (Tanmay Deshpande) Date: Sat, 7 Nov 2020 19:33:57 +0530 Subject: Trouble Uninstalling Python 3.7.9 & 3.8.6 on Windows 10 Message-ID: Hi there, I have been using multiple versions of Python on my laptop running Windows 10. I installed 3.7.9 (64-bit) for my school work and 3.8.6 (64-bit) for my personal usage. *Build Number: 19041.572* I had decided to uninstall both Python versions from my system as I wanted to have a clean install. (There seems to be virtually no problems with the python installations itself as I can use both pip and the REPL without any issues.) However, whenever I try to uninstall any Python version from the Programs & Features section of the Control Panel, the files do not seem to get removed. There is no error message and the output is shown as "Uninstall was successful." I tried a couple of things listed below: 1) I tried removing the files myself in order to uninstall Python 3.7.9 . I had installed Python 3.7.9 at C:\Python37 and permanently deleted the files from that folder. However, Python 3.7.9 was still showing up in Programs & Features. 2) I tried using the Repair option from the Programs & Features and the "Repair was successful". However, when I tried to select the Uninstall option, no files were removed and I received the same message again ("Uninstall was successful") 3) I tried finding the *Uninstall String within the Registry Editor in Windows 10*. I found it and ran it and it also removed no files. 4) I restarted the laptop multiple times and the result was still the same. I tried the above steps with both Python 3.7.9 and Python 3.8.6 and I got the same result every time (Uninstall was successful, however no files were deleted) I would be highly grateful if the person receiving this mail could provide a solution Thanks & Regards Tanmay Deshpande From drexl at fastmail.com Sat Nov 7 09:33:47 2020 From: drexl at fastmail.com (Mike) Date: Sat, 07 Nov 2020 14:33:47 +0000 Subject: Any better way for this removal? In-Reply-To: References: Message-ID: <472973b7-b1e7-4b11-afcb-904236ee7e6f@www.fastmail.com> Use .split() to split the string on the character and then use .join() to rejoin the first 2 tokens tokens = text.split(?,?) new_string = ?,?.join(tokens[:2]) On Sat, Nov 7, 2020, at 1:46 PM, Bischoop wrote: > > > So I was training with slicing. > Came to idea to remove text after second occurence of character, below > is how I've figured it out, I know if it works it good but.... how you > guys would made it in more pythonic way? > > text = "This is string, remove text after second comma, to be removed." > > k= (text.find(",")) #find "," in a string > m = (text.find(",", k+1)) #Find second "," in a string > new_string = text[:m] > > print(new_string) > > > -- > https://mail.python.org/mailman/listinfo/python-list > From python.list at tim.thechases.com Sat Nov 7 11:51:59 2020 From: python.list at tim.thechases.com (Tim Chase) Date: Sat, 7 Nov 2020 10:51:59 -0600 Subject: Any better way for this removal? In-Reply-To: References: Message-ID: <20201107105159.439a7cbc@bigbox.attlocal.net> On 2020-11-07 13:46, Bischoop wrote: > text = "This is string, remove text after second comma, to be > removed." > > k= (text.find(",")) #find "," in a string > m = (text.find(",", k+1)) #Find second "," in a string > new_string = text[:m] > > print(new_string) How about: new_string = text.rsplit(',', 1)[0] This also expands to throwing away more than one right-hand bit if you want: from string import ascii_lowercase text = ",".join(ascii_lowercase) to_throw_away = 5 new_string = text.rsplit(',', n)[0] or throwing away `n` left-hand bits too using .split() left_portion = text.split(',', n)[-1] -tkc From Gronicus at SGA.Ninja Sat Nov 7 13:26:30 2020 From: Gronicus at SGA.Ninja (Steve) Date: Sat, 7 Nov 2020 13:26:30 -0500 Subject: Is there a conflict of libraries here? In-Reply-To: <58689f34-0961-e65e-b473-a3fb596d6e39@wichmann.us> References: <02ce01d6b40d$ff230cf0$fd6926d0$@SGA.Ninja> <006301d6b489$001b0ba0$005122e0$@SGA.Ninja> <58689f34-0961-e65e-b473-a3fb596d6e39@wichmann.us> Message-ID: <014501d6b533$8444cfb0$8cce6f10$@SGA.Ninja> Ok, I think I see a light in the fog. It looks as if I can identify a variable to contain a library. Import datetime as dt1 I guess that I can have a second variable containing that same library: Import datetime as dt2 Should I presume that not doing this is what caused the interference in my code? In your example: >>> import datetime as dt >>> from datetime import datetime >>> globals() {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': , '__spec__': None, '__annotations__': {}, '__builtins__': , 'dt': , 'datetime': } How does your line3 and line2 relate to line1? It looks as if they relate to dt but it is not specifically stated. Is it because they are consecutive lines? In the list of globals, I see :{}, seems bizarre.. Is my dt1 now a variable containing the properties of datetime and they are listed between { } and available globally. Do I then have dt1.datetime and dt2.datetime as separate instances? Is that how they are identified? How are they applied? More questions will follow. Step by step, slowly I turned.. Steve ------------------------------------------------------------------------ 98% of lawyers give the other 2% a bad name. -----Original Message----- From: Python-list On Behalf Of Mats Wichmann Sent: Friday, November 6, 2020 5:57 PM To: python-list at python.org Subject: Re: Is there a conflict of libraries here? On 11/6/20 3:05 PM, Steve wrote: > "Right, because the name "datetime" points to the class datetime in > the module datetime. > The class, unlike the module, has no "datetime" attribute." > > > > Ok, how do I unpoint/repoint a "datetime" to let the two locations work? > > > > "Apologies if you already knew this. I wasn't sure." > > > > Absolutely did not know any of this. > Libraries are a slow learning process for me.... > The Python import command does some stuff behind the scenes, but from the programmer viewpoint, you're just manipulating names in namespaces - making a mapping of a name to the relevant object. import boo gives you a name 'boo' in the relevant namespace, which refers to the module object made for boo when it was imported (that's some of the behind the scenes stuff). A quick interactive sample showing this in action: >>> globals() {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': , '__spec__': None, '__annotations__': {}, '__builtins__': } >>> import sys >>> globals() {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': , '__spec__': None, '__annotations__': {}, '__builtins__': , 'sys': } here's the case you are running into: >>> import datetime >>> globals() {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': , '__spec__': None, '__annotations__': {}, '__builtins__': , 'datetime': } >>> from datetime import datetime >>> globals() {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': , '__spec__': None, '__annotations__': {}, '__builtins__': , 'datetime': } If you want to import the datetime class and still have the full datetime module available, you can for example import as a different name - here's a sample of that: >>> import datetime as dt >>> from datetime import datetime >>> globals() {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': , '__spec__': None, '__annotations__': {}, '__builtins__': , 'dt': , 'datetime': } Does this make it clearer? -- https://mail.python.org/mailman/listinfo/python-list From dieter at handshake.de Sat Nov 7 14:03:16 2020 From: dieter at handshake.de (Dieter Maurer) Date: Sat, 7 Nov 2020 20:03:16 +0100 Subject: Questions about XML processing? In-Reply-To: <5bab621e-6811-4296-d1d5-3649f9688362@gmail.com> References: <519d01c1-d584-2c22-f82e-859a6a634367@gmail.com> <5bab621e-6811-4296-d1d5-3649f9688362@gmail.com> Message-ID: <24486.61300.350766.623469@ixdm.fritz.box> Hern?n De Angelis wrote at 2020-11-6 21:54 +0100: > ... >However, the hard thing to do here is to get those only when >tagC/note/title/string='value'. I was expecting to find a way of >specifying a certain construction in square brackets, like >[@string='value'] or [@/tagC/note/title/string='value'], as is usual in >XML and possible in xml.etree. However this proved difficult (at least >for me). So this is the "brute" solution I implemented: You might have a look at `lxml`. It supports XPath (1.0) which is more powerfull in selecting nodes than `etree`. From hjp-python at hjp.at Sat Nov 7 14:32:35 2020 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sat, 7 Nov 2020 20:32:35 +0100 Subject: Is there a conflict of libraries here? In-Reply-To: <014501d6b533$8444cfb0$8cce6f10$@SGA.Ninja> References: <02ce01d6b40d$ff230cf0$fd6926d0$@SGA.Ninja> <006301d6b489$001b0ba0$005122e0$@SGA.Ninja> <58689f34-0961-e65e-b473-a3fb596d6e39@wichmann.us> <014501d6b533$8444cfb0$8cce6f10$@SGA.Ninja> Message-ID: <20201107193235.GA21534@hjp.at> On 2020-11-07 13:26:30 -0500, Steve wrote: > Ok, I think I see a light in the fog. > > It looks as if I can identify a variable to contain a library. > > Import datetime as dt1 > > I guess that I can have a second variable containing that same library: > > Import datetime as dt2 > > Should I presume that not doing this is what caused the interference in my > code? Not quite. The problem isn't that you imported the library twice, but that you have a library (package/module) and a class of the same name. When you try to import both with that name, only one of them will be visible, since you can't have one name refer to two different things at the same time. >>> import datetime The name datetime now refers to the module datetime: >>> datetime >>> id(datetime) 140407076788160 >>> from datetime import datetime Now the name datetime now refers to the class datetime: >>> datetime >>> id(datetime) 9612160 You can import one or both of them with different names: >>> import datetime as dt_module >>> dt_module >>> id(dt_module) 140407076788160 >>> from datetime import datetime as dt_class >>> dt_class >>> id(dt_class) 9612160 hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From python.list at tim.thechases.com Sat Nov 7 14:51:24 2020 From: python.list at tim.thechases.com (Tim Chase) Date: Sat, 7 Nov 2020 13:51:24 -0600 Subject: Any better way for this removal? [typo correction] In-Reply-To: <20201107105159.439a7cbc@bigbox.attlocal.net> References: <20201107105159.439a7cbc@bigbox.attlocal.net> Message-ID: <20201107135124.4394b4ed@bigbox.attlocal.net> On 2020-11-07 10:51, Tim Chase wrote: > from string import ascii_lowercase > text = ",".join(ascii_lowercase) > to_throw_away = 5 [derp] For obvious reasons, these should be s/\/to_throw_away/g To throw away the trailing N delimited portions: > new_string = text.rsplit(',', n)[0] new_string = text.rsplit(',', to_throw_away)[0] and to remove the leading N fields > new_string = text.split(',', n)[-1] new_string = text.split(',', to_throw_away)[-1] -tkc From mats at wichmann.us Sat Nov 7 17:16:27 2020 From: mats at wichmann.us (Mats Wichmann) Date: Sat, 7 Nov 2020 15:16:27 -0700 Subject: Is there a conflict of libraries here? In-Reply-To: <014501d6b533$8444cfb0$8cce6f10$@SGA.Ninja> References: <02ce01d6b40d$ff230cf0$fd6926d0$@SGA.Ninja> <006301d6b489$001b0ba0$005122e0$@SGA.Ninja> <58689f34-0961-e65e-b473-a3fb596d6e39@wichmann.us> <014501d6b533$8444cfb0$8cce6f10$@SGA.Ninja> Message-ID: <50ddc8de-d53c-9d2f-c93f-84abd7d9e236@wichmann.us> On 11/7/20 11:26 AM, Steve wrote: > Ok, I think I see a light in the fog. > > > > It looks as if I can identify a variable to contain a library. > > Import datetime as dt1 > > > > I guess that I can have a second variable containing that same library: > > Import datetime as dt2 > > > > Should I presume that not doing this is what caused the interference in my > code? > > > > In your example: > >>>> import datetime as dt > >>>> from datetime import datetime > >>>> globals() > > {'__name__': '__main__', '__doc__': None, '__package__': None, > > '__loader__': , '__spec__': > > None, '__annotations__': {}, '__builtins__': > (built-in)>, 'dt': '/usr/lib64/python3.8/datetime.py'>, > 'datetime': } > > > > How does your line3 and line2 relate to line1? > It looks as if they relate to dt but it is not specifically stated. Is it > because they are consecutive lines? > > In the list of globals, I see :{}, seems bizarre.. it was just to show that the symbol 'dt' refers to the module object for datetime, and the symbol 'datetime' refers to the datetime class from the datetime module - since they're different names they can coexist; earlier when you imported both as datetime, the second one overwrote the first one. Sorry, I'm probably confusing you more. From Gronicus at SGA.Ninja Sat Nov 7 22:57:22 2020 From: Gronicus at SGA.Ninja (Steve) Date: Sat, 7 Nov 2020 22:57:22 -0500 Subject: Is there a conflict of libraries here? In-Reply-To: <20201107193235.GA21534@hjp.at> References: <02ce01d6b40d$ff230cf0$fd6926d0$@SGA.Ninja> <006301d6b489$001b0ba0$005122e0$@SGA.Ninja> <58689f34-0961-e65e-b473-a3fb596d6e39@wichmann.us> <014501d6b533$8444cfb0$8cce6f10$@SGA.Ninja> <20201107193235.GA21534@hjp.at> Message-ID: <002401d6b583$43aaf970$cb00ec50$@SGA.Ninja> Ok, the light just went out. I thought I was getting something, but no... I will keep on reading, maybe it will hatch. Maybe a different approach. What is happening here? (Should this be a new thread?) import tkinter as tk from tkinter import * from tkinter import ttk ------------------------------------------------------------------ Footnote: Mars is the only known planet in our solar system solely inhabited by functioning robots. -----Original Message----- From: Python-list On Behalf Of Peter J. Holzer Sent: Saturday, November 7, 2020 2:33 PM To: python-list at python.org Subject: Re: Is there a conflict of libraries here? On 2020-11-07 13:26:30 -0500, Steve wrote: > Ok, I think I see a light in the fog. > > It looks as if I can identify a variable to contain a library. > > Import datetime as dt1 > > I guess that I can have a second variable containing that same library: > > Import datetime as dt2 > > Should I presume that not doing this is what caused the interference > in my code? Not quite. The problem isn't that you imported the library twice, but that you have a library (package/module) and a class of the same name. When you try to import both with that name, only one of them will be visible, since you can't have one name refer to two different things at the same time. >>> import datetime The name datetime now refers to the module datetime: >>> datetime >>> id(datetime) 140407076788160 >>> from datetime import datetime Now the name datetime now refers to the class datetime: >>> datetime >>> id(datetime) 9612160 You can import one or both of them with different names: >>> import datetime as dt_module >>> dt_module >>> id(dt_module) 140407076788160 >>> from datetime import datetime as dt_class dt_class >>> id(dt_class) 9612160 hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" From cs at cskk.id.au Sun Nov 8 04:04:43 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Sun, 8 Nov 2020 20:04:43 +1100 Subject: Is there a conflict of libraries here? In-Reply-To: <002401d6b583$43aaf970$cb00ec50$@SGA.Ninja> References: <002401d6b583$43aaf970$cb00ec50$@SGA.Ninja> Message-ID: <20201108090443.GA69171@cskk.homeip.net> On 07Nov2020 22:57, Steve wrote: >Ok, the light just went out. >I thought I was getting something, but no... > >I will keep on reading, maybe it will hatch. You're probably overthinking this. I'll address your new example below. First up: numbers are objects, strings are objects, classes are objects, modules are objects. A variable can refer to any of them. So when you do an import you're setting a name to refer to a module, or to refer to something from within a module. Consider this: x = 3 x = 4 What is x? It's 4, because that happened second. An import is just a special form of assignment statement, with an implicit module load behind the scenes. So consider this: import datetime from datetime import datetime Each of these assigns to the name "datetime". The former assigns the module named "datetime". The latter assigns the _class_ named 'datetime" from inside the module. One happens after the other, so after this the name "datetime" refers to the class. Alternatively: import datetime datetime = datetime.datetime "datetime" starts referring to the datetime module. Then we reassign it to the "datetime" class that is inside the module. The effect is the same as the previous pair of lines. It is unfortunate that the "datetime" module contains a "datetime" class. It makes for a lot of confusion. Modern classes start with uppercase letters (entirely by convention), which reduces this issue - you have a better idea of what you're looking at just from the name. It's been mentioned in this thread, but perhaps been as obvious as it could have been: if you need to refer to the module "datetime", and also the class "datetime" from within it, assign them to different variables: import datetime dt = datetime.datetime Now you have "datetime" referring to the module, and "dt" referring to the class. >Maybe a different approach. >What is happening here? >(Should this be a new thread?) No, keep the thread -it is the same discussion and really the same issue. It keeps it all together for us, too. >import tkinter as tk Equivalent to this: import sys tk = sys.modules['tkinter'] >from tkinter import * a = sys.modules['tkinter'].a b = sys.modules['tkinter'].b c = sys.modules['tkinter'].c ... for each name defined in the tkinter module. Try to avoid this incantation - it sucks in a large uncontrolled list of names into your script. Some small scripts do it for simple things where's they're really working against only one module. In most things it is unhelpful. >from tkinter import ttk ttk = sys.modules['tkinter'].ttk All of these 3 things set local variables/names in your script to some value. The "*" import sets a bunch of variables. Cheers, Cameron Simpson From variablestarlight at gmail.com Sun Nov 8 06:56:58 2020 From: variablestarlight at gmail.com (=?UTF-8?Q?Hern=c3=a1n_De_Angelis?=) Date: Sun, 8 Nov 2020 12:56:58 +0100 Subject: Questions about XML processing? In-Reply-To: <24486.61300.350766.623469@ixdm.fritz.box> References: <519d01c1-d584-2c22-f82e-859a6a634367@gmail.com> <5bab621e-6811-4296-d1d5-3649f9688362@gmail.com> <24486.61300.350766.623469@ixdm.fritz.box> Message-ID: On 2020-11-07 20:03, Dieter Maurer wrote: > Hern?n De Angelis wrote at 2020-11-6 21:54 +0100: >> ... >> However, the hard thing to do here is to get those only when >> tagC/note/title/string='value'. I was expecting to find a way of >> specifying a certain construction in square brackets, like >> [@string='value'] or [@/tagC/note/title/string='value'], as is usual in >> XML and possible in xml.etree. However this proved difficult (at least >> for me). So this is the "brute" solution I implemented: > You might have a look at `lxml`. > It supports XPath (1.0) which is more powerfull in selecting nodes > than `etree`. Yes, I am having a look at that. Thanks. From tjreedy at udel.edu Sat Nov 7 21:26:01 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Sat, 7 Nov 2020 21:26:01 -0500 Subject: Is there a conflict of libraries here? In-Reply-To: <006301d6b489$001b0ba0$005122e0$@SGA.Ninja> References: <02ce01d6b40d$ff230cf0$fd6926d0$@SGA.Ninja> <006301d6b489$001b0ba0$005122e0$@SGA.Ninja> Message-ID: On 11/6/2020 5:05 PM, Steve wrote: > "Right, because the name "datetime" points to the class datetime in the > module datetime. A module containing an object with the same name as the module is a real pain, a constant mental papercut. I consider datetime.datetime to be a design mistake*. You are the 2nd person in about a month to post the same resulting code problem. * Either the class should have been 'Datetime', capitalized like classes in modules other that builtins generally should be, or the module should have been given a different name. I personally would always rename the module when imported. -- Terry Jan Reedy From smoa.blx at yahoo.com Sun Nov 8 05:03:29 2020 From: smoa.blx at yahoo.com (SMOA BLX) Date: Sun, 8 Nov 2020 10:03:29 +0000 (UTC) Subject: Is there a conflict of libraries here? In-Reply-To: <20201108090443.GA69171@cskk.homeip.net> References: <002401d6b583$43aaf970$cb00ec50$@SGA.Ninja> <20201108090443.GA69171@cskk.homeip.net> Message-ID: <1753083160.3013980.1604829809425@mail.yahoo.com> ha! ha! 2 empowering___ we make it. ______________ +44 1635 887711 On Sunday, November 8, 2020, 01:06:03 a.m. PST, Cameron Simpson wrote: On 07Nov2020 22:57, Steve wrote: >Ok, the light just went out. >I thought I was getting something, but no... > >I will keep on reading, maybe it will hatch. You're probably overthinking this. I'll address your new example below. First up: numbers are objects, strings are objects, classes are objects, modules are objects. A variable can refer to any of them. So when you do an import you're setting a name to refer to a module, or to refer to something from within a module. Consider this: ? ? x = 3 ? ? x = 4 What is x? It's 4, because that happened second. An import is just a special form of assignment statement, with an implicit module load behind the scenes. So consider this: ? ? import datetime ? ? from datetime import datetime Each of these assigns to the name "datetime". The former assigns the module named "datetime". The latter assigns the _class_ named 'datetime" from inside the module. One happens after the other, so after this the name "datetime" refers to the class. Alternatively: ? ? import datetime ? ? datetime = datetime.datetime "datetime" starts referring to the datetime module. Then we reassign it to the "datetime" class that is inside the module. The effect is the same as the previous pair of lines. It is unfortunate that the "datetime" module contains a "datetime" class. It makes for a lot of confusion. Modern classes start with uppercase letters (entirely by convention), which reduces this issue - you have a better idea of what you're looking at just from the name. It's been mentioned in this thread, but perhaps been as obvious as it could have been: if you need to refer to the module "datetime", and also the class "datetime" from within it, assign them to different variables: ? ? import datetime ? ? dt = datetime.datetime Now you have "datetime" referring to the module, and "dt" referring to the class. >Maybe a different approach. >What is happening here? >(Should this be a new thread?) No, keep the thread? -it is the same discussion and really the same issue. It keeps it all together for us, too. >import tkinter as tk Equivalent to this: ? ? import sys ? ? tk = sys.modules['tkinter'] >from tkinter import * ? ? a = sys.modules['tkinter'].a ? ? b = sys.modules['tkinter'].b ? ? c = sys.modules['tkinter'].c ? ? ... for each name defined in the tkinter module. Try to avoid this incantation - it sucks in a large uncontrolled list of names into your script. Some small scripts do it for simple things where's they're really working against only one module. In most things it is unhelpful. >from tkinter import ttk ? ? ttk = sys.modules['tkinter'].ttk All of these 3 things set local variables/names in your script to some value. The "*" import sets a bunch of variables. Cheers, Cameron Simpson -- https://mail.python.org/mailman/listinfo/python-list From rosuav at gmail.com Sun Nov 8 09:56:41 2020 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 9 Nov 2020 01:56:41 +1100 Subject: Is there a conflict of libraries here? In-Reply-To: References: <02ce01d6b40d$ff230cf0$fd6926d0$@SGA.Ninja> <006301d6b489$001b0ba0$005122e0$@SGA.Ninja> Message-ID: On Mon, Nov 9, 2020 at 1:11 AM Terry Reedy wrote: > > On 11/6/2020 5:05 PM, Steve wrote: > > "Right, because the name "datetime" points to the class datetime in the > > module datetime. > > A module containing an object with the same name as the module is a real > pain, a constant mental papercut. I consider datetime.datetime to be a > design mistake*. You are the 2nd person in about a month to post the > same resulting code problem. > > * Either the class should have been 'Datetime', capitalized like classes > in modules other that builtins generally should be, or the module should > have been given a different name. I personally would always rename the > module when imported. > Yes, it's annoying, but it's only annoying when code on the internet suggests "from datetime import *", which IMO is the real mental papercut. If everything was written assuming "import datetime", there'd be only a very minor confusion. So, my suggestion to anyone who's struggling with datetime is: Don't ever write "from datetime import *" or "from datetime import datetime". Your code may break in the short term, but if it does, it's a solvable break. ChrisA From Richard at Damon-Family.org Sun Nov 8 11:40:21 2020 From: Richard at Damon-Family.org (Richard Damon) Date: Sun, 8 Nov 2020 11:40:21 -0500 Subject: Is there a conflict of libraries here? In-Reply-To: References: <02ce01d6b40d$ff230cf0$fd6926d0$@SGA.Ninja> <006301d6b489$001b0ba0$005122e0$@SGA.Ninja> Message-ID: <0709cd2f-d96c-6802-920d-e43c54a013b5@Damon-Family.org> On 11/7/20 9:26 PM, Terry Reedy wrote: > On 11/6/2020 5:05 PM, Steve wrote: >> "Right, because the name "datetime" points to the class datetime in the >> module datetime. > > A module containing an object with the same name as the module is a > real pain, a constant mental papercut.? I consider datetime.datetime > to be a design mistake*.? You are the 2nd person in about a month to > post the same resulting code problem. > > * Either the class should have been 'Datetime', capitalized like > classes in modules other that builtins generally should be, or the > module should have been given a different name.? I personally would > always rename the module when imported. > Which says that if you do: import datetime from datetime import datatime as Datatime you get the class in your module as the more modern capitalized name, and avoid the name conflict. It just says that in your code, to use the class you either need to use Datatime or datetime.datetime -- Richard Damon From qberz2005 at gmail.com Sun Nov 8 13:50:19 2020 From: qberz2005 at gmail.com (Quentin Bock) Date: Sun, 8 Nov 2020 13:50:19 -0500 Subject: returning totals in functions of math Message-ID: Errors say that add takes 1 positional argument but 3 were given? Does this limit how many numbers I can have or do I need other variables? Here is what I have: def add(numbers): total = 1 for x in numbers: total += x return total print(add(1999, -672, 84)) I have a multiply function above it but that was solved and I'm trying to figure everything out for each of the different math functions. Thank you From pkpearson at nowhere.invalid Sun Nov 8 14:00:34 2020 From: pkpearson at nowhere.invalid (Peter Pearson) Date: 8 Nov 2020 19:00:34 GMT Subject: returning totals in functions of math References: Message-ID: On Sun, 8 Nov 2020 13:50:19 -0500, Quentin Bock wrote: > Errors say that add takes 1 positional argument but 3 were given? Does this > limit how many numbers I can have or do I need other variables? > Here is what I have: > def add(numbers): > total = 1 > for x in numbers: > total += x > return total > print(add(1999, -672, 84)) Your function "add" expects a single argument that is a list of numbers. You're passing it three arguments, each a number. Try add([1999, -672, 84]). -- To email me, substitute nowhere->runbox, invalid->com. From qberz2005 at gmail.com Sun Nov 8 14:25:22 2020 From: qberz2005 at gmail.com (Quentin Bock) Date: Sun, 8 Nov 2020 14:25:22 -0500 Subject: answer not correct Message-ID: *def add(numbers):* * total = 1* * for x in numbers:* * total += 1* * return total* *print(add[1999, -672, 64]))* *the answer I get is 4 but it should be 1,411* From 2QdxY4RzWzUUiLuE at potatochowder.com Sun Nov 8 14:14:30 2020 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Sun, 8 Nov 2020 13:14:30 -0600 Subject: returning totals in functions of math In-Reply-To: References: Message-ID: <20201108191430.GG33753@scrozzle> On 2020-11-08 at 19:00:34 +0000, Peter Pearson wrote: > On Sun, 8 Nov 2020 13:50:19 -0500, Quentin Bock wrote: > > Errors say that add takes 1 positional argument but 3 were given? Does this > > limit how many numbers I can have or do I need other variables? > > Here is what I have: > > def add(numbers): > > total = 1 > > for x in numbers: > > total += x > > return total > > print(add(1999, -672, 84)) > > Your function "add" expects a single argument that is a list > of numbers. You're passing it three arguments, each a number. > Try add([1999, -672, 84]). Or change add to accept an arbitrary number of arguments and collect them into a tuple: def add(*numbers): # then the rest of the function as before BTW, why initialize total to 1? From qberz2005 at gmail.com Sun Nov 8 14:47:51 2020 From: qberz2005 at gmail.com (Quentin Bock) Date: Sun, 8 Nov 2020 14:47:51 -0500 Subject: returning totals in functions of math In-Reply-To: <20201108191430.GG33753@scrozzle> References: <20201108191430.GG33753@scrozzle> Message-ID: Ok, I don't know how to change add to accept an arbitrary number of arguments (I'm pretty new) and as for total = 1 idk but it worked for other versions of this (multiplication), and figured it might work for this one, do you have any tips on what a better number might be for the total to equal? On Sun, 8 Nov 2020 at 14:37, <2QdxY4RzWzUUiLuE at potatochowder.com> wrote: > On 2020-11-08 at 19:00:34 +0000, > Peter Pearson wrote: > > > On Sun, 8 Nov 2020 13:50:19 -0500, Quentin Bock > wrote: > > > Errors say that add takes 1 positional argument but 3 were given? Does > this > > > limit how many numbers I can have or do I need other variables? > > > Here is what I have: > > > def add(numbers): > > > total = 1 > > > for x in numbers: > > > total += x > > > return total > > > print(add(1999, -672, 84)) > > > > Your function "add" expects a single argument that is a list > > of numbers. You're passing it three arguments, each a number. > > Try add([1999, -672, 84]). > > Or change add to accept an arbitrary number of arguments and collect > them into a tuple: > > def add(*numbers): > # then the rest of the function as before > > BTW, why initialize total to 1? > -- > https://mail.python.org/mailman/listinfo/python-list > From rambiusparkisanius at gmail.com Sun Nov 8 14:53:45 2020 From: rambiusparkisanius at gmail.com (Ivan "Rambius" Ivanov) Date: Sun, 8 Nov 2020 14:53:45 -0500 Subject: answer not correct In-Reply-To: References: Message-ID: Hello, First of all, remove the asterisks around the snippet, it makes it so hard to copy and paste your code. My answer is inlined. On Sun, Nov 8, 2020 at 2:28 PM Quentin Bock wrote: > > *def add(numbers):* > * total = 1* If this is your sum, you need to initialize it to zero: total = 0 > * for x in numbers:* > * total += 1* Do you mean total += x? Regards rambius > * return total* > *print(add[1999, -672, 64]))* > > *the answer I get is 4 but it should be 1,411* > -- > https://mail.python.org/mailman/listinfo/python-list -- Tangra Mega Rock: http://www.radiotangra.com From python at mrabarnett.plus.com Sun Nov 8 14:57:09 2020 From: python at mrabarnett.plus.com (MRAB) Date: Sun, 8 Nov 2020 19:57:09 +0000 Subject: answer not correct In-Reply-To: References: Message-ID: On 2020-11-08 19:25, Quentin Bock wrote: > *def add(numbers):* > * total = 1* > * for x in numbers:* > * total += 1* > * return total* > *print(add[1999, -672, 64]))* > > *the answer I get is 4 but it should be 1,411* > 1. You typed "total += 1", which means it's adding 1 each time around the loop. 2. The print line as written above is incorrect. 3. I don't see how can the answer be 1,411! From PythonList at DancesWithMice.info Sun Nov 8 15:11:49 2020 From: PythonList at DancesWithMice.info (dn) Date: Mon, 9 Nov 2020 09:11:49 +1300 Subject: returning totals in functions of math In-Reply-To: References: <20201108191430.GG33753@scrozzle> Message-ID: On 09/11/2020 08:47, Quentin Bock wrote: > Ok, I don't know how to change add to accept an arbitrary number of > arguments (I'm pretty new) and as for total = 1 idk but it worked for other > versions of this (multiplication), and figured it might work for this one, > do you have any tips on what a better number might be for the total to > equal? Fair comment - arguments discussed in previous post - try what has been suggested... The "Law of Identity" is that zero added to anything doesn't change the value, eg 1 + 0 = 1; 1 million + 0 = 1 million... -- Regards =dn From PythonList at DancesWithMice.info Sun Nov 8 15:09:11 2020 From: PythonList at DancesWithMice.info (dn) Date: Mon, 9 Nov 2020 09:09:11 +1300 Subject: returning totals in functions of math In-Reply-To: <20201108191430.GG33753@scrozzle> References: <20201108191430.GG33753@scrozzle> Message-ID: <49b2aecb-671a-70c8-b5ed-9d00beea1ebe@DancesWithMice.info> Comments interposed:- On 09/11/2020 08:14, 2QdxY4RzWzUUiLuE at potatochowder.com wrote: > On 2020-11-08 at 19:00:34 +0000, > Peter Pearson wrote: >> On Sun, 8 Nov 2020 13:50:19 -0500, Quentin Bock wrote: >>> Errors say that add takes 1 positional argument but 3 were given? Does this >>> limit how many numbers I can have or do I need other variables? >>> Here is what I have: >>> def add(numbers): >>> total = 1 >>> for x in numbers: >>> total += x >>> return total >>> print(add(1999, -672, 84)) >> >> Your function "add" expects a single argument that is a list >> of numbers. You're passing it three arguments, each a number. >> Try add([1999, -672, 84]). Minor point ('here'): aren't arguments passed as a tuple? (cf "list") [next point probably more advanced than OP requires] Major 'gotchas' elsewhere: remember the difference between passing an immutable, cf a mutable, argument (tuple cf list)! Also related, functions' name-spaces: >>> my_list = [ 1, 2, 3 ] >>> def function1( any_list ): ... any_list = [ 4, 5, 6 ] ... >>> function1( my_list ) >>> my_list [1, 2, 3] >>> def function2( any_list ): ... any_list.append( [ 4, 5, 6 ] ) ... >>> function2( my_list ) >>> my_list [1, 2, 3, [4, 5, 6]] - neither of which works with tuples... Some refer to such mutable 'flexibility' as a "side-effect" and thus undesirable/to be avoided. > Or change add to accept an arbitrary number of arguments and collect > them into a tuple: > > def add(*numbers): > # then the rest of the function as before +1 > BTW, why initialize total to 1? Because OP copied 'multiply' code, completed earlier? [OP] Once you have this code working, as above, consider refactoring to use sum()... Web.Refs: https://docs.python.org/3/library/functions.html https://riptutorial.com/python/example/28509/mutable-and-immutable-as-arguments -- Regards =dn From PythonList at danceswithmice.info Sun Nov 8 15:52:21 2020 From: PythonList at danceswithmice.info (dn) Date: Mon, 9 Nov 2020 09:52:21 +1300 Subject: returning totals in functions of math In-Reply-To: References: <20201108191430.GG33753@scrozzle> <49b2aecb-671a-70c8-b5ed-9d00beea1ebe@DancesWithMice.info> Message-ID: <46520bfb-1ab1-70a0-c6bb-aca3f36f499a@DancesWithMice.info> On 09/11/2020 09:41, Quentin Bock wrote: > Okay, thank you :) I didn't understand about 90% of what you explained > lol (sorry) but the sum worked and I have the correct answer. Also, do > you know any numbers that could replace 1 in this function as the total? > just curious > Thanks :) Yes, apologies to you. Some of those points were discussing another response. Its content was quite advanced. Please ignore, as noted. Am assuming that the question about "1" has been answered. OK? Please post* the successful code for both multiply() and add(), then we will be able to help you draw comparisons and/or re-factor (improve the code - or improve the approach) - whether your question is about 'math' or about 'Python'. * best to copy-paste directly from the code-editor. Incidentally, if you would prefer, there is a "Tutor" list where <<>> https://mail.python.org/mailman/listinfo/tutor -- Regards =dn From inhahe at gmail.com Sun Nov 8 16:46:40 2020 From: inhahe at gmail.com (inhahe) Date: Sun, 8 Nov 2020 16:46:40 -0500 Subject: returning totals in functions of math In-Reply-To: References: Message-ID: On Sun, Nov 8, 2020 at 1:51 PM Quentin Bock wrote: > Errors say that add takes 1 positional argument but 3 were given? Does this > limit how many numbers I can have or do I need other variables? > Here is what I have: > def add(numbers): > total = 1 > for x in numbers: > total += x > return total > print(add(1999, -672, 84)) > > I have a multiply function above it but that was solved and I'm trying to > figure everything out for each of the different math functions. > Thank you > -- > https://mail.python.org/mailman/listinfo/python-list By the way, did you know about the `sum` function? It does basically what your add function does, except I think you'd need to pass it an initial value so it knows what type it's adding, or something like that. From tjreedy at udel.edu Sun Nov 8 19:47:34 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Sun, 8 Nov 2020 19:47:34 -0500 Subject: Is there a conflict of libraries here? In-Reply-To: References: <02ce01d6b40d$ff230cf0$fd6926d0$@SGA.Ninja> <006301d6b489$001b0ba0$005122e0$@SGA.Ninja> Message-ID: On 11/8/2020 9:56 AM, Chris Angelico wrote: > On Mon, Nov 9, 2020 at 1:11 AM Terry Reedy wrote: >> A module containing an object with the same name as the module is a real >> pain, a constant mental papercut. I consider datetime.datetime to be a >> design mistake*. You are the 2nd person in about a month to post the >> same resulting code problem. >> >> * Either the class should have been 'Datetime', capitalized like classes >> in modules other that builtins generally should be, or the module should >> have been given a different name. I personally would always rename the >> module when imported. >> > > Yes, it's annoying, but it's only annoying when code on the internet > suggests "from datetime import *", I agree that the latter is annoying, but I disagree about 'only'. Names pointing to two different objects (or people ;-) are ambiguous without additional disambiguation. If I write 'datetime has an off-by-one bug' or 'datetime is great', which datetime do I mean? idlelib once had multiple name.name pairs, such as Debugger.Debugger, and to me, the nuisance of fixing them (as per PEP 434 and subsequent decision by the BDFL-delegate) has now been outweighed by the continuing benefit. -- Terry Jan Reedy From rosuav at gmail.com Mon Nov 9 00:20:58 2020 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 9 Nov 2020 16:20:58 +1100 Subject: Is there a conflict of libraries here? In-Reply-To: References: <02ce01d6b40d$ff230cf0$fd6926d0$@SGA.Ninja> <006301d6b489$001b0ba0$005122e0$@SGA.Ninja> Message-ID: On Mon, Nov 9, 2020 at 3:32 PM Terry Reedy wrote: > > On 11/8/2020 9:56 AM, Chris Angelico wrote: > > On Mon, Nov 9, 2020 at 1:11 AM Terry Reedy wrote: > > >> A module containing an object with the same name as the module is a real > >> pain, a constant mental papercut. I consider datetime.datetime to be a > >> design mistake*. You are the 2nd person in about a month to post the > >> same resulting code problem. > >> > >> * Either the class should have been 'Datetime', capitalized like classes > >> in modules other that builtins generally should be, or the module should > >> have been given a different name. I personally would always rename the > >> module when imported. > >> > > > > Yes, it's annoying, but it's only annoying when code on the internet > > suggests "from datetime import *", > > I agree that the latter is annoying, but I disagree about 'only'. Names > pointing to two different objects (or people ;-) are ambiguous without > additional disambiguation. If I write 'datetime has an off-by-one bug' > or 'datetime is great', which datetime do I mean? Perhaps, but certainly the confusion is far less when the module is always imported as itself, and then the class is "datetime.datetime" which nicely parallels "datetime.date" and "datetime.time". If we could abuse Guido's time machine and have them as "datetime.DateTime" etc, I would definitely be in favour of it. I don't know that it'd be worth actually changing, though, and even adding aliases doesn't really seem worthwhile IMO. > idlelib once had multiple name.name pairs, such as Debugger.Debugger, > and to me, the nuisance of fixing them (as per PEP 434 and subsequent > decision by the BDFL-delegate) has now been outweighed by the continuing > benefit. Yes, but the nuisance of fixing internal idlelib details isn't nearly as strong as renaming a public class :) ChrisA From ethan at stoneleaf.us Mon Nov 9 13:24:55 2020 From: ethan at stoneleaf.us (Ethan Furman) Date: Mon, 9 Nov 2020 10:24:55 -0800 Subject: Is there a conflict of libraries here? In-Reply-To: References: <02ce01d6b40d$ff230cf0$fd6926d0$@SGA.Ninja> <006301d6b489$001b0ba0$005122e0$@SGA.Ninja> Message-ID: On 11/8/20 9:20 PM, Chris Angelico wrote: > Perhaps, but certainly the confusion is far less when the module is > always imported as itself, and then the class is "datetime.datetime" > which nicely parallels "datetime.date" and "datetime.time". I find doubled names such as "datetime.datetime" both jarring and visual noise. Thankfully, we can rename modules on import: import datetime as dt import time as t import PIL.Image as im As for "from blablah import *" -- that should only be done with modules specifically designed for it; having said that, it looks like datetime.py was so designed. So, if I had a module making extensive use of the datetime contents, and wasn't using the time module, I would have no problem with "from datetime import *". On the other hand, if datetime was only a small portion of my module, I would "import datetime as dt". -- ~Ethan~ From qberz2005 at gmail.com Mon Nov 9 16:04:28 2020 From: qberz2005 at gmail.com (Quentin Bock) Date: Mon, 9 Nov 2020 16:04:28 -0500 Subject: How can I make this more complex? Message-ID: grade = input("Enter your grade: ") if grade >= 90: print("You got an A ") if grade >= 80: print("You got a B ") if grade >= 70: print("You got a C") if grade >= 60: print("You got a D ") if grade >= 50: print("You failed") How can I make this to say if your grade is 90 or higher BUT less than 100 you got an A, Thanks From inhahe at gmail.com Mon Nov 9 18:12:22 2020 From: inhahe at gmail.com (inhahe) Date: Mon, 9 Nov 2020 18:12:22 -0500 Subject: How can I make this more complex? In-Reply-To: References: Message-ID: if 100 > grade >= 90: On Mon, Nov 9, 2020 at 6:01 PM Quentin Bock wrote: > grade = input("Enter your grade: ") > if grade >= 90: > print("You got an A ") > if grade >= 80: > print("You got a B ") > if grade >= 70: > print("You got a C") > if grade >= 60: > print("You got a D ") > if grade >= 50: > print("You failed") > > > > > How can I make this to say if your grade is 90 or higher BUT less than 100 > you got an A, > Thanks > -- > https://mail.python.org/mailman/listinfo/python-list > From bgailer at gmail.com Mon Nov 9 18:21:07 2020 From: bgailer at gmail.com (Bob Gailer) Date: Mon, 9 Nov 2020 18:21:07 -0500 Subject: How can I make this more complex? In-Reply-To: References: Message-ID: On Nov 9, 2020 5:59 PM, "Quentin Bock" wrote: > > grade = input("Enter your grade: ") > if grade >= 90: > print("You got an A ") > if grade >= 80: > print("You got a B ") > if grade >= 70: > print("You got a C") > if grade >= 60: > print("You got a D ") > if grade >= 50: > print("You failed") > > > > > How can I make this to say if your grade is 90 or higher BUT less than 100 > you got an A if 100 > grade <= 90: Additional suggestions: change all but the first if to elif From python at mrabarnett.plus.com Mon Nov 9 19:00:33 2020 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 10 Nov 2020 00:00:33 +0000 Subject: How can I make this more complex? In-Reply-To: References: Message-ID: <4de1f5af-8687-6093-57e5-68b73bdc343d@mrabarnett.plus.com> On 2020-11-09 21:04, Quentin Bock wrote: > grade = input("Enter your grade: ") > if grade >= 90: > print("You got an A ") > if grade >= 80: > print("You got a B ") > if grade >= 70: > print("You got a C") > if grade >= 60: > print("You got a D ") > if grade >= 50: > print("You failed") > > > > > How can I make this to say if your grade is 90 or higher BUT less than 100 > you got an A, > In addition to other the answers, you should note that the 'input' function returns a string, so you'll need to convert that string to a number, most probably by using 'int', and, ideally, print a helpful message if that raises ValueError because it's not a valid number. From PythonList at DancesWithMice.info Mon Nov 9 21:35:02 2020 From: PythonList at DancesWithMice.info (dn) Date: Tue, 10 Nov 2020 15:35:02 +1300 Subject: How can I make this more complex? In-Reply-To: References: Message-ID: <5492f1d0-af76-2adb-bdbd-ecee8175cd74@DancesWithMice.info> On 10/11/2020 10:04, Quentin Bock wrote: > grade = input("Enter your grade: ") > if grade >= 90: > print("You got an A ") > if grade >= 80: > print("You got a B ") > if grade >= 70: > print("You got a C") > if grade >= 60: > print("You got a D ") > if grade >= 50: > print("You failed") First: open a Python terminal (REPL) and try: import this (wrt the post's title, lines three and four apply. This output is known as "The Zen of Python"!) Did you ever run the code? Hint: it won't work, and even when 'fixed' won't work the way you want, either. What if the grade is < 50? If the grade is 55, which message(s) should be printed? (compare: syntax errors, semantic errors, and errors in logic) Others have mentioned elif. Why? If the code looks like a "ladder" with criteria being applied to the same variable at every step, only one will be chosen with an elif structure, but >=1 choice will be made without (as above). Complexity? Sure, if that's what you want, we've got complexity, but it'll cost you... (as I tell my trainees: "just because we can do it, does not make it a good idea!") Build a dictionary of "buckets" - with the (lowest point) grade-steps as keys and the applicable messages as values (this will actually be easier to maintain than the 'ladder'!), eg 90:"You got an A " 80:"You got a B " ... 0:"You didn't say what should happen" Take the grade, check, and properly prepare it(!) (why "check"?) Loop through the dictionary: if the grade 'fits into' this bucket: print the message break # no point in continuing to loop # otherwise continue looping Not to be recommended - but if you are a 'glutton for punishment', don't bother with the dictionary's 0/last entry. Instead use a for-else structure... Such would be an excellent case-study illustration of why 'simple' beats 'complex'! (sorry for the sardonic humor, disregard the last paragraph - most professional coders (in fact, all that I know) eschew for-else, or-else!) -- Regards =dn From ml_news at posteo.de Tue Nov 10 01:24:44 2020 From: ml_news at posteo.de (Manfred Lotz) Date: Tue, 10 Nov 2020 07:24:44 +0100 Subject: Changing strings in files Message-ID: <20201110072444.5acf0769@arcor.com> I have a situation where in a directory tree I want to change a certain string in all files where that string occurs. My idea was to do - os.scandir and for each file - check if a file is a text file - if it is not a text file skip that file - change the string as often as it occurs in that file What is the best way to check if a file is a text file? In a script I could use the `file` command which is not ideal as I have to grep the result. In Perl I could do -T file. How to do best in Python? -- Thanks, Manfred From loris.bennett at fu-berlin.de Tue Nov 10 02:19:55 2020 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Tue, 10 Nov 2020 08:19:55 +0100 Subject: Changing strings in files References: <20201110072444.5acf0769@arcor.com> Message-ID: <87v9edsmp0.fsf@hornfels.zedat.fu-berlin.de> Manfred Lotz writes: > I have a situation where in a directory tree I want to change a certain > string in all files where that string occurs. > > My idea was to do > > - os.scandir and for each file > - check if a file is a text file > - if it is not a text file skip that file > - change the string as often as it occurs in that file > > > What is the best way to check if a file is a text file? In a script I > could use the `file` command which is not ideal as I have to grep the > result. In Perl I could do -T file. > > How to do best in Python? If you are on Linux and more interested in the result than the programming exercise, I would suggest the following non-Python solution: find . -type -f -exec sed -i 's/foo/bar/g' {} \; Having said that, I would be interested to know what the most compact way of doing the same thing in Python might be. Cheers, Loris -- This signature is currently under construction. From cs at cskk.id.au Tue Nov 10 02:37:54 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Tue, 10 Nov 2020 18:37:54 +1100 Subject: Changing strings in files In-Reply-To: <20201110072444.5acf0769@arcor.com> References: <20201110072444.5acf0769@arcor.com> Message-ID: <20201110073754.GA46480@cskk.homeip.net> On 10Nov2020 07:24, Manfred Lotz wrote: >I have a situation where in a directory tree I want to change a certain >string in all files where that string occurs. > >My idea was to do > >- os.scandir and for each file Use os.walk for trees. scandir does a single directory. > - check if a file is a text file This requires reading the entire file. You want to check that it consists entirely of lines of text. In your expected text encoding - these days UTF-8 is the common default, but getting this correct is essential if you want to recognise text. So as a first cut, totally untested: for dirpath, filenames, dirnames in os.walk(top_dirpath): is_text = False try: # expect utf-8, fail if non-utf-8 bytes encountered with open(filename, encoding='utf-8', errors='strict') as f: for lineno, line in enumerate(f, 1): ... other checks on each line of the file ... if not line.endswith('\n'): raise ValueError("line %d: no trailing newline" lineno) if str.isprintable(line[:-1]): raise ValueError("line %d: not all printable" % lineno) # if we get here all checks passed, consider the file to # be text is_text = True except Exception as e: print(filename, "not text", e) if not is_text: print("skip", filename) continue You could add all sorts of other checks. "text" is a loosely defined idea. But you could assert: all these lines decoded cleanly, so I can't do much damage rewriting them. > - if it is not a text file skip that file > - change the string as often as it occurs in that file You could, above, gather up all the lines in the file in a list. If you get through, replace your string in the list and if anything was changed, rewrite the file from the list of lines. >What is the best way to check if a file is a text file? In a script I >could use the `file` command which is not ideal as I have to grep the >result. Not to mention relying on file, which (a) has a simple idea of text and (b) only looks at the start of each file, not the whole content. Very dodgy. If you're really batch editing files, you could (a) put everything into a VCS (eg hg or git) so you can roll back changes or (b) work on a copy of your directory tree or (c) just print the "text" filenames to stdout and pipe that into GNU parallel, invoking "sed -i.bak s/this/that/g" to batch edit the checked files, keeping a backup. Cheers, Cameron Simpson From miked at dewhirst.com.au Tue Nov 10 02:52:26 2020 From: miked at dewhirst.com.au (Mike Dewhirst) Date: Tue, 10 Nov 2020 18:52:26 +1100 Subject: Changing strings in files In-Reply-To: <20201110072444.5acf0769@arcor.com> References: <20201110072444.5acf0769@arcor.com> Message-ID: <935a0b5a-4337-243f-2545-a77f8abf00cd@dewhirst.com.au> On 10/11/2020 5:24 pm, Manfred Lotz wrote: > I have a situation where in a directory tree I want to change a certain > string in all files where that string occurs. > > My idea was to do > > - os.scandir and for each file > - check if a file is a text file > - if it is not a text file skip that file > - change the string as often as it occurs in that file > > > What is the best way to check if a file is a text file? In a script I > could use the `file` command which is not ideal as I have to grep the > result. In Perl I could do -T file. > > How to do best in Python? Not necessarily best but I rolled this earlier. Much earlier. But I still use it. I don't need to worry about text files or binary because I specify .py files. # -*- coding: utf-8 -*- """ Look for string 'find' and replace it with string 'repl' in all files in the current directory and all sub-dirs. If anything untoward happens, laboriously retrieve each original file from each individual backup made by suffixing ~ to the filename. If everything went well, make find == repl and run again to remove backups. """ import os find = """# Copyright (c) 2019 Xyz Pty Ltd""" repl = """# Copyright (c) 2020 Xyz Pty Ltd""" ii = 0 kk = 0 for dirpath, dirnames, filenames in os.walk(".", topdown=True): if "migrations" in dirpath: continue for filename in filenames: if filename.endswith(".py"): # or filename.endswith(".txt"): fil = os.path.join(dirpath, filename) bak = "{0}~".format(fil) if find == repl: if os.path.isfile(bak): ii += 1 os.remove(bak) else: with open(fil, "r") as src: lines = src.readlines() # make a backup file with open(bak, "w", encoding="utf-8") as dst: for line in lines: dst.write(line) with open(bak, "r") as src: lines = src.readlines() # re-write the original src with open(fil, "w", encoding="utf-8") as dst: kk += 1 for line in lines: dst.write(line.replace(find, repl)) print("\nbak deletions = %s, tried = %s\n" % (ii, kk)) -- Signed email is an absolute defence against phishing. This email has been signed with my private key. If you import my public key you can automatically decrypt my signature and be sure it came from me. Just ask and I'll send it to you. Your email software can handle signing. -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 495 bytes Desc: OpenPGP digital signature URL: From cl at isbd.net Tue Nov 10 03:25:59 2020 From: cl at isbd.net (Chris Green) Date: Tue, 10 Nov 2020 08:25:59 +0000 Subject: Changing strings in files References: <20201110072444.5acf0769@arcor.com> <87v9edsmp0.fsf@hornfels.zedat.fu-berlin.de> Message-ID: Loris Bennett wrote: > Having said that, I would be interested to know what the most compact > way of doing the same thing in Python might be. > Here's my Python replace script:- #!/usr/bin/python3 # # # String replacement utility # import os import re import sys import shutil def replaceString(s1, s2, fn): tmpfn = "/tmp/replace.tmp" tofn = fn # # # copy the file to /tmp # shutil.copy(fn, tmpfn); # # # Open the files # fromfd = open(tmpfn, 'r'); tofd = open(tofn, 'w'); # # # copy the file back where it came from, replacing the string on the way for ln in fromfd: ln = re.sub(s1, s2, ln) tofd.write(ln) tofd.close() s1 = sys.argv[1] s2 = sys.argv[2] for fn in sys.argv[3:]: if (os.path.isfile(fn)): replaceString(s1, s2, fn) else: for srcPath, srcDirs, srcFiles in os.walk(fn): for f in srcFiles: replaceString(s1, s2, os.path.join(srcPath, f)) -- Chris Green ? From ml_news at posteo.de Tue Nov 10 03:57:37 2020 From: ml_news at posteo.de (Manfred Lotz) Date: Tue, 10 Nov 2020 09:57:37 +0100 Subject: Changing strings in files References: <20201110072444.5acf0769@arcor.com> <87v9edsmp0.fsf@hornfels.zedat.fu-berlin.de> Message-ID: <20201110095737.63f9496d@arcor.com> On Tue, 10 Nov 2020 08:19:55 +0100 "Loris Bennett" wrote: > Manfred Lotz writes: > > > I have a situation where in a directory tree I want to change a > > certain string in all files where that string occurs. > > > > My idea was to do > > > > - os.scandir and for each file > > - check if a file is a text file > > - if it is not a text file skip that file > > - change the string as often as it occurs in that file > > > > > > What is the best way to check if a file is a text file? In a script > > I could use the `file` command which is not ideal as I have to grep > > the result. In Perl I could do -T file. > > > > How to do best in Python? > > If you are on Linux and more interested in the result than the > programming exercise, I would suggest the following non-Python > solution: > > find . -type -f -exec sed -i 's/foo/bar/g' {} \; > My existing script in Perl which I wanted to migrate to Python I used `-T $file` and called sed I like the -T which I assume does some heuristics to tell me if a file is a text file. -- Manfred From loris.bennett at fu-berlin.de Tue Nov 10 04:57:05 2020 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Tue, 10 Nov 2020 10:57:05 +0100 Subject: Changing strings in files References: <20201110072444.5acf0769@arcor.com> <87v9edsmp0.fsf@hornfels.zedat.fu-berlin.de> <20201110095737.63f9496d@arcor.com> Message-ID: <87zh3pr0um.fsf@hornfels.zedat.fu-berlin.de> Manfred Lotz writes: > On Tue, 10 Nov 2020 08:19:55 +0100 > "Loris Bennett" wrote: > >> Manfred Lotz writes: >> >> > I have a situation where in a directory tree I want to change a >> > certain string in all files where that string occurs. >> > >> > My idea was to do >> > >> > - os.scandir and for each file >> > - check if a file is a text file >> > - if it is not a text file skip that file >> > - change the string as often as it occurs in that file >> > >> > >> > What is the best way to check if a file is a text file? In a script >> > I could use the `file` command which is not ideal as I have to grep >> > the result. In Perl I could do -T file. >> > >> > How to do best in Python? >> >> If you are on Linux and more interested in the result than the >> programming exercise, I would suggest the following non-Python >> solution: >> >> find . -type -f -exec sed -i 's/foo/bar/g' {} \; >> > > My existing script in Perl which I wanted to migrate to Python I used > `-T $file` and called sed > > I like the -T which I assume does some heuristics to tell me if a file > is a text file. Sorry, I missed the bit about text files. By '-T' I assume you mean Perl's taint mode option. I am no security expert, but as I understand it, taint mode does more than just check whether something is a text file, although the "more" probably applies mainly to files which contain Perl code. Sorry also to bang on about non-Python solutions but you could do find . -type f -exec grep -Iq . {} \; -and -exec sed -i 's/foo/bar/g' {} \; i.e. let grep ignore binary files and quietly match all non-binary files. -- This signature is currently under construction. From ml_news at posteo.de Tue Nov 10 04:07:10 2020 From: ml_news at posteo.de (Manfred Lotz) Date: Tue, 10 Nov 2020 10:07:10 +0100 Subject: Changing strings in files References: <20201110072444.5acf0769@arcor.com> <20201110073754.GA46480@cskk.homeip.net> Message-ID: <20201110100710.033b129d@arcor.com> On Tue, 10 Nov 2020 18:37:54 +1100 Cameron Simpson wrote: > On 10Nov2020 07:24, Manfred Lotz wrote: > >I have a situation where in a directory tree I want to change a > >certain string in all files where that string occurs. > > > >My idea was to do > > > >- os.scandir and for each file > > Use os.walk for trees. scandir does a single directory. > Perhaps better. I like to use os.scandir this way def scantree(path: str) -> Iterator[os.DirEntry[str]]: """Recursively yield DirEntry objects (no directories) for a given directory. """ for entry in os.scandir(path): if entry.is_dir(follow_symlinks=False): yield from scantree(entry.path) yield entry Worked fine so far. I think I coded it this way because I wanted the full path of the file the easy way. > > - check if a file is a text file > > This requires reading the entire file. You want to check that it > consists entirely of lines of text. In your expected text encoding - > these days UTF-8 is the common default, but getting this correct is > essential if you want to recognise text. So as a first cut, totally > untested: > > ... The reason I want to check if a file is a text file is that I don't want to try replacing patterns in binary files (executable binaries, archives, audio files aso). Of course, to make this nicely work some heuristic check would be the right thing (this is what file command does). I am aware that an heuristic check is not 100% but I think it is good enough. -- Manfred From ml_news at posteo.de Tue Nov 10 04:08:20 2020 From: ml_news at posteo.de (Manfred Lotz) Date: Tue, 10 Nov 2020 10:08:20 +0100 Subject: Changing strings in files References: <20201110072444.5acf0769@arcor.com> <935a0b5a-4337-243f-2545-a77f8abf00cd@dewhirst.com.au> Message-ID: <20201110100820.31cdfcf6@arcor.com> On Tue, 10 Nov 2020 18:52:26 +1100 Mike Dewhirst wrote: > On 10/11/2020 5:24 pm, Manfred Lotz wrote: > > I have a situation where in a directory tree I want to change a > > certain string in all files where that string occurs. > > > > My idea was to do > > > > - os.scandir and for each file > > - check if a file is a text file > > - if it is not a text file skip that file > > - change the string as often as it occurs in that file > > > > > > What is the best way to check if a file is a text file? In a script > > I could use the `file` command which is not ideal as I have to grep > > the result. In Perl I could do -T file. > > > > How to do best in Python? > Not necessarily best but I rolled this earlier. Much earlier. But I > still use it. I don't need to worry about text files or binary > because I specify .py files. > > > > # -*- coding: utf-8 -*- > """ > Look for string 'find' and replace it with string 'repl' in all files > in the current directory and all sub-dirs. > > If anything untoward happens, laboriously retrieve each original file > from each individual backup made by suffixing ~ to the filename. > > If everything went well, make find == repl and run again to remove > backups. > > """ > import os > > find = """# Copyright (c) 2019 Xyz Pty Ltd""" > > repl = """# Copyright (c) 2020 Xyz Pty Ltd""" > > ii = 0 > kk = 0 > for dirpath, dirnames, filenames in os.walk(".", topdown=True): > if "migrations" in dirpath: > continue > for filename in filenames: > if filename.endswith(".py"): # or filename.endswith(".txt"): > fil = os.path.join(dirpath, filename) > bak = "{0}~".format(fil) > if find == repl: > if os.path.isfile(bak): > ii += 1 > os.remove(bak) > else: > with open(fil, "r") as src: > lines = src.readlines() > # make a backup file > with open(bak, "w", encoding="utf-8") as dst: > for line in lines: > dst.write(line) > with open(bak, "r") as src: > lines = src.readlines() > # re-write the original src > with open(fil, "w", encoding="utf-8") as dst: > kk += 1 > for line in lines: > dst.write(line.replace(find, repl)) > print("\nbak deletions = %s, tried = %s\n" % (ii, kk)) > > Thanks, will take a look. -- Manfred From chalao.adda at gmail.com Tue Nov 10 05:01:16 2020 From: chalao.adda at gmail.com (ChalaoAdda) Date: Tue, 10 Nov 2020 02:01:16 -0800 (PST) Subject: Tkinter List of Canvases Message-ID: <8e5933b6-3873-42e9-b76b-a93cae46c279n@googlegroups.com> Hello, I have a list of canvas of images. I would like to display all the images. But it displays the last image. Here is my code. from tkinter import * from PIL import Image, ImageTk root = Tk() canvas_width = 265 canvas_height = 130 canvases = [] r, c = 0, 0 for tile in tiles: img = tile.image photo = ImageTk.PhotoImage(image=img) can = Canvas(root, width=canvas_width, height=canvas_height) can.create_image(0, 0, image=photo, anchor=NW) canvases.append(can) can.grid(row=r, column=c) c += 1 if c % 5 == 0: r += 1 c = 0 root.mainloop() Please help. Thanks. From rosuav at gmail.com Tue Nov 10 05:20:07 2020 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 10 Nov 2020 21:20:07 +1100 Subject: Changing strings in files In-Reply-To: <20201110100710.033b129d@arcor.com> References: <20201110072444.5acf0769@arcor.com> <20201110073754.GA46480@cskk.homeip.net> <20201110100710.033b129d@arcor.com> Message-ID: On Tue, Nov 10, 2020 at 9:06 PM Manfred Lotz wrote: > The reason I want to check if a file is a text file is that I don't > want to try replacing patterns in binary files (executable binaries, > archives, audio files aso). > I'd recommend two checks, then: 1) Can the file be decoded as UTF-8? 2) Does it contain any NULs? The checks can be done in either order; you can check if the file contains any b"\0" or you can check if the decoded text contains any u"\0", since UTF-8 guarantees that those are the same. If both those checks pass, it's still possible that the file isn't one you want to edit, but it is highly likely to be text. ChrisA From cs at cskk.id.au Tue Nov 10 06:08:54 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Tue, 10 Nov 2020 22:08:54 +1100 Subject: Changing strings in files In-Reply-To: <20201110100710.033b129d@arcor.com> References: <20201110100710.033b129d@arcor.com> Message-ID: <20201110110854.GA41537@cskk.homeip.net> On 10Nov2020 10:07, Manfred Lotz wrote: >On Tue, 10 Nov 2020 18:37:54 +1100 >Cameron Simpson wrote: >> Use os.walk for trees. scandir does a single directory. > >Perhaps better. I like to use os.scandir this way > >def scantree(path: str) -> Iterator[os.DirEntry[str]]: > """Recursively yield DirEntry objects (no directories) > for a given directory. > """ > for entry in os.scandir(path): > if entry.is_dir(follow_symlinks=False): > yield from scantree(entry.path) > > yield entry > >Worked fine so far. I think I coded it this way because I wanted the >full path of the file the easy way. Yes, that's fine and easy to read. Note that this is effectively a recursive call though, with the associated costs: - a scandir (or listdir, whatever) has the directory open, and holds it open while you scan the subdirectories; by contrast os.walk only opens one directory at a time - likewise, if you're maintaining data during a scan, that is held while you process the subdirectories; with an os.walk you tend to do that and release the memory before the next iteration of the main loop (obviously, depending exactly what you're doing) However, directory trees tend not to be particularly deep, and the depth governs the excess state you're keeping around. >> > - check if a file is a text file >> >> This requires reading the entire file. You want to check that it >> consists entirely of lines of text. In your expected text encoding - >> these days UTF-8 is the common default, but getting this correct is >> essential if you want to recognise text. So as a first cut, totally >> untested: >> >> ... > >The reason I want to check if a file is a text file is that I don't >want to try replacing patterns in binary files (executable binaries, >archives, audio files aso). Exactly, which is why you should not trust, say, the "file" utility. It scans only the opening part of the file. Great for rejecting files, but not reliable for being _sure_ about the whole file being text when it doesn't reject. >Of course, to make this nicely work some heuristic check would be the >right thing (this is what file command does). I am aware that an >heuristic check is not 100% but I think it is good enough. Shrug. That is a risk you must evaluate yourself. I'm quite paranoid about data loss, myself. If you've got backups or are working on copies the risks are mitigated. You could perhaps take a more targeted approach: do your target files have distinctive file extensions (for example, all the .py files in a source tree). Cheers, Cameron Simpson From grant.b.edwards at gmail.com Tue Nov 10 09:24:41 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Tue, 10 Nov 2020 14:24:41 -0000 (UTC) Subject: Changing strings in files References: <20201110072444.5acf0769@arcor.com> Message-ID: On 2020-11-10, Manfred Lotz wrote: > What is the best way to check if a file is a text file? Step 1: define "text file" -- Grant From david at kolovratnik.net Tue Nov 10 09:45:01 2020 From: david at kolovratnik.net (David =?iso-8859-1?Q?Kolovratn=EDk?=) Date: Tue, 10 Nov 2020 15:45:01 +0100 Subject: constant folding - why not more Message-ID: <20201110144501.GC32237@crfreenet.org> Dear all, I would like to learn about constant folding optimisation in Python. It seems to be implemented in Python/ast_opt.c. In order to get impression I used python3 and dis module: $ python3 -V Python 3.7.3 Arithmetics expression is folded as expected: >>> dis.dis(compile('1 * 2', filename='', mode='eval', >>> optimize=2)) 1 0 LOAD_CONST 0 (2) 2 RETURN_VALUE On the contrary, comparison remains for runtime: >>> dis.dis(compile('1 < 2', filename='', mode='eval', >>> optimize=2)) 1 0 LOAD_CONST 0 (1) 2 LOAD_CONST 1 (2) 4 COMPARE_OP 0 (<) 6 RETURN_VALUE In function fold_unaryop (though comparison is a binary operation) in Python/ast_opt.c is remark: /* Fold not into comparison */ Is there a reason why comparison (== != < > <= >=) is not folded? I would expect it handled in fold_binop. Besides comparison there are other expressions that might be optimized out due to constant expression. Ternary operator with constant condition True has IF optimized out (just some dead code remains): >>> dis.dis(compile('"a" if True else "b"', filename='', >>> mode='eval', optimize=2)) 1 0 LOAD_CONST 1 ('a') 2 RETURN_VALUE 4 LOAD_CONST 2 ('b') 6 RETURN_VALUE On the contrary, the same ternary operator with constant condition False still loads the constat and contains POP_JUMP_IF_FALSE: >>> dis.dis(compile('"a" if False else "b"', filename='', >>> mode='eval', optimize=2)) 1 0 LOAD_CONST 0 (False) 2 POP_JUMP_IF_FALSE 8 4 LOAD_CONST 1 ('a') 6 RETURN_VALUE >> 8 LOAD_CONST 2 ('b') 10 RETURN_VALUE Any ideas or links, please? Best regards, Davis From garyfallidis at gmail.com Tue Nov 10 10:16:05 2020 From: garyfallidis at gmail.com (Eleftherios Garyfallidis) Date: Tue, 10 Nov 2020 10:16:05 -0500 Subject: ANN: DIPY 1.3.0 Message-ID: Hello all, We are excited to announce a new release of DIPY: DIPY 1.3 is out! Please support us by citing DIPY in your papers using the following DOI: 10.3389/fninf.2014.00008 DIPY 1.3.0 (Wednesday, 3 November 2020) This release received contributions from 27 developers (the full release notes are at: https://dipy.org/documentation/1.3.0./release_notes/release1.3/). Thank you all for your contributions and feedback! Please click here to check API changes. Highlights of this release include: - Gibbs ringing correction 10X faster. - Spherical harmonics basis definitions updated. - Added SMT2 metrics from mean signal diffusion kurtosis. - New interface functions added to the registration module. - New linear transform added to the registration module. - New tutorials for DIPY command line interfaces. - Fixed compatibility issues with different dependencies. - Tqdm (multiplatform progress bar) dependency added. - Large documentation update. - Bundle section highlight from BUAN added in Horizon. - Closed 134 issues and merged 49 pull requests. Note: Have in mind that DIPY does not support Python 2 after version 0.16.0. All major Python projects have switched to Python 3. It is time that you switch too. To upgrade or install DIPY Run the following command in your terminal: pip install --upgrade dipy or conda install -c conda-forge dipy This version of DIPY depends on nibabel (3.0.0+). For visualization you need FURY (0.6.1+). Questions or suggestions? For any questions go to https://dipy.org, or send an e-mail to dipy at python.org We also have an instant messaging service and chat room available at https://gitter.im/dipy/dipy On behalf of the DIPY developers, Eleftherios Garyfallidis, Ariel Rokem, Serge Koudoro https://dipy.org/contributors From python at mrabarnett.plus.com Tue Nov 10 12:21:04 2020 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 10 Nov 2020 17:21:04 +0000 Subject: Tkinter List of Canvases In-Reply-To: <8e5933b6-3873-42e9-b76b-a93cae46c279n@googlegroups.com> References: <8e5933b6-3873-42e9-b76b-a93cae46c279n@googlegroups.com> Message-ID: <7bfd95db-e53c-d40e-8359-cdc257ec7a2b@mrabarnett.plus.com> On 2020-11-10 10:01, ChalaoAdda wrote: > Hello, > > I have a list of canvas of images. I would like to display all the images. But it displays the last image. Here is my code. > > from tkinter import * > from PIL import Image, ImageTk > > root = Tk() > > canvas_width = 265 > canvas_height = 130 > canvases = [] > > r, c = 0, 0 > > for tile in tiles: > img = tile.image > photo = ImageTk.PhotoImage(image=img) > can = Canvas(root, width=canvas_width, height=canvas_height) > can.create_image(0, 0, image=photo, anchor=NW) > canvases.append(can) > can.grid(row=r, column=c) > > c += 1 > if c % 5 == 0: > r += 1 > c = 0 > > > root.mainloop() > You need to keep a reference to the images. In your code, 'photo' still refers to the last photoimage, so that's why it's displayed; there are no references to the others, so they're garbage-collected. (You probably expected that 'create_image' would keep a reference to the image, but it doesn't. tkinter has its idiosyncrasies!) Try adding a list for the photoimages: ... photos = [] for tile in tiles: img = tile.image photo = ImageTk.PhotoImage(image=img) photos.append(photo) can = Canvas(root, width=canvas_width, height=canvas_height) ... From barry at barrys-emacs.org Tue Nov 10 13:03:12 2020 From: barry at barrys-emacs.org (Barry Scott) Date: Tue, 10 Nov 2020 18:03:12 +0000 Subject: constant folding - why not more In-Reply-To: <20201110144501.GC32237@crfreenet.org> References: <20201110144501.GC32237@crfreenet.org> Message-ID: > On 10 Nov 2020, at 14:45, David Kolovratn?k wrote: > > Dear all, > > I would like to learn about constant folding optimisation in Python. It seems > to be implemented in Python/ast_opt.c. In order to get impression I used > python3 and dis module: > > $ python3 -V > Python 3.7.3 I do not have answers to your questions, but I would suggest that you look at 3.9 or even 3.10a2 to see if this is still the case. Barry > > Arithmetics expression is folded as expected: > >>>> dis.dis(compile('1 * 2', filename='', mode='eval', >>>> optimize=2)) > 1 0 LOAD_CONST 0 (2) > 2 RETURN_VALUE > > On the contrary, comparison remains for runtime: >>>> dis.dis(compile('1 < 2', filename='', mode='eval', >>>> optimize=2)) > 1 0 LOAD_CONST 0 (1) > 2 LOAD_CONST 1 (2) > 4 COMPARE_OP 0 (<) > 6 RETURN_VALUE > In function fold_unaryop (though comparison is a binary operation) in > Python/ast_opt.c is remark: /* Fold not into comparison */ > > Is there a reason why comparison (== != < > <= >=) is not folded? I would > expect it handled in fold_binop. > > Besides comparison there are other expressions that might be optimized out > due to constant expression. Ternary operator with constant condition True > has IF optimized out (just some dead code remains): >>>> dis.dis(compile('"a" if True else "b"', filename='', >>>> mode='eval', optimize=2)) > 1 0 LOAD_CONST 1 ('a') > 2 RETURN_VALUE > 4 LOAD_CONST 2 ('b') > 6 RETURN_VALUE > > On the contrary, the same ternary operator with constant condition False > still loads the constat and contains POP_JUMP_IF_FALSE: >>>> dis.dis(compile('"a" if False else "b"', filename='', >>>> mode='eval', optimize=2)) > 1 0 LOAD_CONST 0 (False) > 2 POP_JUMP_IF_FALSE 8 > 4 LOAD_CONST 1 ('a') > 6 RETURN_VALUE >>> 8 LOAD_CONST 2 ('b') > 10 RETURN_VALUE > > Any ideas or links, please? > > Best regards, > Davis > -- > https://mail.python.org/mailman/listinfo/python-list > From * at eli.users.panix.com Tue Nov 10 13:33:54 2020 From: * at eli.users.panix.com (Eli the Bearded) Date: Tue, 10 Nov 2020 18:33:54 +0000 (UTC) Subject: Changing strings in files References: <20201110072444.5acf0769@arcor.com> <87v9edsmp0.fsf@hornfels.zedat.fu-berlin.de> Message-ID: In comp.lang.python, Loris Bennett wrote: > Manfred Lotz writes: > > My idea was to do > > > > - os.scandir and for each file > > - check if a file is a text file ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > - if it is not a text file skip that file > > - change the string as often as it occurs in that file > > > > What is the best way to check if a file is a text file? In a script I ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > could use the `file` command which is not ideal as I have to grep the > > result. In Perl I could do -T file. > If you are on Linux and more interested in the result than the > programming exercise, I would suggest the following non-Python solution: > > find . -type -f -exec sed -i 's/foo/bar/g' {} \; That 100% fails the "check if a text file" part. > Having said that, I would be interested to know what the most compact > way of doing the same thing in Python might be. Read first N lines of a file. If all parse as valid UTF-8, consider it text. That's probably the rough method file(1) and Perl's -T use. (In particular allow no nulls. Maybe allow ISO-8859-1.) Elijah ------ pretty no nulls is file(1) check From rosuav at gmail.com Tue Nov 10 13:40:56 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 11 Nov 2020 05:40:56 +1100 Subject: Changing strings in files In-Reply-To: References: <20201110072444.5acf0769@arcor.com> <87v9edsmp0.fsf@hornfels.zedat.fu-berlin.de> Message-ID: On Wed, Nov 11, 2020 at 5:36 AM Eli the Bearded <*@eli.users.panix.com> wrote: > Read first N lines of a file. If all parse as valid UTF-8, consider it text. > That's probably the rough method file(1) and Perl's -T use. (In > particular allow no nulls. Maybe allow ISO-8859-1.) > ISO-8859-1 is basically "allow any byte values", so all you'd be doing is checking for a lack of NUL bytes. I'd definitely recommend mandating UTF-8, as that's a very good way of recognizing valid text, but if you can't do that then the simple NUL check is all you really need. And let's be honest here, there aren't THAT many binary files that manage to contain a total of zero NULs, so you won't get many false hits :) ChrisA From ml_news at posteo.de Tue Nov 10 13:43:26 2020 From: ml_news at posteo.de (Manfred Lotz) Date: Tue, 10 Nov 2020 19:43:26 +0100 Subject: Changing strings in files References: <20201110072444.5acf0769@arcor.com> <87v9edsmp0.fsf@hornfels.zedat.fu-berlin.de> <20201110095737.63f9496d@arcor.com> <87zh3pr0um.fsf@hornfels.zedat.fu-berlin.de> Message-ID: <20201110194326.22006673@arcor.com> On Tue, 10 Nov 2020 10:57:05 +0100 "Loris Bennett" wrote: > Manfred Lotz writes: > > > On Tue, 10 Nov 2020 08:19:55 +0100 > > "Loris Bennett" wrote: > > > >> Manfred Lotz writes: > >> > >> > I have a situation where in a directory tree I want to change a > >> > certain string in all files where that string occurs. > >> > > >> > My idea was to do > >> > > >> > - os.scandir and for each file > >> > - check if a file is a text file > >> > - if it is not a text file skip that file > >> > - change the string as often as it occurs in that file > >> > > >> > > >> > What is the best way to check if a file is a text file? In a > >> > script I could use the `file` command which is not ideal as I > >> > have to grep the result. In Perl I could do -T file. > >> > > >> > How to do best in Python? > >> > >> If you are on Linux and more interested in the result than the > >> programming exercise, I would suggest the following non-Python > >> solution: > >> > >> find . -type -f -exec sed -i 's/foo/bar/g' {} \; > >> > > > > My existing script in Perl which I wanted to migrate to Python I > > used `-T $file` and called sed > > > > I like the -T which I assume does some heuristics to tell me if a > > file is a text file. > > Sorry, I missed the bit about text files. By '-T' I assume you mean > Perl's taint mode option. I am no security expert, but as I > understand it, taint mode does more than just check whether something > is a text file, although the "more" probably applies mainly to files > which contain Perl code. > > Sorry also to bang on about non-Python solutions but you could do > > find . -type f -exec grep -Iq . {} \; -and -exec sed -i > 's/foo/bar/g' {} \; > > i.e. let grep ignore binary files and quietly match all non-binary > files. > Very nice. Thanks for this. -- Manfred From ml_news at posteo.de Tue Nov 10 13:48:54 2020 From: ml_news at posteo.de (Manfred Lotz) Date: Tue, 10 Nov 2020 19:48:54 +0100 Subject: Changing strings in files References: <20201110100710.033b129d@arcor.com> <20201110110854.GA41537@cskk.homeip.net> Message-ID: <20201110194854.4aa09916@arcor.com> On Tue, 10 Nov 2020 22:08:54 +1100 Cameron Simpson wrote: > On 10Nov2020 10:07, Manfred Lotz wrote: > >On Tue, 10 Nov 2020 18:37:54 +1100 > >Cameron Simpson wrote: > >> Use os.walk for trees. scandir does a single directory. > > > >Perhaps better. I like to use os.scandir this way > > > >def scantree(path: str) -> Iterator[os.DirEntry[str]]: > > """Recursively yield DirEntry objects (no directories) > > for a given directory. > > """ > > for entry in os.scandir(path): > > if entry.is_dir(follow_symlinks=False): > > yield from scantree(entry.path) > > > > yield entry > > > >Worked fine so far. I think I coded it this way because I wanted the > >full path of the file the easy way. > > Yes, that's fine and easy to read. Note that this is effectively a > recursive call though, with the associated costs: > > - a scandir (or listdir, whatever) has the directory open, and holds > it open while you scan the subdirectories; by contrast os.walk only > opens one directory at a time > > - likewise, if you're maintaining data during a scan, that is held > while you process the subdirectories; with an os.walk you tend to do > that and release the memory before the next iteration of the main > loop (obviously, depending exactly what you're doing) > > However, directory trees tend not to be particularly deep, and the > depth governs the excess state you're keeping around. > Very interesting information. Thanks a lot for this. I will take a closer look at os.walk. > >> > - check if a file is a text file > >> > >> This requires reading the entire file. You want to check that it > >> consists entirely of lines of text. In your expected text encoding > >> - these days UTF-8 is the common default, but getting this correct > >> is essential if you want to recognise text. So as a first cut, > >> totally untested: > >> > >> ... > > > >The reason I want to check if a file is a text file is that I don't > >want to try replacing patterns in binary files (executable binaries, > >archives, audio files aso). > > Exactly, which is why you should not trust, say, the "file" utility. > It scans only the opening part of the file. Great for rejecting > files, but not reliable for being _sure_ about the whole file being > text when it doesn't reject. > > >Of course, to make this nicely work some heuristic check would be the > >right thing (this is what file command does). I am aware that an > >heuristic check is not 100% but I think it is good enough. > > Shrug. That is a risk you must evaluate yourself. I'm quite paranoid > about data loss, myself. If you've got backups or are working on > copies the risks are mitigated. > > You could perhaps take a more targeted approach: do your target files > have distinctive file extensions (for example, all the .py files in a > source tree). > There are some distinctive file extensions. The reason I am satisfieg with heuristics is that the string to change is pretty long so that there is no real danger if I try to change in a binary file because that string it not to be found in binary files. The idea to skip binary files was simply to save time. -- Manfred From * at eli.users.panix.com Tue Nov 10 14:30:43 2020 From: * at eli.users.panix.com (Eli the Bearded) Date: Tue, 10 Nov 2020 19:30:43 +0000 (UTC) Subject: Changing strings in files References: <20201110072444.5acf0769@arcor.com> Message-ID: In comp.lang.python, Chris Angelico wrote: > Eli the Bearded <*@eli.users.panix.com> wrote: >> Read first N lines of a file. If all parse as valid UTF-8, consider it text. >> That's probably the rough method file(1) and Perl's -T use. (In >> particular allow no nulls. Maybe allow ISO-8859-1.) > ISO-8859-1 is basically "allow any byte values", so all you'd be doing > is checking for a lack of NUL bytes. ISO-8859-1, unlike similar Windows "charset"s, does not use octets 128-190. Charsets like Windows CP-1252 are nastier, because they do use that range. Usage of 1-31 will be pretty restricted in either, probably not more than tab, linefeed, and carriage return. > I'd definitely recommend > mandating UTF-8, as that's a very good way of recognizing valid text, > but if you can't do that then the simple NUL check is all you really > need. Dealing with all UTF-8 is my preference, too. > And let's be honest here, there aren't THAT many binary files that > manage to contain a total of zero NULs, so you won't get many false > hits :) There's always the issue of how much to read before deciding. Elijah ------ ASCII with embedded escapes? could be a VT100 animation From barry at barrys-emacs.org Tue Nov 10 14:50:39 2020 From: barry at barrys-emacs.org (Barry Scott) Date: Tue, 10 Nov 2020 19:50:39 +0000 Subject: Changing strings in files In-Reply-To: References: <20201110072444.5acf0769@arcor.com> Message-ID: > On 10 Nov 2020, at 19:30, Eli the Bearded <*@eli.users.panix.com> wrote: > > In comp.lang.python, Chris Angelico wrote: >> Eli the Bearded <*@eli.users.panix.com> wrote: >>> Read first N lines of a file. If all parse as valid UTF-8, consider it text. >>> That's probably the rough method file(1) and Perl's -T use. (In >>> particular allow no nulls. Maybe allow ISO-8859-1.) >> ISO-8859-1 is basically "allow any byte values", so all you'd be doing >> is checking for a lack of NUL bytes. NUL check does not work for windows UTF-16 files. > > ISO-8859-1, unlike similar Windows "charset"s, does not use octets > 128-190. Charsets like Windows CP-1252 are nastier, because they do > use that range. Usage of 1-31 will be pretty restricted in either, > probably not more than tab, linefeed, and carriage return. Who told you that? The C1 control plane is used in ISO 8 bit char sets. One optimisation for the Vt100 family of terminals is to send CSI as 0x8b and not as 0x1b '['. Back in the days of 9600 bps or 1200 bps connections that was worth the effort. > >> I'd definitely recommend >> mandating UTF-8, as that's a very good way of recognizing valid text, >> but if you can't do that then the simple NUL check is all you really >> need. > > Dealing with all UTF-8 is my preference, too. > >> And let's be honest here, there aren't THAT many binary files that >> manage to contain a total of zero NULs, so you won't get many false >> hits :) There is the famous EICAR virus test file that is a valid 8086 program for DOS that is printing ASCII. > > There's always the issue of how much to read before deciding. Simple read it all, after all you have to scan all the file to do the replacement. > > Elijah > ------ > ASCII with embedded escapes? could be a VT100 animation The output of software that colours its logs maybe? Barry > -- > https://mail.python.org/mailman/listinfo/python-list > From tjreedy at udel.edu Tue Nov 10 15:03:40 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Tue, 10 Nov 2020 15:03:40 -0500 Subject: constant folding - why not more In-Reply-To: References: <20201110144501.GC32237@crfreenet.org> Message-ID: On 11/10/2020 1:03 PM, Barry Scott wrote: > > >> On 10 Nov 2020, at 14:45, David Kolovratn?k wrote: >> >> Dear all, >> >> I would like to learn about constant folding optimisation in Python. It seems >> to be implemented in Python/ast_opt.c. In order to get impression I used >> python3 and dis module: >> >> $ python3 -V >> Python 3.7.3 > > I do not have answers to your questions, but I would suggest that you look at 3.9 > or even 3.10a2 to see if this is still the case. Checking with 3.10... >> Arithmetics expression is folded as expected: >> >>>>> dis.dis(compile('1 * 2', filename='', mode='eval', >>>>> optimize=2)) >> 1 0 LOAD_CONST 0 (2) >> 2 RETURN_VALUE >> >> On the contrary, comparison remains for runtime: >>>>> dis.dis(compile('1 < 2', filename='', mode='eval', >>>>> optimize=2)) >> 1 0 LOAD_CONST 0 (1) >> 2 LOAD_CONST 1 (2) >> 4 COMPARE_OP 0 (<) >> 6 RETURN_VALUE Same. >> In function fold_unaryop (though comparison is a binary operation) in >> Python/ast_opt.c is remark: /* Fold not into comparison */ Use git blame to find out who and when made that remark. >> Is there a reason why comparison (== != < > <= >=) is not folded? I would >> expect it handled in fold_binop. >> >> Besides comparison there are other expressions that might be optimized out >> due to constant expression. Ternary operator with constant condition True >> has IF optimized out (just some dead code remains): >>>>> dis.dis(compile('"a" if True else "b"', filename='', >>>>> mode='eval', optimize=2)) >> 1 0 LOAD_CONST 1 ('a') >> 2 RETURN_VALUE Remains. >> 4 LOAD_CONST 2 ('b') >> 6 RETURN_VALUE Gone. >> On the contrary, the same ternary operator with constant condition False >> still loads the constat and contains POP_JUMP_IF_FALSE: >>>>> dis.dis(compile('"a" if False else "b"', filename='', >>>>> mode='eval', optimize=2)) >> 1 0 LOAD_CONST 0 (False) >> 2 POP_JUMP_IF_FALSE 8 >> 4 LOAD_CONST 1 ('a') >> 6 RETURN_VALUE >> >> 8 LOAD_CONST 2 ('b') >> 10 RETURN_VALUE Same. You could file issue for this, but one guess is that else clause might spill over to another line, and current decision is that for tracing, every line of code that naively should be executed is executed rather than optimized away. But I would first try to find the file that produces bytecode and then use git blame to find issue where the True else part was removed. -- Terry Jan Reedy From rosuav at gmail.com Tue Nov 10 15:25:57 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 11 Nov 2020 07:25:57 +1100 Subject: Changing strings in files In-Reply-To: References: <20201110072444.5acf0769@arcor.com> Message-ID: On Wed, Nov 11, 2020 at 6:36 AM Eli the Bearded <*@eli.users.panix.com> wrote: > > In comp.lang.python, Chris Angelico wrote: > > Eli the Bearded <*@eli.users.panix.com> wrote: > >> Read first N lines of a file. If all parse as valid UTF-8, consider it text. > >> That's probably the rough method file(1) and Perl's -T use. (In > >> particular allow no nulls. Maybe allow ISO-8859-1.) > > ISO-8859-1 is basically "allow any byte values", so all you'd be doing > > is checking for a lack of NUL bytes. > > ISO-8859-1, unlike similar Windows "charset"s, does not use octets > 128-190. Charsets like Windows CP-1252 are nastier, because they do > use that range. Usage of 1-31 will be pretty restricted in either, > probably not more than tab, linefeed, and carriage return. Define "does not use", though. You can decode those bytes just fine: >>> bytes(range(256)).decode("ISO-8859-1") '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0????????????\xad??????????????????????????????????????????????????????????????????????????????????' This is especially true of \x01 to \x1F, since they are most definitely defined, even though they aren't commonly used. > > I'd definitely recommend > > mandating UTF-8, as that's a very good way of recognizing valid text, > > but if you can't do that then the simple NUL check is all you really > > need. > > Dealing with all UTF-8 is my preference, too. > > > And let's be honest here, there aren't THAT many binary files that > > manage to contain a total of zero NULs, so you won't get many false > > hits :) > > There's always the issue of how much to read before deciding. > Right; but a lot of binary file formats are going to include structured data that will frequently include a NUL byte. For instance, a PNG file (after the header) consists of chunks, where each chunk is identified by a four-byte size; and the first chunk (IHDR) is generally going to be a very short one, meaning that its size will generally have three NULs. So a typical PNG file will have a NUL probably as the ninth byte of the file. Other file formats will be similar, or even better; an ELF binary actually has a sixteen byte header of which the last few bytes are reserved for future expansion and must be zeroes, so that's an even stronger guarantee. If the main job of the program, as in this situation, is to read the entire file, I would probably have it read in the first 1KB or 16KB or thereabouts, see if that has any NUL bytes, and if not, proceed to read in the rest of the file. But depending on the situation, I might actually have a hard limit on the file size (say, "any file over 1GB isn't what I'm looking for"), so that would reduce the risks too. ChrisA From rosuav at gmail.com Tue Nov 10 15:30:34 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 11 Nov 2020 07:30:34 +1100 Subject: Changing strings in files In-Reply-To: References: <20201110072444.5acf0769@arcor.com> Message-ID: On Wed, Nov 11, 2020 at 6:52 AM Barry Scott wrote: > > > > > On 10 Nov 2020, at 19:30, Eli the Bearded <*@eli.users.panix.com> wrote: > > > > In comp.lang.python, Chris Angelico wrote: > >> Eli the Bearded <*@eli.users.panix.com> wrote: > >>> Read first N lines of a file. If all parse as valid UTF-8, consider it text. > >>> That's probably the rough method file(1) and Perl's -T use. (In > >>> particular allow no nulls. Maybe allow ISO-8859-1.) > >> ISO-8859-1 is basically "allow any byte values", so all you'd be doing > >> is checking for a lack of NUL bytes. > > NUL check does not work for windows UTF-16 files. Yeah, so if you're expecting UTF-16, you would have to do the decode to text first, and the check for NULs second. One of the big advantages of UTF-8 is that you can do the checks in either order. > >> And let's be honest here, there aren't THAT many binary files that > >> manage to contain a total of zero NULs, so you won't get many false > >> hits :) > > There is the famous EICAR virus test file that is a valid 8086 program for > DOS that is printing ASCII. Yes. I didn't say "none", I said "aren't many" :) There's fundamentally no way to know whether something is or isn't text based on its contents alone; raw audio data might just happen to look like an RFC822 email, it's just really really unlikely. > > There's always the issue of how much to read before deciding. > > Simple read it all, after all you have to scan all the file to do the replacement. If the script's assuming it'll mostly work on small text files, it might be very annoying to suddenly read in a 4GB blob of video file just to find out that it's not text. But since we're talking heuristics here, reading in a small chunk of the file is going to give an extremely high chance of recognizing a binary file, with a relatively small cost. ChrisA From rosuav at gmail.com Tue Nov 10 15:44:22 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 11 Nov 2020 07:44:22 +1100 Subject: constant folding - why not more In-Reply-To: <20201110144501.GC32237@crfreenet.org> References: <20201110144501.GC32237@crfreenet.org> Message-ID: On Wed, Nov 11, 2020 at 4:01 AM David Kolovratn?k wrote: > On the contrary, comparison remains for runtime: > >>> dis.dis(compile('1 < 2', filename='', mode='eval', > >>> optimize=2)) > 1 0 LOAD_CONST 0 (1) > 2 LOAD_CONST 1 (2) > 4 COMPARE_OP 0 (<) > 6 RETURN_VALUE > In function fold_unaryop (though comparison is a binary operation) in > Python/ast_opt.c is remark: /* Fold not into comparison */ > > Is there a reason why comparison (== != < > <= >=) is not folded? I would > expect it handled in fold_binop. I think that comment is unrelated. It's more about this: >>> dis.dis(lambda x, y: x is y) 1 0 LOAD_FAST 0 (x) 2 LOAD_FAST 1 (y) 4 IS_OP 0 6 RETURN_VALUE >>> dis.dis(lambda x, y: not (x is y)) 1 0 LOAD_FAST 0 (x) 2 LOAD_FAST 1 (y) 4 IS_OP 1 6 RETURN_VALUE >>> dis.dis(lambda x, y: x is not y) 1 0 LOAD_FAST 0 (x) 2 LOAD_FAST 1 (y) 4 IS_OP 1 6 RETURN_VALUE The leading "not" gets folded into the operator, since there's absolutely no way for "x is not y" and "not (x is y)" to return different results. Same is true for "not (x in y)". ChrisA From cs at cskk.id.au Tue Nov 10 17:55:26 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Wed, 11 Nov 2020 09:55:26 +1100 Subject: Changing strings in files In-Reply-To: References: Message-ID: <20201110225526.GA70469@cskk.homeip.net> On 11Nov2020 07:25, Chris Angelico wrote: >If the main job of the program, as in this situation, is to read the >entire file, I would probably have it read in the first 1KB or 16KB or >thereabouts, see if that has any NUL bytes, and if not, proceed to >read in the rest of the file. But depending on the situation, I might >actually have a hard limit on the file size (say, "any file over 1GB >isn't what I'm looking for"), so that would reduce the risks too. You could shoehorn my suggested code for this efficiently. It had a loop body like this: is_text = False try: # expect utf-8, fail if non-utf-8 bytes encountered with open(filename, encoding='utf-8', errors='strict') as f: for lineno, line in enumerate(f, 1): ... other checks on each line of the file ... if not line.endswith('\n'): raise ValueError("line %d: no trailing newline" lineno) if str.isprintable(line[:-1]): raise ValueError("line %d: not all printable" % lineno) # if we get here all checks passed, consider the file # to # be text is_text = True except Exception as e: print(filename, "not text", e) if not is_text: print("skip", filename) continue which scans the entire file to see if it is all text (criteria to be changed to suit the user, but I was going for clean strict utf-8 decode, all chars "printable"). Since we're doing that, we could accumulate the lines as we went and make the replacement in memory. If we get all the way out the bottom, rewrite the file. If memory is a concern, we could copy modified lines to a temporary file, and copy back if everything was good (or not if we make no replacements). Cheers, Cameron Simpson From cs at cskk.id.au Tue Nov 10 17:56:31 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Wed, 11 Nov 2020 09:56:31 +1100 Subject: Changing strings in files In-Reply-To: References: Message-ID: <20201110225631.GA85417@cskk.homeip.net> On 11Nov2020 07:30, Chris Angelico wrote: >If the script's assuming it'll mostly work on small text files, it >might be very annoying to suddenly read in a 4GB blob of video file >just to find out that it's not text. You can abort as soon as the decode fails. Which will usually be pretty early for video. Cheers, Cameron Simpson From rosuav at gmail.com Tue Nov 10 19:07:58 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 11 Nov 2020 11:07:58 +1100 Subject: Changing strings in files In-Reply-To: <20201110225631.GA85417@cskk.homeip.net> References: <20201110225631.GA85417@cskk.homeip.net> Message-ID: On Wed, Nov 11, 2020 at 10:00 AM Cameron Simpson wrote: > > On 11Nov2020 07:30, Chris Angelico wrote: > >If the script's assuming it'll mostly work on small text files, it > >might be very annoying to suddenly read in a 4GB blob of video file > >just to find out that it's not text. > > You can abort as soon as the decode fails. Which will usually be pretty > early for video. > Only if you haven't already read it from the file system, which is the point of the early abort :) ChrisA From chrisuchytil1234 at gmail.com Tue Nov 10 19:33:10 2020 From: chrisuchytil1234 at gmail.com (Chris) Date: Tue, 10 Nov 2020 16:33:10 -0800 (PST) Subject: ctypes struct alignment specification Message-ID: <2d6203f3-c558-438e-904d-a27fb5b959e0n@googlegroups.com> I am working on a CUDA python API using ctypes. Within CUDA there are vector type structs defined (float2, float3, float4, int2, int3, int4, ...), all of which have an alignment specification (example of how this is specified https://stackoverflow.com/questions/12778949/cuda-memory-alignment/12779757) . I want to include these structs in the Python api but as far as I can tell, ctypes does not have a way to specify a structure's alignment in the same fashion (the #pragma pack(n) alignment feature that ctypes does support does not do the same thing). If the alignment specification is omitted on the Python side, the structure's alignment can be mismatched between the host (CPU) and device (GPU) causing segfaults/etc. . Is this something that could be added to ctypes or is it not feasible/possible? From skip.montanaro at gmail.com Tue Nov 10 19:46:18 2020 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Tue, 10 Nov 2020 18:46:18 -0600 Subject: constant folding - why not more In-Reply-To: <20201110144501.GC32237@crfreenet.org> References: <20201110144501.GC32237@crfreenet.org> Message-ID: > > On the contrary, comparison remains for runtime: > >>> dis.dis(compile('1 < 2', filename='', mode='eval', > >>> optimize=2)) > 1 0 LOAD_CONST 0 (1) > 2 LOAD_CONST 1 (2) > 4 COMPARE_OP 0 (<) > 6 RETURN_VALUE > In function fold_unaryop (though comparison is a binary operation) in > Python/ast_opt.c is remark: /* Fold not into comparison */ > > Is there a reason why comparison (== != < > <= >=) is not folded? > I can think of two reasons. One, this kind of comparison will almost never appear in production code (maybe in unit tests?). Unlike the C family of languages, Python doesn't have a macro processor which would give symbolic names to numeric constants or string literals. Code generators might conceivably generate constant comparisons, but they might be able to easily do constant folding of comparisons themselves. Two, given that this sort of construct will almost never be found in the wild, folding constant comparisons in the compiler would increase the maintenance burden of the compiler (just slightly, but still...) with no clear benefit. Skip > From Bischoop at vimart.net Tue Nov 10 20:26:28 2020 From: Bischoop at vimart.net (Bischoop) Date: Wed, 11 Nov 2020 01:26:28 -0000 (UTC) Subject: Problem with rearanging list with paired letters next to each others Message-ID: Can anybody help?Here's the code that gives me a hedeache for second day https://bpa.st/XLOA If I have letter_list = ["a","a",,"b","b","c","c"] it's working correctly but if I have three or more of any letters for example:letter_list = ["a","a","a","b","b","c","c"], I'm ending up with some pairs somewhere. I took another way approach today: https://bpa.st/E7HQ, was thinking about iterating and checking if neighbour characters won't make a pair but I've end up with error: if x != letter_list[i+1] and letter_list[i-1]: IndexError: list index out of range andin addition: got 4 "a" (had 3only) and missing 1 "b" :-/ From python at mrabarnett.plus.com Tue Nov 10 21:22:07 2020 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 11 Nov 2020 02:22:07 +0000 Subject: Problem with rearanging list with paired letters next to each others In-Reply-To: References: Message-ID: <4b477203-fbc6-9d04-9ff9-412ee6d7015a@mrabarnett.plus.com> On 2020-11-11 01:26, Bischoop wrote: > > Can anybody help?Here's the code that gives me a hedeache for second day https://bpa.st/XLOA > If I have letter_list = ["a","a",,"b","b","c","c"] it's working > correctly but if I have three or more of any letters for > example:letter_list = ["a","a","a","b","b","c","c"], I'm ending up with > some pairs somewhere. > I took another way approach today: https://bpa.st/E7HQ, was thinking > about iterating and checking if neighbour characters won't make a pair > but I've end up with error: > if x != letter_list[i+1] and letter_list[i-1]: > IndexError: list index out of range > andin addition: got 4 "a" (had 3only) and missing 1 "b" :-/ > Points to note in your first code: 1. Modifying a list while iterating over it is a bad idea. 2. You're modifying the list that you're passing in and also returning it. That's a bad idea. Either modify it in place or modify and return a copy. 3. The line: m = (letter_list.index(x)) returns the position of the first occurrence of x. Points to note in your second code: 1. (See above) 2. (See above) 3. (See above) 4. 'i' goes from 0 to len(letter_list)-1, so i+1 goes from 1 to len(letter_list), but the maximum index permitted by letter_list is len(letter_list)-1, hence letter_list[i+1] will raise IndexError on the last iteration. 5. 'i' goes from 0 to len(letter_list)-1, so i-1 goes from -1 to len(letter_list)-2. letter_list[-1] returns the last (final) letter in the list, and it's treated as a true. 6. This: x != letter_list[i+1] and letter_list[i-1] is checking whether: x != letter_list[i+1] is true and also whether: letter_list[i-1] is true. From chalao.adda at gmail.com Wed Nov 11 00:12:21 2020 From: chalao.adda at gmail.com (ChalaoAdda) Date: Wed, 11 Nov 2020 05:12:21 +0000 (UTC) Subject: Tkinter List of Canvases References: <8e5933b6-3873-42e9-b76b-a93cae46c279n@googlegroups.com> <7bfd95db-e53c-d40e-8359-cdc257ec7a2b@mrabarnett.plus.com> Message-ID: On Tue, 10 Nov 2020 17:21:04 +0000, MRAB wrote: > On 2020-11-10 10:01, ChalaoAdda wrote: >> Hello, >> >> I have a list of canvas of images. I would like to display all the >> images. But it displays the last image. Here is my code. >> >> from tkinter import * >> from PIL import Image, ImageTk >> >> root = Tk() >> >> canvas_width = 265 canvas_height = 130 canvases = [] >> >> r, c = 0, 0 >> >> for tile in tiles: >> img = tile.image photo = ImageTk.PhotoImage(image=img) >> can = Canvas(root, width=canvas_width, height=canvas_height) >> can.create_image(0, 0, image=photo, anchor=NW) >> canvases.append(can) >> can.grid(row=r, column=c) >> >> c += 1 >> if c % 5 == 0: >> r += 1 c = 0 >> >> >> root.mainloop() >> > You need to keep a reference to the images. In your code, 'photo' still > refers to the last photoimage, so that's why it's displayed; there are > no references to the others, so they're garbage-collected. (You probably > expected that 'create_image' would keep a reference to the image, but it > doesn't. tkinter has its idiosyncrasies!) > > Try adding a list for the photoimages: > > ... > photos = [] > > for tile in tiles: > img = tile.image photo = ImageTk.PhotoImage(image=img) > photos.append(photo) > can = Canvas(root, width=canvas_width, height=canvas_height) > ... Thanks a lot. From jucaranlu at gmail.com Wed Nov 11 05:59:50 2020 From: jucaranlu at gmail.com (j c) Date: Wed, 11 Nov 2020 02:59:50 -0800 (PST) Subject: Getting rid of virtual environments with a better dependency system Message-ID: <3bc57280-5bd9-42f4-8b29-3fb5b01216ddn@googlegroups.com> Hello all, I don't know if this suggestion is missing some point, or it's part of something already proposed before. In a professional environment, we've came to a point in which most people use virtual environments or code environments to avoid "polluting a global environment". However, I think that's a problem with the default behaviour of the module management in Python. A nice default behaviour would be to search for a requirements.txt file in the same directory as __file__, and use the newest version of every module that matches the constraints. If no requirements where given, the newest version already installed could be used. That would require a structure that allows multiple versions of the same module to be downloaded. I already anticipate some problems: increased disk usage for people that are not using virtual environments, the possibility of breaking changes for scripts with no constraints over a module (so that if a different module download a newer version, both would be using it), and of course the hassle of a completely new default behaviour that would require a transition in many codebases. But still, I believe it would pay off in terms of time saved in environment installing and switching. Also, I think it's a good step in the path to integrating pip as something closer to the Python core. What's your opinion, is the effort required too big for the returns? Do you think other problems may arise? From jucaranlu at gmail.com Wed Nov 11 06:04:06 2020 From: jucaranlu at gmail.com (j c) Date: Wed, 11 Nov 2020 03:04:06 -0800 (PST) Subject: Getting rid of virtual environments with a better dependency system Message-ID: Hello all, I don't know if this suggestion is missing some point, or it's part of something already proposed. In a professional environment, we've came to a point in which most people use virtual environments or conda environments to avoid "polluting a global environment". However, I think that's a problem with the default behaviour of the module management in Python. A nice default behaviour would be to search for a requirements.txt file in the same directory as __file__, and use the newest version of every module that matches the constraints. If no requirements where given, the newest version already installed could be used. That would require allowing multiple versions of the same module to be downloaded. I already anticipate some problems: increased disk usage for people that are not using virtual environments, the possibility of breaking changes for scripts with no constraints over a module (so that if a different module download a newer version, both would be using it), and of course the hassle of a completely new default behaviour that would require a transition in many codebases. That there are other solutions to the problem, such as forcing the usage of semantic versioning, but that's a bit utopic. But still, I believe it would pay off in terms of time saved in environment installing and switching. Also, it's a good step in the path to integrating pip as something closer to the Python core. What's your opinion, is the effort required too big for the returns? Do you think other problems may arise? From rosuav at gmail.com Wed Nov 11 06:21:45 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 11 Nov 2020 22:21:45 +1100 Subject: Getting rid of virtual environments with a better dependency system In-Reply-To: References: Message-ID: On Wed, Nov 11, 2020 at 10:06 PM j c wrote: > > Hello all, > > I don't know if this suggestion is missing some point, or it's part of something already proposed. > > In a professional environment, we've came to a point in which most people use virtual environments or conda environments to avoid "polluting a global environment". > > However, I think that's a problem with the default behaviour of the module management in Python. A nice default behaviour would be to search for a requirements.txt file in the same directory as __file__, and use the newest version of every module that matches the constraints. If no requirements where given, the newest version already installed could be used. That would require allowing multiple versions of the same module to be downloaded. > This would stop venvs from providing the isolation that they are supposed to, and instead would just create yet another way to invoke dependency hell. No thank you. A virtual environment isn't just a way to install different versions of modules. It's way WAY more than that, and if you need to have too many different versions around, you have bigger problems to deal with. (As a simple thought experiment to prove the problem with your proposal: what happens with your dependencies' dependencies, and what if they conflict? At what point would that be detected?) ChrisA From Bischoop at vimart.net Wed Nov 11 06:45:53 2020 From: Bischoop at vimart.net (Bischoop) Date: Wed, 11 Nov 2020 11:45:53 -0000 (UTC) Subject: Problem with rearanging list with paired letters next to each others References: <4b477203-fbc6-9d04-9ff9-412ee6d7015a@mrabarnett.plus.com> Message-ID: On 2020-11-11, MRAB wrote: >> > Points to note in your first code: > > 1. Modifying a list while iterating over it is a bad idea. > > 2. You're modifying the list that you're passing in and also returning > it. That's a bad idea. Either modify it in place or modify and return a > copy. > > 3. The line: > > m = (letter_list.index(x)) > > returns the position of the first occurrence of x. > > Points to note in your second code: > > 1. (See above) > > 2. (See above) > > 3. (See above) > > 4. 'i' goes from 0 to len(letter_list)-1, so i+1 goes from 1 to > len(letter_list), but the maximum index permitted by letter_list is > len(letter_list)-1, hence letter_list[i+1] will raise IndexError on the > last iteration. > > 5. 'i' goes from 0 to len(letter_list)-1, so i-1 goes from -1 to > len(letter_list)-2. letter_list[-1] returns the last (final) letter in > the list, and it's treated as a true. > > 6. This: > > x != letter_list[i+1] and letter_list[i-1] > > is checking whether: > > x != letter_list[i+1] > > is true and also whether: > > letter_list[i-1] > > is true. I see now I overcomplicated it, what is a good idea then? From adelamsaleh at yahoo.com Tue Nov 10 18:32:11 2020 From: adelamsaleh at yahoo.com (adelamsaleh at yahoo.com) Date: Tue, 10 Nov 2020 23:32:11 +0000 (UTC) Subject: Need help in installing numpy References: <1860226974.4039411.1605051131552.ref@mail.yahoo.com> Message-ID: <1860226974.4039411.1605051131552@mail.yahoo.com> Dear Python Community, I am new to python.? I sucessfully installed python 3.9 from python.org on my windows 10 pc. I checked it by typing 'py' in the windows cmd prompt and the system indeed responds with the version number, then the >>> prompt, and I can run simple programs without any problem. BUT, if I go back to the cmd prompt and type 'python --version', I simply get the cmd prompt again with no outputs whatsoever. I want to install the 'numpy' package. But when I type on the cmd prompt 'pip install numpy', I get the response:pip : The term 'pip' is not recognized as the name of a cmd let ... etc. I thought that pip is now a part of later versions of python versions 3.x. If so, what did I do wrong? I know this is a very elementary question for this site, but I would appreciate any help. Thanks, From storchaka at gmail.com Wed Nov 11 01:59:27 2020 From: storchaka at gmail.com (Serhiy Storchaka) Date: Wed, 11 Nov 2020 08:59:27 +0200 Subject: constant folding - why not more In-Reply-To: References: <20201110144501.GC32237@crfreenet.org> Message-ID: 11.11.20 02:46, Skip Montanaro ????: > I can think of two reasons. One, this kind of comparison will almost never > appear in production code (maybe in unit tests?). Unlike the C family of > languages, Python doesn't have a macro processor which would give symbolic > names to numeric constants or string literals. Code generators might > conceivably generate constant comparisons, but they might be able to easily > do constant folding of comparisons themselves. > > Two, given that this sort of construct will almost never be found in the > wild, folding constant comparisons in the compiler would increase the > maintenance burden of the compiler (just slightly, but still...) with no > clear benefit. I concur with Skip. Expressions like 2**32-1 or 1/3 or b'A'[0] are pretty common, so it makes sense to evaluate them at compile time. But comparison and boolean operators are newer used with constants in production code. From storchaka at gmail.com Wed Nov 11 03:03:54 2020 From: storchaka at gmail.com (Serhiy Storchaka) Date: Wed, 11 Nov 2020 10:03:54 +0200 Subject: Changing strings in files In-Reply-To: <15ulqfl72ac1rftk224bul2hchks2ogb2o@4ax.com> References: <20201110100710.033b129d@arcor.com> <20201110110854.GA41537@cskk.homeip.net> <20201110194854.4aa09916@arcor.com> <15ulqfl72ac1rftk224bul2hchks2ogb2o@4ax.com> Message-ID: 10.11.20 22:40, Dennis Lee Bieber ????: > Testing for extension in a list of exclusions would be much faster than > scanning the contents of a file, and the few that do get through would have > to be scanned anyway. Then the simplest method should work: read the first 512 bytes and check if they contain b'\0'. Chance that a random sequences of bytes does not contain NUL is (1-1/256)**512 = 0.13. So this will filter out 87% of binary files. Likely6 more, because binary files usually have some structure, and reserve fixed size for integers. Most integers are much less than the maximal value, so higher bits and bytes are zeroes. You can also decrease the probability of false results by increasing the size of tested data or by testing few other byte values (b'\1', b'\2', etc). Anything more sophisticate is just a waste of your time. From storchaka at gmail.com Wed Nov 11 03:19:17 2020 From: storchaka at gmail.com (Serhiy Storchaka) Date: Wed, 11 Nov 2020 10:19:17 +0200 Subject: Changing strings in files In-Reply-To: <20201110100710.033b129d@arcor.com> References: <20201110072444.5acf0769@arcor.com> <20201110073754.GA46480@cskk.homeip.net> <20201110100710.033b129d@arcor.com> Message-ID: 10.11.20 11:07, Manfred Lotz ????: > Perhaps better. I like to use os.scandir this way > > def scantree(path: str) -> Iterator[os.DirEntry[str]]: > """Recursively yield DirEntry objects (no directories) > for a given directory. > """ > for entry in os.scandir(path): > if entry.is_dir(follow_symlinks=False): > yield from scantree(entry.path) > > yield entry > > Worked fine so far. I think I coded it this way because I wanted the > full path of the file the easy way. If this simple code works to you, that's fine, use it. But there are some pitfalls: 1. If you add or remove entries while iterate the directory, the behavior is not specified. It depends on the OS and file system. If you do not modify directories -- all okay. 2. As Cameron said, this method holds open file descriptors for all parent directories. It is usually not problem, because the maximal depth of directories is usually less than the limit of open files. But it can be problem if you process several trees in parallel. The common mistake also to not handle symlinks, but your code does it correctly. From python at mrabarnett.plus.com Wed Nov 11 11:54:05 2020 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 11 Nov 2020 16:54:05 +0000 Subject: Need help in installing numpy In-Reply-To: <1860226974.4039411.1605051131552@mail.yahoo.com> References: <1860226974.4039411.1605051131552.ref@mail.yahoo.com> <1860226974.4039411.1605051131552@mail.yahoo.com> Message-ID: On 2020-11-10 23:32, adelamsaleh--- via Python-list wrote: > Dear Python Community, > I am new to python.? I sucessfully installed python 3.9 from python.org on my windows 10 pc. > I checked it by typing 'py' in the windows cmd prompt and the system indeed responds with the version number, then the >>> prompt, and I can run simple programs without any problem. > BUT, if I go back to the cmd prompt and type 'python --version', I simply get the cmd prompt again with no outputs whatsoever. > I want to install the 'numpy' package. But when I type on the cmd prompt 'pip install numpy', I get the response:pip : The term 'pip' is not recognized as the name of a cmd let ... etc. > > I thought that pip is now a part of later versions of python versions 3.x. If so, what did I do wrong? > > I know this is a very elementary question for this site, but I would appreciate any help. > Using the Python launcher: py --version and: py -m pip install numpy From drsalists at gmail.com Wed Nov 11 12:34:20 2020 From: drsalists at gmail.com (Dan Stromberg) Date: Wed, 11 Nov 2020 09:34:20 -0800 Subject: Getting rid of virtual environments with a better dependency system In-Reply-To: <3bc57280-5bd9-42f4-8b29-3fb5b01216ddn@googlegroups.com> References: <3bc57280-5bd9-42f4-8b29-3fb5b01216ddn@googlegroups.com> Message-ID: On Wed, Nov 11, 2020 at 3:00 AM j c wrote: > Hello all, > > I don't know if this suggestion is missing some point, or it's part of > something already proposed before. > > In a professional environment, we've came to a point in which most people > use virtual environments or code environments to avoid "polluting a global > environment". > I think it'd be a good idea to have a directory (hierarchy) for each python application, and make pip (or similar tool) download to that directory - and then modify the _application's_ sys.path to include that directory at the beginning. This is what I've done with backshift ( https://stromberg.dnsalias.org/~strombrg/backshift/). It works well, without a need for a virtual environment, while still giving dependency isolation. But it's not as automatic as I'd like - I've had to manually specify what dependencies to put in the directory. I use virtual environments sometimes, but I always cringe slightly when doing so. There should be a better way. This is one of the chief benefits of languages like C, C++ and Rust over Python - they don't require you to source something before you can run an app written in them. From PythonList at DancesWithMice.info Wed Nov 11 12:47:31 2020 From: PythonList at DancesWithMice.info (dn) Date: Thu, 12 Nov 2020 06:47:31 +1300 Subject: Problem with rearanging list with paired letters next to each others In-Reply-To: References: <4b477203-fbc6-9d04-9ff9-412ee6d7015a@mrabarnett.plus.com> Message-ID: On 12/11/2020 00:45, Bischoop wrote: > I see now I overcomplicated it, what is a good idea then? This is a variation on a data-compression technique called RLE=Run-Length Encoding (excepting that in this case there is no need to count the repetitions). Web.Ref: https://stackabuse.com/run-length-encoding/ -- Regards =dn From rosuav at gmail.com Wed Nov 11 13:38:03 2020 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 12 Nov 2020 05:38:03 +1100 Subject: Getting rid of virtual environments with a better dependency system In-Reply-To: References: <3bc57280-5bd9-42f4-8b29-3fb5b01216ddn@googlegroups.com> Message-ID: On Thu, Nov 12, 2020 at 4:35 AM Dan Stromberg wrote: > > On Wed, Nov 11, 2020 at 3:00 AM j c wrote: > > > Hello all, > > > > I don't know if this suggestion is missing some point, or it's part of > > something already proposed before. > > > > In a professional environment, we've came to a point in which most people > > use virtual environments or code environments to avoid "polluting a global > > environment". > > > I think it'd be a good idea to have a directory (hierarchy) for each python > application, and make pip (or similar tool) download to that directory - > and then modify the _application's_ sys.path to include that directory at > the beginning. > > This is what I've done with backshift ( > https://stromberg.dnsalias.org/~strombrg/backshift/). It works well, > without a need for a virtual environment, while still giving dependency > isolation. But it's not as automatic as I'd like - I've had to manually > specify what dependencies to put in the directory. > Can you elaborate on exactly how this is different? When you create a venv, it creates some symlinks and such that basically mean you get that - a directory for the application, pip installs into it, and then when you run that Python binary, it'll automatically have sys.path contain the appropriate directory. ChrisA From drsalists at gmail.com Wed Nov 11 18:44:20 2020 From: drsalists at gmail.com (Dan Stromberg) Date: Wed, 11 Nov 2020 15:44:20 -0800 Subject: Getting rid of virtual environments with a better dependency system In-Reply-To: References: <3bc57280-5bd9-42f4-8b29-3fb5b01216ddn@googlegroups.com> Message-ID: On Wed, Nov 11, 2020 at 10:38 AM Chris Angelico wrote: > On Thu, Nov 12, 2020 at 4:35 AM Dan Stromberg wrote: > > > > On Wed, Nov 11, 2020 at 3:00 AM j c wrote: > > > > > Hello all, > > > > > > I don't know if this suggestion is missing some point, or it's part of > > > something already proposed before. > > > > > > In a professional environment, we've came to a point in which most > people > > > use virtual environments or code environments to avoid "polluting a > global > > > environment". > > > > > I think it'd be a good idea to have a directory (hierarchy) for each > python > > application, and make pip (or similar tool) download to that directory - > > and then modify the _application's_ sys.path to include that directory at > > the beginning. > > > > This is what I've done with backshift ( > > https://stromberg.dnsalias.org/~strombrg/backshift/). It works well, > > without a need for a virtual environment, while still giving dependency > > isolation. But it's not as automatic as I'd like - I've had to manually > > specify what dependencies to put in the directory. > > > > Can you elaborate on exactly how this is different? When you create a > venv, it creates some symlinks and such that basically mean you get > that - a directory for the application, pip installs into it, and then > when you run that Python binary, it'll automatically have sys.path > contain the appropriate directory. > Maybe it's not that different. I do get a .../bin/backshift though, which is a bash script that knows how to start up python on the main module. So the user need not source something at install time or at run time. The install process is ./configure and make install, where ./configure is Not autoconf, but acts sort of like an autoconf script. From jucaranlu at gmail.com Wed Nov 11 18:54:47 2020 From: jucaranlu at gmail.com (j c) Date: Wed, 11 Nov 2020 15:54:47 -0800 (PST) Subject: Getting rid of virtual environments with a better dependency system In-Reply-To: References: Message-ID: <9fa83e29-93a6-4f96-8c54-a4ea692ae48dn@googlegroups.com> On Wednesday, 11 November 2020 at 12:22:24 UTC+1, Chris Angelico wrote: > On Wed, Nov 11, 2020 at 10:06 PM j c wrote: > > > > Hello all, > > > > I don't know if this suggestion is missing some point, or it's part of something already proposed. > > > > In a professional environment, we've came to a point in which most people use virtual environments or conda environments to avoid "polluting a global environment". > > > > However, I think that's a problem with the default behaviour of the module management in Python. A nice default behaviour would be to search for a requirements.txt file in the same directory as __file__, and use the newest version of every module that matches the constraints. If no requirements where given, the newest version already installed could be used. That would require allowing multiple versions of the same module to be downloaded. > > > This would stop venvs from providing the isolation that they are > supposed to, and instead would just create yet another way to invoke > dependency hell. No thank you. > > A virtual environment isn't just a way to install different versions > of modules. It's way WAY more than that, and if you need to have too > many different versions around, you have bigger problems to deal with. > > (As a simple thought experiment to prove the problem with your > proposal: what happens with your dependencies' dependencies, and what > if they conflict? At what point would that be detected?) > > ChrisA How can this behaviour turn into dependency hell? Every dependency use the specified version if any, otherwise the most recent one, which also applies to second order dependencies. In case of conflict, the first version would be imported, which is currently the default behaviour. The main difference is that this approach would be able to generate a warning before running the script with no need for pipdeptree. From rosuav at gmail.com Wed Nov 11 18:56:45 2020 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 12 Nov 2020 10:56:45 +1100 Subject: Getting rid of virtual environments with a better dependency system In-Reply-To: References: <3bc57280-5bd9-42f4-8b29-3fb5b01216ddn@googlegroups.com> Message-ID: On Thu, Nov 12, 2020 at 10:44 AM Dan Stromberg wrote: > > > On Wed, Nov 11, 2020 at 10:38 AM Chris Angelico wrote: >> >> On Thu, Nov 12, 2020 at 4:35 AM Dan Stromberg wrote: >> > >> > On Wed, Nov 11, 2020 at 3:00 AM j c wrote: >> > >> > > Hello all, >> > > >> > > I don't know if this suggestion is missing some point, or it's part of >> > > something already proposed before. >> > > >> > > In a professional environment, we've came to a point in which most people >> > > use virtual environments or code environments to avoid "polluting a global >> > > environment". >> > > >> > I think it'd be a good idea to have a directory (hierarchy) for each python >> > application, and make pip (or similar tool) download to that directory - >> > and then modify the _application's_ sys.path to include that directory at >> > the beginning. >> > >> > This is what I've done with backshift ( >> > https://stromberg.dnsalias.org/~strombrg/backshift/). It works well, >> > without a need for a virtual environment, while still giving dependency >> > isolation. But it's not as automatic as I'd like - I've had to manually >> > specify what dependencies to put in the directory. >> > >> >> Can you elaborate on exactly how this is different? When you create a >> venv, it creates some symlinks and such that basically mean you get >> that - a directory for the application, pip installs into it, and then >> when you run that Python binary, it'll automatically have sys.path >> contain the appropriate directory. > > > Maybe it's not that different. > > I do get a .../bin/backshift though, which is a bash script that knows how to start up python on the main module. So the user need not source something at install time or at run time. > > The install process is ./configure and make install, where ./configure is Not autoconf, but acts sort of like an autoconf script. > Ah, fair enough. Did you know that, with a vanilla venv, you can actually just run a Python interpreter from within there, without sourcing anything? Very handy for automated scripts. rosuav at sikorsky:~$ mustard-mine/env/bin/python3 -c 'import sys; print(sys.path)' ['', '/usr/local/lib/python38.zip', '/usr/local/lib/python3.8', '/usr/local/lib/python3.8/lib-dynload', '/home/rosuav/mustard-mine/env/lib/python3.8/site-packages'] ChrisA From klsshaeffer at icloud.com Thu Nov 12 00:26:39 2020 From: klsshaeffer at icloud.com (Karen Shaeffer) Date: Wed, 11 Nov 2020 21:26:39 -0800 Subject: io.TextIOWrapper.readlines Message-ID: <48A9575D-51DB-4009-B18F-99A50E01394C@icloud.com> Hi folks, import io with io.open(filename, ?r?) as fd: lines = fd.readlines(hint=1000) for line in lines: # do something I was just looking at the io module. io.open(?file?, ?r') returns an io.TextIOWrapper object, which has the io.TextIOWrapper.readlines(hint=-1/) method. >>> help(io.TextIOWrapper.readlines) readlines(self, hint=-1, /) Return a list of lines from the stream. hint can be specified to control the number of lines read: no more lines will be read if the total size (in bytes/characters) of all lines so far exceeds hint. I haven?t verified this, but that looks like it isn?t reading the entire file. With hint=1000, the method returns as many complete lines that consume less than 1000 bytes of the stream. I?m lazy. Didn?t test it. Seems like only 1000 bytes would be read from the file, rather than the entire file? The builtin ?open? function is defined in the io streams module. I presume the builtin open(?file?, ?r?) returns an io.TextIOWrapper object. And maybe the readlines method just isn?t documented? Just curious and lazy. thanks, Karen From cs at cskk.id.au Thu Nov 12 00:42:20 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 12 Nov 2020 16:42:20 +1100 Subject: io.TextIOWrapper.readlines In-Reply-To: <48A9575D-51DB-4009-B18F-99A50E01394C@icloud.com> References: <48A9575D-51DB-4009-B18F-99A50E01394C@icloud.com> Message-ID: <20201112054220.GA75326@cskk.homeip.net> On 11Nov2020 21:26, Karen Shaeffer wrote: >import io > >with io.open(filename, ?r?) as fd: > lines = fd.readlines(hint=1000) > for line in lines: > # do something > > >I was just looking at the io module. io.open(?file?, ?r') returns an io.TextIOWrapper object, which has the io.TextIOWrapper.readlines(hint=-1/) method. > > >>>> help(io.TextIOWrapper.readlines) >readlines(self, hint=-1, /) > Return a list of lines from the stream. > > hint can be specified to control the number of lines read: no more > lines will be read if the total size (in bytes/characters) of all > lines so far exceeds hint. > >I haven?t verified this, but that looks like it isn?t reading the entire file. With hint=1000, the method returns as many complete lines that consume less than 1000 bytes of the stream. I?m lazy. Didn?t test it. Seems like only 1000 bytes would be read from the file, rather than the entire file? Test it. To my eye, I also think that is what it means. >The builtin ?open? function is defined in the io streams module. I presume the builtin open(?file?, ?r?) returns an io.TextIOWrapper object. Test it: >>> open('/dev/null','r') <_io.TextIOWrapper name='/dev/null' mode='r' encoding='UTF-8'> > And maybe the readlines method just isn?t documented? It is documented though. The docs for io.TextIOWrapper start with this (from the 3.8.0 docs I have handy): A buffered text stream over a BufferedIOBase binary stream. It inherits TextIOBase. The docs for io.TextIOBase start with this: Base class for text streams. This class provides a character and line based interface to stream I/O. It inherits IOBase. And the docs for IOBase has the readlines method with the signature you describe from its help. Nte that if I look at the readlines from TextIOWrapper it says: >>> open('/dev/null','r').readlines which probably means TextIOWrapper is a C implementation (for performance), not doing the plain old class inheritance you'd get from a pure Python implementation. Cheers, Cameron Simpson From alan at csail.mit.edu Thu Nov 12 14:47:38 2020 From: alan at csail.mit.edu (Alan Bawden) Date: Thu, 12 Nov 2020 14:47:38 -0500 Subject: Class Definitions References: Message-ID: <867dqqpdb9.fsf@williamsburg.bawden.org> ram at zedat.fu-berlin.de (Stefan Ram) writes: I expected this solution: class Main: def __init__( self ): self.value = 0 def count( self ): self.value += 1 but a student turned in the following solution: class Main: value = 0 def count(self): self.value += 1 I thought that the solution of the student had a shortcoming but I was not able to put my finger on it. Can you? Not exactly a shortcoming, but the fact that it works as a solution to your problem may cause the student to someday write something like: class Main: value = [] def add(self, x): self.value += [x] and be suprised by the resulting behavior. -- Alan Bawden From PythonList at danceswithmice.info Thu Nov 12 15:53:26 2020 From: PythonList at danceswithmice.info (dn) Date: Fri, 13 Nov 2020 09:53:26 +1300 Subject: Class Definitions In-Reply-To: <867dqqpdb9.fsf@williamsburg.bawden.org> References: <867dqqpdb9.fsf@williamsburg.bawden.org> Message-ID: On 13/11/2020 08:47, Alan Bawden wrote: > ram at zedat.fu-berlin.de (Stefan Ram) writes: > > I expected this solution: > > class Main: > def __init__( self ): > self.value = 0 > def count( self ): > self.value += 1 > > but a student turned in the following solution: > > class Main: > value = 0 > def count(self): > self.value += 1 > > I thought that the solution of the student had a shortcoming > but I was not able to put my finger on it. Can you? > > Not exactly a shortcoming, but the fact that it works as a solution to > your problem may cause the student to someday write something like: > > class Main: > value = [] > def add(self, x): > self.value += [x] > > and be suprised by the resulting behavior. You are right to be concerned - although largely because the differences between class-variables and instance-variables is (sadly) one of those topics poorly-understood by many, and thus best avoided simply to prevent confusion. (I'll be the first to concur that this not a good reason, and particularly not for someone in education/training, but that's life ["as we know it, Jim"]) A worthwhile read is: https://docs.python.org/3/tutorial/classes.html (including @Alan's most-pertinent warning of the subtleties introduced by mutable data-structures) On the other hand, Python has long?always had an aversion to the object-induced 'boiler-plate' required in other languages - and I have to say, even building Python classes with __init__(), __str__(), and __repr__() etc "magic methods", can seem a slog for low return-value. AFTER teaching/learning about the 'classic form', you may like to consider DataClasses (Python 3.7+). These look very similar to your student's submission. One of their objectives is to cut-through a load of the boiler-plate - in many circumstances. https://www.python.org/dev/peps/pep-0557/ https://docs.python.org/3/library/dataclasses.html See also Counter Objects: https://docs.python.org/3/library/collections.html#counter-objects -- Regards =dn From hjp-python at hjp.at Thu Nov 12 17:40:18 2020 From: hjp-python at hjp.at (Peter J. Holzer) Date: Thu, 12 Nov 2020 23:40:18 +0100 Subject: Getting rid of virtual environments with a better dependency system In-Reply-To: References: <3bc57280-5bd9-42f4-8b29-3fb5b01216ddn@googlegroups.com> Message-ID: <20201112224018.GA18352@hjp.at> On 2020-11-12 10:56:45 +1100, Chris Angelico wrote: > On Thu, Nov 12, 2020 at 10:44 AM Dan Stromberg wrote: > > I do get a .../bin/backshift though, which is a bash script that > > knows how to start up python on the main module. So the user need > > not source something at install time or at run time. > > > > The install process is ./configure and make install, where > > ./configure is Not autoconf, but acts sort of like an autoconf > > script. > > > > Ah, fair enough. > > Did you know that, with a vanilla venv, you can actually just run a > Python interpreter from within there, without sourcing anything? Very > handy for automated scripts. This also works with the Python interpreter in the shebang line. So if your "make install" for "mytool" creates a venv in /usr/local/lib/mytool/venv and then replaces the shebang in /usr/local/bin/mytool with "#!/usr/local/lib/mytool/venv/python", the user can just invoke "mytool" without caring about the virtual environment. If you do that for every Python script, size may be a problem, though: I just checked a few of my venvs, and they are between 13 and 418 MB: Average 81 MB. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From rosuav at gmail.com Thu Nov 12 20:07:40 2020 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 13 Nov 2020 12:07:40 +1100 Subject: Getting rid of virtual environments with a better dependency system In-Reply-To: <20201112224018.GA18352@hjp.at> References: <3bc57280-5bd9-42f4-8b29-3fb5b01216ddn@googlegroups.com> <20201112224018.GA18352@hjp.at> Message-ID: On Fri, Nov 13, 2020 at 9:41 AM Peter J. Holzer wrote: > > On 2020-11-12 10:56:45 +1100, Chris Angelico wrote: > > On Thu, Nov 12, 2020 at 10:44 AM Dan Stromberg wrote: > > > I do get a .../bin/backshift though, which is a bash script that > > > knows how to start up python on the main module. So the user need > > > not source something at install time or at run time. > > > > > > The install process is ./configure and make install, where > > > ./configure is Not autoconf, but acts sort of like an autoconf > > > script. > > > > > > > Ah, fair enough. > > > > Did you know that, with a vanilla venv, you can actually just run a > > Python interpreter from within there, without sourcing anything? Very > > handy for automated scripts. > > This also works with the Python interpreter in the shebang line. > > So if your "make install" for "mytool" creates a venv in > /usr/local/lib/mytool/venv and then replaces the shebang in > /usr/local/bin/mytool with "#!/usr/local/lib/mytool/venv/python", the > user can just invoke "mytool" without caring about the virtual > environment. > > If you do that for every Python script, size may be a problem, though: I > just checked a few of my venvs, and they are between 13 and 418 MB: > Average 81 MB. > Indeed. I would divide Python scripts into a few categories: 1) System scripts. If the script came from a Debian repository, it runs in the Debian-provided Python and uses libraries installed with apt/dpkg. 2) Scripts that don't really much care about their environment. These will generally run in the latest master branch build of Python (currently 3.10), and if they need anything installed, I install it ("globally") into that instance of Python. They can't interfere with system scripts, but can interfere with each other. 3) Scripts that get their own venv. That could be because they conflict with something else, or something else conflicts with them, or they need specific versions of things, or anything. At the moment, I can find a grand total of nine virtual environments for various scripts. Some of them are because Python 3.10 can't run the scripts in question; others probably could run, but I want a consistent environment for my dev/staging so it's easier to push to production. The largest env directory is 250ish MB, and they average 94MB, so my figures are fairly comparable to yours. ChrisA From asteventon at centurytel.net Thu Nov 12 22:00:21 2020 From: asteventon at centurytel.net (Anthony Steventon) Date: Thu, 12 Nov 2020 20:00:21 -0700 Subject: How to start using python Message-ID: <2416BB9922644447A726C64E5D5AB191@AnthonyPC> I am new to Python and have downloaded the software onto my pc. There is no shortcut on my desktop. How the heck do I access it to start learning how to program with it? Anthony Steventon. -- This email has been checked for viruses by AVG. https://www.avg.com From bgailer at gmail.com Thu Nov 12 22:58:08 2020 From: bgailer at gmail.com (Bob Gailer) Date: Thu, 12 Nov 2020 22:58:08 -0500 Subject: How to start using python In-Reply-To: <2416BB9922644447A726C64E5D5AB191@AnthonyPC> References: <2416BB9922644447A726C64E5D5AB191@AnthonyPC> Message-ID: On Nov 12, 2020 10:41 PM, "Anthony Steventon" wrote: > > I am new to Python and have downloaded the software onto my pc. There is no shortcut on my desktop. How the heck do I access it to start learning how to program with it? Visit www.Python.Org there should be some links to tutorials that should cover the topics of how to install python and how to start using it. If that does not help come back to us with more information including your operating system, the website from which you downloaded the installer, the name of the installer file, and what you did to install python. You also might try from a terminal or command prompt typing py, which should start up a python Interactive session. You should see>>> type 2 + 3 hit enter you should see a new line displaying five. Let us know how it goes and we'll give you a hand from there. Bob Gailer From chalao.adda at gmail.com Fri Nov 13 08:56:41 2020 From: chalao.adda at gmail.com (ChalaoAdda) Date: Fri, 13 Nov 2020 13:56:41 +0000 (UTC) Subject: tkinter global variable Message-ID: Hello, I am trying to read a file from askopenfilename outside the function. I am getting blank file name. What am I doing wrong? Here is my code. from tkinter import * from tkinter import filedialog def on_openfile(): global pic pic = filedialog.askopenfilename() root = Tk() menubar = Menu(root) root.config(menu=menubar) file_menu = Menu(menubar) file_menu.add_command(label="Open", command=on_openfile) file_menu.add_command(label="Exit", command=root.destroy) menubar.add_cascade(label="File", menu=file_menu) f = open(pic) print(f.read()) root.mainloop() Thanks. From chalao.adda at gmail.com Fri Nov 13 10:57:25 2020 From: chalao.adda at gmail.com (ChalaoAdda) Date: Fri, 13 Nov 2020 15:57:25 +0000 (UTC) Subject: tkinter global variable References: Message-ID: On Fri, 13 Nov 2020 15:41:20 +0000, Stefan Ram wrote: > ChalaoAdda writes: >>I am trying to read a file from askopenfilename outside the function. I >>am getting blank file name. What am I doing wrong? Here is my code. > > It is possible that you try to read from "pic" before "on_openfile" > ever was executed. I didn't get you. I click on the menu item "Open" and then from the filedialog select a file. And then outside that function I am trying to read and print the file. From chalao.adda at gmail.com Fri Nov 13 11:42:53 2020 From: chalao.adda at gmail.com (ChalaoAdda) Date: Fri, 13 Nov 2020 16:42:53 +0000 (UTC) Subject: tkinter global variable References: Message-ID: On Fri, 13 Nov 2020 16:04:03 +0000, Stefan Ram wrote: > ChalaoAdda writes: >>On Fri, 13 Nov 2020 15:41:20 +0000, Stefan Ram wrote: >>> ChalaoAdda writes: >>>>I am trying to read a file from askopenfilename outside the function. >>>>I am getting blank file name. What am I doing wrong? Here is my code. >>>It is possible that you try to read from "pic" before "on_openfile" >>>ever was executed. >>I didn't get you. I click on the menu item "Open" and then from the >>filedialog select a file. And then outside that function I am trying to >>read and print the file. > > I have added two additional statements to your source code: > print( "A" ) and print( "B" ). > > If you now execute this new source code, you might observe that "B" is > being printed before "A" is being printed. > > from tkinter import * > from tkinter import filedialog > > def on_openfile(): > print( "A" ) > global pic pic = filedialog.askopenfilename() > > > root = Tk() > > menubar = Menu(root) > root.config(menu=menubar) > file_menu = Menu(menubar) file_menu.add_command(label="Open", > command=on_openfile) file_menu.add_command(label="Exit", > command=root.destroy) > menubar.add_cascade(label="File", menu=file_menu) > > > print( "B" ) > f = open(pic) > print(f.read()) > > root.mainloop() Ok. I got the point. So what do I need to do access the variable? How do I return a value from that function? Thanks. From Richard at Damon-Family.org Fri Nov 13 12:04:53 2020 From: Richard at Damon-Family.org (Richard Damon) Date: Fri, 13 Nov 2020 12:04:53 -0500 Subject: tkinter global variable In-Reply-To: References: Message-ID: <4ad5d3b6-74d1-6584-1225-7c1078a1eccb@Damon-Family.org> On 11/13/20 11:42 AM, ChalaoAdda wrote: > On Fri, 13 Nov 2020 16:04:03 +0000, Stefan Ram wrote: > >> ChalaoAdda writes: >>> On Fri, 13 Nov 2020 15:41:20 +0000, Stefan Ram wrote: >>>> ChalaoAdda writes: >>>>> I am trying to read a file from askopenfilename outside the function. >>>>> I am getting blank file name. What am I doing wrong? Here is my code. >>>> It is possible that you try to read from "pic" before "on_openfile" >>>> ever was executed. >>> I didn't get you. I click on the menu item "Open" and then from the >>> filedialog select a file. And then outside that function I am trying to >>> read and print the file. >> I have added two additional statements to your source code: >> print( "A" ) and print( "B" ). >> >> If you now execute this new source code, you might observe that "B" is >> being printed before "A" is being printed. >> >> from tkinter import * >> from tkinter import filedialog >> >> def on_openfile(): >> print( "A" ) >> global pic pic = filedialog.askopenfilename() >> >> >> root = Tk() >> >> menubar = Menu(root) >> root.config(menu=menubar) >> file_menu = Menu(menubar) file_menu.add_command(label="Open", >> command=on_openfile) file_menu.add_command(label="Exit", >> command=root.destroy) >> menubar.add_cascade(label="File", menu=file_menu) >> >> >> print( "B" ) >> f = open(pic) >> print(f.read()) >> >> root.mainloop() > Ok. I got the point. So what do I need to do access the variable? How do > I return a value from that function? > > Thanks. The problem is that you are accessing the variable BEFORE the box has been put up and the user clicking on it. That doesn't happen until the mainloop() call. You need to delay the opening and reading of the file till the filedialog has been used and returned. Perhaps on_openfile could open and read the file. -- Richard Damon From chalao.adda at gmail.com Fri Nov 13 12:12:10 2020 From: chalao.adda at gmail.com (ChalaoAdda) Date: Fri, 13 Nov 2020 17:12:10 +0000 (UTC) Subject: tkinter global variable References: <4ad5d3b6-74d1-6584-1225-7c1078a1eccb@Damon-Family.org> Message-ID: On Fri, 13 Nov 2020 12:04:53 -0500, Richard Damon wrote: > On 11/13/20 11:42 AM, ChalaoAdda wrote: >> On Fri, 13 Nov 2020 16:04:03 +0000, Stefan Ram wrote: >> >>> ChalaoAdda writes: >>>> On Fri, 13 Nov 2020 15:41:20 +0000, Stefan Ram wrote: >>>>> ChalaoAdda writes: >>>>>> I am trying to read a file from askopenfilename outside the >>>>>> function. >>>>>> I am getting blank file name. What am I doing wrong? Here is my >>>>>> code. >>>>> It is possible that you try to read from "pic" before "on_openfile" >>>>> ever was executed. >>>> I didn't get you. I click on the menu item "Open" and then from the >>>> filedialog select a file. And then outside that function I am trying >>>> to read and print the file. >>> I have added two additional statements to your source code: >>> print( "A" ) and print( "B" ). >>> >>> If you now execute this new source code, you might observe that "B" >>> is being printed before "A" is being printed. >>> >>> from tkinter import * >>> from tkinter import filedialog >>> >>> def on_openfile(): >>> print( "A" ) >>> global pic pic = filedialog.askopenfilename() >>> >>> >>> root = Tk() >>> >>> menubar = Menu(root) >>> root.config(menu=menubar) >>> file_menu = Menu(menubar) file_menu.add_command(label="Open", >>> command=on_openfile) file_menu.add_command(label="Exit", >>> command=root.destroy) >>> menubar.add_cascade(label="File", menu=file_menu) >>> >>> >>> print( "B" ) >>> f = open(pic) >>> print(f.read()) >>> >>> root.mainloop() >> Ok. I got the point. So what do I need to do access the variable? How >> do I return a value from that function? >> >> Thanks. > > The problem is that you are accessing the variable BEFORE the box has > been put up and the user clicking on it. That doesn't happen until the > mainloop() call. You need to delay the opening and reading of the file > till the filedialog has been used and returned. > > Perhaps on_openfile could open and read the file. Ok. Then how do I access the content of the file from outside the function? How can I access return value? Thanks. From david at kolovratnik.net Fri Nov 13 12:40:53 2020 From: david at kolovratnik.net (David =?iso-8859-1?Q?Kolovratn=EDk?=) Date: Fri, 13 Nov 2020 18:40:53 +0100 Subject: tkinter global variable In-Reply-To: References: <4ad5d3b6-74d1-6584-1225-7c1078a1eccb@Damon-Family.org> Message-ID: <20201113174053.GE32237@crfreenet.org> On Fri, Nov 13, 2020 at 05:12:10PM +0000, ChalaoAdda wrote: > On Fri, 13 Nov 2020 12:04:53 -0500, Richard Damon wrote: > > > On 11/13/20 11:42 AM, ChalaoAdda wrote: > >> On Fri, 13 Nov 2020 16:04:03 +0000, Stefan Ram wrote: > >> > >>> ChalaoAdda writes: > >>>> On Fri, 13 Nov 2020 15:41:20 +0000, Stefan Ram wrote: > >>>>> ChalaoAdda writes: > >>>>>> I am trying to read a file from askopenfilename outside the > >>>>>> function. > >>>>>> I am getting blank file name. What am I doing wrong? Here is my > >>>>>> code. > >>>>> It is possible that you try to read from "pic" before "on_openfile" > >>>>> ever was executed. > >>>> I didn't get you. I click on the menu item "Open" and then from the > >>>> filedialog select a file. And then outside that function I am trying > >>>> to read and print the file. > >>> I have added two additional statements to your source code: > >>> print( "A" ) and print( "B" ). > >>> > >>> If you now execute this new source code, you might observe that "B" > >>> is being printed before "A" is being printed. > >>> > >>> from tkinter import * > >>> from tkinter import filedialog > >>> > >>> def on_openfile(): > >>> print( "A" ) > >>> global pic pic = filedialog.askopenfilename() > >>> > >>> > >>> root = Tk() > >>> > >>> menubar = Menu(root) > >>> root.config(menu=menubar) > >>> file_menu = Menu(menubar) file_menu.add_command(label="Open", > >>> command=on_openfile) file_menu.add_command(label="Exit", > >>> command=root.destroy) > >>> menubar.add_cascade(label="File", menu=file_menu) > >>> > >>> > >>> print( "B" ) > >>> f = open(pic) > >>> print(f.read()) > >>> > >>> root.mainloop() > >> Ok. I got the point. So what do I need to do access the variable? How > >> do I return a value from that function? > >> > >> Thanks. > > > > The problem is that you are accessing the variable BEFORE the box has > > been put up and the user clicking on it. That doesn't happen until the > > mainloop() call. You need to delay the opening and reading of the file > > till the filedialog has been used and returned. > > > > Perhaps on_openfile could open and read the file. > > Ok. Then how do I access the content of the file from outside the > function? How can I access return value? > Thanks. What about def on_printfilename(): global pic try: print( f"C: {pic}" ) except NameError: print( f"C! pic not set yet" ) together with file_menu.add_command(label="Print filename", command=on_printfilename) Or move your print("B") block behind the mainloop(). David From Richard at Damon-Family.org Fri Nov 13 13:51:04 2020 From: Richard at Damon-Family.org (Richard Damon) Date: Fri, 13 Nov 2020 13:51:04 -0500 Subject: tkinter global variable In-Reply-To: References: <4ad5d3b6-74d1-6584-1225-7c1078a1eccb@Damon-Family.org> Message-ID: <645eecdb-0a28-9ed8-962c-bede0f001da5@Damon-Family.org> On 11/13/20 12:12 PM, ChalaoAdda wrote: > On Fri, 13 Nov 2020 12:04:53 -0500, Richard Damon wrote: > >> On 11/13/20 11:42 AM, ChalaoAdda wrote: >>> On Fri, 13 Nov 2020 16:04:03 +0000, Stefan Ram wrote: >>> >>>> ChalaoAdda writes: >>>>> On Fri, 13 Nov 2020 15:41:20 +0000, Stefan Ram wrote: >>>>>> ChalaoAdda writes: >>>>>>> I am trying to read a file from askopenfilename outside the >>>>>>> function. >>>>>>> I am getting blank file name. What am I doing wrong? Here is my >>>>>>> code. >>>>>> It is possible that you try to read from "pic" before "on_openfile" >>>>>> ever was executed. >>>>> I didn't get you. I click on the menu item "Open" and then from the >>>>> filedialog select a file. And then outside that function I am trying >>>>> to read and print the file. >>>> I have added two additional statements to your source code: >>>> print( "A" ) and print( "B" ). >>>> >>>> If you now execute this new source code, you might observe that "B" >>>> is being printed before "A" is being printed. >>>> >>>> from tkinter import * >>>> from tkinter import filedialog >>>> >>>> def on_openfile(): >>>> print( "A" ) >>>> global pic pic = filedialog.askopenfilename() >>>> >>>> >>>> root = Tk() >>>> >>>> menubar = Menu(root) >>>> root.config(menu=menubar) >>>> file_menu = Menu(menubar) file_menu.add_command(label="Open", >>>> command=on_openfile) file_menu.add_command(label="Exit", >>>> command=root.destroy) >>>> menubar.add_cascade(label="File", menu=file_menu) >>>> >>>> >>>> print( "B" ) >>>> f = open(pic) >>>> print(f.read()) >>>> >>>> root.mainloop() >>> Ok. I got the point. So what do I need to do access the variable? How >>> do I return a value from that function? >>> >>> Thanks. >> The problem is that you are accessing the variable BEFORE the box has >> been put up and the user clicking on it. That doesn't happen until the >> mainloop() call. You need to delay the opening and reading of the file >> till the filedialog has been used and returned. >> >> Perhaps on_openfile could open and read the file. > Ok. Then how do I access the content of the file from outside the > function? How can I access return value? > Thanks. When you are using a menuing system like tkinter, you have to think about program structure differently. Note that YOU never called on_open in your code (at least not directly), so you can't really get to its return value. It actually gets called somewhere deep inside mainoop(), so you could access the value after that, but you won't get there until you issue the command inside tkinter to shut down the mainloop (your File / Exit), which is probably later than you want. Inside interfaces like this, you generally respond to things in the callbacks. Now, one other option is that rather than wait for the user to select the File / Open command, you could just call your on_openfile() function, which will pop up the dialog, wait for a response, and the set the answer, then you could use it, but then as I said, that question comes up before the user does the File / Open command. -- Richard Damon From bgailer at gmail.com Fri Nov 13 16:30:18 2020 From: bgailer at gmail.com (Bob Gailer) Date: Fri, 13 Nov 2020 16:30:18 -0500 Subject: How to start using python In-Reply-To: <2416BB9922644447A726C64E5D5AB191@AnthonyPC> References: <2416BB9922644447A726C64E5D5AB191@AnthonyPC> Message-ID: I am not feeling well these days. It is sometimes difficult for me to respond to others the way I would like to. This is a long reply; in my humble opinion is important to read all of it 1-whenever you respond to an email from one of us please include the help list what you can do by reply-all since there are others on this list who also help. 2 - you did not provide the information I had requested. It's really hard to help without that information. 3 - problems like you are facing are usually due to some unusual installation method. 4 - I suspect when you run the Visual Basic icon you enter an interactive development environment. True? Python also comes with an interactive development environment its name is IDLE. Idle is normally installed in a subdirectory how's the one that contains python.exe. once you locate that director you'll be able to run idle and you will be in an environment that will look somewhat familiar to you. There are tutorials specifically written to help you use IDLE. Others on this list can tell you how to locate that tutorial. 5 - I am sorry you are having such difficulty. It is relatively unusual for newcomers to experience that. 6 - suggestion: uninstall the thing you installed. go to python.Org. find, download and run the correct installer paying attention to any information it gives you on where it is installing python. then try running py again. On Nov 12, 2020 10:41 PM, "Anthony Steventon" wrote: > I am new to Python and have downloaded the software onto my pc. There is > no shortcut on my desktop. How the heck do I access it to start learning > how to program with it? > Anthony Steventon. > > -- > This email has been checked for viruses by AVG. > https://www.avg.com > -- > https://mail.python.org/mailman/listinfo/python-list > From charledeon at gmail.com Fri Nov 13 00:28:23 2020 From: charledeon at gmail.com (Charles Okorobo) Date: Fri, 13 Nov 2020 06:28:23 +0100 Subject: Unable to set up Python correctly Message-ID: I have a problem going to one(1) week now. Our instructor told us that we can check if our Python is well installed or well set up correctly by typing Control-Shift- P on Windows OS while in VS Code Editor. We cut out the path enclosed within the Quotation Marks, then we type "Select Interpreter" and this will auto detect the installation path of our Python installation. And when we click on that path, it will auto populate the Path for us. I did that, and it never happened. I mean that--when I followed all the instructions, my path never auto populated. So while the Path of our instructor is 3.8 and 32-bit, mine is 3.9 and 64-bit. But I am not able to auto populate the path to reflect my own path and Python version. And when I try to print out Hello World, I get an error. See screenshot of the path error-- https://prnt.sc/vidqif [image: Mine vs default Path.png] See screenshot of my Hello World error-- https://prnt.sc/vh6130 [image: Python VS Code error.png] How can I fix this? And is anyone willing to use Team Member software to help me remotely fix this and still show me what you did to fix it? I've not been able to move forward. Needing help desperately. From asteventon at centurytel.net Fri Nov 13 17:53:27 2020 From: asteventon at centurytel.net (Anthony Steventon) Date: Fri, 13 Nov 2020 15:53:27 -0700 Subject: How to start using python In-Reply-To: References: <2416BB9922644447A726C64E5D5AB191@AnthonyPC> Message-ID: Thanks for the help from everyone. Operating system is windows 7. Download installation file is python-3.7.9-amd64.exe downloaded from python.org. No problems when I run it, installation successful. Have tried 2 + 3 with a result of 5 at the command prompt. whatever I put in after that I get a message telling me the entry is undefined. Anthony Steventon. From: Bob Gailer Sent: Thursday, November 12, 2020 8:58 PM To: Anthony Steventon Cc: python list Subject: Re: How to start using python On Nov 12, 2020 10:41 PM, "Anthony Steventon" wrote: > > I am new to Python and have downloaded the software onto my pc. There is no shortcut on my desktop. How the heck do I access it to start learning how to program with it? Visit www.Python.Org there should be some links to tutorials that should cover the topics of how to install python and how to start using it. If that does not help come back to us with more information including your operating system, the website from which you downloaded the installer, the name of the installer file, and what you did to install python. You also might try from a terminal or command prompt typing py, which should start up a python Interactive session. You should see>>> type 2 + 3 hit enter you should see a new line displaying five. Let us know how it goes and we'll give you a hand from there. Bob Gailer -- This email has been checked for viruses by AVG. https://www.avg.com From cs at cskk.id.au Fri Nov 13 18:51:40 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Sat, 14 Nov 2020 10:51:40 +1100 Subject: How to start using python In-Reply-To: References: Message-ID: <20201113235140.GA71819@cskk.homeip.net> On 13Nov2020 15:53, Anthony Steventon wrote: >Thanks for the help from everyone. >Operating system is windows 7. Download installation file is python-3.7.9-amd64.exe downloaded from python.org. No problems when I run it, installation successful. >Have tried 2 + 3 with a result of 5 at the command prompt. whatever I put in after that I get a message telling me the entry is undefined. >Anthony Steventon. Please cut/paste the text of what you're trying, along with the full error messages. Then we can explain the output to you. This is a text only list, so no attachments - just paste the text inline in your message. Cheers, Cameron Simpson From cs at cskk.id.au Fri Nov 13 18:56:14 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Sat, 14 Nov 2020 10:56:14 +1100 Subject: tkinter global variable In-Reply-To: References: Message-ID: <20201113235614.GA83425@cskk.homeip.net> On 13Nov2020 12:48, Dennis Lee Bieber wrote: >On Fri, 13 Nov 2020 18:40:53 +0100, David Kolovratn?k > declaimed the following: >>def on_printfilename(): >> global pic >> try: >> print( f"C: {pic}" ) >> except NameError: >> print( f"C! pic not set yet" ) >> > > Just an aside: you only need "global " if you are modifying the >value bound to . If does not exist as a local and all one is >doing is reading , Python will automatically check the module >(global) scope for that . This might be confusing< because that state is fragile, only applying if "pic" is never set, only accessed. As soon as David modifies on_printfilename() to _assign_ to pic, it becomes a local name if he hasn't used "global". IMO, if he must use "pic" as a global it is better to explicitly use "global" anyway. Cheers, Cameron Simpson From python at mrabarnett.plus.com Fri Nov 13 19:47:21 2020 From: python at mrabarnett.plus.com (MRAB) Date: Sat, 14 Nov 2020 00:47:21 +0000 Subject: Unable to set up Python correctly In-Reply-To: References: Message-ID: <36dd7b6b-54ec-9525-4dd6-624b072753e5@mrabarnett.plus.com> On 2020-11-13 05:28, Charles Okorobo wrote: > I have a problem going to one(1) week now. Our instructor told us that we > can check if our Python is well installed or well set up correctly by > typing Control-Shift- P on Windows OS while in VS Code Editor. We cut out > the path enclosed within the Quotation Marks, then we type "Select > Interpreter" and this will auto detect the installation path of our Python > installation. And when we click on that path, it will auto populate the > Path for us. > > I did that, and it never happened. I mean that--when I followed all the > instructions, my path never auto populated. > > So while the Path of our instructor is 3.8 and 32-bit, mine is 3.9 and > 64-bit. But I am not able to auto populate the path to reflect my own path > and Python version. And when I try to print out Hello World, I get an error. > > See screenshot of the path error-- https://prnt.sc/vidqif > [image: Mine vs default Path.png] > > See screenshot of my Hello World error-- https://prnt.sc/vh6130 > [image: Python VS Code error.png] > > How can I fix this? > > And is anyone willing to use Team Member software to help me remotely fix > this and still show me what you did to fix it? > > I've not been able to move forward. > Needing help desperately. > Have you tried just editing the path in settings.json? It might be as simple as changing "Python38-32" to "Python39-64", assuming that you installed Python in a similar place. From chalao.adda at gmail.com Fri Nov 13 23:25:31 2020 From: chalao.adda at gmail.com (ChalaoAdda) Date: Sat, 14 Nov 2020 04:25:31 +0000 (UTC) Subject: tkinter global variable References: <4ad5d3b6-74d1-6584-1225-7c1078a1eccb@Damon-Family.org> <20201113174053.GE32237@crfreenet.org> Message-ID: On Fri, 13 Nov 2020 18:40:53 +0100, David Kolovratn?k wrote: > On Fri, Nov 13, 2020 at 05:12:10PM +0000, ChalaoAdda wrote: >> On Fri, 13 Nov 2020 12:04:53 -0500, Richard Damon wrote: >> >> > On 11/13/20 11:42 AM, ChalaoAdda wrote: >> >> On Fri, 13 Nov 2020 16:04:03 +0000, Stefan Ram wrote: >> >> >> >>> ChalaoAdda writes: >> >>>> On Fri, 13 Nov 2020 15:41:20 +0000, Stefan Ram wrote: >> >>>>> ChalaoAdda writes: >> >>>>>> I am trying to read a file from askopenfilename outside the >> >>>>>> function. >> >>>>>> I am getting blank file name. What am I doing wrong? Here is my >> >>>>>> code. >> >>>>> It is possible that you try to read from "pic" before >> >>>>> "on_openfile" >> >>>>> ever was executed. >> >>>> I didn't get you. I click on the menu item "Open" and then from >> >>>> the filedialog select a file. And then outside that function I am >> >>>> trying to read and print the file. >> >>> I have added two additional statements to your source code: >> >>> print( "A" ) and print( "B" ). >> >>> >> >>> If you now execute this new source code, you might observe that >> >>> "B" >> >>> is being printed before "A" is being printed. >> >>> >> >>> from tkinter import * >> >>> from tkinter import filedialog >> >>> >> >>> def on_openfile(): >> >>> print( "A" ) >> >>> global pic pic = filedialog.askopenfilename() >> >>> >> >>> >> >>> root = Tk() >> >>> >> >>> menubar = Menu(root) >> >>> root.config(menu=menubar) >> >>> file_menu = Menu(menubar) file_menu.add_command(label="Open", >> >>> command=on_openfile) file_menu.add_command(label="Exit", >> >>> command=root.destroy) >> >>> menubar.add_cascade(label="File", menu=file_menu) >> >>> >> >>> >> >>> print( "B" ) >> >>> f = open(pic) >> >>> print(f.read()) >> >>> >> >>> root.mainloop() >> >> Ok. I got the point. So what do I need to do access the variable? >> >> How do I return a value from that function? >> >> >> >> Thanks. >> > >> > The problem is that you are accessing the variable BEFORE the box has >> > been put up and the user clicking on it. That doesn't happen until >> > the mainloop() call. You need to delay the opening and reading of the >> > file till the filedialog has been used and returned. >> > >> > Perhaps on_openfile could open and read the file. >> >> Ok. Then how do I access the content of the file from outside the >> function? How can I access return value? >> Thanks. > What about > > def on_printfilename(): > global pic try: > print( f"C: {pic}" ) > except NameError: > print( f"C! pic not set yet" ) > > together with > > file_menu.add_command(label="Print filename", command=on_printfilename) > > Or move your print("B") block behind the mainloop(). > > David Thanks. That solved my problem. Thanks. From ml_news at posteo.de Sat Nov 14 04:09:32 2020 From: ml_news at posteo.de (Manfred Lotz) Date: Sat, 14 Nov 2020 10:09:32 +0100 Subject: Class Definitions References: Message-ID: <20201114100932.28d796a1@arcor.com> On 11 Nov 2020 19:21:57 GMT ram at zedat.fu-berlin.de (Stefan Ram) wrote: > In my Python course I gave the assignment to define a > counter class "Main" so that > > counter0 = Main() > counter1 = Main() > counter1.count(); counter1.count(); counter1.count() > counter1.count(); counter1.count() > print( counter0.value ) > print( counter1.value ) > > would print > > 0 > 5 > > . > > I expected this solution: > > class Main: > def __init__( self ): > self.value = 0 > def count( self ): > self.value += 1 > > but a student turned in the following solution: > > class Main: > value = 0 > def count(self): > self.value += 1 > > . I am still a Python beginner and didn't even believe that the student's solution would work. I had expected an error as the instance variable self.value was not initialized. -- Manfred From 2QdxY4RzWzUUiLuE at potatochowder.com Sat Nov 14 06:08:07 2020 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Sat, 14 Nov 2020 05:08:07 -0600 Subject: Class Definitions In-Reply-To: <20201114100932.28d796a1@arcor.com> References: <20201114100932.28d796a1@arcor.com> Message-ID: On 2020-11-14 at 10:09:32 +0100, Manfred Lotz wrote: > On 11 Nov 2020 19:21:57 GMT > ram at zedat.fu-berlin.de (Stefan Ram) wrote: > > > In my Python course I gave the assignment to define a > > counter class "Main" so that > > > > counter0 = Main() > > counter1 = Main() > > counter1.count(); counter1.count(); counter1.count() > > counter1.count(); counter1.count() > > print( counter0.value ) > > print( counter1.value ) > > > > would print > > > > 0 > > 5 > > > > . > > > > I expected this solution: > > > > class Main: > > def __init__( self ): > > self.value = 0 > > def count( self ): > > self.value += 1 > > > > but a student turned in the following solution: > > > > class Main: > > value = 0 > > def count(self): > > self.value += 1 > > > > . > > I am still a Python beginner and didn't even believe that the student's > solution would work. I had expected an error as the instance variable > self.value was not initialized. Remember: (1) x += 1 behaves like x = x + 1, and (2) bindings created inside a class statement but outside any method create class attributes. So after counter0 = Main(), Main (the class) has an attribute called "value" whose value is 0, and counter0.value refers to that attribute. Then counter0.count() executes self.value += 1, which behaves like self.value = self.value + 1. The right side of that assignment evaluates to 1 (the value of the class attribute plus the constant 1), and then the assignment statement initializes self.value to *that* value. There's nothing special about initializing instance attributes in __init__. An instance attribute can be created/initialized anywhere. HTH, Dan From ml_news at posteo.de Sat Nov 14 08:59:16 2020 From: ml_news at posteo.de (Manfred Lotz) Date: Sat, 14 Nov 2020 14:59:16 +0100 Subject: Class Definitions References: <20201114100932.28d796a1@arcor.com> Message-ID: <20201114145916.5b126027@arcor.com> On Sat, 14 Nov 2020 05:08:07 -0600 2QdxY4RzWzUUiLuE at potatochowder.com wrote: > On 2020-11-14 at 10:09:32 +0100, > Manfred Lotz wrote: > > > On 11 Nov 2020 19:21:57 GMT > > ram at zedat.fu-berlin.de (Stefan Ram) wrote: > > > > > In my Python course I gave the assignment to define a > > > counter class "Main" so that > > > > > > counter0 = Main() > > > counter1 = Main() > > > counter1.count(); counter1.count(); counter1.count() > > > counter1.count(); counter1.count() > > > print( counter0.value ) > > > print( counter1.value ) > > > > > > would print > > > > > > 0 > > > 5 > > > > > > . > > > > > > I expected this solution: > > > > > > class Main: > > > def __init__( self ): > > > self.value = 0 > > > def count( self ): > > > self.value += 1 > > > > > > but a student turned in the following solution: > > > > > > class Main: > > > value = 0 > > > def count(self): > > > self.value += 1 > > > > > > . > > > > I am still a Python beginner and didn't even believe that the > > student's solution would work. I had expected an error as the > > instance variable self.value was not initialized. > > Remember: (1) x += 1 behaves like x = x + 1, and (2) bindings created > inside a class statement but outside any method create class > attributes. > > So after counter0 = Main(), Main (the class) has an attribute called > "value" whose value is 0, and counter0.value refers to that attribute. > > Then counter0.count() executes self.value += 1, which behaves like > self.value = self.value + 1. The right side of that assignment > evaluates to 1 (the value of the class attribute plus the constant 1), > and then the assignment statement initializes self.value to *that* > value. > > There's nothing special about initializing instance attributes in > __init__. An instance attribute can be created/initialized anywhere. > > Thanks to you and Stefan. I did not know that if an instance variable doesn't exist the same name is searched for as a class variable. -- Manfred From tjreedy at udel.edu Sat Nov 14 06:16:05 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Sat, 14 Nov 2020 06:16:05 -0500 Subject: Class Definitions In-Reply-To: <20201114100932.28d796a1@arcor.com> References: <20201114100932.28d796a1@arcor.com> Message-ID: On 11/14/2020 4:09 AM, Manfred Lotz wrote: > On 11 Nov 2020 19:21:57 GMT > ram at zedat.fu-berlin.de (Stefan Ram) wrote: > >> In my Python course I gave the assignment to define a >> counter class "Main" so that >> >> counter0 = Main() >> counter1 = Main() >> counter1.count(); counter1.count(); counter1.count() >> counter1.count(); counter1.count() >> print( counter0.value ) >> print( counter1.value ) >> >> would print >> >> 0 >> 5 >> >> . >> >> I expected this solution: >> >> class Main: >> def __init__( self ): >> self.value = 0 >> def count( self ): >> self.value += 1 >> >> but a student turned in the following solution: >> >> class Main: >> value = 0 >> def count(self): >> self.value += 1 >> >> . > > I am still a Python beginner and didn't even believe that the student's > solution would work. I had expected an error as the instance variable > self.value was not initialized. It was not. But self.x as a value, rather than a target, first looks for instance x, then class x, then superclass x, up to object.x. Such lookup is routine for methods, much rarer for data. self.value += 1 is roughly equivalent to self.value = self.value +1 where the right self.value is Main.value. 'self' is only looked up once, but apparently the value attribute is looked up twice, in spite of what one might think from the doc, so that the first assignment to self.value initializes an instance value rather than overwriting the class value. -- Terry Jan Reedy From jmoguill2 at gmail.com Sat Nov 14 16:41:27 2020 From: jmoguill2 at gmail.com (Jeff) Date: Sat, 14 Nov 2020 14:41:27 -0700 Subject: Debugging native cython module with visual studio toolchain In-Reply-To: References: <20201114100932.28d796a1@arcor.com> Message-ID: > > Hi, > > We developed a Python module that interfaces with native code via Cython. > > We currently build on Windows with Visual Studio Toolchain. > > We encounter the following issues when trying to build a debug version: > > 1) 3rd party modules installed via PIP are Release mode, but Visual Studio >> toolchain doesn't allow to mix Debug and Release libs. To workaround this >> issue, we build our module in "Release" mode, with debug symbols enabled, >> and with compiled optimization disabled (essentially a hack). > > 2) To build our module we currently use the following hack: > > step 1: run python.exe setup.py build --compiler=msvc > > step 2: extract the output > > step 3: change /Ox to /Od (disable compiler optimization) > > add /Zi flag to compiler flags (enable debug symbols) > > add /DEBUG flag to linker flags > > >> Please advise what is the best solution? > > From drsalists at gmail.com Sat Nov 14 19:03:08 2020 From: drsalists at gmail.com (Dan Stromberg) Date: Sat, 14 Nov 2020 16:03:08 -0800 Subject: Debugging native cython module with visual studio toolchain In-Reply-To: References: <20201114100932.28d796a1@arcor.com> Message-ID: I can happily say I haven't used a Microsoft compiler/linker in decades, but: 1) Maybe clang-cl will do what you want? 2) Maybe it'd be easier to put debugging print's/printf's/cout <<'s in your code? HTH On Sat, Nov 14, 2020 at 1:55 PM Jeff wrote: > > > > Hi, > > > > We developed a Python module that interfaces with native code via Cython. > > > > We currently build on Windows with Visual Studio Toolchain. > > > > We encounter the following issues when trying to build a debug version: > > > > 1) 3rd party modules installed via PIP are Release mode, but Visual > Studio > >> toolchain doesn't allow to mix Debug and Release libs. To workaround > this > >> issue, we build our module in "Release" mode, with debug symbols > enabled, > >> and with compiled optimization disabled (essentially a hack). > > > > 2) To build our module we currently use the following hack: > > > > step 1: run python.exe setup.py build --compiler=msvc > > > > step 2: extract the output > > > > step 3: change /Ox to /Od (disable compiler optimization) > > > > add /Zi flag to compiler flags (enable debug symbols) > > > > add /DEBUG flag to linker flags > > > > > >> Please advise what is the best solution? > > > > > -- > https://mail.python.org/mailman/listinfo/python-list > From info at wingware.com Mon Nov 16 09:49:25 2020 From: info at wingware.com (Wingware) Date: Mon, 16 Nov 2020 09:49:25 -0500 Subject: ANN: Wing Python IDE 7.2.7 has been released Message-ID: <5FB29175.1000808@wingware.com> Wing 7.2.7 improves running unit tests for Django and other testing frameworks, fixes Command-Alt-Click to add multiple selections on macOS, changes Goto Source in the Testing tool to display the innermost project file stack frame, and makes a number of other usability improvements. Details: https://wingware.com/news/2020-11-13 Downloads: https://wingware.com/downloads == About Wing == Wing is a light-weight but full-featured Python IDE designed specifically for Python, with powerful editing, code inspection, testing, and debugging capabilities. Wing's deep code analysis provides auto-completion, auto-editing, and refactoring that speed up development. Its top notch debugger works with any Python code, locally or on a remote host. Wing also supports test-driven development, version control, UI color and layout customization, and includes extensive documentation and support. Wing is available in three product levels: Wing Pro is the full-featured Python IDE for professional developers, Wing Personal is a free Python IDE for students and hobbyists (omits some features), and Wing 101 is a very simplified free Python IDE for beginners (omits many features). Learn more at https://wingware.com/ From loris.bennett at fu-berlin.de Tue Nov 17 04:01:30 2020 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Tue, 17 Nov 2020 10:01:30 +0100 Subject: Dispatch table of methods with various return value types Message-ID: <87lff0icgl.fsf@hornfels.zedat.fu-berlin.de> Hi, I have a method for manipulating the membership of groups such as: def execute(self, operation, users, group): """ Perform the given operation on the users with respect to the group """ action = { 'get': self.get, 'add': self.add, 'delete': self.delete, } return action.get(operation)(users, group) The 'get' action would return, say, a dict of users attribute, whereas the 'add/delete' actions would return, say, nothing, and all actions could raise an exception if something goes wrong. The method which calls 'execute' has to print something to the terminal, such as the attributes in the case of 'get' and 'OK' in the cases of 'add/delete' (assuming no exception occurred). Is there a canonical way of dealing with a method which returns different types of data, or should I just make all actions return the same data structure so that I can generate a generic response? Cheers, Loris -- This signature is currently under construction. From PythonList at DancesWithMice.info Tue Nov 17 04:56:34 2020 From: PythonList at DancesWithMice.info (dn) Date: Tue, 17 Nov 2020 22:56:34 +1300 Subject: Dispatch table of methods with various return value types In-Reply-To: <87lff0icgl.fsf@hornfels.zedat.fu-berlin.de> References: <87lff0icgl.fsf@hornfels.zedat.fu-berlin.de> Message-ID: On 17/11/2020 22:01, Loris Bennett wrote: > Hi, > > I have a method for manipulating the membership of groups such as: > > def execute(self, operation, users, group): > """ > Perform the given operation on the users with respect to the > group > """ > > action = { > 'get': self.get, > 'add': self.add, > 'delete': self.delete, > } > > return action.get(operation)(users, group) > > The 'get' action would return, say, a dict of users attribute, whereas > the 'add/delete' actions would return, say, nothing, and all actions > could raise an exception if something goes wrong. > > The method which calls 'execute' has to print something to the terminal, > such as the attributes in the case of 'get' and 'OK' in the cases of > 'add/delete' (assuming no exception occurred). > > Is there a canonical way of dealing with a method which returns different > types of data, or should I just make all actions return the same data > structure so that I can generate a generic response? Is the problem caused by coding the first step before thinking of the overall task? Try diagramming or pseudo-coding the complete solution (with multiple approaches), ie the operations AND the printing and exception-handling. Might it be more appropriate to complete not only the get but also its reporting, as a unit. Similarly the add and whatever happens after that; and the delete, likewise. Otherwise the code must first decide which action-handler, and later, which result-handler - but aren't they effectively the same decision? Thus, is the reporting integral to the get (even if they are in separate routines)? -- Regards =dn From loris.bennett at fu-berlin.de Tue Nov 17 05:35:45 2020 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Tue, 17 Nov 2020 11:35:45 +0100 Subject: Dispatch table of methods with various return value types References: <87lff0icgl.fsf@hornfels.zedat.fu-berlin.de> Message-ID: <87d00ci83i.fsf@hornfels.zedat.fu-berlin.de> dn writes: > On 17/11/2020 22:01, Loris Bennett wrote: >> Hi, >> >> I have a method for manipulating the membership of groups such as: >> >> def execute(self, operation, users, group): >> """ >> Perform the given operation on the users with respect to the >> group >> """ >> >> action = { >> 'get': self.get, >> 'add': self.add, >> 'delete': self.delete, >> } >> >> return action.get(operation)(users, group) >> >> The 'get' action would return, say, a dict of users attribute, whereas >> the 'add/delete' actions would return, say, nothing, and all actions >> could raise an exception if something goes wrong. >> >> The method which calls 'execute' has to print something to the terminal, >> such as the attributes in the case of 'get' and 'OK' in the cases of >> 'add/delete' (assuming no exception occurred). >> >> Is there a canonical way of dealing with a method which returns different >> types of data, or should I just make all actions return the same data >> structure so that I can generate a generic response? > > > Is the problem caused by coding the first step before thinking of the overall > task? Try diagramming or pseudo-coding the complete solution (with multiple > approaches), ie the operations AND the printing and exception-handling. You could have a point, although I do have a reasonable idea of what the task is and coming from a Perl background, Python always feels a bit like pseudocode anyway (which is one of the things I like about Python). > Might it be more appropriate to complete not only the get but also its > reporting, as a unit. Similarly the add and whatever happens after that; and the > delete, likewise. Currently I am already obtaining the result and doing the reporting in one method, but that makes it difficult to write tests, since it violates the idea that one method should, in general, just do one thing. That separation would seem appropriate here, since testing whether a data set is correctly retrieved from a database seems to be significantly different to testing whether the reporting of an action is correctly laid out and free of typos. > Otherwise the code must first decide which action-handler, and later, > which result-handler - but aren't they effectively the same decision? > Thus, is the reporting integral to the get (even if they are in > separate routines)? I think you are right here. Perhaps I should just ditch the dispatch table. Maybe that only really makes sense if the methods being dispatched are indeed more similar. Since I don't anticipate having more than half a dozen actions, if that, so an if-elif-else chain wouldn't be too clunky. Cheers, Loris -- This signature is currently under construction. From zanderkraig18 at gmail.com Tue Nov 17 13:39:32 2020 From: zanderkraig18 at gmail.com (Zander Kraig) Date: Tue, 17 Nov 2020 10:39:32 -0800 (PST) Subject: Unable to set up Python correctly In-Reply-To: References: Message-ID: According to my understanding, when the "Select Interpreter" option is used, only the current session is affected. It does not change the path of the default interpreter that VS Code tries to use. My suggestion would be to try to change the path specified in "Python: Default Interpreter Path" setting. From PythonList at DancesWithMice.info Tue Nov 17 15:17:28 2020 From: PythonList at DancesWithMice.info (dn) Date: Wed, 18 Nov 2020 09:17:28 +1300 Subject: Dispatch table of methods with various return value types In-Reply-To: <87d00ci83i.fsf@hornfels.zedat.fu-berlin.de> References: <87lff0icgl.fsf@hornfels.zedat.fu-berlin.de> <87d00ci83i.fsf@hornfels.zedat.fu-berlin.de> Message-ID: <5d0f0715-91db-8586-e77f-ca7158a504af@DancesWithMice.info> On 17/11/2020 23:35, Loris Bennett wrote: > dn writes: > >> On 17/11/2020 22:01, Loris Bennett wrote: >>> Hi, >>> >>> I have a method for manipulating the membership of groups such as: >>> >>> def execute(self, operation, users, group): >>> """ >>> Perform the given operation on the users with respect to the >>> group >>> """ >>> >>> action = { >>> 'get': self.get, >>> 'add': self.add, >>> 'delete': self.delete, >>> } >>> >>> return action.get(operation)(users, group) >>> >>> The 'get' action would return, say, a dict of users attribute, whereas >>> the 'add/delete' actions would return, say, nothing, and all actions >>> could raise an exception if something goes wrong. >>> >>> The method which calls 'execute' has to print something to the terminal, >>> such as the attributes in the case of 'get' and 'OK' in the cases of >>> 'add/delete' (assuming no exception occurred). >>> >>> Is there a canonical way of dealing with a method which returns different >>> types of data, or should I just make all actions return the same data >>> structure so that I can generate a generic response? >> >> >> Is the problem caused by coding the first step before thinking of the overall >> task? Try diagramming or pseudo-coding the complete solution (with multiple >> approaches), ie the operations AND the printing and exception-handling. > > You could have a point, although I do have a reasonable idea of what the > task is and coming from a Perl background, Python always feels a bit > like pseudocode anyway (which is one of the things I like about Python). +1 the ease of Python, but can this be seductive? Per the comment about Perl/Python experience, the operative part is the "thinking", not the tool - as revealed in responses below... Sometimes we design one 'solution' to a problem, and forget (or 'brainwash' ourselves into thinking) that there might be 'another way'. It may/not apply in this case, but adjusting from a diagram-first methodology, to the habit of 'jumping straight into code' exhibited by many colleagues, before readjusting back to (hopefully) a better balance; I felt that coding-first often caused me to 'paint myself into a corner' with some 'solutions, by being too-close to the code and not 'stepping back' to take a wider view of the design - but enough about me... >> Might it be more appropriate to complete not only the get but also its >> reporting, as a unit. Similarly the add and whatever happens after that; and the >> delete, likewise. > > Currently I am already obtaining the result and doing the reporting in > one method, but that makes it difficult to write tests, since it > violates the idea that one method should, in general, just do one thing. > That separation would seem appropriate here, since testing whether a > data set is correctly retrieved from a database seems to be > significantly different to testing whether the > reporting of an action is correctly laid out and free of typos. SRP = design thinking! +1 TDD = early testing! +1 Agreed: The tasks are definitely separate. The first is data-related. The second is about presentation. In keeping with the SRP philosophy, keep the split of execution-flow into the three (or more) functional-tasks by data-process, but turn each of those tasks into two steps/routines. (once the reporting routine following "add" has been coded, and it comes time to implement "delete", it may become possible to repeat the pattern, and thus 're-use' the second-half...) Putting it more formally: as the second-half is effectively 'chosen' at the same time as the first, is the reporting-routine "dependent" upon the data-processor? function get( self, ... ) self.get_data() self.present_data() function add( self, ... ) self.add_data() self.report_success_fail() ... Thus, the functional task can be tested independently of any reporting follow-up (for example in "get"); whilst maintaining/multiplying SRP... >> Otherwise the code must first decide which action-handler, and later, >> which result-handler - but aren't they effectively the same decision? >> Thus, is the reporting integral to the get (even if they are in >> separate routines)? > > I think you are right here. Perhaps I should just ditch the dispatch > table. Maybe that only really makes sense if the methods being > dispatched are indeed more similar. Since I don't anticipate having > more than half a dozen actions, if that, so an if-elif-else chain > wouldn't be too clunky. An if...elif...else 'ladder' is logically-easy to read, but with many choices it may become logistically-complicated - even too long to display at-once on a single screen. Whereas, the table is a more complex solution (see 'Zen of Python') that only becomes 'simple' with practice. So, now we must balance the 'level(s)' of the team likely to maintain the program(me) against the evaluation of simple~complex. Someone with a ComSc background will have no trouble coping with the table - and once Python's concepts of dictionaries and functions as 'first-class objects' are understood, will take to it like the proverbial "duck to water". Whereas, someone else may end-up scratching his/her head trying to cope with 'all the above'. Given that Python does not (yet) have a switch/case construct, does the table idea assume a greater importance? Could it be (reasonably) expected that pythonista will understand such more readily? IMHO the table is easier to maintain - particularly 'six months later', but likely 'appears' as a 'natural effect' of re-factoring*, once I've implemented the beginnings of an if-ladder and 'found' some of those common follow-up functions. * although, like you, I may well 'see' it at the design-stage, particularly if there are a number (more) cases to implement! Is functional "similar"[ity] (as above) the most-appropriate metric? What about the number of decision-points in the code? (ie please re-consider "effectively the same decision") # which data-function to execute? if action==get do get_data elif action == add do add_data elif ... ... # now 'the work' has been done, what is the follow-through? if action=get do present_data elif action == add report success/fail ... Back to the comment about maintainability - is there a risk that an extension requested in six months' time will tempt the coding of a new "do" function AND induce failure to notice that there must be a corresponding additional function in the second 'ladder'? This becomes worse if we re-factor to re-use/share some of the follow-throughs, eg ... elif action in [ add, delete, update] report success/fail ... because, at first glance, the second 'ladder' appears to be quite dissimilar - is a different length, doesn't have the condition-clause symmetry of the first, etc! So, our fictional maintainer can ignore the second, correct??? Consider SRP again, and add DRY: should the "despatch" decision be made once, or twice, or... ? -- Regards =dn From mal at europython.eu Wed Nov 18 05:56:55 2020 From: mal at europython.eu (M.-A. Lemburg) Date: Wed, 18 Nov 2020 11:56:55 +0100 Subject: EuroPython "Ask me Anything" - Nov Edition Message-ID: Dear Community, after our first successful ?Ask me Anything? (AMA) session in September https://blog.europython.eu/post/629951901661790208/europython-ask-me-anything we want to run another meeting this Thursday to answer any questions you may have, share our knowledge or help you in planning your online event. Some of the topics we can cover: - our tools research and findings - our concepts for running an online conference or event - our experience with running EuroPython online - what we could do to support you - how our Zoom license sharing works - how you can apply for a grant - how the EuroPython Society works - how we run the EuroPython organization with fully remote work groups and, of course, anything else :-) Join us on Thursday ------------------- If you?re interested in joining the call, please send your name and email to helpdesk at europython.eu and we?ll send you the invite for the call on Thursday, Nov 19, starting at 19:30 CET. When requesting the invite, please also consider adding more context, in case we?d have to prepare for the answers, so we can better prepare and make the meeting more effective. Please note that we will be recording the meeting and put it up on our YouTube account after the call, just like we did last time. BTW: We are making our conference resources available on our website, in case you have missed our blog post earlier this year. Many thanks. 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/634934022827622400/europython-ask-me-anything-november-edition Tweet: https://twitter.com/europython/status/1328274983743877121 Thanks, -- EuroPython 2020 Team https://ep2020.europython.eu/ https://www.europython-society.org/ From loris.bennett at fu-berlin.de Wed Nov 18 08:13:01 2020 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Wed, 18 Nov 2020 14:13:01 +0100 Subject: Dispatch table of methods with various return value types References: <87lff0icgl.fsf@hornfels.zedat.fu-berlin.de> <87d00ci83i.fsf@hornfels.zedat.fu-berlin.de> <5d0f0715-91db-8586-e77f-ca7158a504af@DancesWithMice.info> Message-ID: <878sayu7tu.fsf@hornfels.zedat.fu-berlin.de> dn writes: Firsty, thanks for taking the time to write such a detailed reply. > On 17/11/2020 23:35, Loris Bennett wrote: >> dn writes: >> >>> On 17/11/2020 22:01, Loris Bennett wrote: >>>> Hi, >>>> >>>> I have a method for manipulating the membership of groups such as: >>>> >>>> def execute(self, operation, users, group): >>>> """ >>>> Perform the given operation on the users with respect to the >>>> group >>>> """ >>>> >>>> action = { >>>> 'get': self.get, >>>> 'add': self.add, >>>> 'delete': self.delete, >>>> } >>>> >>>> return action.get(operation)(users, group) >>>> >>>> The 'get' action would return, say, a dict of users attribute, whereas >>>> the 'add/delete' actions would return, say, nothing, and all actions >>>> could raise an exception if something goes wrong. >>>> >>>> The method which calls 'execute' has to print something to the terminal, >>>> such as the attributes in the case of 'get' and 'OK' in the cases of >>>> 'add/delete' (assuming no exception occurred). >>>> >>>> Is there a canonical way of dealing with a method which returns different >>>> types of data, or should I just make all actions return the same data >>>> structure so that I can generate a generic response? >>> >>> >>> Is the problem caused by coding the first step before thinking of the overall >>> task? Try diagramming or pseudo-coding the complete solution (with multiple >>> approaches), ie the operations AND the printing and exception-handling. >> >> You could have a point, although I do have a reasonable idea of what the >> task is and coming from a Perl background, Python always feels a bit >> like pseudocode anyway (which is one of the things I like about Python). > > +1 the ease of Python, but can this be seductive? > > Per the comment about Perl/Python experience, the operative part is the > "thinking", not the tool - as revealed in responses below... > > Sometimes we design one 'solution' to a problem, and forget (or 'brainwash' > ourselves into thinking) that there might be 'another way'. > > It may/not apply in this case, but adjusting from a diagram-first methodology, > to the habit of 'jumping straight into code' exhibited by many colleagues, > before readjusting back to (hopefully) a better balance; I felt that > coding-first often caused me to 'paint myself into a corner' with some > 'solutions, by being too-close to the code and not 'stepping back' to take a > wider view of the design - but enough about me... > > >>> Might it be more appropriate to complete not only the get but also its >>> reporting, as a unit. Similarly the add and whatever happens after that; and the >>> delete, likewise. >> >> Currently I am already obtaining the result and doing the reporting in >> one method, but that makes it difficult to write tests, since it >> violates the idea that one method should, in general, just do one thing. >> That separation would seem appropriate here, since testing whether a >> data set is correctly retrieved from a database seems to be >> significantly different to testing whether the >> reporting of an action is correctly laid out and free of typos. > > SRP = design thinking! +1 I knew the idea, but I didn't now the TLA for it ;-) > TDD = early testing! +1 > > Agreed: The tasks are definitely separate. The first is data-related. The second > is about presentation. > > In keeping with the SRP philosophy, keep the split of execution-flow into the > three (or more) functional-tasks by data-process, but turn each of those tasks > into two steps/routines. (once the reporting routine following "add" has been > coded, and it comes time to implement "delete", it may become possible to repeat > the pattern, and thus 're-use' the second-half...) > > Putting it more formally: as the second-half is effectively 'chosen' at the same > time as the first, is the reporting-routine "dependent" upon the data-processor? > > function get( self, ... ) > self.get_data() > self.present_data() > > function add( self, ... ) > self.add_data() > self.report_success_fail() > > ... > > Thus, the functional task can be tested independently of any reporting follow-up > (for example in "get"); whilst maintaining/multiplying SRP... The above approach appeals to me a lot. Slight downsides are that such 'metafunctions' by necessity non-SRP functions and that, as there would be no point writing tests for such functions, some tools which try to determine test coverage might moan. >>> Otherwise the code must first decide which action-handler, and later, >>> which result-handler - but aren't they effectively the same decision? >>> Thus, is the reporting integral to the get (even if they are in >>> separate routines)? >> >> I think you are right here. Perhaps I should just ditch the dispatch >> table. Maybe that only really makes sense if the methods being >> dispatched are indeed more similar. Since I don't anticipate having >> more than half a dozen actions, if that, so an if-elif-else chain >> wouldn't be too clunky. > > An if...elif...else 'ladder' is logically-easy to read, but with many choices it > may become logistically-complicated - even too long to display at-once on a > single screen. > > Whereas, the table is a more complex solution (see 'Zen of Python') that only > becomes 'simple' with practice. > > So, now we must balance the 'level(s)' of the team likely to maintain the > program(me) against the evaluation of simple~complex. Someone with a ComSc > background will have no trouble coping with the table - and once Python's > concepts of dictionaries and functions as 'first-class objects' are understood, > will take to it like the proverbial "duck to water". Whereas, someone else may > end-up scratching his/her head trying to cope with 'all the above'. The team? L'?quipe, c'est moi :-) Having said that I do try to program not only with my fictitious replacement in mind, should I be hit by the proverbial bus, but also my future self, and so tend to err on the side of 'simple'. > Given that Python does not (yet) have a switch/case construct, does the table > idea assume a greater importance? Could it be (reasonably) expected that > pythonista will understand such more readily? > > > IMHO the table is easier to maintain - particularly 'six months later', but > likely 'appears' as a 'natural effect' of re-factoring*, once I've implemented > the beginnings of an if-ladder and 'found' some of those common follow-up > functions. > * although, like you, I may well 'see' it at the design-stage, particularly if > there are a number (more) cases to implement! > > Is functional "similar"[ity] (as above) the most-appropriate metric? What about > the number of decision-points in the code? (ie please re-consider "effectively > the same decision") > > # which data-function to execute? > if action==get > do get_data > elif action == add > do add_data > elif ... > > ... > > # now 'the work' has been done, what is the follow-through? > if action=get > do present_data > elif action == add > report success/fail > ... In my current case this is there is a one-to-one relationship between the 'work' and the 'follow-through', so this approach doesn't seem that appealing to me. However I have other cases in which the data to be displayed comes from multiple sources where the structure above might be a good fit. Having said that, I do prefer the idea of having a single jumping off point, be it a dispatch table or a single if-then-else ladder, which reflects the actions which the user can take and where the unpleasant details of, say, how the data are gathered are deferred to a lower level of the code. > Back to the comment about maintainability - is there a risk that an extension > requested in six months' time will tempt the coding of a new "do" function AND > induce failure to notice that there must be a corresponding additional function > in the second 'ladder'? > > This becomes worse if we re-factor to re-use/share some of the follow-throughs, > eg > > ... > elif action in [ add, delete, update] > report success/fail > ... > > because, at first glance, the second 'ladder' appears to be quite dissimilar - > is a different length, doesn't have the condition-clause symmetry of the first, > etc! So, our fictional maintainer can ignore the second, correct??? > > Consider SRP again, and add DRY: should the "despatch" decision be made once, or > twice, or... ? With my non-fictional-maintainer-cum-six-month-older-self hat on I think you have made a good case for the dispatch table, which is my latent preference anyway, especially in connection with the 'do/display' metafunctions and the fact that in my current case DRY implies that the dispatch decision should only be made once. Thanks again for the input! Cheers, Loris -- This signature is currently under construction. From othmanmusa081 at gmail.com Thu Nov 19 07:19:07 2020 From: othmanmusa081 at gmail.com (Usman Musa) Date: Thu, 19 Nov 2020 13:19:07 +0100 Subject: EnvironmentError Message-ID: When I try to install a package or upgrade pip, using pip install I got this error massage. WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate is not yet valid (_ssl.c:1122)'))': /packages/97/f3/c064343ac58d1a54c393a3f66483a29500f644a5918deeb935d28673edd9/virtualenv-20.1.0-py2.py3-none-any.whl WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate is not yet valid (_ssl.c:1122)'))': /packages/97/f3/c064343ac58d1a54c393a3f66483a29500f644a5918deeb935d28673edd9/virtualenv-20.1.0-py2.py3-none-any.whl WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate is not yet valid (_ssl.c:1122)'))': /packages/97/f3/c064343ac58d1a54c393a3f66483a29500f644a5918deeb935d28673edd9/virtualenv-20.1.0-py2.py3-none-any.whl WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate is not yet valid (_ssl.c:1122)'))': /packages/97/f3/c064343ac58d1a54c393a3f66483a29500f644a5918deeb935d28673edd9/virtualenv-20.1.0-py2.py3-none-any.whl WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate is not yet valid (_ssl.c:1122)'))': /packages/97/f3/c064343ac58d1a54c393a3f66483a29500f644a5918deeb935d28673edd9/virtualenv-20.1.0-py2.py3-none-any.whl ERROR: Could not install packages due to an EnvironmentError: HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Max retries exceeded with url: /packages/97/f3/c064343ac58d1a54c393a3f66483a29500f644a5918deeb935d28673edd9/virtualenv-20.1.0-py2.py3-none-any.whl (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate is not yet valid (_ssl.c:1122)'))) Please help me out From bhushan.shelke at thermofisher.com Thu Nov 19 10:12:39 2020 From: bhushan.shelke at thermofisher.com (Shelke, Bhushan) Date: Thu, 19 Nov 2020 15:12:39 +0000 Subject: Python Client Rest API Invocation - POST with empty body - Invalid character found in method name [{}POST]. HTTP method names must be tokens Message-ID: I have a Tomcat+Java based server exposing REST APIs. I am writing a client in python to consume those APIs. Everything is fine until I send empty body in POST request. It is a valid use case for us. If I send empty body I get 400 bad request error - Invalid character found in method name [{}POST]. HTTP method names must be tokens. If I send empty request from POSTMAN or Java or CURL it works fine, problem is only when I used python as a client. Following is python snippet - json_object={} header = {'alias': 'A', 'Content-Type' : 'application/json', 'Content-Length' : '0'} resp = requests.post(url, auth=(username, password), headers=header, json=json_object) I tried using data as well instead of json param to send payload with not much of success. I captured the wireshark dumps to understand it further and found that the request tomcat received is not as per RFC2616 (https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html). Especially the part - Request-Line = Method SP Request-URI SP HTTP-Version CRLF I could see in from wireshark dumps it looked like - {}POST HTTP/1.1 As we can see the empty body is getting prefixed with http-method, hence tomcat reports that as an error. I then looked at python http library code - client.py. Following are relevant details - File - client.py Method - _send_output (starting at line # 1001) - It first sends the header at line #1010 and then the body somewhere down in the code. My hunch is that (I could be wrong here) perhaps in this case header is way longer 310 bytes than body 2 bytes, so by the time complete header is sent on wire body is already pushed and hence TCP frames are order in such a way that body appears first. To corroborate this I added a delay of 1 second just after sending header line#1011 and bingo, the error disappeared and it started working fine. Not sure if this is completely correct analysis, but can someone in the know can confirm or let me know how to fix this. Env Details - Client and Server on local machine as of now. * Client * Python Version - 3.9, Python Requests module version - 2.25 * Server * Java 13, Tomcat 9. P.S. - Please see attached screenshots of wireshark dump with relevant part highlighted. Regards, Bhushan From PythonList at DancesWithMice.info Fri Nov 20 00:08:28 2020 From: PythonList at DancesWithMice.info (dn) Date: Fri, 20 Nov 2020 18:08:28 +1300 Subject: Dispatch table of methods with various return value types In-Reply-To: <878sayu7tu.fsf@hornfels.zedat.fu-berlin.de> References: <87lff0icgl.fsf@hornfels.zedat.fu-berlin.de> <87d00ci83i.fsf@hornfels.zedat.fu-berlin.de> <5d0f0715-91db-8586-e77f-ca7158a504af@DancesWithMice.info> <878sayu7tu.fsf@hornfels.zedat.fu-berlin.de> Message-ID: <0ffe7b55-36aa-718c-8cfe-11fe36c16ee1@DancesWithMice.info> On 19/11/2020 02:13, Loris Bennett wrote: > dn writes: > > Firsty, thanks for taking the time to write such a detailed reply. Bitte! >>>>> I have a method for manipulating the membership of groups such as: >>>>> >>>>> def execute(self, operation, users, group): >>>>> """ >>>>> Perform the given operation on the users with respect to the >>>>> group >>>>> """ >>>>> >>>>> action = { >>>>> 'get': self.get, >>>>> 'add': self.add, >>>>> 'delete': self.delete, >>>>> } >>>>> >>>>> return action.get(operation)(users, group) >>>>> >>>>> The 'get' action would return, say, a dict of users attribute, whereas >>>>> the 'add/delete' actions would return, say, nothing, and all actions >>>>> could raise an exception if something goes wrong. >>>>> >>>>> The method which calls 'execute' has to print something to the terminal, >>>>> such as the attributes in the case of 'get' and 'OK' in the cases of >>>>> 'add/delete' (assuming no exception occurred). >>>>> >>>>> Is there a canonical way of dealing with a method which returns different >>>>> types of data, or should I just make all actions return the same data >>>>> structure so that I can generate a generic response? >>>> >>>> >>>> Is the problem caused by coding the first step before thinking of the overall >>>> task? Try diagramming or pseudo-coding the complete solution (with multiple >>>> approaches), ie the operations AND the printing and exception-handling. >>> >>> You could have a point, although I do have a reasonable idea of what the >>> task is and coming from a Perl background, Python always feels a bit >>> like pseudocode anyway (which is one of the things I like about Python). >> >> +1 the ease of Python, but can this be seductive? >> >> Per the comment about Perl/Python experience, the operative part is the >> "thinking", not the tool - as revealed in responses below... >> >> Sometimes we design one 'solution' to a problem, and forget (or 'brainwash' >> ourselves into thinking) that there might be 'another way'. >> >> It may/not apply in this case, but adjusting from a diagram-first methodology, >> to the habit of 'jumping straight into code' exhibited by many colleagues, >> before readjusting back to (hopefully) a better balance; I felt that >> coding-first often caused me to 'paint myself into a corner' with some >> 'solutions, by being too-close to the code and not 'stepping back' to take a >> wider view of the design - but enough about me... >> >> >>>> Might it be more appropriate to complete not only the get but also its >>>> reporting, as a unit. Similarly the add and whatever happens after that; and the >>>> delete, likewise. >>> >>> Currently I am already obtaining the result and doing the reporting in >>> one method, but that makes it difficult to write tests, since it >>> violates the idea that one method should, in general, just do one thing. >>> That separation would seem appropriate here, since testing whether a >>> data set is correctly retrieved from a database seems to be >>> significantly different to testing whether the >>> reporting of an action is correctly laid out and free of typos. >> >> SRP = design thinking! +1 > > I knew the idea, but I didn't now the TLA for it ;-) Yes, there are plenty of those! You may be interested in reading about "Clean Code", instigated (IIRC) by "Uncle Bob" (Robert Martin). NB Python may/not be used for book-examples. Just the other day I came across "Clean Code in Python", Mariano Anaya, PacktPub, 2018. I have yet to read it, but the contents page seemed to 'tick all the boxes'. The book is two years old, and IIRC he presented at EuroPython a few years before that (YouTube videos on-line - in case you prefer that medium, or want to gain a flavor before spending money...). All of these TLAs, and others comprising the "SOLID Principles" appear in the ToC, along with plenty of others, eg YAGNI and EAFP; plus some specific to Python, eg MRO. >> TDD = early testing! +1 >> >> Agreed: The tasks are definitely separate. The first is data-related. The second >> is about presentation. >> >> In keeping with the SRP philosophy, keep the split of execution-flow into the >> three (or more) functional-tasks by data-process, but turn each of those tasks >> into two steps/routines. (once the reporting routine following "add" has been >> coded, and it comes time to implement "delete", it may become possible to repeat >> the pattern, and thus 're-use' the second-half...) >> >> Putting it more formally: as the second-half is effectively 'chosen' at the same >> time as the first, is the reporting-routine "dependent" upon the data-processor? >> >> function get( self, ... ) >> self.get_data() >> self.present_data() >> >> function add( self, ... ) >> self.add_data() >> self.report_success_fail() >> >> ... >> >> Thus, the functional task can be tested independently of any reporting follow-up >> (for example in "get"); whilst maintaining/multiplying SRP... > > The above approach appeals to me a lot. Slight downsides are that > such 'metafunctions' by necessity non-SRP functions and that, as there > would be no point writing tests for such functions, some tools which try > to determine test coverage might moan. First comes (Python) 'duty': the word "meta", perhaps more in the context of "meta-classes" has particular meaning in Python, that may not align with expectations generated by understanding the term "meta" in other contexts! Second, we return to earlier comments about up-front design. Consider "Stepwise Decomposition" (https://en.wikipedia.org/wiki/Top-down_and_bottom-up_design) and how solving a 'large problem' is likened to pealing an onion, ie one 'layer' at a time. Thus there is a sub-problem, eg report on xyz; this divides into smaller problems: (i) from where do I find the data on xyz, and (ii) how do I present this. If you code top-down, then it may be that there are three subroutines (functions in Python) which implement the three of these. Further, that only the two "smaller" routines appear to be doing any 'work'. However, remember that the function names both document the solution and reproduce the specification. Thus three well-chosen names will add value and ease understanding for you/us, six months later... If you code bottom-up and have TDD-built the two "smaller" functions, then adding the 'higher' function as an 'umbrella' will tie them together - for the reasons/results mentioned above. There are different types of testing. Unit testing is straightforward with pytest or similar. This takes care of tests such as 'did "get" realise the correct data?' and 'after "delete" does this data exist?'. These are likely tests of functions at the lowest and/or lower levels of the implementation - hence the name. When it comes to reporting, life becomes more complicated. Whereas pytest will capture and allow testing of sysout, when we move to Qt, gtk, or some other UI took-kit, we need to find a compatible testing tool. If presentation is HTML, then web-page testing is accomplished with the likes of Selenium. If we are talking UX (User Experience) testing, then the information-presented is almost-irrelevant. If you have a user on the dev.team (see also Agile teams), then (s)he will perform such 'testing' manually (and give rapid feedback). Thus, no tool required, as such. NB If you are concerned about the actual information being presented, surely that will have already been tested as accurate by the unit test mentioned earlier? Regarding the comment about "moan[ing]" tools. Who's in-charge here? When it is helping you it is a "tool". What is something that is getting in your way, causing you frustration, or otherwise interfering with your happiness and productivity? Pointy-headed managers [a reference to the Dilbert cartoons] have often tried to create/impose 'rules' on developers. One of my favorites is: "there will be at least one comment for every ten lines of code". Do you need to strain-the-brain to know what happens? # this code has a comment ... # add one to x x += 1 I'm afraid the idea of 100% code-coverage is a nirvana that is probably not worth seeking. See also @Ned's comments (about his own coverage.py tool) https://nedbatchelder.com/blog/200710/flaws_in_coverage_measurement.html The car's speedo might tell you that it can motor-along at some incredible speed, but using the information sensibly might attract less attention from the Highway Patrol! >>>> Otherwise the code must first decide which action-handler, and later, >>>> which result-handler - but aren't they effectively the same decision? >>>> Thus, is the reporting integral to the get (even if they are in >>>> separate routines)? >>> >>> I think you are right here. Perhaps I should just ditch the dispatch >>> table. Maybe that only really makes sense if the methods being >>> dispatched are indeed more similar. Since I don't anticipate having >>> more than half a dozen actions, if that, so an if-elif-else chain >>> wouldn't be too clunky. >> >> An if...elif...else 'ladder' is logically-easy to read, but with many choices it >> may become logistically-complicated - even too long to display at-once on a >> single screen. >> >> Whereas, the table is a more complex solution (see 'Zen of Python') that only >> becomes 'simple' with practice. >> >> So, now we must balance the 'level(s)' of the team likely to maintain the >> program(me) against the evaluation of simple~complex. Someone with a ComSc >> background will have no trouble coping with the table - and once Python's >> concepts of dictionaries and functions as 'first-class objects' are understood, >> will take to it like the proverbial "duck to water". Whereas, someone else may >> end-up scratching his/her head trying to cope with 'all the above'. > > The team? L'?quipe, c'est moi :-) Having said that I do try to program > not only with my fictitious replacement in mind, should I be hit by the > proverbial bus, but also my future self, and so tend to err on the side > of 'simple'. +1 "simple" +1 "ego-less programming" German, English, and now French? >> Given that Python does not (yet) have a switch/case construct, does the table >> idea assume a greater importance? Could it be (reasonably) expected that >> pythonista will understand such more readily? >> >> >> IMHO the table is easier to maintain - particularly 'six months later', but >> likely 'appears' as a 'natural effect' of re-factoring*, once I've implemented >> the beginnings of an if-ladder and 'found' some of those common follow-up >> functions. >> * although, like you, I may well 'see' it at the design-stage, particularly if >> there are a number (more) cases to implement! >> >> Is functional "similar"[ity] (as above) the most-appropriate metric? What about >> the number of decision-points in the code? (ie please re-consider "effectively >> the same decision") >> >> # which data-function to execute? >> if action==get >> do get_data >> elif action == add >> do add_data >> elif ... >> >> ... >> >> # now 'the work' has been done, what is the follow-through? >> if action=get >> do present_data >> elif action == add >> report success/fail >> ... > > In my current case this is there is a one-to-one relationship between > the 'work' and the 'follow-through', so this approach doesn't seem that > appealing to me. However I have other cases in which the data to be > displayed comes from multiple sources where the structure above might > be a good fit. I hope to have addressed this above. To help (I hope), consider if, in the proverbial six-months time, you are asked to add logging to each of these various actions. Now, there are three tasks: 'work', 'follow-through', and 'logging'; to be done for each of the n-action choices. Would an 'umbrella function' which acts as both the single destination for an action-choice, and as a 'distributor' for the various specific tasks that must be executed, start to appear more viable? > Having said that, I do prefer the idea of having a single jumping off > point, be it a dispatch table or a single if-then-else ladder, which > reflects the actions which the user can take and where the unpleasant > details of, say, how the data are gathered are deferred to a lower level > of the code. +1 >> Back to the comment about maintainability - is there a risk that an extension >> requested in six months' time will tempt the coding of a new "do" function AND >> induce failure to notice that there must be a corresponding additional function >> in the second 'ladder'? >> >> This becomes worse if we re-factor to re-use/share some of the follow-throughs, >> eg >> >> ... >> elif action in [ add, delete, update] >> report success/fail >> ... >> >> because, at first glance, the second 'ladder' appears to be quite dissimilar - >> is a different length, doesn't have the condition-clause symmetry of the first, >> etc! So, our fictional maintainer can ignore the second, correct??? >> >> Consider SRP again, and add DRY: should the "despatch" decision be made once, or >> twice, or... ? > > With my non-fictional-maintainer-cum-six-month-older-self hat on I think > you have made a good case for the dispatch table, which is my latent > preference anyway, especially in connection with the 'do/display' > metafunctions and the fact that in my current case DRY implies that the > dispatch decision should only be made once. +1 Definitely! See also @Wulfraed's point about OOP (Object-Oriented Programming)! If we were talking about people, then I'd expect to find a class Person, or similar, in the code. That means that "get" and "delete" might refer to database transactions. Hence, they should be part of the Person class, rather than functions 'in the wild'. Thus, where we have used the term "function" (or even "subroutine"), we should have said "method". A class is a (very good) way to 'collect' related functionality and keep it 'together'! Another aspect, following-on from UI comments (above). If you are using a framework, the presentation code will largely fit within those objects. Therefore, logically-separate from manipulating the source-object. Another consideration (maybe) for how to structure and relate the routines... As a general rule, I keep print() out of functions which 'calculate' - even, out of the Person class. This facilitates re-use, where the next use may want to present the results differently, or merely to use the calculation as 'input' and not present 'it' at all! > Thanks again for the input! It is good that you are reviewing your code and considering alternate approaches! Many others 'here' will have benefited from considering your points/questions... You may like to pass some information about the Free University: - is Python the primary teaching language - is Python widely used within various schools/departments - is instruction in English, or... - what does "Free" mean - is it also $free - is it open to (non-German) foreigners Tsch?ss! -- Regards =dn From rambiusparkisanius at gmail.com Fri Nov 20 10:24:23 2020 From: rambiusparkisanius at gmail.com (Ivan "Rambius" Ivanov) Date: Fri, 20 Nov 2020 10:24:23 -0500 Subject: EnvironmentError In-Reply-To: References: Message-ID: Hello, On Thu, Nov 19, 2020 at 1:56 PM Usman Musa wrote: > > When I try to install a package or upgrade pip, using pip install I got > this error massage. > WARNING: Retrying (Retry(total=4, connect=None, read=None, > redirect=None, status=None)) after connection broken by > 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] > certificate verify failed: certificate is not yet valid (_ssl.c:1122)'))': > /packages/97/f3/c064343ac58d1a54c393a3f66483a29500f644a5918deeb935d28673edd9/virtualenv-20.1.0-py2.py3-none-any.whl > WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, > status=None)) after connection broken by > 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] > certificate verify failed: certificate is not yet valid (_ssl.c:1122)'))': > /packages/97/f3/c064343ac58d1a54c393a3f66483a29500f644a5918deeb935d28673edd9/virtualenv-20.1.0-py2.py3-none-any.whl > WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, > status=None)) after connection broken by > 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] > certificate verify failed: certificate is not yet valid (_ssl.c:1122)'))': > /packages/97/f3/c064343ac58d1a54c393a3f66483a29500f644a5918deeb935d28673edd9/virtualenv-20.1.0-py2.py3-none-any.whl > WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, > status=None)) after connection broken by > 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] > certificate verify failed: certificate is not yet valid (_ssl.c:1122)'))': > /packages/97/f3/c064343ac58d1a54c393a3f66483a29500f644a5918deeb935d28673edd9/virtualenv-20.1.0-py2.py3-none-any.whl > WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, > status=None)) after connection broken by > 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] > certificate verify failed: certificate is not yet valid (_ssl.c:1122)'))': > /packages/97/f3/c064343ac58d1a54c393a3f66483a29500f644a5918deeb935d28673edd9/virtualenv-20.1.0-py2.py3-none-any.whl > ERROR: Could not install packages due to an EnvironmentError: > HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Max retries > exceeded with url: > /packages/97/f3/c064343ac58d1a54c393a3f66483a29500f644a5918deeb935d28673edd9/virtualenv-20.1.0-py2.py3-none-any.whl > (Caused by SSLError(SSLCertVerificationError(1, '[SSL: > CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate is not > yet valid (_ssl.c:1122)'))) > Please help me out > -- > https://mail.python.org/mailman/listinfo/python-list The error says that the certificate of files.pythonhosted.org is not valid, but this is definitely not the case. I think you sit behind some ssl proxy and it behaves as a man-in-the-middle and replaces the certificate with its own (I was experiencing that in a previous job). You have several choices: 1) pass --trusted-host files.pythonhosted.org to disable the certificate check 2) import the ssl certificate of the ssl proxy (if you have such) into python's certificate store 3) speak with the local system administrators about that. They may be of help. Regards rambius -- Tangra Mega Rock: http://www.radiotangra.com From pkpearson at nowhere.invalid Fri Nov 20 10:25:38 2020 From: pkpearson at nowhere.invalid (Peter Pearson) Date: 20 Nov 2020 15:25:38 GMT Subject: EnvironmentError References: Message-ID: On Thu, 19 Nov 2020 13:19:07 +0100, Usman Musa wrote: > When I try to install a package or upgrade pip, using pip install I got > this error massage. > WARNING: Retrying (Retry(total=4, connect=None, read=None, > redirect=None, status=None)) after connection broken by > 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] > certificate verify failed: certificate is not yet valid (_ssl.c:1122)'))': [snip] > Please help me out Just guessing, here. Might "not yet valid" mean that your computer's clock is set to 1970? Is there any indication *whose* certificate is "not yet valid"? E.g., some URL from which pip is trying to load things? -- To email me, substitute nowhere->runbox, invalid->com. From dieter at handshake.de Fri Nov 20 13:52:49 2020 From: dieter at handshake.de (Dieter Maurer) Date: Fri, 20 Nov 2020 19:52:49 +0100 Subject: Python Client Rest API Invocation - POST with empty body - Invalid character found in method name [{}POST]. HTTP method names must be tokens In-Reply-To: References: Message-ID: <24504.4225.165066.782984@ixdm.fritz.box> Shelke, Bhushan wrote at 2020-11-19 15:12 +0000: >I have a Tomcat+Java based server exposing REST APIs. I am writing a client in python to consume those APIs. Everything is fine until I send empty body in POST request. It is a valid use case for us. If I send empty body I get 400 bad request error - Invalid character found in method name [{}POST]. HTTP method names must be tokens. `[{}POST]` would definitely be a wrong method. I would use the Python debugger (--> module `pdb`) to find out where it comes from. From jcasale at activenetwerx.com Fri Nov 20 16:47:32 2020 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Fri, 20 Nov 2020 21:47:32 +0000 Subject: Python Client Rest API Invocation - POST with empty body - Invalid character found in method name [{}POST]. HTTP method names must be tokens In-Reply-To: References: Message-ID: <5f90db8230a3419daba82dee635eb40e@activenetwerx.com> > Invalid character found in method name [{}POST]. HTTP method names must be tokens. /snip > I could see in from wireshark dumps it looked like - {}POST HTTP/1.1 The error message and your own debugging indicate the error. Your method *name* is {}POST, you have somehow included two brackets in the name of the method. jlc From hjp-python at hjp.at Sat Nov 21 07:01:10 2020 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sat, 21 Nov 2020 13:01:10 +0100 Subject: Python Client Rest API Invocation - POST with empty body - Invalid character found in method name [{}POST]. HTTP method names must be tokens In-Reply-To: References: Message-ID: <20201121120110.GA21493@hjp.at> On 2020-11-19 15:12:39 +0000, Shelke, Bhushan wrote: > I have a Tomcat+Java based server exposing REST APIs. I am writing a > client in python to consume those APIs. Everything is fine until I > send empty body in POST request. It is a valid use case for us. If I > send empty body I get 400 bad request error - Invalid character found > in method name [{}POST]. HTTP method names must be tokens. > > If I send empty request from POSTMAN or Java or CURL it works fine, > problem is only when I used python as a client. > > Following is python snippet - > > json_object={} > > header = {'alias': 'A', 'Content-Type' : 'application/json', 'Content-Length' : '0'} 'Content-Length' : '0' is wrong, but it seems that requests.post overrides that, so it doesn't matter. > resp = requests.post(url, auth=(username, password), headers=header, json=json_object) > > > > I tried using data as well instead of json param to send payload with > not much of success. > > I captured the wireshark dumps to understand it further and found that > the request tomcat received is not as per RFC2616 > (https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html). Especially > the part - > > Request-Line = Method SP Request-URI SP HTTP-Version CRLF > > I could see in from wireshark dumps it looked like - {}POST > HTTP/1.1 > > As we can see the empty body is getting prefixed with http-method, > hence tomcat reports that as an error. I then looked at python http > library code - client.py. I cannot reproduce this. Using Python 3.8.2 and requests 2.22.0 (as included in Ubuntu 20.04), the request sent is "POST /env HTTP/1.1", not "{}POST /env HTTP/1.1", In wireshark "Follow TCP connection", the "{}" at the end of the request is squished together with the "HTTP/1.1 302 Found" at the beginning of the response, but they are in different colors so that shouldn't be a problem unless you are visually impaired, and it doesn't match your description. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From Cecil at decebal.nl Sat Nov 21 09:36:01 2020 From: Cecil at decebal.nl (Cecil Westerhof) Date: Sat, 21 Nov 2020 15:36:01 +0100 Subject: Cannot update parso Message-ID: <87k0uedbfy.fsf@munus.decebal.nl> I cannot update parso because of the rule from jedi: <0.8.0,>=0.7.0 This kind of things happens more often, but normally in less of a week the module that prevents another to be installed is updated and the restriction is lifted. But I think it is about half a year that this restriction is active. Why is jedi not updated. (I cannot uninstall jedi, because it is used by ipython.) -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof From goluhng at gmail.com Sat Nov 21 14:30:55 2020 From: goluhng at gmail.com (Go Luhng) Date: Sat, 21 Nov 2020 14:30:55 -0500 Subject: Automatically advancing a bi-directional generator to the point of accepting a non-None value? Message-ID: Suppose we write a very simple bi-directional generator in Python: def share_of_total(): s = 0 new_num = 0 while True: new_num = yield new_num / (s or 1) s += new_num share_calculator = share_of_total() next(share_calculator) # Without this we get the TypeError for num in [1, 2, 3]: print(share_calculator.send(num)) This generator just accepts a number and yields a float representing its share of the sum of all previously provided numbers. We would ideally like to just use it immediately as follows: share_calculator = share_of_total() print(share_calculator.send(num)) However, this causes `TypeError: can't send non-None value to a just-started generator`. All users of the `share_of_total()` must remember to execute `next(share_calculator)` before the generator is usable as intended. Is there an elegant way to make `share_calculator` immediately usable - i.e. to be able to immediately call `share_calculator.send(num)` after creating `share_calculator`? I know it can be done with a fairly trivial wrapper, but I was hoping for a more elegant solution that doesn't require boilerplate. From p_d_a_s_i_l_v_a_ns at nonetnoaddress.pt Sat Nov 21 17:14:20 2020 From: p_d_a_s_i_l_v_a_ns at nonetnoaddress.pt (Paulo da Silva) Date: Sat, 21 Nov 2020 22:14:20 +0000 Subject: Problem exiting from a script using tkinter Message-ID: Hi! Why this does not work?! from tkinter import * def terminate(root): root.quit root=Tk() #b=Button(root,text="QUIT",command=root.quit) b=Button(root,text="QUIT",command=lambda: terminate(root)) b.pack() mainloop() Thanks From rosuav at gmail.com Sat Nov 21 17:18:01 2020 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 22 Nov 2020 09:18:01 +1100 Subject: Problem exiting from a script using tkinter In-Reply-To: References: Message-ID: On Sun, Nov 22, 2020 at 9:16 AM Paulo da Silva wrote: > > Hi! > > Why this does not work?! > > from tkinter import * > > def terminate(root): > root.quit > Is root.quit a function? Simply referencing a function's name does not call it (because functions are first-class objects - you can put a function in a variable or pass it as a parameter etc). In order to make it do its work, you have to call it. ChrisA From p_d_a_s_i_l_v_a_ns at nonetnoaddress.pt Sat Nov 21 17:31:11 2020 From: p_d_a_s_i_l_v_a_ns at nonetnoaddress.pt (Paulo da Silva) Date: Sat, 21 Nov 2020 22:31:11 +0000 Subject: Problem exiting from a script using tkinter References: Message-ID: ?s 22:18 de 21/11/20, Chris Angelico escreveu: > On Sun, Nov 22, 2020 at 9:16 AM Paulo da Silva > wrote: >> >> Hi! >> >> Why this does not work?! >> >> from tkinter import * >> >> def terminate(root): >> root.quit >> > > Is root.quit a function? Simply referencing a function's name does not > call it (because functions are first-class objects - you can put a > function in a variable or pass it as a parameter etc). In order to > make it do its work, you have to call it. > A newbie Error :-( Sorry. I am giving my first steps in tkinter and I thought it was another problem :-) I just copied the "root.quit" inside the function. Thanks Chris. From rosuav at gmail.com Sat Nov 21 17:44:21 2020 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 22 Nov 2020 09:44:21 +1100 Subject: Problem exiting from a script using tkinter In-Reply-To: References: Message-ID: On Sun, Nov 22, 2020 at 9:36 AM Paulo da Silva wrote: > > ?s 22:18 de 21/11/20, Chris Angelico escreveu: > > On Sun, Nov 22, 2020 at 9:16 AM Paulo da Silva > > wrote: > >> > >> Hi! > >> > >> Why this does not work?! > >> > >> from tkinter import * > >> > >> def terminate(root): > >> root.quit > >> > > > > Is root.quit a function? Simply referencing a function's name does not > > call it (because functions are first-class objects - you can put a > > function in a variable or pass it as a parameter etc). In order to > > make it do its work, you have to call it. > > > > A newbie Error :-( > Sorry. I am giving my first steps in tkinter and I thought it was > another problem :-) > I just copied the "root.quit" inside the function. > No need to feel bad about it :) Getting your head around "this is a function, that's where the function's being called" is not easy, and it takes experience. Your question was very well put. You provided a short, compact example that showcased the problem you were experiencing. That made it easy to answer your question. Keep on asking questions like that, please - you're helping yourself and making the mailing list a great place too :) ChrisA From dieter at handshake.de Sun Nov 22 13:22:23 2020 From: dieter at handshake.de (Dieter Maurer) Date: Sun, 22 Nov 2020 19:22:23 +0100 Subject: Automatically advancing a bi-directional generator to the point of accepting a non-None value? In-Reply-To: References: Message-ID: <24506.44127.226855.272841@ixdm.fritz.box> Go Luhng wrote at 2020-11-21 14:30 -0500: >Suppose we write a very simple bi-directional generator in Python: > > def share_of_total(): > s = 0 > new_num = 0 > while True: > new_num = yield new_num / (s or 1) > s += new_num > > share_calculator = share_of_total() > next(share_calculator) # Without this we get the TypeError > > for num in [1, 2, 3]: > print(share_calculator.send(num)) > >This generator just accepts a number and yields a float representing >its share of the sum of all previously provided numbers. > >We would ideally like to just use it immediately as follows: > > share_calculator = share_of_total() > print(share_calculator.send(num)) > >However, this causes `TypeError: can't send non-None value to a >just-started generator`. All users of the `share_of_total()` must >remember to execute `next(share_calculator)` before the generator is >usable as intended. When you want to automate things, you write a function. In your case, you have a generator function and you want that this generator function is called, then `next` is applied to the resulting generator; the resulting generator is what you actually want. >From this description, it should be easy to define a function which does precisely this for you. If you find that you regularly want to automate the initial `next`, you can implement your function as a so called "decorator", say `auto_next`. Then you can define generator functions with automatic `next` via: @auto_next def gen_fun(...): ... From sheetalchavanm at rediffmail.com Sun Nov 22 14:17:08 2020 From: sheetalchavanm at rediffmail.com (sheetal chavan) Date: 22 Nov 2020 19:17:08 -0000 Subject: =?utf-8?B?RXJyb3IgaXNzdWUgLSBLaW5kbHkgcmVzb2x2ZQ==?= Message-ID: <20201122191708.18514.qmail@f4mail-235-231.rediffmail.com> Dear Sir/Madam,I am trying to install python on my laptop with windows 7, 32 bit operating system with service pac 1 installed. I have installed python 3.7.1 and some more versions but while opening the command prompt always it is showing the message as :The above program can’t start because api-ms-win-crt-runtime-|1-1-0.dll is missing from  your computer. Try reinstalling the program to fix this problem.Kindly resolve this issue and suggest the solution.Thanks and regardsSheetal M Chavan   From ikorot01 at gmail.com Sun Nov 22 16:14:35 2020 From: ikorot01 at gmail.com (Igor Korot) Date: Sun, 22 Nov 2020 15:14:35 -0600 Subject: Error issue - Kindly resolve In-Reply-To: <20201122191708.18514.qmail@f4mail-235-231.rediffmail.com> References: <20201122191708.18514.qmail@f4mail-235-231.rediffmail.com> Message-ID: Hi, Sheetal, On Sun, Nov 22, 2020 at 2:44 PM sheetal chavan via Python-list wrote: > > Dear Sir/Madam,I am trying to install python on my laptop with windows 7, 32 bit operating system with service pac 1 installed. I have installed python 3.7.1 and some more versions but while opening the command prompt always it is showing the message as :The above program can’t start because api-ms-win-crt-runtime-|1-1-0.dll is missing from  your computer. Try reinstalling the program to fix this problem.Kindly resolve this issue and suggest the solution.Thanks and regardsSheetal M Chavan Unfortunately we can't resolve it for you as we don't have access to your machine. But in reality - you are missing the Windows Runtime DLL. Google that name given to you in the error, download it and instal it (preferably from the MS site). Then you should be good to go. Thank you. > >   > -- > https://mail.python.org/mailman/listinfo/python-list From python at mrabarnett.plus.com Sun Nov 22 16:16:01 2020 From: python at mrabarnett.plus.com (MRAB) Date: Sun, 22 Nov 2020 21:16:01 +0000 Subject: Error issue - Kindly resolve In-Reply-To: <20201122191708.18514.qmail@f4mail-235-231.rediffmail.com> References: <20201122191708.18514.qmail@f4mail-235-231.rediffmail.com> Message-ID: <198d917c-dde0-b8bc-158b-e836bf3e1093@mrabarnett.plus.com> On 2020-11-22 19:17, sheetal chavan via Python-list wrote: > Dear Sir/Madam,I am trying to install python on my laptop with windows 7, 32 bit operating system with service pac 1 installed. I have installed python 3.7.1 and some more versions but while opening the command prompt always it is showing the message as :The above program can’t start because api-ms-win-crt-runtime-|1-1-0.dll is missing from  your computer. Try reinstalling the program to fix this problem.Kindly resolve this issue and suggest the solution.Thanks and regardsSheetal M Chavan > 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 mchakrain at yahoo.com Mon Nov 23 09:10:18 2020 From: mchakrain at yahoo.com (Mayukh Chakraborty) Date: Mon, 23 Nov 2020 14:10:18 +0000 (UTC) Subject: Python Error References: <1183930009.832611.1606140618819.ref@mail.yahoo.com> Message-ID: <1183930009.832611.1606140618819@mail.yahoo.com> Hi, I had uninstalled and installed Python in Windows 10 but I am getting the error below. Can you please help ? C:\Users\mchak>pythonFatal Python error: init_sys_streams: can't initialize sys standard streamsPython runtime state: core initializedAttributeError: module 'io' has no attribute 'OpenWrapper' Current thread 0x00009d44 (most recent call first): Regards,Mayukh From barry at barrys-emacs.org Mon Nov 23 13:16:57 2020 From: barry at barrys-emacs.org (Barry Scott) Date: Mon, 23 Nov 2020 18:16:57 +0000 Subject: Python Error In-Reply-To: <1183930009.832611.1606140618819@mail.yahoo.com> References: <1183930009.832611.1606140618819.ref@mail.yahoo.com> <1183930009.832611.1606140618819@mail.yahoo.com> Message-ID: <92E83519-411E-4A80-BE80-6F9417805B61@barrys-emacs.org> > On 23 Nov 2020, at 14:10, Mayukh Chakraborty via Python-list wrote: > > Hi, > I had uninstalled and installed Python in Windows 10 but I am getting the error below. Can you please help ? > C:\Users\mchak>pythonFatal Python error: init_sys_streams: can't initialize sys standard streamsPython runtime state: core initializedAttributeError: module 'io' has no attribute 'OpenWrapper' > Current thread 0x00009d44 (most recent call first): > Regards,Mayukh Which version of python are you installing and where did you download it from? Do you have more than one version of python installed? Does the command: py work? If you have python from python.org installed you should be able to list all the version you have installed with the command: py -0 That is zero not oh. Barry > -- > https://mail.python.org/mailman/listinfo/python-list > From tjreedy at udel.edu Mon Nov 23 13:18:43 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Mon, 23 Nov 2020 13:18:43 -0500 Subject: Python Error In-Reply-To: <1183930009.832611.1606140618819@mail.yahoo.com> References: <1183930009.832611.1606140618819.ref@mail.yahoo.com> <1183930009.832611.1606140618819@mail.yahoo.com> Message-ID: On 11/23/2020 9:10 AM, Mayukh Chakraborty via Python-list wrote: > Hi, > I had uninstalled and installed Python in Windows 10 but I am getting the error below. Can you please help ? > C:\Users\mchak>python Fatal Python error: init_sys_streams: can't initialize sys standard streams Python runtime state: core initialized AttributeError: module 'io' has no attribute 'OpenWrapper' Current thread 0x00009d44 (most recent call first): It is true that io has no OpenWrapper class. The question is What is trying to use that? What installer are you using? I would (re)download the one from python.org. -- Terry Jan Reedy From mchakrain at yahoo.com Mon Nov 23 15:13:01 2020 From: mchakrain at yahoo.com (Mayukh Chakraborty) Date: Mon, 23 Nov 2020 20:13:01 +0000 (UTC) Subject: Python Error In-Reply-To: <92E83519-411E-4A80-BE80-6F9417805B61@barrys-emacs.org> References: <1183930009.832611.1606140618819.ref@mail.yahoo.com> <1183930009.832611.1606140618819@mail.yahoo.com> <92E83519-411E-4A80-BE80-6F9417805B61@barrys-emacs.org> Message-ID: <897849660.966144.1606162381417@mail.yahoo.com> 1. The command 'py' doesn't work. It gives me the error below : C:\Users\mchak>pyFatal Python error: init_sys_streams: can't initialize sys standard streamsPython runtime state: core initializedAttributeError: module 'io' has no attribute 'open' Current thread 0x00008290 (most recent call first): 2. If I use py -0, I get two installed versions. However, if I try to uninstall from Control Panel, I see only 3.9 version C:\Users\mchak>py -0Installed Pythons found by py Launcher for Windows?-3.9-64 *?-3.8-64 3. I tried to uninstall v3.9 and reinstall but it didn't solve the issue. Regards,Mayukh On Monday, November 23, 2020, 06:17:00 PM GMT, Barry Scott wrote: > On 23 Nov 2020, at 14:10, Mayukh Chakraborty via Python-list wrote: > > Hi, > I had uninstalled and installed Python in Windows 10 but I am getting the error below. Can you please help ? > C:\Users\mchak>pythonFatal Python error: init_sys_streams: can't initialize sys standard streamsPython runtime state: core initializedAttributeError: module 'io' has no attribute 'OpenWrapper' > Current thread 0x00009d44 (most recent call first): > Regards,Mayukh Which version of python are you installing and where did you download it from? Do you have more than one version of python installed? Does the command: ? py work? If you have python from python.org installed you should be able to list all the version you have installed with the command: ? py -0 That is zero not oh. Barry > -- > https://mail.python.org/mailman/listinfo/python-list > From mchakrain at yahoo.com Mon Nov 23 15:15:12 2020 From: mchakrain at yahoo.com (Mayukh Chakraborty) Date: Mon, 23 Nov 2020 20:15:12 +0000 (UTC) Subject: Python Error In-Reply-To: References: <1183930009.832611.1606140618819.ref@mail.yahoo.com> <1183930009.832611.1606140618819@mail.yahoo.com> Message-ID: <971995481.974110.1606162512529@mail.yahoo.com> Hi Terry, 1. The command py doesn't work. It gives me the error below : C:\Users\mchak>pyFatal Python error: init_sys_streams: can't initialize sys standard streamsPython runtime state: core initializedAttributeError: module 'io' has no attribute 'open' Current thread 0x00008290 (most recent call first): 2. If I use py -0, I get two installed versions. However, if I try to uninstall from Control Panel, I see only 3.9 version C:\Users\mchak>py -0Installed Pythons found by py Launcher for Windows?-3.9-64 *?-3.8-64 3. I tried to uninstall v3.9 and reinstall but it didn't solve the issue. Regards,Mayukh On Monday, November 23, 2020, 06:34:43 PM GMT, Terry Reedy wrote: On 11/23/2020 9:10 AM, Mayukh Chakraborty via Python-list wrote: > Hi, > I had uninstalled and installed Python in Windows 10 but I am getting the error below. Can you please help ? > C:\Users\mchak>python Fatal Python error: init_sys_streams: can't initialize sys standard streams Python runtime state: core initialized AttributeError: module 'io' has no attribute 'OpenWrapper' Current thread 0x00009d44 (most recent call first): It is true that io has no OpenWrapper class.? The question is What is trying to use that?? What installer are you using?? I would (re)download the one from python.org. -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list From mchakrain at yahoo.com Mon Nov 23 17:34:23 2020 From: mchakrain at yahoo.com (Mayukh Chakraborty) Date: Mon, 23 Nov 2020 22:34:23 +0000 (UTC) Subject: Python Error In-Reply-To: <971995481.974110.1606162512529@mail.yahoo.com> References: <1183930009.832611.1606140618819.ref@mail.yahoo.com> <1183930009.832611.1606140618819@mail.yahoo.com> <971995481.974110.1606162512529@mail.yahoo.com> Message-ID: <1235127085.1017706.1606170863964@mail.yahoo.com> Hi, I have solved the issue by updating the Environment variables, now I am able to launch 'py' from the command prompt. However, I can't launch 'python' from command prompt. I am also encountering an issue when I try to execute the 'python' command from command prompt. I had reinstalled the python packages (numpy, pandas, scipy etc) but I can't find a solution for this error. --------------------------------------------------------------------------------------------------------------------------------------- C:\Users\mchak\Documents\Python>py ES.pyTraceback (most recent call last):? File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\numpy\core\__init__.py", line 22, in ? ? from . import multiarray? File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\numpy\core\multiarray.py", line 12, in ? ? from . import overrides? File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\numpy\core\overrides.py", line 7, in ? ? from numpy.core._multiarray_umath import (ModuleNotFoundError: No module named 'numpy.core._multiarray_umath' During handling of the above exception, another exception occurred: Traceback (most recent call last):? File "C:\Users\mchak\Documents\Python\ES.py", line 1, in ? ? import scipy as sp? File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\scipy\__init__.py", line 61, in ? ? from numpy import show_config as show_numpy_config? File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\numpy\__init__.py", line 140, in ? ? from . import core? File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\numpy\core\__init__.py", line 48, in ? ? raise ImportError(msg)ImportError: IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE! Importing the numpy C-extensions failed. This error can happen formany reasons, often due to issues with your setup or how NumPy wasinstalled. We have compiled some common reasons and troubleshooting tips at: ? ? https://numpy.org/devdocs/user/troubleshooting-importerror.html Please note and check the following: ? * The Python version is: Python3.9 from "C:\Users\mchak\AppData\Local\Programs\Python\Python39\python.exe"? * The NumPy version is: "1.19.4" and make sure that they are the versions you expect.Please carefully study the documentation linked above for further help. Original error was: No module named 'numpy.core._multiarray_umath' Regards,Mayukh On Monday, November 23, 2020, 08:17:06 PM GMT, Mayukh Chakraborty via Python-list wrote: Hi Terry, 1. The command py doesn't work. It gives me the error below : C:\Users\mchak>pyFatal Python error: init_sys_streams: can't initialize sys standard streamsPython runtime state: core initializedAttributeError: module 'io' has no attribute 'open' Current thread 0x00008290 (most recent call first): 2. If I use py -0, I get two installed versions. However, if I try to uninstall from Control Panel, I see only 3.9 version C:\Users\mchak>py -0Installed Pythons found by py Launcher for Windows?-3.9-64 *?-3.8-64 3. I tried to uninstall v3.9 and reinstall but it didn't solve the issue. Regards,Mayukh? ? On Monday, November 23, 2020, 06:34:43 PM GMT, Terry Reedy wrote:? On 11/23/2020 9:10 AM, Mayukh Chakraborty via Python-list wrote: > Hi, > I had uninstalled and installed Python in Windows 10 but I am getting the error below. Can you please help ? > C:\Users\mchak>python Fatal Python error: init_sys_streams: can't initialize sys standard streams Python runtime state: core initialized AttributeError: module 'io' has no attribute 'OpenWrapper' Current thread 0x00009d44 (most recent call first): It is true that io has no OpenWrapper class.? The question is What is trying to use that?? What installer are you using?? I would (re)download the one from python.org. -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list ? -- https://mail.python.org/mailman/listinfo/python-list From gisle.vanem at gmail.com Tue Nov 24 02:12:44 2020 From: gisle.vanem at gmail.com (Gisle Vanem) Date: Tue, 24 Nov 2020 08:12:44 +0100 Subject: Python Error In-Reply-To: <92E83519-411E-4A80-BE80-6F9417805B61@barrys-emacs.org> References: <1183930009.832611.1606140618819.ref@mail.yahoo.com> <1183930009.832611.1606140618819@mail.yahoo.com> <92E83519-411E-4A80-BE80-6F9417805B61@barrys-emacs.org> Message-ID: Barry Scott wrote: > If you have python from python.org installed you should be able to list all the version you have installed > with the command: > > py -0 When was that '-0' feature added? I have Python 3.6 from Python.org and here a 'py.exe -0' gives: Requested Python version (0) not installed But using 'py.exe -0' from Python 3.9 correctly gives: -3.6-32 * -2.7-32 -- --gv From mchakrain at yahoo.com Tue Nov 24 06:15:36 2020 From: mchakrain at yahoo.com (Mayukh Chakraborty) Date: Tue, 24 Nov 2020 11:15:36 +0000 (UTC) Subject: Python Error In-Reply-To: References: <1183930009.832611.1606140618819.ref@mail.yahoo.com> <1183930009.832611.1606140618819@mail.yahoo.com> <92E83519-411E-4A80-BE80-6F9417805B61@barrys-emacs.org> Message-ID: <1525886497.1140251.1606216536051@mail.yahoo.com> Thanks - I am able to launch 'py' from the command prompt and it gives me the python versions installed in my machine from python.org website. However, when I am trying to execute a python program from command prompt, I am getting the error below. I had reinstalled python packages (numpy, pandas) but it didn't resolve the issue. Any help would be appreciated. Original error was: No module named 'numpy.core._multiarray_umath' --------------------------------------------------------------------------------------------------------------------------------------- C:\Users\mchak\Documents\Python>py ES.pyTraceback (most recent call last):? File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\numpy\core\__init__.py", line 22, in ? ? from . import multiarray? File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\numpy\core\multiarray.py", line 12, in ? ? from . import overrides? File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\numpy\core\overrides.py", line 7, in ? ? from numpy.core._multiarray_umath import (ModuleNotFoundError: No module named 'numpy.core._multiarray_umath' During handling of the above exception, another exception occurred: Traceback (most recent call last):? File "C:\Users\mchak\Documents\Python\ES.py", line 1, in ? ? import scipy as sp? File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\scipy\__init__.py", line 61, in ? ? from numpy import show_config as show_numpy_config? File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\numpy\__init__.py", line 140, in ? ? from . import core? File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\numpy\core\__init__.py", line 48, in ? ? raise ImportError(msg)ImportError: IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE! Importing the numpy C-extensions failed. This error can happen formany reasons, often due to issues with your setup or how NumPy wasinstalled. We have compiled some common reasons and troubleshooting tips at: ? ??https://numpy.org/devdocs/user/troubleshooting-importerror.html Please note and check the following: ? * The Python version is: Python3.9 from "C:\Users\mchak\AppData\Local\Programs\Python\Python39\python.exe"? * The NumPy version is: "1.19.4" and make sure that they are the versions you expect.Please carefully study the documentation linked above for further help. Original error was: No module named 'numpy.core._multiarray_umath' On Tuesday, November 24, 2020, 07:13:04 AM GMT, Gisle Vanem wrote: Barry Scott wrote: > If you have python from python.org installed you should be able to list all the version you have installed > with the command: > >? ? py -0 When was that '-0' feature added? I have Python 3.6 from Python.org and here a 'py.exe -0' gives: ? Requested Python version (0) not installed But using 'py.exe -0' from Python 3.9 correctly gives: ? -3.6-32 * ? -2.7-32 -- --gv -- https://mail.python.org/mailman/listinfo/python-list From barry at barrys-emacs.org Tue Nov 24 16:26:57 2020 From: barry at barrys-emacs.org (Barry) Date: Tue, 24 Nov 2020 21:26:57 +0000 Subject: Python Error In-Reply-To: <1525886497.1140251.1606216536051@mail.yahoo.com> References: <1525886497.1140251.1606216536051@mail.yahoo.com> Message-ID: Two observations. Python.exe is not on your PATH. But that does not matter as you can use the py command instead And nymph may not be available for python 3.9 yet. Check on pypi to see if there is a build for 3.9. Maybe use 3.8 for the time being. Barry > On 24 Nov 2020, at 11:18, Mayukh Chakraborty via Python-list wrote: > > ? Thanks - I am able to launch 'py' from the command prompt and it gives me the python versions installed in my machine from python.org website. > However, when I am trying to execute a python program from command prompt, I am getting the error below. I had reinstalled python packages (numpy, pandas) but it didn't resolve the issue. Any help would be appreciated. > Original error was: No module named 'numpy.core._multiarray_umath' > > --------------------------------------------------------------------------------------------------------------------------------------- > C:\Users\mchak\Documents\Python>py ES.pyTraceback (most recent call last): File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\numpy\core\__init__.py", line 22, in from . import multiarray File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\numpy\core\multiarray.py", line 12, in from . import overrides File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\numpy\core\overrides.py", line 7, in from numpy.core._multiarray_umath import (ModuleNotFoundError: No module named 'numpy.core._multiarray_umath' > During handling of the above exception, another exception occurred: > Traceback (most recent call last): File "C:\Users\mchak\Documents\Python\ES.py", line 1, in import scipy as sp File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\scipy\__init__.py", line 61, in from numpy import show_config as show_numpy_config File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\numpy\__init__.py", line 140, in from . import core File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\numpy\core\__init__.py", line 48, in raise ImportError(msg)ImportError: > IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE! > Importing the numpy C-extensions failed. This error can happen formany reasons, often due to issues with your setup or how NumPy wasinstalled. > We have compiled some common reasons and troubleshooting tips at: > https://numpy.org/devdocs/user/troubleshooting-importerror.html > Please note and check the following: > * The Python version is: Python3.9 from "C:\Users\mchak\AppData\Local\Programs\Python\Python39\python.exe" * The NumPy version is: "1.19.4" > and make sure that they are the versions you expect.Please carefully study the documentation linked above for further help. > Original error was: No module named 'numpy.core._multiarray_umath' > >> On Tuesday, November 24, 2020, 07:13:04 AM GMT, Gisle Vanem wrote: >> >> Barry Scott wrote: >> >> If you have python from python.org installed you should be able to list all the version you have installed >> with the command: >> >> py -0 > When was that '-0' feature added? > I have Python 3.6 from Python.org and here a > 'py.exe -0' gives: > Requested Python version (0) not installed > > But using 'py.exe -0' from Python 3.9 correctly > gives: > -3.6-32 * > -2.7-32 > > -- > --gv > -- > https://mail.python.org/mailman/listinfo/python-list > > -- > https://mail.python.org/mailman/listinfo/python-list From mchakrain at yahoo.com Tue Nov 24 17:28:59 2020 From: mchakrain at yahoo.com (Mayukh Chakraborty) Date: Tue, 24 Nov 2020 22:28:59 +0000 (UTC) Subject: Python Error In-Reply-To: References: <1525886497.1140251.1606216536051@mail.yahoo.com> Message-ID: <1008974658.1334587.1606256939175@mail.yahoo.com> Thanks. I updated the path and was able to launch python.exe for v3.8. I got rid of the other errors but now facing an error with 'pandas' although? it is installed ok and the path correctly updated. C:\Users\mchak>pythonPython 3.8.6 (tags/v3.8.6:db45529, Sep 23 2020, 15:52:53) [MSC v.1927 64 bit (AMD64)] on win32Type "help", "copyright", "credits" or "license" for more information.>>> import pandas as pdTraceback (most recent call last):? File "", line 1, in ? File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\pandas\__init__.py", line 22, in ? ? from pandas.compat.numpy import (ModuleNotFoundError: No module named 'pandas.compat.numpy'>>> - Mayukh On Tuesday, November 24, 2020, 09:27:00 PM GMT, Barry wrote: Two observations. Python.exe is not on your PATH. But that does not matter as you can use the py command instead And nymph may not be available for python 3.9 yet. Check on pypi to see if there is a build for 3.9. Maybe use 3.8 for the time being. Barry > On 24 Nov 2020, at 11:18, Mayukh Chakraborty via Python-list wrote: > > ? Thanks - I am able to launch 'py' from the command prompt and it gives me the python versions installed in my machine from python.org website. > However, when I am trying to execute a python program from command prompt, I am getting the error below. I had reinstalled python packages (numpy, pandas) but it didn't resolve the issue. Any help would be appreciated. > Original error was: No module named 'numpy.core._multiarray_umath' > > --------------------------------------------------------------------------------------------------------------------------------------- > C:\Users\mchak\Documents\Python>py ES.pyTraceback (most recent call last):? File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\numpy\core\__init__.py", line 22, in ? ? from . import multiarray? File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\numpy\core\multiarray.py", line 12, in ? ? from . import overrides? File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\numpy\core\overrides.py", line 7, in ? ? from numpy.core._multiarray_umath import (ModuleNotFoundError: No module named 'numpy.core._multiarray_umath' > During handling of the above exception, another exception occurred: > Traceback (most recent call last):? File "C:\Users\mchak\Documents\Python\ES.py", line 1, in ? ? import scipy as sp? File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\scipy\__init__.py", line 61, in ? ? from numpy import show_config as show_numpy_config? File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\numpy\__init__.py", line 140, in ? ? from . import core? File "C:\Users\mchak\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\numpy\core\__init__.py", line 48, in ? ? raise ImportError(msg)ImportError: > IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE! > Importing the numpy C-extensions failed. This error can happen formany reasons, often due to issues with your setup or how NumPy wasinstalled. > We have compiled some common reasons and troubleshooting tips at: >? ? https://numpy.org/devdocs/user/troubleshooting-importerror.html > Please note and check the following: >? * The Python version is: Python3.9 from "C:\Users\mchak\AppData\Local\Programs\Python\Python39\python.exe"? * The NumPy version is: "1.19.4" > and make sure that they are the versions you expect.Please carefully study the documentation linked above for further help. > Original error was: No module named 'numpy.core._multiarray_umath' > >>? ? On Tuesday, November 24, 2020, 07:13:04 AM GMT, Gisle Vanem wrote:? >> >> Barry Scott wrote: >> >> If you have python from python.org installed you should be able to list all the version you have installed >> with the command: >> >>? ? py -0 > When was that '-0' feature added? > I have Python 3.6 from Python.org and here a > 'py.exe -0' gives: >? Requested Python version (0) not installed > > But using 'py.exe -0' from Python 3.9 correctly > gives: >? -3.6-32 * >? -2.7-32 > > -- > --gv > -- > https://mail.python.org/mailman/listinfo/python-list > > -- > https://mail.python.org/mailman/listinfo/python-list From pjfarley3 at earthlink.net Wed Nov 25 01:47:58 2020 From: pjfarley3 at earthlink.net (pjfarley3 at earthlink.net) Date: Wed, 25 Nov 2020 01:47:58 -0500 Subject: Why can't numpy array be restored to saved value? Message-ID: <000001d6c2f6$e9a0ef30$bce2cd90$@earthlink.net> Why isn't the final value of the numpy array npary in the following code the same as the initial value before some but not all elements of the array were changed to a new value? I know I am missing something basic here. I thought I understood the concepts of immutable vs mutable values but obviously I missed something. My environment is Win10-64, Python 3.8.5, numpy 1.19.2. Code and output follows. TIA for any help you can provide to cure my ignorance. Peter --- nptest.py --- import numpy as np import sys if len(sys.argv) > 0: try: asz = int(sys.argv[1]) + 0 except: asz = 4 npary = np.full([asz, asz, asz], 0, dtype=np.int32) print("Array before change=\n{}".format(npary)) svary = npary[:, :, :] npary[1:-1, 1:-1, 1:-1] = 1 print("Array after change=\n{}".format(npary)) npary = svary[:, :, :] print("Array after restore=\n{}".format(npary)) --- nptest.py --- --- output --- Array before change= [[[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]] [[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]] [[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]] [[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]]] Array after change= [[[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]] [[0 0 0 0] [0 1 1 0] [0 1 1 0] [0 0 0 0]] [[0 0 0 0] [0 1 1 0] [0 1 1 0] [0 0 0 0]] [[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]]] Array after restore= [[[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]] [[0 0 0 0] [0 1 1 0] [0 1 1 0] [0 0 0 0]] [[0 0 0 0] [0 1 1 0] [0 1 1 0] [0 0 0 0]] [[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]]] --- output --- From pjfarley3 at earthlink.net Wed Nov 25 03:03:14 2020 From: pjfarley3 at earthlink.net (pjfarley3 at earthlink.net) Date: Wed, 25 Nov 2020 03:03:14 -0500 Subject: Why can't numpy array be restored to saved value? Message-ID: <000001d6c301$6d8ba420$48a2ec60$@earthlink.net> Never mind, I found the numpy.copy function does what I need. Revised code below works. Sorry for wasting bandwidth. Peter --- nptest.py --- import numpy as np import sys if len(sys.argv) > 0: try: asz = int(sys.argv[1]) + 0 except: asz = 4 npary = np.full([asz, asz, asz], 0, dtype=np.int32) print("Array before change=\n{}".format(npary)) svary = np.copy(npary, order='C') npary[1:-1, 1:-1, 1:-1] = 1 print("Array after change=\n{}".format(npary)) npary = svary print("Array after restore=\n{}".format(npary)) --- nptest.py --- > -----Original Message----- > From: pjfarley3 at earthlink.net > Sent: Wednesday, November 25, 2020 1:48 AM > To: 'python-list at python.org' > Subject: Why can't numpy array be restored to saved value? > > Why isn't the final value of the numpy array npary in the following code the > same as the initial value before some but not all elements of the array were > changed to a new value? > > I know I am missing something basic here. I thought I understood the concepts > of immutable vs mutable values but obviously I missed something. > > My environment is Win10-64, Python 3.8.5, numpy 1.19.2. > > Code and output follows. TIA for any help you can provide to cure my > ignorance. > > Peter > > --- nptest.py --- > import numpy as np > import sys > > if len(sys.argv) > 0: > try: > asz = int(sys.argv[1]) + 0 > except: > asz = 4 > > npary = np.full([asz, asz, asz], 0, dtype=np.int32) > print("Array before change=\n{}".format(npary)) > svary = npary[:, :, :] > npary[1:-1, 1:-1, 1:-1] = 1 > print("Array after change=\n{}".format(npary)) > npary = svary[:, :, :] > print("Array after restore=\n{}".format(npary)) > --- nptest.py --- > > --- output --- > Array before change= > [[[0 0 0 0] > [0 0 0 0] > [0 0 0 0] > [0 0 0 0]] > > [[0 0 0 0] > [0 0 0 0] > [0 0 0 0] > [0 0 0 0]] > > [[0 0 0 0] > [0 0 0 0] > [0 0 0 0] > [0 0 0 0]] > > [[0 0 0 0] > [0 0 0 0] > [0 0 0 0] > [0 0 0 0]]] > Array after change= > [[[0 0 0 0] > [0 0 0 0] > [0 0 0 0] > [0 0 0 0]] > > [[0 0 0 0] > [0 1 1 0] > [0 1 1 0] > [0 0 0 0]] > > [[0 0 0 0] > [0 1 1 0] > [0 1 1 0] > [0 0 0 0]] > > [[0 0 0 0] > [0 0 0 0] > [0 0 0 0] > [0 0 0 0]]] > Array after restore= > [[[0 0 0 0] > [0 0 0 0] > [0 0 0 0] > [0 0 0 0]] > > [[0 0 0 0] > [0 1 1 0] > [0 1 1 0] > [0 0 0 0]] > > [[0 0 0 0] > [0 1 1 0] > [0 1 1 0] > [0 0 0 0]] > > [[0 0 0 0] > [0 0 0 0] > [0 0 0 0] > [0 0 0 0]]] > --- output --- From bob at mellowood.ca Wed Nov 25 11:46:21 2020 From: bob at mellowood.ca (Bob van der Poel) Date: Wed, 25 Nov 2020 09:46:21 -0700 Subject: Environment vars Message-ID: I've got a program which accepts an optional env variable listing a single or multiple directory for the app to use. I've done a bit of a search and see both a comma and semicolon being used/suggested as a path separator. Any consensus on which is better? MYPATHS=foo,bar,woof or MYPATHS=foo;bar;woof And, certainly not MYPATHS=foo,bar;woof I did think I could be clever and check to see if the string contained a , or ; and spit it accordingly, but then what if the reason (hopefully, pretty damned unlikely!) that a , or ; is being used as part of a path name? -- **** Listen to my FREE CD at http://www.mellowood.ca/music/cedars **** Bob van der Poel ** Wynndel, British Columbia, CANADA ** EMAIL: bob at mellowood.ca WWW: http://www.mellowood.ca From rosuav at gmail.com Wed Nov 25 12:59:46 2020 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 26 Nov 2020 04:59:46 +1100 Subject: Environment vars In-Reply-To: References: Message-ID: On Thu, Nov 26, 2020 at 4:36 AM Bob van der Poel wrote: > > I've got a program which accepts an optional env variable listing a single > or multiple directory for the app to use. I've done a bit of a search and > see both a comma and semicolon being used/suggested as a path separator. > Any consensus on which is better? > > MYPATHS=foo,bar,woof > or > MYPATHS=foo;bar;woof > And, certainly not > MYPATHS=foo,bar;woof > > I did think I could be clever and check to see if the string contained a , > or ; and spit it accordingly, but then what if the reason (hopefully, > pretty damned unlikely!) that a , or ; is being used as part of a path name? > Both are very much possible. I would recommend following a well-known standard; fortunately, there are plenty to choose from. 1) Separate them with spaces, because words. 2) Separate them with commas, because lists in English. 3) Separate with colons the way $PATH is. Whichever way you do it, you'll have to cope with the possibility that the character exists in a path name. That means you'll either need an escaping system (eg "\ " meaning a space, or ",," meaning a comma) or a quoting system (so "foo,bar",woof would mean two entries, the first of which contains a comma). Or you just acknowledge that MYPATHS is unable to represent something with the delimiter - which is how $PATH works - and then you'll probably need some workaround for that, like maybe a command line argument. The one thing I really would *not* recommend is a DWIM arrangement of having it guess at which delimiter to use. :) ChrisA From PythonList at DancesWithMice.info Wed Nov 25 13:00:02 2020 From: PythonList at DancesWithMice.info (dn) Date: Thu, 26 Nov 2020 07:00:02 +1300 Subject: Environment vars In-Reply-To: References: Message-ID: <17aa9ce0-0d4c-4e82-c748-2d49e420e856@DancesWithMice.info> On 26/11/2020 05:46, Bob van der Poel wrote: > I've got a program which accepts an optional env variable listing a single > or multiple directory for the app to use. I've done a bit of a search and > see both a comma and semicolon being used/suggested as a path separator. > Any consensus on which is better? > > MYPATHS=foo,bar,woof > or > MYPATHS=foo;bar;woof > And, certainly not > MYPATHS=foo,bar;woof > > I did think I could be clever and check to see if the string contained a , > or ; and spit it accordingly, but then what if the reason (hopefully, > pretty damned unlikely!) that a , or ; is being used as part of a path name? Is this a Python question? ie the above code should be run inside the Python interpreter (it won't). MS-Windows has an option to use a comma or a semi-colon as a list-separator on the 'command line' - as a local/locale definition, but there are caveats. Alternately, did you mean that the above is part of a data-file? -- Regards =dn From p_d_a_s_i_l_v_a_ns at nonetnoaddress.pt Wed Nov 25 13:08:42 2020 From: p_d_a_s_i_l_v_a_ns at nonetnoaddress.pt (Paulo da Silva) Date: Wed, 25 Nov 2020 18:08:42 +0000 Subject: Problem exiting from a script using tkinter References: Message-ID: ?s 22:44 de 21/11/20, Chris Angelico escreveu: > On Sun, Nov 22, 2020 at 9:36 AM Paulo da Silva > wrote: >> >> ?s 22:18 de 21/11/20, Chris Angelico escreveu: >>> On Sun, Nov 22, 2020 at 9:16 AM Paulo da Silva >>> wrote: >>>> >>>> Hi! >>>> >>>> Why this does not work?! >>>> >>>> from tkinter import * >>>> >>>> def terminate(root): >>>> root.quit >>>> >>> >>> Is root.quit a function? Simply referencing a function's name does not >>> call it (because functions are first-class objects - you can put a >>> function in a variable or pass it as a parameter etc). In order to >>> make it do its work, you have to call it. >>> >> >> A newbie Error :-( >> Sorry. I am giving my first steps in tkinter and I thought it was >> another problem :-) >> I just copied the "root.quit" inside the function. >> > > No need to feel bad about it :) Getting your head around "this is a > function, that's where the function's being called" is not easy, and > it takes experience. > > Your question was very well put. You provided a short, compact example > that showcased the problem you were experiencing. That made it easy to > answer your question. Keep on asking questions like that, please - > you're helping yourself and making the mailing list a great place too > :) Thank you :-) Paulo From bob at mellowood.ca Wed Nov 25 13:26:17 2020 From: bob at mellowood.ca (Bob van der Poel) Date: Wed, 25 Nov 2020 11:26:17 -0700 Subject: Environment vars In-Reply-To: References: Message-ID: On Wed, Nov 25, 2020 at 10:59 AM Chris Angelico wrote: > On Thu, Nov 26, 2020 at 4:36 AM Bob van der Poel wrote: > > > > I've got a program which accepts an optional env variable listing a > single > > or multiple directory for the app to use. I've done a bit of a search and > > see both a comma and semicolon being used/suggested as a path separator. > > Any consensus on which is better? > > > > MYPATHS=foo,bar,woof > > or > > MYPATHS=foo;bar;woof > > And, certainly not > > MYPATHS=foo,bar;woof > > > > I did think I could be clever and check to see if the string contained a > , > > or ; and spit it accordingly, but then what if the reason (hopefully, > > pretty damned unlikely!) that a , or ; is being used as part of a path > name? > > > > Both are very much possible. I would recommend following a well-known > standard; fortunately, there are plenty to choose from. > > 1) Separate them with spaces, because words. > 2) Separate them with commas, because lists in English. > 3) Separate with colons the way $PATH is. > > Whichever way you do it, you'll have to cope with the possibility that > the character exists in a path name. That means you'll either need an > escaping system (eg "\ " meaning a space, or ",," meaning a comma) or > a quoting system (so "foo,bar",woof would mean two entries, the first > of which contains a comma). Or you just acknowledge that MYPATHS is > unable to represent something with the delimiter - which is how $PATH > works - and then you'll probably need some workaround for that, like > maybe a command line argument. > > The one thing I really would *not* recommend is a DWIM arrangement of > having it guess at which delimiter to use. :) > Thanks Chris. What does DWIN mean? Hmmm, using colons? Yet another option :) Spaces ... nope. That means the entire option will need to be quoted to escape the shell's work. So, back to commas or semicolons. I think I'll just stick with the commas 'cause I already wrote it that way :) -- **** Listen to my FREE CD at http://www.mellowood.ca/music/cedars **** Bob van der Poel ** Wynndel, British Columbia, CANADA ** EMAIL: bob at mellowood.ca WWW: http://www.mellowood.ca From bob at mellowood.ca Wed Nov 25 13:29:23 2020 From: bob at mellowood.ca (Bob van der Poel) Date: Wed, 25 Nov 2020 11:29:23 -0700 Subject: Environment vars In-Reply-To: <17aa9ce0-0d4c-4e82-c748-2d49e420e856@DancesWithMice.info> References: <17aa9ce0-0d4c-4e82-c748-2d49e420e856@DancesWithMice.info> Message-ID: On Wed, Nov 25, 2020 at 11:00 AM dn via Python-list wrote: > On 26/11/2020 05:46, Bob van der Poel wrote: > > I've got a program which accepts an optional env variable listing a > single > > or multiple directory for the app to use. I've done a bit of a search and > > see both a comma and semicolon being used/suggested as a path separator. > > Any consensus on which is better? > > > > MYPATHS=foo,bar,woof > > or > > MYPATHS=foo;bar;woof > > And, certainly not > > MYPATHS=foo,bar;woof > > > > I did think I could be clever and check to see if the string contained a > , > > or ; and spit it accordingly, but then what if the reason (hopefully, > > pretty damned unlikely!) that a , or ; is being used as part of a path > name? > > > Is this a Python question? ie the above code should be run inside the > Python interpreter (it won't). > > MS-Windows has an option to use a comma or a semi-colon as a > list-separator on the 'command line' - as a local/locale definition, but > there are caveats. > > Alternately, did you mean that the above is part of a data-file? > - > Just to clarify, the variable can be set on the command line or in a shell script. Most likely: MYPATH=aa,bb,cc myprogram and myprogram will look for the variable and slice it into chunks at ","s or ";". You're right, this is not really a python question. Probably a shell thing. Thanks. -- **** Listen to my FREE CD at http://www.mellowood.ca/music/cedars **** Bob van der Poel ** Wynndel, British Columbia, CANADA ** EMAIL: bob at mellowood.ca WWW: http://www.mellowood.ca From ashutoshsharma737 at gmail.com Wed Nov 25 12:53:58 2020 From: ashutoshsharma737 at gmail.com (ASHUTOSH SHARMA) Date: Wed, 25 Nov 2020 23:23:58 +0530 Subject: unable to use numpy Message-ID: <5fbe9a3d.1c69fb81.76939.6777@mx.google.com> Good Evening I had installed numpy and updated to latest version also but getting runtime error pop while using. So please resolve this issue by giving a suitable solution of this. THANKS & REGARDS ASHUTOSH SHARMA Sent from Mail for Windows 10 From grant.b.edwards at gmail.com Wed Nov 25 13:50:12 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Wed, 25 Nov 2020 18:50:12 -0000 (UTC) Subject: Environment vars References: Message-ID: On 2020-11-25, Bob van der Poel wrote: > What does DWIN mean? It's DWIM: "do what I mean". It refers to software (like PHP) that instead of requiring unambiguous input, it silently (and often incorrectly) guesses what ambiguous input is supposed to mean using heuristics known to and understood by only the developer. [I'm giving PHP developers the benefit of the doubt with the assumption that they do understand what they do and that that it makes sense to them.] > Hmmm, using colons? Yet another option :) That's quite certainly what Unix users are going to expect to use. -- Grant From PythonList at DancesWithMice.info Wed Nov 25 14:17:31 2020 From: PythonList at DancesWithMice.info (dn) Date: Thu, 26 Nov 2020 08:17:31 +1300 Subject: Environment vars In-Reply-To: References: Message-ID: <8e8408a9-cfc8-6991-b219-9690edfae0a4@DancesWithMice.info> >> I've got a program which accepts an optional env variable listing a single >> or multiple directory for the app to use. I've done a bit of a search and >> see both a comma and semicolon being used/suggested as a path separator. >> Any consensus on which is better? ... > The one thing I really would *not* recommend is a DWIM arrangement of > having it guess at which delimiter to use. :) Interesting description. Historically I've always quoted "Postel's Law": <<< Robustness principle In computing, the robustness principle is a design guideline for software: Be conservative in what you do, be liberal in what you accept from others (often reworded as "Be conservative in what you send, be liberal in what you accept"). The principle is also known as Postel's law, after Jon Postel, who wrote in an early specification of TCP:[1] >>> https://en.wikipedia.org/wiki/Robustness_principle More recently, folk have been reading Steve Krug - "oh you mean, Don't Make Me Think!"; which I fear is too readily taken literally, if not as non sequitur. https://en.wikipedia.org/wiki/Don%27t_Make_Me_Think (but reading the book will be time well-spent by anyone working at the 'front end'!) In psychology the jargon is "satisficing" - being happy with whichever works when we try it: Why look [for a label]? I'll just push the door away from me - and if that doesn't work, then I'll pull on the handle (but if it's locked, my frustration will result in words being said...) How quickly does something 'easy' move from 'who cares' to 'almost anger'? So, if some users are likely to assume commas, but others [semi-]colons, perhaps the best service is to enable either/both! (hint: str.translate() ) Conversely, consider the level of frustration faced by a user who expects one thing but is *restricted* to something else, eg sites which ask one to register a password, but don't advise up-front that they require some arcane combination/mix of characters - until after you've entered your [ignorant] choice - twice. Grrr! -- Regards =dn From PythonList at DancesWithMice.info Wed Nov 25 14:20:20 2020 From: PythonList at DancesWithMice.info (dn) Date: Thu, 26 Nov 2020 08:20:20 +1300 Subject: unable to use numpy In-Reply-To: <5fbe9a3d.1c69fb81.76939.6777@mx.google.com> References: <5fbe9a3d.1c69fb81.76939.6777@mx.google.com> Message-ID: <4c5e43b4-846e-3e5e-3531-a541f5b69abe@DancesWithMice.info> On 26/11/2020 06:53, ASHUTOSH SHARMA wrote: > Good Evening Welcome to the *world wide* web, where it is also Thursday, and breakfast time (for late risers)!? > I had installed numpy and updated to latest version also but getting runtime error pop while using. > So please resolve this issue by giving a suitable solution of this. Please copy-paste the actual commands being used and error messages reported. OpSys? Source of Python? Source of numpy? -- Regards =dn From rosuav at gmail.com Wed Nov 25 14:43:04 2020 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 26 Nov 2020 06:43:04 +1100 Subject: Environment vars In-Reply-To: <8e8408a9-cfc8-6991-b219-9690edfae0a4@DancesWithMice.info> References: <8e8408a9-cfc8-6991-b219-9690edfae0a4@DancesWithMice.info> Message-ID: On Thu, Nov 26, 2020 at 6:19 AM dn via Python-list wrote: > > >> I've got a program which accepts an optional env variable listing a single > >> or multiple directory for the app to use. I've done a bit of a search and > >> see both a comma and semicolon being used/suggested as a path separator. > >> Any consensus on which is better? > ... > > The one thing I really would *not* recommend is a DWIM arrangement of > > having it guess at which delimiter to use. :) > > > Interesting description. Historically I've always quoted "Postel's Law": > ... > In psychology the jargon is "satisficing" - being happy with whichever > works when we try it: Why look [for a label]? I'll just push the door > away from me - and if that doesn't work, then I'll pull on the handle > (but if it's locked, my frustration will result in words being said...) > How quickly does something 'easy' move from 'who cares' to 'almost anger'? > > So, if some users are likely to assume commas, but others [semi-]colons, > perhaps the best service is to enable either/both! (hint: str.translate() ) That's absolutely fine IF and ONLY IF you can guarantee that all those forms of punctuation cannot occur within the elements. I do this kind of thing all the time when it's unambiguous; for instance, a multiline input saying "enter Twitch channel names" takes the user input and splits it on comma, semicolon, newline, or space, and then trims individual entries with "http%*[s]://twitch.tv/%s%*[?/]" to get to just the channel name. That works really well, because there's no way that a channel name can contain that sort of punctuation. It's completely NOT okay if you're working with something that might contain anything - especially if your users aren't thinking about the different separators. You might get away with using a comma to separate names of people, happily working with lists like "Fred, Barney, Wilma" and "Elsa, Anna, Kristoff, Sven" and "Steve, Steven, Stephen, Stefan, Stephanie", but then along comes "Charles, Prince of Wales" and suddenly your system breaks. But far worse than simply using commas as separators is magically deciding to do so on the basis of what someone's given you to parse. If someone tries to use "Fred; Barney; Wilma" and "Elsa; Anna; Kristoff; Sven" and it works fine, then they might expect that it'd be safe to list the British royal family with semicolons between their names - but your code suddenly decides to use commas, and now everything's broken. The worst part of a DWIM system is that it's hard - often impossible - to correct its errors. You end up fighting with it to interpret your input correctly. With a simpler system, it might be bizarre and arcane (seriously, look at bash's argument splitting and interpolation rules!), but at least you don't have to fight it, and what works with one set of data will definitely work with another. > Conversely, consider the level of frustration faced by a user who > expects one thing but is *restricted* to something else, eg sites which > ask one to register a password, but don't advise up-front that they > require some arcane combination/mix of characters - until after you've > entered your [ignorant] choice - twice. Grrr! Ohh I hear you on that. Especially when they think they need more security than everyone else, so they say "have to have two uppercase, two lowercase, one digit, and two symbols". And then they reject password after password because, apparently, "!" isn't one of their list of symbols. Or something. And of course, they never permit long passwords. Oh no, that would be way too helpful, not to mention that it'd actually be more secure. Sigh. ChrisA From eryksun at gmail.com Wed Nov 25 14:43:35 2020 From: eryksun at gmail.com (Eryk Sun) Date: Wed, 25 Nov 2020 13:43:35 -0600 Subject: Environment vars In-Reply-To: References: Message-ID: On 11/25/20, Bob van der Poel wrote: > I've got a program which accepts an optional env variable listing a single > or multiple directory for the app to use. In Unix one would use colon as the preferred delimiter. In Windows, it's a semicolon because DOS paths use colon to designate drives. Python makes the platform's preferred path delimiter available as os.pathsep. A bonus with using semicolon in Windows 10 is that the system environment variable editor implements a multi-line form to edit the value if it detects a drive-like path as the first item. For example, editing "MYPATH=Z:\Spam;foo;bar" splits the value into three single-line text-edit fields containing "Z:\Spam", "foo", and "bar". From PythonList at DancesWithMice.info Wed Nov 25 15:48:23 2020 From: PythonList at DancesWithMice.info (dn) Date: Thu, 26 Nov 2020 09:48:23 +1300 Subject: Environment vars In-Reply-To: References: <8e8408a9-cfc8-6991-b219-9690edfae0a4@DancesWithMice.info> Message-ID: <82347db7-3711-04d2-2b0d-2477b75ccdb8@DancesWithMice.info> On 26/11/2020 08:43, Chris Angelico wrote: > On Thu, Nov 26, 2020 at 6:19 AM dn via Python-list > wrote: >> >>>> I've got a program which accepts an optional env variable listing a single >>>> or multiple directory for the app to use. I've done a bit of a search and >>>> see both a comma and semicolon being used/suggested as a path separator. >>>> Any consensus on which is better? >> ... >>> The one thing I really would *not* recommend is a DWIM arrangement of >>> having it guess at which delimiter to use. :) >> >> >> Interesting description. Historically I've always quoted "Postel's Law": >> ... >> In psychology the jargon is "satisficing" - being happy with whichever >> works when we try it: Why look [for a label]? I'll just push the door >> away from me - and if that doesn't work, then I'll pull on the handle >> (but if it's locked, my frustration will result in words being said...) >> How quickly does something 'easy' move from 'who cares' to 'almost anger'? >> >> So, if some users are likely to assume commas, but others [semi-]colons, >> perhaps the best service is to enable either/both! (hint: str.translate() ) > > That's absolutely fine IF and ONLY IF you can guarantee that all those > forms of punctuation cannot occur within the elements. I do this kind > of thing all the time when it's unambiguous; for instance, a multiline > input saying "enter Twitch channel names" takes the user input and > splits it on comma, semicolon, newline, or space, and then trims > individual entries with "http%*[s]://twitch.tv/%s%*[?/]" to get to > just the channel name. That works really well, because there's no way > that a channel name can contain that sort of punctuation. That's the dichotomy: as soon as we aim for 'flexibility', we risk ambiguity. Sometimes it might be better to go with the Zen of Python: "There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch."* Sadly, whilst we coders can reasonably be encouraged "In the face of ambiguity, refuse the temptation to guess.", it will never appear in (many) user's manifestos - possibly an 'age' thing, more likely a "don't think" thing... * I'm amused (not offended) by this casual racism, but wonder how it continues to be allowed given the Python Foundation's diversity principles. That said, Python/PSL enables differences between OpSys to be 'abstracted away', eg using / or \ as separator in a file/dir's path. Where applicable, use! > It's completely NOT okay if you're working with something that might > contain anything - especially if your users aren't thinking about the > different separators. You might get away with using a comma to Well, as debated earlier, Steve Krug suggests that users aren't/shouldn't be thinking. So, fallacies abound! > separate names of people, happily working with lists like "Fred, > Barney, Wilma" and "Elsa, Anna, Kristoff, Sven" and "Steve, Steven, > Stephen, Stefan, Stephanie", but then along comes "Charles, Prince of > Wales" and suddenly your system breaks. But far worse than simply > using commas as separators is magically deciding to do so on the basis > of what someone's given you to parse. If someone tries to use "Fred; > Barney; Wilma" and "Elsa; Anna; Kristoff; Sven" and it works fine, > then they might expect that it'd be safe to list the British royal > family with semicolons between their names - but your code suddenly > decides to use commas, and now everything's broken. Hey, they're the Australian Royal Family too, aren't they? (cue Republicanism sentiment) How often does Prince Charles (the rest is "title" not name, BTW - thus "Charles Windsor" or even "Charles Wales") visit your web site/use your app? Wouldn't you expect to cater less to princes and more to frogs? > The worst part of a DWIM system is that it's hard - often impossible - > to correct its errors. You end up fighting with it to interpret your > input correctly. With a simpler system, it might be bizarre and arcane > (seriously, look at bash's argument splitting and interpolation > rules!), but at least you don't have to fight it, and what works with > one set of data will definitely work with another. Yes, the issue lies with, and starts with, the combination. Referencing @Eryk's post, even users with knowledge of their OpSys will come to the problem with a different set of assumptions (hopes, fears, ...) Accordingly, it may be appropriate to eschew free-form lists entirely. Thus: MYPATH=Z:\Spam MYPATH=foo MYPATH=bar ... but then sit-back and wait for the first help-call from a user worrying that the first/last is the only specification that will be applied. Are we likely to 'win' any-time soon? Clearly, what might be appropriate or usable in one 'solution', should be out-right rejected in another situation. >> Conversely, consider the level of frustration faced by a user who >> expects one thing but is *restricted* to something else, eg sites which >> ask one to register a password, but don't advise up-front that they >> require some arcane combination/mix of characters - until after you've >> entered your [ignorant] choice - twice. Grrr! > > Ohh I hear you on that. Especially when they think they need more > security than everyone else, so they say "have to have two uppercase, > two lowercase, one digit, and two symbols". And then they reject > password after password because, apparently, "!" isn't one of their > list of symbols. Or something. And of course, they never permit long > passwords. Oh no, that would be way too helpful, not to mention that > it'd actually be more secure. Sigh. Or... how about the form requesting an email address, which is rejected - presumably because the RegEx/library-routine has restrictions which don't include certain 'new' TLDs? Well excuse me, but if I am responding to *your* email-message, which *you* sent to my email-address, surely the address has been proven and MUST be 'legal'!? (and why am I entering it manually, when the email-message's link could have included same?) Welcome to the wonderful world of UX! We (computer people) have long been encouraged to 'make things idiot-proof'. The trouble with this injunction, is that the harder we try to achieve such, the faster 'the world' comes up with a better class of idiot! By which I don't mean to imply that it is not worth trying. I spend quite a bit of time and effort 'in UX' - simply because there is often no-one else doing it (proper Agile teams aside). Why? There's plenty of 'hard' and anecdotal research which confirms that if users find a tool 'difficult', 'awkward', or even 'different' (from what they expect), then it will be dropped! -- Regards =dn From bob at mellowood.ca Wed Nov 25 16:00:35 2020 From: bob at mellowood.ca (Bob van der Poel) Date: Wed, 25 Nov 2020 14:00:35 -0700 Subject: Environment vars In-Reply-To: References: Message-ID: On Wed, Nov 25, 2020 at 12:43 PM Eryk Sun wrote: > On 11/25/20, Bob van der Poel wrote: > > I've got a program which accepts an optional env variable listing a > single > > or multiple directory for the app to use. > > In Unix one would use colon as the preferred delimiter. In Windows, > it's a semicolon because DOS paths use colon to designate drives. > Python makes the platform's preferred path delimiter available as > os.pathsep. > > A bonus with using semicolon in Windows 10 is that the system > environment variable editor implements a multi-line form to edit the > value if it detects a drive-like path as the first item. For example, > editing "MYPATH=Z:\Spam;foo;bar" splits the value into three > single-line text-edit fields containing "Z:\Spam", "foo", and "bar". > Ahha! Didn't know about os.pathsep. Seems simple enough to use that and be done with it. I'm just using str.split() just now. Is there a os.splitpath()? I don't see anything in the docs. From PythonList at DancesWithMice.info Wed Nov 25 16:22:29 2020 From: PythonList at DancesWithMice.info (dn) Date: Thu, 26 Nov 2020 10:22:29 +1300 Subject: Environment vars In-Reply-To: References: Message-ID: > Ahha! Didn't know about os.pathsep. Seems simple enough to use that and be > done with it. > > I'm just using str.split() just now. Is there a os.splitpath()? I don't see > anything in the docs. https://docs.python.org/3/library/os.path.html#os.path.split -- Regards =dn From bob at mellowood.ca Wed Nov 25 16:30:45 2020 From: bob at mellowood.ca (Bob van der Poel) Date: Wed, 25 Nov 2020 14:30:45 -0700 Subject: Environment vars In-Reply-To: References: Message-ID: On Wed, Nov 25, 2020 at 2:22 PM dn via Python-list wrote: > > Ahha! Didn't know about os.pathsep. Seems simple enough to use that and > be > > done with it. > > > > I'm just using str.split() just now. Is there a os.splitpath()? I don't > see > > anything in the docs. > > > https://docs.python.org/3/library/os.path.html#os.path.split > -- > Regards =dn Yes, but os.path.split() turns a single path into its components. We're chatting about a bunch of complete path names separated by os.pathsep. From eryksun at gmail.com Wed Nov 25 17:02:13 2020 From: eryksun at gmail.com (Eryk Sun) Date: Wed, 25 Nov 2020 16:02:13 -0600 Subject: Environment vars In-Reply-To: References: Message-ID: On 11/25/20, Bob van der Poel wrote: > > Ahha! Didn't know about os.pathsep. Seems simple enough to use that and be > done with it. > > I'm just using str.split() just now. Is there a os.splitpath()? I don't see > anything in the docs. There are no platform standard rules to follow when splitting a path list. A string split() on os.pathsep suffices. If you don't have a special use for empty entries, you can filter the result with a list comprehension, e.g. [p for p in (os.environ.get('MYPATH') or default).split(os.pathsep) if p]. The `default` value here is for when MYPATH isn't defined or has an empty-string value. From greg.ewing at canterbury.ac.nz Wed Nov 25 23:54:46 2020 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Thu, 26 Nov 2020 17:54:46 +1300 Subject: Environment vars In-Reply-To: References: Message-ID: On 26/11/20 10:30 am, Bob van der Poel wrote: > Yes, but os.path.split() turns a single path into its components. We're > chatting about a bunch of complete path names separated by os.pathsep. Yeah, it's unfortunate that the word "path" is conventionally used for two very different things... -- Greg From greg.ewing at canterbury.ac.nz Thu Nov 26 00:00:47 2020 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Thu, 26 Nov 2020 18:00:47 +1300 Subject: Why can't numpy array be restored to saved value? In-Reply-To: References: <000001d6c2f6$e9a0ef30$bce2cd90$@earthlink.net> Message-ID: On 25/11/20 7:47 pm, pjfarley3 at earthlink.net wrote: > Why isn't the final value of the numpy array npary in the following code the > same as the initial value before some but not all elements of the array were > changed to a new value? Slicing a numpy array doesn't copy anything, it just gives you another view of the underlying data. This is a trap you need to watch out for, since it's different from the way sequences normally behave in Python. -- Greg From auriocus at gmx.de Thu Nov 26 03:26:25 2020 From: auriocus at gmx.de (Christian Gollwitzer) Date: Thu, 26 Nov 2020 09:26:25 +0100 Subject: Why can't numpy array be restored to saved value? In-Reply-To: References: <000001d6c2f6$e9a0ef30$bce2cd90$@earthlink.net> Message-ID: Am 25.11.20 um 07:47 schrieb pjfarley3 at earthlink.net: > Why isn't the final value of the numpy array npary in the following code the > same as the initial value before some but not all elements of the array were > changed to a new value? > > I know I am missing something basic here. I thought I understood the > concepts of immutable vs mutable values but obviously I missed something. > > My environment is Win10-64, Python 3.8.5, numpy 1.19.2. > > Code and output follows. TIA for any help you can provide to cure my > ignorance. > > Peter > > --- nptest.py --- > import numpy as np > import sys > > if len(sys.argv) > 0: > try: > asz = int(sys.argv[1]) + 0 > except: > asz = 4 > > npary = np.full([asz, asz, asz], 0, dtype=np.int32) > print("Array before change=\n{}".format(npary)) > svary = npary[:, :, :] Because this does not copy the array, rather it creates a view into the original array. This is an optimization to avoid copying. If you want a copy, do svary = npary.copy() Christian From pjfarley3 at earthlink.net Thu Nov 26 13:08:37 2020 From: pjfarley3 at earthlink.net (pjfarley3 at earthlink.net) Date: Thu, 26 Nov 2020 13:08:37 -0500 Subject: Why can't numpy array be restored to saved value? In-Reply-To: References: <000001d6c2f6$e9a0ef30$bce2cd90$@earthlink.net> Message-ID: <005101d6c41f$29b36020$7d1a2060$@earthlink.net> > -----Original Message----- > From: Greg Ewing > Sent: Thursday, November 26, 2020 12:01 AM > To: python-list at python.org > Subject: Re: Why can't numpy array be restored to saved value? > > On 25/11/20 7:47 pm, pjfarley3 at earthlink.net wrote: > > Why isn't the final value of the numpy array npary in the following code the > > same as the initial value before some but not all elements of the array were > > changed to a new value? > > Slicing a numpy array doesn't copy anything, it just > gives you another view of the underlying data. > > This is a trap you need to watch out for, since it's > different from the way sequences normally behave in > Python. > > -- > Greg Thank you for that explanation. I will certainly watch out for it in the future. Peter From pjfarley3 at earthlink.net Thu Nov 26 13:10:48 2020 From: pjfarley3 at earthlink.net (pjfarley3 at earthlink.net) Date: Thu, 26 Nov 2020 13:10:48 -0500 Subject: Why can't numpy array be restored to saved value? In-Reply-To: References: <000001d6c2f6$e9a0ef30$bce2cd90$@earthlink.net> Message-ID: <005201d6c41f$78003c80$6800b580$@earthlink.net> > -----Original Message----- > From: Christian Gollwitzer > Sent: Thursday, November 26, 2020 3:26 AM > To: python-list at python.org > Subject: Re: Why can't numpy array be restored to saved value? > > Am 25.11.20 um 07:47 schrieb pjfarley3 at earthlink.net: > > Why isn't the final value of the numpy array npary in the following code the > > same as the initial value before some but not all elements of the array were > > changed to a new value? > > > > I know I am missing something basic here. I thought I understood the > > concepts of immutable vs mutable values but obviously I missed something. > > > > Because this does not copy the array, rather it creates a view into the > original array. This is an optimization to avoid copying. If you want a > copy, do svary = npary.copy() Thank you for the explanation. I did indeed find that using the copy() function did what I needed to do. Peter From lukasz at langa.pl Thu Nov 26 17:53:48 2020 From: lukasz at langa.pl (=?utf-8?Q?=C5=81ukasz_Langa?=) Date: Thu, 26 Nov 2020 23:53:48 +0100 Subject: [RELEASE] Python 3.9.1rc1 is now ready for testing Message-ID: Python 3.9.1rc1 is the release candidate of the first maintenance release of Python 3.9. Go get it here: https://www.python.org/downloads/release/python-391rc1/ Assuming no critical problems are found prior to 2020-12-11, the currently scheduled release date for 3.9.1, no code changes are planned between this release candidate and the final release. That being said, please keep in mind that this is a pre-release of 3.9.1 and as such its main purpose is testing. Maintenance releases for the 3.9 series will continue at regular bi-monthly intervals, with 3.9.2 planned for end of January 2021. Installer news 3.9.1rc1 is the first version of Python to support macOS 11 Big Sur. With Xcode 11 and later it is now possible to build ?Universal 2? binaries which work on Apple Silicon. We are providing such an installer as the macosx11.0 variant. This installer can be deployed back to older versions, tested down to OS X 10.9. As we are waiting for an updated version of pip, please consider the macosx11.0 installer experimental. This work would not have been possible without the effort of Ronald Oussoren, Ned Deily, and Lawrence D?Anna from Apple. Thank you! In other news, this is the first version of Python to default to the 64-bit installer on Windows. The installer now also actively disallows installation on Windows 7. Python 3.9 is incompatible with this unsupported version of Windows. What?s new in Python 3.9.1rc1? We?ve made 240 changes since v3.9.0 which is a significant amount. To compare, 3.8.1rc1 only saw 168 commits since 3.8.0. See the full change log at https://docs.python.org/release/3.9.1rc1/whatsnew/changelog.html . For more information about features included in the 3.9 series, see the ?What?s New in Python 3.9 ? document. What about Python 3.8.7rc1? There?s additional work needed to make this release support macOS 11 Big Sur. This should be ready next week, stay tuned. We hope you enjoy the new releases! Thanks to all of the many volunteers who help make Python Development and these releases possible! Please consider supporting our efforts by volunteering yourself or through organization contributions to the Python Software Foundation. https://www.python.org/psf/ More resources Online Documentation PEP 596 , 3.9 Release Schedule PEP 619 , 3.10 Release Schedule Report bugs at https://bugs.python.org . Help fund Python and its community . Your friendly release team, Ned Deily @nad Steve Dower @steve.dower ?ukasz Langa @ambv From loris.bennett at fu-berlin.de Fri Nov 27 11:42:26 2020 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Fri, 27 Nov 2020 17:42:26 +0100 Subject: Dispatch table of methods with various return value types References: <87lff0icgl.fsf@hornfels.zedat.fu-berlin.de> <87d00ci83i.fsf@hornfels.zedat.fu-berlin.de> <5d0f0715-91db-8586-e77f-ca7158a504af@DancesWithMice.info> <878sayu7tu.fsf@hornfels.zedat.fu-berlin.de> <0ffe7b55-36aa-718c-8cfe-11fe36c16ee1@DancesWithMice.info> Message-ID: <87zh32ycnh.fsf@hornfels.zedat.fu-berlin.de> dn writes: > On 19/11/2020 02:13, Loris Bennett wrote: >> dn writes: >> >> Firsty, thanks for taking the time to write such a detailed reply. > > Bitte! > > >>>>>> I have a method for manipulating the membership of groups such as: >>>>>> >>>>>> def execute(self, operation, users, group): >>>>>> """ >>>>>> Perform the given operation on the users with respect to the >>>>>> group >>>>>> """ >>>>>> >>>>>> action = { >>>>>> 'get': self.get, >>>>>> 'add': self.add, >>>>>> 'delete': self.delete, >>>>>> } >>>>>> >>>>>> return action.get(operation)(users, group) >>>>>> >>>>>> The 'get' action would return, say, a dict of users attribute, whereas >>>>>> the 'add/delete' actions would return, say, nothing, and all actions >>>>>> could raise an exception if something goes wrong. >>>>>> >>>>>> The method which calls 'execute' has to print something to the terminal, >>>>>> such as the attributes in the case of 'get' and 'OK' in the cases of >>>>>> 'add/delete' (assuming no exception occurred). >>>>>> >>>>>> Is there a canonical way of dealing with a method which returns different >>>>>> types of data, or should I just make all actions return the same data >>>>>> structure so that I can generate a generic response? >>>>> >>>>> >>>>> Is the problem caused by coding the first step before thinking of the overall >>>>> task? Try diagramming or pseudo-coding the complete solution (with multiple >>>>> approaches), ie the operations AND the printing and exception-handling. >>>> >>>> You could have a point, although I do have a reasonable idea of what the >>>> task is and coming from a Perl background, Python always feels a bit >>>> like pseudocode anyway (which is one of the things I like about Python). >>> >>> +1 the ease of Python, but can this be seductive? >>> >>> Per the comment about Perl/Python experience, the operative part is the >>> "thinking", not the tool - as revealed in responses below... >>> >>> Sometimes we design one 'solution' to a problem, and forget (or 'brainwash' >>> ourselves into thinking) that there might be 'another way'. >>> >>> It may/not apply in this case, but adjusting from a diagram-first methodology, >>> to the habit of 'jumping straight into code' exhibited by many colleagues, >>> before readjusting back to (hopefully) a better balance; I felt that >>> coding-first often caused me to 'paint myself into a corner' with some >>> 'solutions, by being too-close to the code and not 'stepping back' to take a >>> wider view of the design - but enough about me... >>> >>> >>>>> Might it be more appropriate to complete not only the get but also its >>>>> reporting, as a unit. Similarly the add and whatever happens after that; and the >>>>> delete, likewise. >>>> >>>> Currently I am already obtaining the result and doing the reporting in >>>> one method, but that makes it difficult to write tests, since it >>>> violates the idea that one method should, in general, just do one thing. >>>> That separation would seem appropriate here, since testing whether a >>>> data set is correctly retrieved from a database seems to be >>>> significantly different to testing whether the >>>> reporting of an action is correctly laid out and free of typos. >>> >>> SRP = design thinking! +1 >> >> I knew the idea, but I didn't now the TLA for it ;-) > > Yes, there are plenty of those! > > You may be interested in reading about "Clean Code", instigated (IIRC) by "Uncle > Bob" (Robert Martin). NB Python may/not be used for book-examples. Just the > other day I came across "Clean Code in Python", Mariano Anaya, PacktPub, 2018. I > have yet to read it, but the contents page seemed to 'tick all the boxes'. The > book is two years old, and IIRC he presented at EuroPython a few years before > that (YouTube videos on-line - in case you prefer that medium, or want to gain a > flavor before spending money...). All of these TLAs, and others comprising the > "SOLID Principles" appear in the ToC, along with plenty of others, eg YAGNI and > EAFP; plus some specific to Python, eg MRO. I had a look at the Europython 2016 video and found it very instructive. I'm a not very familiar with using exceptions, but when I have tried to use them, its seems to have generated a lot of code clutter. The approach shown in the video seems to be an elegant solution for certain category of exception handling code repetition. >>> TDD = early testing! +1 >>> >>> Agreed: The tasks are definitely separate. The first is data-related. The second >>> is about presentation. >>> >>> In keeping with the SRP philosophy, keep the split of execution-flow into the >>> three (or more) functional-tasks by data-process, but turn each of those tasks >>> into two steps/routines. (once the reporting routine following "add" has been >>> coded, and it comes time to implement "delete", it may become possible to repeat >>> the pattern, and thus 're-use' the second-half...) >>> >>> Putting it more formally: as the second-half is effectively 'chosen' at the same >>> time as the first, is the reporting-routine "dependent" upon the data-processor? >>> >>> function get( self, ... ) >>> self.get_data() >>> self.present_data() >>> >>> function add( self, ... ) >>> self.add_data() >>> self.report_success_fail() >>> >>> ... >>> >>> Thus, the functional task can be tested independently of any reporting follow-up >>> (for example in "get"); whilst maintaining/multiplying SRP... >> >> The above approach appeals to me a lot. Slight downsides are that >> such 'metafunctions' by necessity non-SRP functions and that, as there >> would be no point writing tests for such functions, some tools which try >> to determine test coverage might moan. > > First comes (Python) 'duty': the word "meta", perhaps more in the context of > "meta-classes" has particular meaning in Python, that may not align with > expectations generated by understanding the term "meta" in other contexts! OK, thanks for pointing that out. > Second, we return to earlier comments about up-front design. Consider "Stepwise > Decomposition" (https://en.wikipedia.org/wiki/Top-down_and_bottom-up_design) and > how solving a 'large problem' is likened to pealing an onion, ie one 'layer' at > a time. Thus there is a sub-problem, eg report on xyz; this divides into smaller > problems: (i) from where do I find the data on xyz, and (ii) how do I present > this. > > If you code top-down, then it may be that there are three subroutines (functions > in Python) which implement the three of these. Further, that only the two > "smaller" routines appear to be doing any 'work'. However, remember that the > function names both document the solution and reproduce the specification. Thus > three well-chosen names will add value and ease understanding for you/us, six > months later... > > If you code bottom-up and have TDD-built the two "smaller" functions, then > adding the 'higher' function as an 'umbrella' will tie them together - for the > reasons/results mentioned above. My programs are fairly small, so there isn't much between the top and the bottom - probably a maximum of five calls. In fact, if calls did get much deeper, I would think about farming some of the code out to a separate module, if possible. > There are different types of testing. Unit testing is straightforward with > pytest or similar. This takes care of tests such as 'did "get" realise the > correct data?' and 'after "delete" does this data exist?'. These are likely > tests of functions at the lowest and/or lower levels of the implementation - > hence the name. > > When it comes to reporting, life becomes more complicated. Whereas pytest will > capture and allow testing of sysout, when we move to Qt, gtk, or some other UI > took-kit, we need to find a compatible testing tool. If presentation is HTML, > then web-page testing is accomplished with the likes of Selenium. Luckily I just have to deal with console output. > If we are talking UX (User Experience) testing, then the information-presented > is almost-irrelevant. If you have a user on the dev.team (see also Agile teams), > then (s)he will perform such 'testing' manually (and give rapid feedback). Thus, > no tool required, as such. As I am the main user, I usually give myself fairly rapid feedback ;-) > NB If you are concerned about the actual information being presented, surely > that will have already been tested as accurate by the unit test mentioned > earlier? This is true. Although obviously, if the information is correct, but somehow mangled by the presentation, that a problem. I have more than once shot myself in the foot by, say, getting a correct value of zero indicating success, but mistakenly converting this into the string indicating failure. > Regarding the comment about "moan[ing]" tools. Who's in-charge here? When it is > helping you it is a "tool". What is something that is getting in your way, > causing you frustration, or otherwise interfering with your happiness and > productivity? > > Pointy-headed managers [a reference to the Dilbert cartoons] have often tried to > create/impose 'rules' on developers. One of my favorites is: "there will be at > least one comment for every ten lines of code". Do you need to strain-the-brain > to know what happens? > > # this code has a comment > ... > > # add one to x > x += 1 > > I'm afraid the idea of 100% code-coverage is a nirvana that is probably not > worth seeking. See also @Ned's comments (about his own coverage.py tool) > https://nedbatchelder.com/blog/200710/flaws_in_coverage_measurement.html > > The car's speedo might tell you that it can motor-along at some incredible > speed, but using the information sensibly might attract less attention from the > Highway Patrol! You're right, of course, but as I am my own pointy-headed boss, as far as setting development rules goes, I don't have to worry about coverage too much. However, as I code fairly sporadically, it is a useful metric to check how well I am doing with my self-set TDD goal. >>>>> Otherwise the code must first decide which action-handler, and later, >>>>> which result-handler - but aren't they effectively the same decision? >>>>> Thus, is the reporting integral to the get (even if they are in >>>>> separate routines)? >>>> >>>> I think you are right here. Perhaps I should just ditch the dispatch >>>> table. Maybe that only really makes sense if the methods being >>>> dispatched are indeed more similar. Since I don't anticipate having >>>> more than half a dozen actions, if that, so an if-elif-else chain >>>> wouldn't be too clunky. >>> >>> An if...elif...else 'ladder' is logically-easy to read, but with many choices it >>> may become logistically-complicated - even too long to display at-once on a >>> single screen. >>> >>> Whereas, the table is a more complex solution (see 'Zen of Python') that only >>> becomes 'simple' with practice. >>> >>> So, now we must balance the 'level(s)' of the team likely to maintain the >>> program(me) against the evaluation of simple~complex. Someone with a ComSc >>> background will have no trouble coping with the table - and once Python's >>> concepts of dictionaries and functions as 'first-class objects' are understood, >>> will take to it like the proverbial "duck to water". Whereas, someone else may >>> end-up scratching his/her head trying to cope with 'all the above'. >> >> The team? L'?quipe, c'est moi :-) Having said that I do try to program >> not only with my fictitious replacement in mind, should I be hit by the >> proverbial bus, but also my future self, and so tend to err on the side >> of 'simple'. > > +1 "simple" > +1 "ego-less programming" > > German, English, and now French? That's by country of residence, birth, and almost forgotten schooling. >>> Given that Python does not (yet) have a switch/case construct, does the table >>> idea assume a greater importance? Could it be (reasonably) expected that >>> pythonista will understand such more readily? >>> >>> >>> IMHO the table is easier to maintain - particularly 'six months later', but >>> likely 'appears' as a 'natural effect' of re-factoring*, once I've implemented >>> the beginnings of an if-ladder and 'found' some of those common follow-up >>> functions. >>> * although, like you, I may well 'see' it at the design-stage, particularly if >>> there are a number (more) cases to implement! >>> >>> Is functional "similar"[ity] (as above) the most-appropriate metric? What about >>> the number of decision-points in the code? (ie please re-consider "effectively >>> the same decision") >>> >>> # which data-function to execute? >>> if action==get >>> do get_data >>> elif action == add >>> do add_data >>> elif ... >>> >>> ... >>> >>> # now 'the work' has been done, what is the follow-through? >>> if action=get >>> do present_data >>> elif action == add >>> report success/fail >>> ... >> >> In my current case this is there is a one-to-one relationship between >> the 'work' and the 'follow-through', so this approach doesn't seem that >> appealing to me. However I have other cases in which the data to be >> displayed comes from multiple sources where the structure above might >> be a good fit. > > I hope to have addressed this above. > > To help (I hope), consider if, in the proverbial six-months time, you are asked > to add logging to each of these various actions. Now, there are three tasks: > 'work', 'follow-through', and 'logging'; to be done for each of the n-action > choices. > > Would an 'umbrella function' which acts as both the single destination for an > action-choice, and as a 'distributor' for the various specific tasks that must > be executed, start to appear more viable? > > >> Having said that, I do prefer the idea of having a single jumping off >> point, be it a dispatch table or a single if-then-else ladder, which >> reflects the actions which the user can take and where the unpleasant >> details of, say, how the data are gathered are deferred to a lower level >> of the code. > > +1 > > >>> Back to the comment about maintainability - is there a risk that an extension >>> requested in six months' time will tempt the coding of a new "do" function AND >>> induce failure to notice that there must be a corresponding additional function >>> in the second 'ladder'? >>> >>> This becomes worse if we re-factor to re-use/share some of the follow-throughs, >>> eg >>> >>> ... >>> elif action in [ add, delete, update] >>> report success/fail >>> ... >>> >>> because, at first glance, the second 'ladder' appears to be quite dissimilar - >>> is a different length, doesn't have the condition-clause symmetry of the first, >>> etc! So, our fictional maintainer can ignore the second, correct??? >>> >>> Consider SRP again, and add DRY: should the "despatch" decision be made once, or >>> twice, or... ? >> >> With my non-fictional-maintainer-cum-six-month-older-self hat on I think >> you have made a good case for the dispatch table, which is my latent >> preference anyway, especially in connection with the 'do/display' >> metafunctions and the fact that in my current case DRY implies that the >> dispatch decision should only be made once. > > +1 Definitely! > > > See also @Wulfraed's point about OOP (Object-Oriented Programming)! If we were > talking about people, then I'd expect to find a class Person, or similar, in the > code. That means that "get" and "delete" might refer to database > transactions. Hence, they should be part of the Person class, rather than > functions 'in the wild'. Thus, where we have used the term "function" (or even > "subroutine"), we should have said "method". A class is a (very good) way to > 'collect' related functionality and keep it 'together'! > > > Another aspect, following-on from UI comments (above). If you are using a > framework, the presentation code will largely fit within those > objects. Therefore, logically-separate from manipulating the > source-object. Another consideration (maybe) for how to structure and relate the > routines... > > As a general rule, I keep print() out of functions which 'calculate' - > even, out of the Person class. This facilitates re-use, where the next use may > want to present the results differently, or merely to use the calculation as > 'input' and not present 'it' at all! > > >> Thanks again for the input! > > It is good that you are reviewing your code and considering alternate > approaches! Many others 'here' will have benefited from considering your > points/questions... > > > You may like to pass some information about the Free University: > - is Python the primary teaching language I don't know. It probably depends quite a bit on the subject. > - is Python widely used within various schools/departments Anyone doing ML, which these days seems to be everyone, tends to use Python because of torch. People doing genomics seem to like it too. > - is instruction in English, or... Mainly German, for undergrads. In the Sciences, which is were most of my contacts are, some of the Master's students and quite a few of people doing doctorates seem to mainly speak English > - what does "Free" mean The implication is that it is ideologically free. The university was founded in 1948 in the context of Berlin being divided into different sectors after WWII. The old Berlin University (of Einstein and Planck fame) was in the Soviet sector, so a new university was set up in the western part of the city in the American sector. > - is it also $free All state universities in Germany are $free. You might have to pay for some exotic Master's courses, particularly if they are in English. > - is it open to (non-German) foreigners Yes. > Tsch?ss! A presto! ;-) From shahiquzzama at gmail.com Fri Nov 27 07:33:28 2020 From: shahiquzzama at gmail.com (Shahique Khan) Date: Fri, 27 Nov 2020 18:03:28 +0530 Subject: Regarding Regex timeout behavior to minimize CPU consumption In-Reply-To: References: Message-ID: Hi Team, I have noticed if our regex sometimes does not give a result and on that time regex took more time in returning response (empty response). My Question is can we set a timeout parameter (in seconds/millisecond) with re.find or anywhere in code to avoid CPU consumption if regex takes more time in execution. Below is the example, which take more time in execution: (in this case can we set timeout to kill the execution to avoid CPU consumption) regex = r'data-stid="section-room-list"[\s\S]*?>\s*([\s\S]*?)\s*' \ r'(?:class\s*=\s*"\s*sticky-book-now\s*"|\s*|id\s*=\s*"Location")' rooms_blocks_to_be_replace = re.findall(regex, html_template) Please help me, I will be very thankful for this. Thanks, From darcy at VybeNetworks.com Fri Nov 27 14:37:52 2020 From: darcy at VybeNetworks.com (D'Arcy Cain) Date: Fri, 27 Nov 2020 15:37:52 -0400 Subject: Cannot marshal objects Message-ID: <86cb8d03-b591-6d99-919a-e9c6fc65c9bf@VybeNetworks.com> I am getting this error. I found this recipe to fix it: from xmlrpclib import Marshaller from decimal import Decimal def dump_decimal(self, value, write): write("") write(str(value)) write("\n") Marshaller.dispatch[Decimal] = dump_decimal That seems to be for Python 2. I am running Python 3.5 (I know but I am stuck there for the moment). I tried changing the import to "from xmlrpcl.client import Marshaller" which didn't raise an error but the problem still persists. Do I need to do something different for Python 3? TIA. -- D'Arcy J.M. Cain Vybe Networks Inc. A unit of Excelsior Solutions Corporation - Propelling Business Forward http://www.VybeNetworks.com/ IM:darcy at VybeNetworks.com VoIP: sip:darcy at VybeNetworks.com -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 236 bytes Desc: OpenPGP digital signature URL: From lthug2652 at gmail.com Fri Nov 27 14:54:29 2020 From: lthug2652 at gmail.com (SONAHI) Date: Sat, 28 Nov 2020 02:54:29 +0700 Subject: Why I always have invalid error when using "pip install matplotlib" in Python 3.9 Message-ID: <6F7DD4E2-0CAC-4105-B447-8FF1F4B9BC5A@hxcore.ol> ? ? Sent from [1]Mail for Windows 10 ? References Visible links 1. https://go.microsoft.com/fwlink/?LinkId=550986 From skip.montanaro at gmail.com Fri Nov 27 15:05:11 2020 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Fri, 27 Nov 2020 14:05:11 -0600 Subject: Cannot marshal objects In-Reply-To: <86cb8d03-b591-6d99-919a-e9c6fc65c9bf@VybeNetworks.com> References: <86cb8d03-b591-6d99-919a-e9c6fc65c9bf@VybeNetworks.com> Message-ID: > I am getting this error. I assume you mean the email subject. It doesn't work in 3.8 either: >>> import decimal >>> d = decimal.Decimal(3.5) >>> d Decimal('3.5') >>> import marshal >>> marshal.dumps(d) Traceback (most recent call last): File "", line 1, in ValueError: unmarshallable object but that's not surprising to me. The marshal module is more-or-less meant to serialize Python byte code. Pickle is more generally used for object serialization. Why not use it? >>> import pickle, decimal >>> d = decimal.Decimal(3.5) >>> pickle.dumps(d) b'\x80\x04\x95!\x00\x00\x00\x00\x00\x00\x00\x8c\x07decimal\x94\x8c\x07Decimal\x94\x93\x94\x8c\x033.5\x94\x85\x94R\x94.' That's meant more for serialization of data objects. Skip From PythonList at DancesWithMice.info Fri Nov 27 15:41:16 2020 From: PythonList at DancesWithMice.info (dn) Date: Sat, 28 Nov 2020 09:41:16 +1300 Subject: Environment vars In-Reply-To: References: Message-ID: <81289f59-9e66-034a-47f0-1a34859326c7@DancesWithMice.info> On 26/11/2020 05:46, Bob van der Poel wrote: > I've got a program which accepts an optional env variable listing a single > or multiple directory for the app to use. I've done a bit of a search and > see both a comma and semicolon being used/suggested as a path separator. > Any consensus on which is better? Further to comments about some users expecting one option, whereas others may be thinking of another... Herewith an irreverent article from "ElReg". NB Do not read "The Register" unless you can cope with sardonic, British, humor; and especially if you do not believe that "confession is good for the soul"! It's always DNS, especially when a sysadmin makes a hash of their semicolons Remember the days when 'we made it up as we went along'? Richard Speed Mon 23 Nov 2020 // 08:15 UTC https://www.theregister.com/2020/11/23/who_me/ -- Regards =dn From bob at mellowood.ca Fri Nov 27 16:13:51 2020 From: bob at mellowood.ca (Bob van der Poel) Date: Fri, 27 Nov 2020 14:13:51 -0700 Subject: Environment vars In-Reply-To: <81289f59-9e66-034a-47f0-1a34859326c7@DancesWithMice.info> References: <81289f59-9e66-034a-47f0-1a34859326c7@DancesWithMice.info> Message-ID: On Fri, Nov 27, 2020 at 1:41 PM dn via Python-list wrote: > On 26/11/2020 05:46, Bob van der Poel wrote: > > I've got a program which accepts an optional env variable listing a > single > > or multiple directory for the app to use. I've done a bit of a search and > > see both a comma and semicolon being used/suggested as a path separator. > > Any consensus on which is better? > > > Further to comments about some users expecting one option, whereas > others may be thinking of another... > > > Herewith an irreverent article from "ElReg". > > NB Do not read "The Register" unless you can cope with sardonic, > British, humor; and especially if you do not believe that "confession is > good for the soul"! > > It's always DNS, especially when a sysadmin makes a hash of their > semicolons > Remember the days when 'we made it up as we went along'? > Richard Speed Mon 23 Nov 2020 // 08:15 UTC > https://www.theregister.com/2020/11/23/who_me/ > -- > Regards =dn > -- > https://mail.python.org/mailman/listinfo/python-list > This article clearly represents things which could go wrong in the good old days. Those days are gone forever and things like that could never go wrong today :) From darcy at VybeNetworks.com Fri Nov 27 17:02:53 2020 From: darcy at VybeNetworks.com (D'Arcy Cain) Date: Fri, 27 Nov 2020 18:02:53 -0400 Subject: Cannot marshal objects In-Reply-To: References: <86cb8d03-b591-6d99-919a-e9c6fc65c9bf@VybeNetworks.com> Message-ID: <05f71825-a46a-198b-9bfc-1858117c8211@VybeNetworks.com> On 11/27/20 4:05 PM, Skip Montanaro wrote: >> I am getting this error. > > I assume you mean the email subject. It doesn't work in 3.8 either: Yes I do and that's too bad. > but that's not surprising to me. The marshal module is more-or-less > meant to serialize Python byte code. Pickle is more generally used for > object serialization. Why not use it? Because the marshaling is happening in the guts of xmlrpc. I may have solved it anyway. The code I was running was spitting out that error but I think it was actually happening in the server that it was connecting to. I just added that same code to the server. Have to wait until Monday to test. I will update the list if it fixes it. -- D'Arcy J.M. Cain Vybe Networks Inc. A unit of Excelsior Solutions Corporation - Propelling Business Forward http://www.VybeNetworks.com/ IM:darcy at VybeNetworks.com VoIP: sip:darcy at VybeNetworks.com -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 236 bytes Desc: OpenPGP digital signature URL: From jsf80238 at gmail.com Fri Nov 27 18:05:42 2020 From: jsf80238 at gmail.com (Jason Friedman) Date: Fri, 27 Nov 2020 16:05:42 -0700 Subject: try/except in loop Message-ID: I'm using the Box API (https://developer.box.com/guides/tooling/sdks/python/). I can get an access token, though it expires after a certain amount of time. My plan is to store the access token on the filesystem and use it until it expires, then fetch a new one. In the example below assume I have an expired access token. # This next line does not throw an error: client.folder('0').get_items() # But iteration does (maybe this is a lazy fetch?) for _ in client.folder('0').get_items(): logger.debug("Using existing access token.") return access_token # So I use try/except try: for _ in client.folder('0').get_items(): logger.debug("Using existing access token.") return access_token except boxsdk.exception.BoxAPIException: pass # access token invalid, let's get one else: pass # access token invalid, let's get one # When running the debugger the except clause seems to catch the first throw, but the loop I think continues, throws the error again, and that second throw is not caught. From skip.montanaro at gmail.com Fri Nov 27 18:28:26 2020 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Fri, 27 Nov 2020 17:28:26 -0600 Subject: Cannot marshal objects In-Reply-To: <05f71825-a46a-198b-9bfc-1858117c8211@VybeNetworks.com> References: <86cb8d03-b591-6d99-919a-e9c6fc65c9bf@VybeNetworks.com> <05f71825-a46a-198b-9bfc-1858117c8211@VybeNetworks.com> Message-ID: > Because the marshaling is happening in the guts of xmlrpc. Okay, I misunderstood your original message. You used the word "marshal" (and the xmlrpc error did as well). I thought you were referring to the marshal module. I didn't understand (and ignored) the references to the xmlrpc module. In Python 3, the Marshaller class has migrated into the xmlrpc.client module. Your code worked for me in 3.8. Note, however, that this is not going to round trip properly. You will stuff in a Decimal object at one end and get out a double at the other end. Recent versions support unmarshalling to Decimal objects in the Unmarshaller class. I don't know why the Marshaller class doesn't accept Decimal objects for serialization. You could try this: def dump_decimal(self, value, write): write("") write(str(value)) write("\n") xmlrpc.client.Marshaller.dispatch[decimal.Decimal] = dump_decimal I used the "ex:" prefix based on this document: http://ws.apache.org/xmlrpc/types.html YMMV. The tag name understood by the Unmarshaller class doesn't include that prefix. Skip From bgailer at gmail.com Fri Nov 27 18:39:26 2020 From: bgailer at gmail.com (Bob Gailer) Date: Fri, 27 Nov 2020 18:39:26 -0500 Subject: try/except in loop In-Reply-To: References: Message-ID: On Fri, Nov 27, 2020, 6:06 PM Jason Friedman wrote: > I'm using the Box API ( > https://developer.box.com/guides/tooling/sdks/python/). > I can get an access token, though it expires after a certain amount of > time. My plan is to store the access token on the filesystem and use it > until it expires, then fetch a new one. In the example below assume I have > an expired access token. > > > # This next line does not throw an error: > > client.folder('0').get_items() > > > # But iteration does (maybe this is a lazy fetch?) > > for _ in client.folder('0').get_items(): > > logger.debug("Using existing access token.") > > return access_token > > > # So I use try/except > > try: > > for _ in client.folder('0').get_items(): > > logger.debug("Using existing access token.") > > return access_token > > except boxsdk.exception.BoxAPIException: > > pass # access token invalid, let's get one > > else: > > pass # access token invalid, let's get one > > > # When running the debugger the except clause seems to catch the first > throw, but the loop I think continues, throws the error again, and that > second throw is not caught. > It would appear that get items is a generator which uses the token exactly once when it is first started; subsequent calls to the generator all use the same token. You need to test the token; if it fails, obtain a new one, then start the loop. Bob Gailer > From jsf80238 at gmail.com Fri Nov 27 20:39:49 2020 From: jsf80238 at gmail.com (Jason Friedman) Date: Fri, 27 Nov 2020 18:39:49 -0700 Subject: try/except in loop In-Reply-To: References: Message-ID: > > >> I'm using the Box API ( >> https://developer.box.com/guides/tooling/sdks/python/). >> I can get an access token, though it expires after a certain amount of >> time. My plan is to store the access token on the filesystem and use it >> until it expires, then fetch a new one. In the example below assume I have >> an expired access token. >> >> # This next line does not throw an error: >> client.folder('0').get_items() >> >> # But iteration does (maybe this is a lazy fetch?) >> for _ in client.folder('0').get_items(): >> logger.debug("Using existing access token.") >> return access_token >> >> # So I use try/except >> try: >> for _ in client.folder('0').get_items(): >> logger.debug("Using existing access token.") >> return access_token >> except boxsdk.exception.BoxAPIException: >> pass # access token invalid, let's get one >> else: >> pass # access token invalid, let's get one >> >> # When running the debugger the except clause seems to catch the first >> throw, but the loop I think continues, throws the error again, and that >> second throw is not caught. >> > > It would appear that get items is a generator which uses the token exactly > once when it is first started; subsequent calls to the generator all use > the same token. You need to test the token; if it fails, > obtain a new one, then start the loop. > # Here's the solution I came up with: try: list(client.folder('0').get_items()) logger.debug("Using existing access token.") return access_token except boxsdk.exception.BoxAPIException: pass # access token invalid, let's get one # And for those who happen to be using the Box API, this command avoids all that and is less expensive: try: client.user().get() logger.debug("Using existing access token.") return access_token except boxsdk.exception.BoxAPIException: pass # access token invalid, let's get one From cs at cskk.id.au Fri Nov 27 21:06:02 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Sat, 28 Nov 2020 13:06:02 +1100 Subject: try/except in loop In-Reply-To: References: Message-ID: <20201128020602.GA49738@cskk.homeip.net> I had to do this with a different API the toehr year, and made this method: def auth_token(self): ''' Obtain a current auth token [...] Refreshes the cached token if stale. ''' while True: with self._auth_token_lock: token = self._auth_token if (token and token.timestamp + FM_TOKEN_LIFESPAN - FM_TOKEN_LIFESPAN_SKEW > time.time()): break try: token = self._get_new_auth_token() except Exception as e: error("error fetching token: %s", e) else: if token: self._auth_token = token break error("token not refreshed, delay then retry") time.sleep(self.DEFAULT_RETRY_DELAY) return token The "while True" bit was because the server was flakey and sometime you just had to wait for it to come back. Then I just called this to obtain a current token whenever I needed a token. in the API, for example: headers = {'Authorization': 'Bearer ' + self.auth_token().token} Means you don't have to embed verbose checks all through your code - just grab "the token" and proceeed. Cheers, Cameron Simpson From jsf80238 at gmail.com Fri Nov 27 23:32:17 2020 From: jsf80238 at gmail.com (Jason Friedman) Date: Fri, 27 Nov 2020 21:32:17 -0700 Subject: filtering out warnings Message-ID: The Box API is noisy ... very helpful for diagnosing, and yet for production code I'd like less noise. I tried this: warnings.filterwarnings( action='ignore', # category=Warning, # module=r'boxsdk.*' ) but I still see this: WARNING:boxsdk.network.default_network:"POST https://api.box.com/oauth2/token" 400 83 {'Date': 'Sat, 28 Nov 2020 04:30:03 GMT', 'Content-Type': 'application/json', 'Transfer-Encoding': 'chunked', 'Connection': 'keep-alive', 'Strict-Transport-Security': 'max-age=31536000', 'Set-Cookie': 'box_visitor_id=5fc1d24b134ce6.76522820; expires=Sun, 28-Nov-2021 04:30:03 GMT; Max-Age=31536000; path=/; domain=.box.com; secure, bv=OPS-44131; expires=Sat, 05-Dec-2020 04:30:03 GMT; Max-Age=604800; path=/; domain=.app.box.com; secure, cn=87; expires=Sun, 28-Nov-2021 04:30:03 GMT; Max-Age=31536000; path=/; domain=.app.box.com; secure, site_preference=desktop; path=/; domain=.box.com; secure', 'Cache-Control': 'no-store'} {'error': 'invalid_client', 'error_description': 'The client credentials are invalid'} My code as written I think should filter ALL warnings. I'll eventually want to restrict the filter to only warnings generated by the Box SDK. From mal at europython.eu Sat Nov 28 07:38:09 2020 From: mal at europython.eu (M.-A. Lemburg) Date: Sat, 28 Nov 2020 13:38:09 +0100 Subject: EuroPython videos all on archive.org Message-ID: <5966e762-d448-f389-a5d0-eb496dca509d@europython.eu> Over the last few weeks, Anthon van der Neut, our media work group chair for EP2015 and EP2016, put in a lot of effort into getting all our conference videos on archive.org, the Internet Archive. Archive.org is not meant as an alternative for YouTube to watch the videos, but it allows you to retrieve the original uploads, and as such also functions as a backup location for the us and the community. He first downloaded all videos from our YouTube account (over 2.5TB as of this writing), then enriched the meta data based on the talk information we have on the websites, fixed issues he found, and then uploaded the videos and meta data to our archive.org account. Overall, around 40 hours of work went into this. We now have more than 1000 conference videos available on our archive.org account, covering EP2014 - EP2020. * EuroPython videos on archive.org * https://archive.org/details/@europythonvideos Thanks, Anthon, for making this possible ! 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/636029350382387200/europython-videos-all-on-archiveorg Tweet: https://twitter.com/europython/status/1332661436632457216 Thanks, -- EuroPython 2021 Team https://www.europython-society.org/ From mystirk at gmail.com Sat Nov 28 08:15:52 2020 From: mystirk at gmail.com (Alex Kaye) Date: Sat, 28 Nov 2020 06:15:52 -0700 Subject: EuroPython videos all on archive.org In-Reply-To: <5966e762-d448-f389-a5d0-eb496dca509d@europython.eu> References: <5966e762-d448-f389-a5d0-eb496dca509d@europython.eu> Message-ID: Without volunteers, the world would end, abruptly ! Thanks, Alex On Sat, Nov 28, 2020 at 5:48 AM M.-A. Lemburg wrote: > Over the last few weeks, Anthon van der Neut, our media work group chair > for EP2015 and EP2016, put in a lot of effort into getting all our > conference videos on archive.org, the Internet Archive. > > Archive.org is not meant as an alternative for YouTube to watch the > videos, but it allows you to retrieve the original uploads, and as such > also functions as a backup location for the us and the community. > > He first downloaded all videos from our YouTube account (over 2.5TB as > of this writing), then enriched the meta data based on the talk > information we have on the websites, fixed issues he found, and then > uploaded the videos and meta data to our archive.org account. Overall, > around 40 hours of work went into this. > > We now have more than 1000 conference videos available on our > archive.org account, covering EP2014 - EP2020. > > > * EuroPython videos on archive.org * > > https://archive.org/details/@europythonvideos > > > Thanks, Anthon, for making this possible ! > > > 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/636029350382387200/europython-videos-all-on-archiveorg > > Tweet: > > https://twitter.com/europython/status/1332661436632457216 > > Thanks, > -- > EuroPython 2021 Team > https://www.europython-society.org/ > > -- > https://mail.python.org/mailman/listinfo/python-list > From thomasomea at gmail.com Sat Nov 28 10:59:58 2020 From: thomasomea at gmail.com (A. M. Thomas [PETech MIET MBA]) Date: Sat, 28 Nov 2020 18:59:58 +0300 Subject: series.py, cannot import series from pandas Message-ID: Kindly guide on how to solve this problem from Python3.9 with pycharm. See the below import numpy as np import pandas as pd from pandas import series object = series([5,10,15,20]) print (object) C:\Users\THOMAS\AppData\Local\Programs\Python\Python39\python.exe C:/Users/THOMAS/PycharmProjects/Example2/series.py Traceback (most recent call last): File "C:\Users\THOMAS\PycharmProjects\Example2\series.py", line 3, in from pandas import series ImportError: cannot import name 'series' from 'pandas' (C:\Users\THOMAS\AppData\Roaming\Python\Python39\site-packages\pandas\__init__.py) Process finished with exit code 1 -- Best Regards, *A. M. Thomas* Electrical & Solar Systems Expert *THE GUY BEHIND THE SCENE* Cell: +254 723 309 157 / +254 731 406 125 Email: thomasomea at gmail.com / thomaso.engineer at gmail.com "Alternative energy for real and sustainable development that we need" From python at mrabarnett.plus.com Sat Nov 28 13:22:40 2020 From: python at mrabarnett.plus.com (MRAB) Date: Sat, 28 Nov 2020 18:22:40 +0000 Subject: series.py, cannot import series from pandas In-Reply-To: References: Message-ID: <1acdbdb4-6dad-cf43-bb65-df89ddac8f1b@mrabarnett.plus.com> On 2020-11-28 15:59, A. M. Thomas [PETech MIET MBA] wrote: > Kindly guide on how to solve this problem from Python3.9 with pycharm. See > the below > > > import numpy as np > import pandas as pd > from pandas import series > object = series([5,10,15,20]) > print (object) > > > C:\Users\THOMAS\AppData\Local\Programs\Python\Python39\python.exe > C:/Users/THOMAS/PycharmProjects/Example2/series.py > Traceback (most recent call last): > File "C:\Users\THOMAS\PycharmProjects\Example2\series.py", line 3, in > > from pandas import series > ImportError: cannot import name 'series' from 'pandas' > (C:\Users\THOMAS\AppData\Roaming\Python\Python39\site-packages\pandas\__init__.py) > > Process finished with exit code 1 > A brief look at the documentation suggests that it should be "Series", not "series". From thomasomea at gmail.com Sat Nov 28 15:15:29 2020 From: thomasomea at gmail.com (A. M. Thomas [PETech MIET MBA]) Date: Sat, 28 Nov 2020 23:15:29 +0300 Subject: series.py, cannot import series from pandas In-Reply-To: <1acdbdb4-6dad-cf43-bb65-df89ddac8f1b@mrabarnett.plus.com> References: <1acdbdb4-6dad-cf43-bb65-df89ddac8f1b@mrabarnett.plus.com> Message-ID: Spot on!! Thank you very much, am back on track with your aid On Sat, Nov 28, 2020 at 9:23 PM MRAB wrote: > On 2020-11-28 15:59, A. M. Thomas [PETech MIET MBA] wrote: > > Kindly guide on how to solve this problem from Python3.9 with pycharm. > See > > the below > > > > > > import numpy as np > > import pandas as pd > > from pandas import series > > object = series([5,10,15,20]) > > print (object) > > > > > > C:\Users\THOMAS\AppData\Local\Programs\Python\Python39\python.exe > > C:/Users/THOMAS/PycharmProjects/Example2/series.py > > Traceback (most recent call last): > > File "C:\Users\THOMAS\PycharmProjects\Example2\series.py", line 3, in > > > > from pandas import series > > ImportError: cannot import name 'series' from 'pandas' > > > (C:\Users\THOMAS\AppData\Roaming\Python\Python39\site-packages\pandas\__init__.py) > > > > Process finished with exit code 1 > > > A brief look at the documentation suggests that it should be "Series", > not "series". > -- > https://mail.python.org/mailman/listinfo/python-list > -- Best Regards, *A. M. Thomas* Electrical & Solar Systems Expert *THE GUY BEHIND THE SCENE* Cell: +254 723 309 157 / +254 731 406 125 Email: thomasomea at gmail.com / thomaso.engineer at gmail.com "Alternative energy for real and sustainable development that we need" From shishaozhong at gmail.com Sat Nov 28 18:29:32 2020 From: shishaozhong at gmail.com (Shaozhong SHI) Date: Sat, 28 Nov 2020 23:29:32 +0000 Subject: ssl connection has been closed unexpectedly Message-ID: Hi, I keep getting the following error when I use engine = create_engine(logging in details to postgres) df.to_sql('table_name', and etc.) OperationalError: (psycopg2.OperationalError) SSL connection has been closed unexpectedly (Background on this error at: http://sqlalche.me/e/13/e3q8) OperationalError: (psycopg2.OperationalError) SSL connection has been closed unexpectedly Can anyone shed any light on this? Regards, David From a0019548 at airmail.net Sat Nov 28 18:28:50 2020 From: a0019548 at airmail.net (Larry Burford) Date: Sat, 28 Nov 2020 17:28:50 -0600 Subject: numpy problem (follow up) Message-ID: <3c63d39c-1e45-afd6-954b-7ffaef089e06@airmail.net> I have completed reloading Still getting the error msg for numpy Gentlemen/Ladies, new to visual studio new-ish to python (I hope this is more to do with python ...) ~5 yr old HP with 16 GB,? 1 TB,? W10 pro,? python 3.9.0,? VSCode 1.51.1,? 3 monitor desktop when trying to run the tutorial program standardplot.py I get a msg that says my numpy won't pass a sanity check due to a problem in the Win runtime reloading everything now Any ideas? Thanks, LB From shishaozhong at gmail.com Sat Nov 28 19:47:00 2020 From: shishaozhong at gmail.com (Shaozhong SHI) Date: Sun, 29 Nov 2020 00:47:00 +0000 Subject: How to record full error message for debugging with nbconvert? Message-ID: Hi, When I use nbconvert to run Jupyter notebook, it is so difficult to see the full error message for debugging? How to save full error messages? Regards, David From blakemalc66 at gmail.com Sat Nov 28 20:28:49 2020 From: blakemalc66 at gmail.com (Malcolm) Date: Sun, 29 Nov 2020 12:28:49 +1100 Subject: numpy problem (follow up) In-Reply-To: <3c63d39c-1e45-afd6-954b-7ffaef089e06@airmail.net> References: <3c63d39c-1e45-afd6-954b-7ffaef089e06@airmail.net> Message-ID: HI Just had the same problem. The solution that worked for me was ( pip uninstall numpy then pip install numpy==1.19.3 The latest update to windows has an error in the BLAS libray causing the error. its a known problem. hope this helps Malcolm On 29/11/2020 10:28 am, Larry Burford wrote: > ?? I have completed reloading > > ?? Still getting the error msg for numpy > > > > Gentlemen/Ladies, > > > > new to visual studio > > new-ish to python (I hope this is more to do with python ...) > > ~5 yr old HP with 16 GB,? 1 TB,? W10 pro,? python 3.9.0,? VSCode > 1.51.1,? 3 monitor desktop > > > when trying to run the tutorial program standardplot.py I get a msg > that says my numpy won't pass a sanity check due to a problem in the > Win runtime > > reloading everything now > > > Any ideas? > > > Thanks, LB From shishaozhong at gmail.com Sat Nov 28 21:29:28 2020 From: shishaozhong at gmail.com (Shaozhong SHI) Date: Sun, 29 Nov 2020 02:29:28 +0000 Subject: How to run Jupyter notebook in command line and get full error message? Message-ID: How to run Jupyter notebook in command line and get full error messages? My VPN keeps dropping and can not run Jupyter Notebook as it is. I started to use nbconvert in command line. But, when it stops due to error, I can not see where the error occurs. In order to make life easier for debugging, what is the best practice? Regards, David From urbangabo at gmail.com Sun Nov 29 02:56:13 2020 From: urbangabo at gmail.com (Gabor Urban) Date: Sun, 29 Nov 2020 08:56:13 +0100 Subject: A problem with opening a file Message-ID: Hi, I am facing an issue I was not able to solve yet. I have a class saving messages to a file. The relevant code is: ---- import OS import sys class MxClass: def __init__(self, fName, fMode,....): self.fileName = fName self.fileMode = fMode .... def writeMethod(self, message): data = open(self.fileName, self.fileMode) .... ---- Tests reveal: the class is instantiated correctly, other methods work perfect. The writeMethod raises a NameError opening the file "name 'open' is not defined " I am stuck here..... -- Urb?n G?bor Linux is like a wigwam: no Gates, no Windows and an Apache inside. From PythonList at DancesWithMice.info Sun Nov 29 03:43:44 2020 From: PythonList at DancesWithMice.info (dn) Date: Sun, 29 Nov 2020 21:43:44 +1300 Subject: A problem with opening a file In-Reply-To: References: Message-ID: On 29/11/2020 20:56, Gabor Urban wrote: > Hi, > > I am facing an issue I was not able to solve yet. I have a class saving > messages to a file. The relevant code is: > > ---- > > import OS if you're wanting the Python Standard Library, this should not be in upper-case > import sys are these two imports used elsewhere? > class MxClass: > > def __init__(self, fName, fMode,....): > self.fileName = fName > self.fileMode = fMode > .... names such as fName and writeMethod are valid Python, but won't pass PEP-8 conventions > def writeMethod(self, message): > data = open(self.fileName, self.fileMode) > .... > > ---- > > Tests reveal: the class is instantiated correctly, other methods work > perfect. The writeMethod raises a NameError opening the file > "name 'open' is not defined" > > I am stuck here..... Please review ALL of the code. Is an open() function defined somewhere? (which will "shadow" the built-in function) That said the description doesn't quite match. Please copy-paste the exact error messages because there's likely missing information... -- Regards =dn From skip.montanaro at gmail.com Sun Nov 29 07:07:29 2020 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Sun, 29 Nov 2020 06:07:29 -0600 Subject: How to run Jupyter notebook in command line and get full error message? In-Reply-To: References: Message-ID: > > My VPN keeps dropping and can not run Jupyter Notebook as it is. > You don't provide a lot of detail, but this seems similar to the kind of flaky networking we used to deal with in the Before Times. Simply connecting directly to a host over the Internet was often plagued by disconnects. For that we used screen(1). You don't mention your operating system. It's available for most/all Linux systems and Macs. If you're on Windows I imagine you could get it using WSL. Of course, I might be way off-base focusing on just the above statement from your post. If so, you might want to provide some more details about your problem. Skip From dieter at handshake.de Sun Nov 29 13:30:46 2020 From: dieter at handshake.de (Dieter Maurer) Date: Sun, 29 Nov 2020 19:30:46 +0100 Subject: ssl connection has been closed unexpectedly In-Reply-To: References: Message-ID: <24515.59606.791651.538799@ixdm.fritz.box> Shaozhong SHI wrote at 2020-11-28 23:29 +0000: >I keep getting the following error when I use engine = >create_engine(logging in details to postgres) >df.to_sql('table_name', and etc.) > > >OperationalError: (psycopg2.OperationalError) SSL connection has been >closed unexpectedly SSL works as follows: a "normal" connection is opened to the specified "communication port". After that, an "SSL handshake" sets up encryption for the following communication over the channel. In your case, the "SSL handshake" was aborted by the communication partner closing the connection. You might get errors like this if the connected "port" is not prepared for SSL connections. Check the Postgres server configuration and your connection parameters. It the specified communication port SSL aware? If so, look whether there is helpful information in the Postgres log file. From dieter at handshake.de Sun Nov 29 13:34:20 2020 From: dieter at handshake.de (Dieter Maurer) Date: Sun, 29 Nov 2020 19:34:20 +0100 Subject: A problem with opening a file In-Reply-To: References: Message-ID: <24515.59820.690332.433247@ixdm.fritz.box> Gabor Urban wrote at 2020-11-29 08:56 +0100: >I am facing an issue I was not able to solve yet. I have a class saving >messages to a file. The relevant code is: > >---- > >import OS >import sys > >class MxClass: > > def __init__(self, fName, fMode,....): > self.fileName = fName > self.fileMode = fMode > .... > > def writeMethod(self, message): > data = open(self.fileName, self.fileMode) > .... > >---- > >Tests reveal: the class is instantiated correctly, other methods work >perfect. The writeMethod raises a NameError opening the file >"name 'open' is not defined " "open" is a so called "built-in" function. In "normal" (i.e. not restricted) mode, it should be available. Are you sure, you operate in "normal" mode? Under Python 3, you could try to import "open" from the module "io". (Under Python 2, "file" is a synonym for "open"). From python at mrabarnett.plus.com Sun Nov 29 15:19:45 2020 From: python at mrabarnett.plus.com (MRAB) Date: Sun, 29 Nov 2020 20:19:45 +0000 Subject: numpy problem (follow up) In-Reply-To: References: <3c63d39c-1e45-afd6-954b-7ffaef089e06@airmail.net> Message-ID: <02078a21-b26d-d936-78ab-7ccbe7efa0c9@mrabarnett.plus.com> On 2020-11-29 18:33, Dennis Lee Bieber wrote: > On Sat, 28 Nov 2020 17:28:50 -0600, Larry Burford > declaimed the following: > >> >>when trying to run the tutorial program standardplot.py I get a msg that >>says my numpy won't pass a sanity check due to a problem in the Win runtime >> > > Wait for M$ to fix their runtime... Or try to install a non-official > numpy release (I haven't figured out where to get 1.19.3; PIP can't locate > it) > > https://github.com/int-brain-lab/iblenv/issues/111 > https://developercommunity.visualstudio.com/content/problem/1207405/fmod-after-an-update-to-windows-2004-is-causing-a.html > Really? I just did what Malcolm did (though with py): py -m pip uninstall numpy py -m pip install numpy==1.19.3 It worked for me! From blakemalc66 at gmail.com Sun Nov 29 15:30:23 2020 From: blakemalc66 at gmail.com (Malcolm) Date: Mon, 30 Nov 2020 07:30:23 +1100 Subject: numpy problem (follow up) In-Reply-To: <02078a21-b26d-d936-78ab-7ccbe7efa0c9@mrabarnett.plus.com> References: <3c63d39c-1e45-afd6-954b-7ffaef089e06@airmail.net> <02078a21-b26d-d936-78ab-7ccbe7efa0c9@mrabarnett.plus.com> Message-ID: Hi https://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy also has a numpy wheel 1.19.4+vanilla?cp39?cp39?win_amd64.whl "Vanilla is a minimal distribution, which does not include any optimized BLAS libray or C runtime DLLs." Have not tried this. cheers Malcolm On 30/11/2020 7:19 am, MRAB wrote: > On 2020-11-29 18:33, Dennis Lee Bieber wrote: >> On Sat, 28 Nov 2020 17:28:50 -0600, Larry Burford >> declaimed the following: >> >>> >>> when trying to run the tutorial program standardplot.py I get a msg >>> that says my numpy won't pass a sanity check due to a problem in the >>> Win runtime >>> >> >> ????Wait for M$ to fix their runtime... Or try to install a non-official >> numpy release (I haven't figured out where to get 1.19.3; PIP can't >> locate >> it) >> >> https://github.com/int-brain-lab/iblenv/issues/111 >> https://developercommunity.visualstudio.com/content/problem/1207405/fmod-after-an-update-to-windows-2004-is-causing-a.html >> >> > Really? > > I just did what Malcolm did (though with py): > > py -m pip uninstall numpy > py -m pip install numpy==1.19.3 > > It worked for me! From drsalists at gmail.com Sun Nov 29 16:29:02 2020 From: drsalists at gmail.com (Dan Stromberg) Date: Sun, 29 Nov 2020 13:29:02 -0800 Subject: ssl connection has been closed unexpectedly In-Reply-To: References: Message-ID: What happens if you execute this from a shell prompt on a system with openssl installed? openssl s_client -connect host.com:443 (replacing host.com with your server's hostname and 443 with your port of interest) On Sat, Nov 28, 2020 at 3:30 PM Shaozhong SHI wrote: > Hi, > > I keep getting the following error when I use engine = > create_engine(logging in details to postgres) > df.to_sql('table_name', and etc.) > > > OperationalError: (psycopg2.OperationalError) SSL connection has been > closed unexpectedly > > (Background on this error at: http://sqlalche.me/e/13/e3q8) > OperationalError: (psycopg2.OperationalError) SSL connection has been > closed unexpectedly > > Can anyone shed any light on this? > > Regards, > > David > -- > https://mail.python.org/mailman/listinfo/python-list > From jsf80238 at gmail.com Sun Nov 29 16:32:24 2020 From: jsf80238 at gmail.com (Jason Friedman) Date: Sun, 29 Nov 2020 14:32:24 -0700 Subject: filtering out warnings In-Reply-To: References: Message-ID: > > The Box API is noisy ... very helpful for diagnosing, and yet for > production code I'd like less noise. > > I tried this: > > warnings.filterwarnings( > action='ignore', > # category=Warning, > # module=r'boxsdk.*' > ) > > but I still see this: > > WARNING:boxsdk.network.default_network:"POST > https://api.box.com/oauth2/token" 400 83 > {'Date': 'Sat, 28 Nov 2020 04:30:03 GMT', 'Content-Type': > 'application/json', 'Transfer-Encoding': 'chunked', 'Connection': > 'keep-alive', 'Strict-Transport-Security': 'max-age=31536000', > 'Set-Cookie': 'box_visitor_id=5fc1d24b134ce6.76522820; expires=Sun, > 28-Nov-2021 04:30:03 GMT; > Posted and answered on StackOverflow ( https://stackoverflow.com/questions/65061846/filtering-out-warnings-from-box-sdk-python/ ). Answer was: import logging logging.getLogger('boxsdk').setLevel(logging.CRITICAL) From urbangabo at gmail.com Sun Nov 29 16:36:09 2020 From: urbangabo at gmail.com (Gabor Urban) Date: Sun, 29 Nov 2020 22:36:09 +0100 Subject: A problem with opening a file -- again Message-ID: Hi guys, I tried to solve the problem once again. I have inserted some print statements the check the variables. The actual code (naplo.py) is copy-pasted here: ---- class Naplo: def __init__(self, pNeve, pMeret, pMode = 'a'): self.logNev = pNeve self.meret = pMeret self.startMode = pMode self.mode = 'a' self.sor = 0 self.puffer = [] self.start = True def __del__(self): print(' .. sor = %d'%self.sor) print(' .. startMode = %s'%self.startMode) print(' .. mode = %s'%self.mode) print(' .. logName = %s'%self.logNev) print(self.puffer) if self.sor != 0: if self.start: trc = open(self.logNev,self.startMode) else: trc = open(self.logNev,self.mode) for idx in xrange(self.meret): trc.write(self.puffer[idx]) trc.close() def Kiir(self, txt): msg = '%s\n'%txt self.puffer.append(msg) self.sor += 1 print(' .. sor = %d'%self.sor) print(' .. startMode = %s'%self.startMode) print(' .. mode = %s'%self.mode) print(' .. logName = %s'%self.logNev) print(self.puffer) print('.. ' + self.logNev) if self.sor == self.meret: if self.start: trc = open(self.logNev,self.startMode) else: trc = open(self.logNev,self.mode) for idx in xrange(self.meret): trc.write(self.puffer[idx]) trc.close() self.start = False self.puffer = [] self.sor = 0 lf = Naplo('nap1.log', 6) lf.Kiir('Ez az elso.') ---- I am using a Windows version: python Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> ^Z ---- python naplo.py .. sor = 1 .. startMode = a .. mode = a .. logName = nap1.log ['Ez az elso.\n'] .. nap1.log .. sor = 1 .. startMode = a .. mode = a .. logName = nap1.log ['Ez az elso.\n'] Exception ignored in: > Traceback (most recent call last): File "naplo.py", line 20, in __del__ NameError: name 'open' is not defined -- Urb?n G?bor Linux is like a wigwam: no Gates, no Windows and an Apache inside. From rosuav at gmail.com Sun Nov 29 16:42:35 2020 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 30 Nov 2020 08:42:35 +1100 Subject: A problem with opening a file -- again In-Reply-To: References: Message-ID: On Mon, Nov 30, 2020 at 8:37 AM Gabor Urban wrote: > class Naplo: > def __del__(self): > if self.sor != 0: > if self.start: > trc = open(self.logNev,self.startMode) > else: > trc = open(self.logNev,self.mode) > for idx in xrange(self.meret): > trc.write(self.puffer[idx]) > trc.close() > This seems like a really REALLY bad idea. You're putting a lot of work into your __del__ function, and that's not getting called until everything's shutting down. (Also, xrange doesn't exist, hence the "exception ignored" thing.) Avoid putting this sort of work into __del__ by explicitly marking that you're done with the object. A context manager is a good choice here. ChrisA From PythonList at DancesWithMice.info Sun Nov 29 16:55:00 2020 From: PythonList at DancesWithMice.info (dn) Date: Mon, 30 Nov 2020 10:55:00 +1300 Subject: A problem with opening a file -- again In-Reply-To: References: Message-ID: On 30/11/2020 10:36, Gabor Urban wrote: > Hi guys, > > I tried to solve the problem once again. I have inserted some print > statements the check the variables. > > The actual code (naplo.py) is copy-pasted here: Thanks = helpful +1 @Chris' response! Meantime, what happens if you start python, and enter into the REPL: trc = open( 'nap1.log', 'a' ) trc -- Regards =dn From eryksun at gmail.com Sun Nov 29 18:17:25 2020 From: eryksun at gmail.com (Eryk Sun) Date: Sun, 29 Nov 2020 17:17:25 -0600 Subject: A problem with opening a file -- again In-Reply-To: References: Message-ID: On 11/29/20, Chris Angelico wrote: > > This seems like a really REALLY bad idea. You're putting a lot of work > into your __del__ function, and that's not getting called until > everything's shutting down. (Also, xrange doesn't exist, hence the > "exception ignored" thing.) > > Avoid putting this sort of work into __del__ by explicitly marking > that you're done with the object. A context manager is a good choice > here. The documentation of the __del__() finalizer contains the following warning: __del__() can be executed during interpreter shutdown. As a consequence, the global variables it needs to access (including other modules) may already have been deleted or set to None. A finalizer can locally reference required globals and builtins as the default value of keyword-only arguments, e.g. __del__(self, *, open=open). But in this case I second the suggestion to make the object a context manager with __enter__() and __exit__() methods. From jsf80238 at gmail.com Sun Nov 29 20:31:30 2020 From: jsf80238 at gmail.com (Jason Friedman) Date: Sun, 29 Nov 2020 18:31:30 -0700 Subject: Reading binary data with the CSV module Message-ID: Using the Box API: print(source_file.content()) returns b'First Name,Last Name,Email Address,Company,Position,Connected On\nPeter,van (and more data, not pasted here) Trying to read it via: with io.TextIOWrapper(source_file.content(), encoding='utf-8') as text_file: reader = csv.DictReader(text_file) for row in reader: print(row) Getting this error: Traceback (most recent call last): File "/home/jason/my_box.py", line 278, in with io.TextIOWrapper(source_file.content(), encoding='utf-8') as text_file: AttributeError: 'bytes' object has no attribute 'readable' From python at mrabarnett.plus.com Sun Nov 29 22:06:23 2020 From: python at mrabarnett.plus.com (MRAB) Date: Mon, 30 Nov 2020 03:06:23 +0000 Subject: Reading binary data with the CSV module In-Reply-To: References: Message-ID: On 2020-11-30 01:31, Jason Friedman wrote: > Using the Box API: > > > print(source_file.content()) > > > returns > > > b'First Name,Last Name,Email Address,Company,Position,Connected > On\nPeter,van > > (and more data, not pasted here) > > > Trying to read it via: > > with io.TextIOWrapper(source_file.content(), encoding='utf-8') as text_file: > > reader = csv.DictReader(text_file) > > for row in reader: > > print(row) > > > Getting this error: > > Traceback (most recent call last): > File "/home/jason/my_box.py", line 278, in > with io.TextIOWrapper(source_file.content(), encoding='utf-8') as > text_file: > AttributeError: 'bytes' object has no attribute 'readable' > csv.DictReader appears to be happy with a list of strings representing the lines. Try this: contents = source_file.content() for row in csv.DictReader(contents.decode('utf-8').splitlines()): print(row) From jsf80238 at gmail.com Sun Nov 29 22:59:48 2020 From: jsf80238 at gmail.com (Jason Friedman) Date: Sun, 29 Nov 2020 20:59:48 -0700 Subject: Reading binary data with the CSV module In-Reply-To: References: Message-ID: > > csv.DictReader appears to be happy with a list of strings representing > the lines. > > Try this: > > contents = source_file.content() > > for row in csv.DictReader(contents.decode('utf-8').splitlines()): > print(row) > Works great, thank you! Question ... will this form potentially use less memory? for row in csv.DictReader(source_file.content().decode('utf-8').splitlines()): print(row) From sh at changeset.nyc Mon Nov 30 08:33:42 2020 From: sh at changeset.nyc (Sumana Harihareswara) Date: Mon, 30 Nov 2020 08:33:42 -0500 Subject: pip 20.3 release (heads-up for potential disruption) Message-ID: <5d8a1134-82a0-6c81-03f9-c8d9de9b21f4@changeset.nyc> On behalf of the Python Packaging Authority, I am pleased to announce that we have just released pip 20.3, a new version of pip. You can install it by running `python -m pip install --upgrade pip`. This is an important and disruptive release -- we explained why in a blog post last year https://pyfound.blogspot.com/2019/12/moss-czi-support-pip.html . We even made a video about it: https://www.youtube.com/watch?v=B4GQCBBsuNU . Blog post with details: https://pyfound.blogspot.com/2020/11/pip-20-3-new-resolver.html Highlights include: * **DISRUPTION**: Switch to the new dependency resolver by default. Watch out for changes in handling editable installs, constraints files, and more: https://pip.pypa.io/en/latest/user_guide/#changes-to-the-pip-dependency-resolver-in-20-3-2020 * **DEPRECATION**: Deprecate support for Python 3.5 (to be removed in pip 21.0) * **DEPRECATION**: pip freeze will stop filtering the pip, setuptools, distribute and wheel packages from pip freeze output in a future version. To keep the previous behavior, users should use the new `--exclude` option. * Support for PEP 600: Future ?manylinux? Platform Tags for Portable Linux Built Distributions. * Add support for MacOS Big Sur compatibility tags. The new resolver is now *on by default*. It is significantly stricter and more consistent when it receives incompatible instructions, and reduces support for certain kinds of constraints files, so some workarounds and workflows may break. Please see our guide on how to test and migrate, and how to report issues: https://pip.pypa.io/en/latest/user_guide/#changes-to-the-pip-dependency-resolver-in-20-3-2020 . You can use the deprecated (old) resolver, using the flag `--use-deprecated=legacy-resolver`, until we remove it in the pip 21.0 release in January 2021. In pip 21.0 we will also remove support for Python 2.7. You can find more details (including deprecations and removals) in the changelog https://pip.pypa.io/en/stable/news/ , and you can find thank-yous and instructions on reporting issues at https://pyfound.blogspot.com/2020/11/pip-20-3-new-resolver.html . Thank you, Sumana Harihareswara pip project manager Changeset Consulting https://changeset.nyc From python at mrabarnett.plus.com Mon Nov 30 12:08:11 2020 From: python at mrabarnett.plus.com (MRAB) Date: Mon, 30 Nov 2020 17:08:11 +0000 Subject: Reading binary data with the CSV module In-Reply-To: References: Message-ID: <659de060-df13-87ec-2b50-601fc2d35ae2@mrabarnett.plus.com> On 2020-11-30 03:59, Jason Friedman wrote: >> >> csv.DictReader appears to be happy with a list of strings representing >> the lines. >> >> Try this: >> >> contents = source_file.content() >> >> for row in csv.DictReader(contents.decode('utf-8').splitlines()): >> print(row) >> > > Works great, thank you! Question ... will this form potentially use less > memory? > > for row in > csv.DictReader(source_file.content().decode('utf-8').splitlines()): > print(row) > Yes, but it won't matter that much unless there's a _lot_ of data. From h.goebel at crazy-compilers.com Mon Nov 30 13:30:26 2020 From: h.goebel at crazy-compilers.com (Hartmut Goebel) Date: Mon, 30 Nov 2020 19:30:26 +0100 Subject: Best-practice for formatted string literals and localization? Message-ID: <677f5213-9d52-0289-4152-b2a9190f7fe1@crazy-compilers.com> Hi, formatted string literals are great, but can't be used together with localization: _(f"These are {count} stones") will crash babel ("NameError: name 'count' is not defined". And even it it would succeed, the *evaluated* string would be passed to "_(?)", resulting in a not-translated string. Is there a better solution than _("These are {count} stones").format(count=count) ("Better" = without passing args or kwargs to `format()`) -- Regards Hartmut Goebel | Hartmut Goebel |h.goebel at crazy-compilers.com | |www.crazy-compilers.com | compilers which you thought are impossible | From rosuav at gmail.com Mon Nov 30 13:58:43 2020 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 1 Dec 2020 05:58:43 +1100 Subject: Best-practice for formatted string literals and localization? In-Reply-To: <677f5213-9d52-0289-4152-b2a9190f7fe1@crazy-compilers.com> References: <677f5213-9d52-0289-4152-b2a9190f7fe1@crazy-compilers.com> Message-ID: On Tue, Dec 1, 2020 at 5:31 AM Hartmut Goebel wrote: > > Hi, > > formatted string literals are great, but can't be used together with > localization: > > _(f"These are {count} stones") > > will crash babel ("NameError: name 'count' is not defined". And even it > it would succeed, the *evaluated* string would be passed to "_(?)", > resulting in a not-translated string. > > Is there a better solution than > > _("These are {count} stones").format(count=count) > > ("Better" = without passing args or kwargs to `format()`) > Not really, no. The whole point of f-strings is keeping the template and the interpolations together, and the whole point of localization tools is keeping them apart. I'm not sure why you're getting that NameError, but the more fundamental problem is still there; you absolutely have to do the localization on the constant string with the template markers still in it, and only afterwards do the interpolation, so you're basically left with what you're already doing. It might be possible to do something with an import hook that translates _f"...." into _("....").format(...) but that would be the best you'd get. ChrisA From rosuav at gmail.com Mon Nov 30 14:02:49 2020 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 1 Dec 2020 06:02:49 +1100 Subject: A problem with opening a file -- again In-Reply-To: References: Message-ID: On Tue, Dec 1, 2020 at 5:36 AM Dennis Lee Bieber wrote: > Off-hand, since you aren't explicitly using "del lf" it means that > __del__() is being called during the process shutdown. Thing is, there is > no guarantee during shutdown of when things are deleted. There is a faint > possibility that the internal "module" that contains the built-in "open" > could be marked unavailable before your "lf" object is deleted. > ... > HOWEVER! YOU DO STILL HAVE THE PROBLEM THAT __del__() is relying on > features that might not be available if it is invoked as part of process > shutdown! You MUST explicitly "del" the object to have any chance that it > runs properly. > Be aware that "del lf" does NOT guarantee that lf.__del__() will be called. The __del__ method is only called when the object is no longer referenced anywhere, and there are certain situations where it might not be called even then (during interpreter shutdown, for instance; and I think some Pythons don't guarantee that __del__ will be called when breaking a reference loop, but don't quote me on that). You absolutely cannot rely on __del__ for this kind of thing, hence the general consensus that a context manager is the way to do it. ChrisA From jesterdev at gmail.com Mon Nov 30 20:20:30 2020 From: jesterdev at gmail.com (Michael Baca) Date: Mon, 30 Nov 2020 17:20:30 -0800 (PST) Subject: Converting images to PDF. Final file has blank pages before and after. Message-ID: <8a0c04c4-3704-4c0d-8888-91df28f8e11dn@googlegroups.com> Hello, new to the group, rather new to programming. I'm writing a program that takes images and converts them into PDF's. It works after quite a few days of trying, however the final file has a blank page inserted before and after each page containing the images. This uses FPDF to do the conversion. I've been up and down trying to figure out where I'm adding an extra page, so it might be an FPDF issue. def multi_convert(pdf_Filename, file_path): if (dir): file_list = [] print(""), print("") print("Converting... This may take awhile depending on the number of images.") for entry in os.scandir(file_path): if (entry.path.endswith(".jpg") or entry.path.endswith(".png")) and entry.is_file(): file_list.append(entry.path) else: print("Error: ") print("Invalid Directory - {}", dir) cover = Image.open(str(file_list[0])) width, height = cover.size pdf = FPDF(unit="pt", format=[width, height]) for page in file_list: pdf.add_page() pdf.image(str(page)) pdf.output(file_path + pdf_Filename + ".pdf", "F") exit() From python at mrabarnett.plus.com Mon Nov 30 21:15:00 2020 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 1 Dec 2020 02:15:00 +0000 Subject: Converting images to PDF. Final file has blank pages before and after. In-Reply-To: <8a0c04c4-3704-4c0d-8888-91df28f8e11dn@googlegroups.com> References: <8a0c04c4-3704-4c0d-8888-91df28f8e11dn@googlegroups.com> Message-ID: <68ed4193-21df-f5c9-f23e-93315ff92574@mrabarnett.plus.com> On 2020-12-01 01:20, Michael Baca wrote: > Hello, new to the group, rather new to programming. > > I'm writing a program that takes images and converts them into PDF's. It works after quite a few days of trying, however the final file has a blank page inserted before and after each page containing the images. > > This uses FPDF to do the conversion. I've been up and down trying to figure out where I'm adding an extra page, so it might be an FPDF issue. > > def multi_convert(pdf_Filename, file_path): > if (dir): > file_list = [] > print(""), print("") > print("Converting... This may take awhile depending on the number of images.") > > for entry in os.scandir(file_path): > if (entry.path.endswith(".jpg") or entry.path.endswith(".png")) and entry.is_file(): > file_list.append(entry.path) > else: > print("Error: ") > print("Invalid Directory - {}", dir) > cover = Image.open(str(file_list[0])) > width, height = cover.size > > pdf = FPDF(unit="pt", format=[width, height]) > > for page in file_list: > pdf.add_page() > pdf.image(str(page)) > > pdf.output(file_path + pdf_Filename + ".pdf", "F") > exit() > It says in the documentation for the .image method: """ x: Abscissa of the upper-left corner. If not specified or equal to None, the current abscissa is used (version 1.7.1 and up). y: Ordinate of the upper-left corner. If not specified or equal to None, the current ordinate is used; moreover, a page break is triggered first if necessary (in case automatic page breaking is enabled) and, after the call, the current ordinate is moved to the bottom of the image (version 1.7.1 and up). """ In other words, you're not specifying where the top-left corner of the image should go, so it's putting it at the current position, wherever that is, and it's responding to the positioning by inserting additional pages. The solution is to specify the images' positions, and, perhaps, also their sizes, if necessary. By the way, why doesn't the function end with "exit()"? That'll make it exit the Python completely; rarely a good idea. From kushal at locationd.net Mon Nov 30 21:24:59 2020 From: kushal at locationd.net (Kushal Kumaran) Date: Mon, 30 Nov 2020 18:24:59 -0800 Subject: Converting images to PDF. Final file has blank pages before and after. In-Reply-To: <8a0c04c4-3704-4c0d-8888-91df28f8e11dn@googlegroups.com> (Michael Baca's message of "Mon, 30 Nov 2020 17:20:30 -0800 (PST)") References: <8a0c04c4-3704-4c0d-8888-91df28f8e11dn@googlegroups.com> Message-ID: <87mtyys1ok.fsf@copper.locationd.net> On Mon, Nov 30 2020 at 05:20:30 PM, Michael Baca wrote: > Hello, new to the group, rather new to programming. > > I'm writing a program that takes images and converts them into PDF's. It works after quite a few days of trying, however the final file has a blank page inserted before and after each page containing the images. > > This uses FPDF to do the conversion. I've been up and down trying to figure out where I'm adding an extra page, so it might be an FPDF issue. > > def multi_convert(pdf_Filename, file_path): > if (dir): > file_list = [] > print(""), print("") > print("Converting... This may take awhile depending on the number of images.") > > for entry in os.scandir(file_path): > if (entry.path.endswith(".jpg") or entry.path.endswith(".png")) and entry.is_file(): > file_list.append(entry.path) > else: > print("Error: ") > print("Invalid Directory - {}", dir) > cover = Image.open(str(file_list[0])) > width, height = cover.size > > pdf = FPDF(unit="pt", format=[width, height]) > > for page in file_list: > pdf.add_page() I've never used FPDF, but have you considered not doing the add_page explicitly here? The documentation at https://pyfpdf.readthedocs.io/en/latest/reference/image/index.html might be useful; see especially the behaviour specified when the "y" parameter is not specified, as in this case. > pdf.image(str(page)) > > pdf.output(file_path + pdf_Filename + ".pdf", "F") > exit() If you're unable to resolve the issue, you should report it to pyfpdf at https://github.com/reingart/pyfpdf/issues (after checking if this is a known problem). -- regards, kushal From alvarodorsnestares at gmail.com Mon Nov 30 19:08:11 2020 From: alvarodorsnestares at gmail.com (=?UTF-8?Q?=C3=81lvaro_d=27Ors?=) Date: Tue, 1 Dec 2020 01:08:11 +0100 Subject: IDLE error Message-ID: The IDLE seems to be malfunctioning, I just re-installed Python and used the reapir function but I can?t open the IDLE, please help. -- Nestares D. ?lvaro