From rambiusparkisanius at gmail.com Tue Dec 1 00:32:23 2020 From: rambiusparkisanius at gmail.com (Ivan "Rambius" Ivanov) Date: Tue, 1 Dec 2020 00:32:23 -0500 Subject: Concatenating a Hash to a String Message-ID: Hello, I want to store the hashes of strings in a database and I have problems generating the sql statements. I generate the hashes using hashlib and then convert it to base64 and I put the base64 representation in the sql. Here is the code: #!/usr/bin/env python3.8 import base64 import hashlib def gen_sql(s): sha = hashlib.sha256() # need to encode s as binary, otherwise the next line throws # TypeError: Unicode-objects must be encoded before hashing sha.update(b"{s}") ehash = base64.b64encode(sha.digest()) sql = "insert into HASHES value ('" + ehash + "')" s = "test" gen_sql(s) This code throws $ ./hashinstr.py Traceback (most recent call last): File "./hashinstr.py", line 16, in gen_sql(s) File "./hashinstr.py", line 13, in gen_sql sql = "insert into HASHES value ('" + ehash + "')" TypeError: can only concatenate str (not "bytes") to str Any help on how to concatenate ehash to the sql? Regards rambius -- Tangra Mega Rock: http://www.radiotangra.com From rosuav at gmail.com Tue Dec 1 00:36:45 2020 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 1 Dec 2020 16:36:45 +1100 Subject: Concatenating a Hash to a String In-Reply-To: References: Message-ID: On Tue, Dec 1, 2020 at 4:34 PM Ivan "Rambius" Ivanov wrote: > > Hello, > > I want to store the hashes of strings in a database and I have > problems generating the sql statements. I generate the hashes using > hashlib and then convert it to base64 and I put the base64 > representation in the sql. Here is the code: > > sql = "insert into HASHES value ('" + ehash + "')" > Don't do this! DO NOT do this! Even if it might happen to work with a base 64 encoded value, this is a terrible terrible bug just waiting to happen. Instead, use *parameterized queries* and keep your SQL safe. Concatenating arbitrary data into an SQL statement is one of the top ten most common and dangerous flaws in application code. Just don't do it. ChrisA From rambiusparkisanius at gmail.com Tue Dec 1 00:53:11 2020 From: rambiusparkisanius at gmail.com (Ivan "Rambius" Ivanov) Date: Tue, 1 Dec 2020 00:53:11 -0500 Subject: Concatenating a Hash to a String In-Reply-To: References: Message-ID: On Tue, Dec 1, 2020 at 12:39 AM Chris Angelico wrote: > Don't do this! DO NOT do this! Even if it might happen to work with a > base 64 encoded value, this is a terrible terrible bug just waiting to > happen. Instead, use *parameterized queries* and keep your SQL safe. OK. What are parameterized queries? Can you give an example? -- Tangra Mega Rock: http://www.radiotangra.com From rosuav at gmail.com Tue Dec 1 01:00:07 2020 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 1 Dec 2020 17:00:07 +1100 Subject: Concatenating a Hash to a String In-Reply-To: References: Message-ID: On Tue, Dec 1, 2020 at 4:53 PM Ivan "Rambius" Ivanov wrote: > > On Tue, Dec 1, 2020 at 12:39 AM Chris Angelico wrote: > > Don't do this! DO NOT do this! Even if it might happen to work with a > > base 64 encoded value, this is a terrible terrible bug just waiting to > > happen. Instead, use *parameterized queries* and keep your SQL safe. > > OK. What are parameterized queries? Can you give an example? > I've no idea what database you're connecting to, what library you're using, or anything, but it would look something like this: conn.execute("insert into hashes values (?)", [hash]) Look up the documentation for what you're working with. It will have a way to do this. ChrisA From doctor at doctor.nl2k.ab.ca Tue Dec 1 10:02:19 2020 From: doctor at doctor.nl2k.ab.ca (The Doctor) Date: Tue, 1 Dec 2020 15:02:19 -0000 (UTC) Subject: XanaNews Statistic for comp.lang.python. 12/1/2020 8:02:16 AM Message-ID: XanaNews Statistic for comp.lang.python. 12/1/2020 8:02:16 AM >From article 584939 (11/1/2020 3:10:51 AM) to article 585435 (11/30/2020 11:00:07 PM) Number of threads ................... 200 Number of articles .................. 538 Average articles per thread ......... 2.69 Number of unanswered posts .......... 137 Number of posts from XanaNews users .. 0 Top Threads Ranking Articles Subject ------- -------- ---------------------------------- 1 26 Changing strings in files 2 22 Re: Find word by given characters 3 20 Is there a conflict of libraries here? 4 18 Environment vars 5 13 Post request and encoding 6 13 Python Error 7 13 tkinter global variable 8 10 Class Definitions 9 9 Dispatch table of methods with various return value types 10 9 returning totals in functions of math 11 9 How to start using python 12 8 strip() method makes me confused 13 8 Questions about XML processing? 14 7 A problem with opening a file 15 7 numpy problem (follow up) 16 7 constant folding - why not more 17 7 Getting rid of virtual environments with a better dependency system 18 7 Any better way for this removal? 19 7 How can I make this more complex? 20 7 A problem with opening a file -- again 21 7 Re: Best way to determine user's screensize? 22 6 Problem exiting from a script using tkinter 23 6 Reading binary data with the CSV module 24 5 try/except in loop 25 5 Solaris 11 GUI framework 26 5 Incoming datas difficult to read "\r\n" and "\n" 27 5 Please help test astral char display in tkinter Text (especially *nix) 28 5 Why can't numpy array be restored to saved value? 29 5 answer not correct 30 5 Python Client Rest API Invocation - POST with empty body - Invalid character found in method name [{}POST]. HTTP method names must be tokens 31 5 Cannot marshal objects 32 5 Concatenating a Hash to a String 33 5 Any experience with Python for GraalVM ? 34 5 Time Date Conversion? 35 5 Re: Strange terminal behavior after quitting Tkinter application 36 4 Unable to set up Python correctly 37 4 Re: ? DA ARRESTARE L'AVVOCATO ASSASSINO DANIELE MINOTTI 38 4 How to run Jupyter notebook in command line and get full error message? 39 4 EnvironmentError 40 4 Problem with rearanging list with paired letters next to each others 41 4 Error issue - Kindly resolve 42 4 EuroPython "Ask me Anything" - Nov Edition 43 4 Help 44 4 Need help in installing numpy 45 4 IDEL from Windows It does not work 46 4 Python 3 47 4 series.py, cannot import series from pandas 48 4 EuroPython videos all on archive.org 49 4 ssl connection has been closed unexpectedly 50 3 Best-practice for formatted string literals and localization? 51 3 Getting rid of virtual environments with a better dependency system 52 3 Re: GUI: I am also looking for a nudge into the best (GUI) direction. 53 3 io.TextIOWrapper.readlines 54 3 I have no clue figuring out how to check dates in workholidays 55 3 Tkinter List of Canvases 56 3 asyncio question 57 3 Automatically advancing a bi-directional generator to the point of accepting a non-None value? 58 3 Converting images to PDF. Final file has blank pages before and after. 59 3 filtering out warnings 60 3 unable to use numpy 61 2 Re: songbird's ngfp 62 2 Seeking guidance to start a career in python programming 63 2 Extending the Python terminology Top Posters Ranking Articles Name Most Used Newsreader ------- -------- -------------------------- -------------------- 1 63 Vagrant G2 2 32 Chini Don G2 3 25 Chris Angelico 4 21 dn Mozilla 5 15 Bischoop slrn 6 14 MRAB Mozilla 7 14 Stefan Ram 8 13 Dennis Lee Bieber ForteAgent 9 12 Cameron Simpson Mutt 10 9 Hern?n De Angelis Mozilla 11 9 Terry Reedy Mozilla 12 8 Manfred Lotz Claws Mail 13 7 ChalaoAdda Pan 14 7 Frank Millman Mozilla 15 7 Grant Edwards slrn 16 7 duncan smith Mozilla 17 6 Python Mozilla 18 6 Dieter Maurer VM 19 6 Loris Bennett Gnus 20 6 Jason Friedman 21 6 Mayukh Chakraborty WebService 22 6 Bob van der Poel 23 6 PEDOFILO SATANISTASSASSINO G2 24 5 Quentin Bock 25 5 TestBank store G2 26 5 Skip Montanaro 27 5 Steve Microsoft Outlook 28 4 moi G2 29 4 Shaozhong SHI 30 4 Dan Stromberg 31 4 Igor Korot 32 4 songbird slrn 33 4 Ivan "Rambius" Ivanov 34 4 Bob Gailer 35 4 Barry Scott Apple Mail ( 36 4 Microsoft Outlook 37 4 Peter Pearson slrn 38 3 Paul Rubin Gnus 39 3 Eryk Sun 40 3 Peter J. Holzer Mutt 41 3 j c G2 42 3 Greg Ewing Mozilla 43 3 Richard Damon Mozilla 44 3 inhahe 45 3 Paulo da Silva Mozilla 46 3 Avi Gross Microsoft Outlook 47 3 Serhiy Storchaka Mozilla 48 2 Tim Chase Claws Mail 49 2 2QdxY4RzWzUUiLuE at potatocho 50 2 David Kolovratn?k Mutt 51 2 Jay Braun G2 52 2 Gabor Urban 53 2 M.-A. Lemburg Mozilla 54 2 Variable Starlight 55 2 Eli the Bearded Vectrex rn 56 2 ROBERTO-GORINI 4 UPPER LTD G2 57 2 Ethan Furman Mozilla 58 2 Karsten Hilbert 59 2 Marek Mosiewicz Evolution 60 2 Mats Wichmann Mozilla 61 2 GIULIANO URBANI VADAINGALE G2 62 2 D'Arcy Cain Mozilla 63 2 Malcolm Mozilla 64 2 Christian Gollwitzer Mozilla 65 2 A. M. Thomas [PETech MIET 66 2 Anthony Steventon Microsoft Windows Live Ma 67 1 Cecil Westerhof Gnus 68 1 FRANCESCO CARBONE USEMLAB G2 69 1 Michael Chinnick Mandarin G2 70 1 Gilmeh Serda Pan 71 1 Zander Kraig G2 72 1 Joseph L. Casale 73 1 shankar ketheeswaran G2 74 1 Usman Musa 75 1 Shelke, Bhushan 76 1 Larry Burford Mozilla 77 1 Andreas Nigg G2 78 1 SONAHI 79 1 Alex Kaye 80 1 Michael Baca G2 81 1 Kushal Kumaran Gnus 82 1 Sumana Harihareswara Mozilla 83 1 Hartmut Goebel Mozilla 84 1 Shahique Khan 85 1 sheetal chavan 86 1 Gisle Vanem Mozilla 87 1 Go Luhng 88 1 LUIGI BISIGNANI- MAI PIU' G2 89 1 ASHUTOSH SHARMA 90 1 Lukasz Langa Apple Mail ( 91 1 LUIGI ROTUNNO LA TORRE RES G2 92 1 Barry iPad Mail ( 93 1 Wingware Postbox 94 1 Larry Martell 95 1 Cousin Stanley KNode 96 1 info cmcc 97 1 David Ru?z Dom?nguez 98 1 flaskee 99 1 DAVIDE BALDI - OSM NETWORK G2 100 1 Nick Li G2 101 1 Anssi Saari Gnus 102 1 J.J. E. 103 1 Abdur-Rahmaan Janhangeer 104 1 Ben Bacarisse 105 1 Bora Evolution 106 1 ALBERTO ALIPPI - PROMOTORE G2 107 1 Pablo Galindo Salgado 108 1 ankur gupta 109 1 Menno Holscher Mozilla 110 1 David Burnette G2 111 1 Kyle Stanley 112 1 Alexander Neilson iPhone Mail ( 113 1 Karen Shaeffer Apple Mail ( 114 1 Alan Bawden Gnus 115 1 adelamsaleh at yahoo.com WebService 116 1 Space Explorers G2 117 1 MICHELE CALZOLARI IGEA BAN G2 118 1 15 Gelbolingo, Rosalie G2 119 1 Jeff 120 1 Korn G2 121 1 Charles Okorobo 122 1 SMOA BLX WebService 123 1 FABIO VENZI-GRAN MAESTRO G G2 124 1 Tanmay Deshpande 125 1 Mike Cyrus-JMAP 126 1 skybuck2000 G2 127 1 Eleftherios Garyfallidis 128 1 Chris G2 129 1 Mike Dewhirst Mozilla 130 1 Chris Green tin Top Newsreaders Ranking Articles Newsreader Users ------- -------- -------------------------------------------- ----- 1 139 G2 29 2 122 42 3 101 Mozilla 23 4 30 slrn 4 5 17 Mutt 3 6 13 ForteAgent 1 7 13 Gnus 6 8 12 Microsoft Outlook 3 9 10 Claws Mail 2 10 8 WebService 3 11 7 Pan 2 12 6 VM 1 13 6 Apple Mail ( 3 14 3 Evolution 2 15 2 Microsoft Windows Live Mail 1 16 2 Vectrex rn 1 17 1 iPad Mail ( 1 18 1 Postbox 1 19 1 Cyrus-JMAP 1 20 1 iPhone Mail ( 1 21 1 tin 1 22 1 KNode 1 -- This email has been checked for viruses by AVG. https://www.avg.com From dieter at handshake.de Tue Dec 1 13:32:00 2020 From: dieter at handshake.de (Dieter Maurer) Date: Tue, 1 Dec 2020 19:32:00 +0100 Subject: Concatenating a Hash to a String In-Reply-To: References: Message-ID: <24518.35872.22642.795263@ixdm.fritz.box> "Ivan \"Rambius\" Ivanov" wrote at 2020-12-1 00:32 -0500: > ... >This code throws > >$ ./hashinstr.py >Traceback (most recent call last): > File "./hashinstr.py", line 16, in > gen_sql(s) > File "./hashinstr.py", line 13, in gen_sql > sql = "insert into HASHES value ('" + ehash + "')" >TypeError: can only concatenate str (not "bytes") to str With Python 3, you must carefully distinquish `bytes` (a sequence of numbers between 0 and 255) and `str` (a sequence of (unicode) characters). `base64` operates on `bytes`; `"..."` constructs an `str`; Python 3 has made `bytes` and `str` (mostly) incompatible. You can use `.decode([charset, error])` to convert `bytes` to `str` and `.encode([charset, error])` to convert `str` to `bytes`. Because `base64.encode` gives you a sequence of values between 0 and 127, you can omit the optional parameters for `.decode`. From python at mrabarnett.plus.com Tue Dec 1 13:30:21 2020 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 1 Dec 2020 18:30:21 +0000 Subject: Concatenating a Hash to a String In-Reply-To: References: Message-ID: <28356456-6624-dec3-8415-ed9a224f2676@mrabarnett.plus.com> On 2020-12-01 05:32, Ivan "Rambius" Ivanov wrote: > Hello, > > I want to store the hashes of strings in a database and I have > problems generating the sql statements. I generate the hashes using > hashlib and then convert it to base64 and I put the base64 > representation in the sql. Here is the code: > > #!/usr/bin/env python3.8 > > import base64 > import hashlib > > def gen_sql(s): > sha = hashlib.sha256() > # need to encode s as binary, otherwise the next line throws > # TypeError: Unicode-objects must be encoded before hashing > sha.update(b"{s}") > ehash = base64.b64encode(sha.digest()) > sql = "insert into HASHES value ('" + ehash + "')" > > s = "test" > gen_sql(s) > > This code throws > > $ ./hashinstr.py > Traceback (most recent call last): > File "./hashinstr.py", line 16, in > gen_sql(s) > File "./hashinstr.py", line 13, in gen_sql > sql = "insert into HASHES value ('" + ehash + "')" > TypeError: can only concatenate str (not "bytes") to str > > Any help on how to concatenate ehash to the sql? > The bytes are all in the ASCII range, so you can convert it into a string using .decode('ascii'). And, of course, use parametrised queries, as ChrisA said. From dieter at handshake.de Tue Dec 1 13:40:29 2020 From: dieter at handshake.de (Dieter Maurer) Date: Tue, 1 Dec 2020 19:40:29 +0100 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: <24518.36381.933046.754777@ixdm.fritz.box> Hartmut Goebel wrote at 2020-11-30 19:30 +0100: >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". Translations are kept in external files (without any runtime association). As a consequence, they cannot contain runtime entities; and therefore, you should not use f-strings for internationalizations. Usually, the translation machinery has special ways to provide parameters for translations. For example with `zope.i18nmessageid`, you can use `_(msg, mapping=)` to provide parameters to the translations -- as in your case `count`). Check, what parameter support your translation machinery support. From alvarodorsnestares at gmail.com Tue Dec 1 03:53:46 2020 From: alvarodorsnestares at gmail.com (=?UTF-8?Q?=C3=81lvaro_d=27Ors?=) Date: Tue, 1 Dec 2020 09:53:46 +0100 Subject: Bot Message-ID: Hi guys, I'm new here, can anyone help me built a bot than can input data in a website? This is not for spam purposes, I just need to reserve a place in the library at the university but they are completed in a matter of minutes and I can't waste time "camping" the website. Thank you Nestares D. ?lvaro From ikorot01 at gmail.com Tue Dec 1 22:15:52 2020 From: ikorot01 at gmail.com (Igor Korot) Date: Tue, 1 Dec 2020 21:15:52 -0600 Subject: IDLE error In-Reply-To: References: Message-ID: Hi, Alvaro, On Tue, Dec 1, 2020 at 9:11 PM ?lvaro d'Ors wrote: > > 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. What OS do you use? Are you trying to run it by double-clicking on the icon? What happens? Does it give you any error? Thank you. > > > > -- > Nestares D. ?lvaro > -- > https://mail.python.org/mailman/listinfo/python-list From PythonList at DancesWithMice.info Wed Dec 2 00:02:44 2020 From: PythonList at DancesWithMice.info (dn) Date: Wed, 2 Dec 2020 18:02:44 +1300 Subject: Bot In-Reply-To: References: Message-ID: On 01/12/2020 21:53, ?lvaro d'Ors wrote: > Hi guys, I'm new here, can anyone help me built a bot than can input data > in a website? > This is not for spam purposes, I just need to reserve a place in the > library at the university but they are completed in a matter of minutes and > I can't waste time "camping" the website. Thank you https://duckduckgo.com/?q=python+web+form+fill - the third or fourth response seemed to handle a log-on screen. Although if you're prepared to pay for their time, others may be able to save your time... -- Regards =dn From rambiusparkisanius at gmail.com Wed Dec 2 01:24:40 2020 From: rambiusparkisanius at gmail.com (Ivan "Rambius" Ivanov) Date: Wed, 2 Dec 2020 01:24:40 -0500 Subject: Concatenating a Hash to a String In-Reply-To: <28356456-6624-dec3-8415-ed9a224f2676@mrabarnett.plus.com> References: <28356456-6624-dec3-8415-ed9a224f2676@mrabarnett.plus.com> Message-ID: Hello, Thank you all for your help. On Tue, Dec 1, 2020 at 1:38 PM MRAB wrote: > The bytes are all in the ASCII range, so you can convert it into a > string using .decode('ascii'). I utilized encode and decode string methods to convert from bytes to strings > And, of course, use parametrised queries, as ChrisA said. I am using sqlite3 and it supports parameterized queries. Overall they are better than constructing the sql statements manually. Regards and thanks rambius -- Tangra Mega Rock: http://www.radiotangra.com From Marco.Sulla.Python at gmail.com Wed Dec 2 06:33:45 2020 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Wed, 2 Dec 2020 12:33:45 +0100 Subject: Bot In-Reply-To: References: Message-ID: On Wed, 2 Dec 2020 at 04:13, ?lvaro d'Ors wrote: > > Hi guys, I'm new here, can anyone help me built a bot than can input data > in a website? I never used it, but you can try Chatterbot: https://chatterbot.readthedocs.io/en/stable/ From priyankgasree10 at gmail.com Wed Dec 2 12:57:39 2020 From: priyankgasree10 at gmail.com (Priyankgasree K) Date: Wed, 2 Dec 2020 12:57:39 -0500 Subject: problem in installation of python 3.9.0 Message-ID: Hello, I am Priyankgasree, i am facing problem in installing python3.9.0. after i finish download it always says you have to repair or uninstall. I have repaired and uninstalled and reinstalled several times but i can't do anything . And also I cant able to download other versions of python. So tell me what`s the problem and the solution From mats at wichmann.us Wed Dec 2 12:44:31 2020 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 2 Dec 2020 10:44:31 -0700 Subject: problem in installation of python 3.9.0 In-Reply-To: References: Message-ID: <72326096-f72d-6881-9d34-f3675152148c@wichmann.us> On 12/2/20 10:57 AM, Priyankgasree K wrote: > Hello, > I am Priyankgasree, i am facing problem in installing python3.9.0. > after i finish download it always says you have to repair or uninstall. I > have repaired and uninstalled and reinstalled several times but i can't do > anything . And also I cant able to download other versions of python. So > tell me what`s the problem and the solution Don't rerun the installer. That's its purpose: to let you install, or modify the existing installation. You can remove the downloaded installer after you're done with it. Instead, either run Python from a shell - use the command name py if you installed the Python launcher. Or use the Windows search box to look for the command named python, the match you want should looke something like "Python 3.9 (64-bit) App" From drsalists at gmail.com Wed Dec 2 12:58:38 2020 From: drsalists at gmail.com (Dan Stromberg) Date: Wed, 2 Dec 2020 09:58:38 -0800 Subject: problem in installation of python 3.9.0 In-Reply-To: <72326096-f72d-6881-9d34-f3675152148c@wichmann.us> References: <72326096-f72d-6881-9d34-f3675152148c@wichmann.us> Message-ID: On Wed, Dec 2, 2020 at 9:45 AM Mats Wichmann wrote: > On 12/2/20 10:57 AM, Priyankgasree K wrote: > > Hello, > > I am Priyankgasree, i am facing problem in installing > python3.9.0. > > after i finish download it always says you have to repair or uninstall. I > > have repaired and uninstalled and reinstalled several times but i can't > do > > anything . And also I cant able to download other versions of python. So > > tell me what`s the problem and the solution > > Don't rerun the installer. That's its purpose: to let you install, or > modify the existing installation. You can remove the downloaded > installer after you're done with it. > > Instead, either run Python from a shell - use the command name py if you > installed the Python launcher. Or use the Windows search box to look > for the command named python, the match you want should looke something > like "Python 3.9 (64-bit) App" > This seems to be a common question and answer. Perhaps the installer could be named better, or Python could provide a shortcut for itself? From mats at wichmann.us Wed Dec 2 13:02:26 2020 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 2 Dec 2020 11:02:26 -0700 Subject: problem in installation of python 3.9.0 In-Reply-To: References: <72326096-f72d-6881-9d34-f3675152148c@wichmann.us> Message-ID: <850454cb-733a-ea3b-4124-985b24cb2ffd@wichmann.us> On 12/2/20 10:58 AM, Dan Stromberg wrote: > Don't rerun the installer. > This seems to be a common question and answer. It certainly does... > Perhaps the installer could be named better, or Python could provide a > shortcut for itself? > I know it makes proper start menu entries for itself, but I guess people don't much look at those any longer? (dunno, I'm not primarily a Windows user). From barry at barrys-emacs.org Wed Dec 2 13:14:25 2020 From: barry at barrys-emacs.org (Barry) Date: Wed, 2 Dec 2020 18:14:25 +0000 Subject: problem in installation of python 3.9.0 In-Reply-To: References: Message-ID: <33388FC6-30C2-48E0-85CA-30700C6124E8@barrys-emacs.org> > On 2 Dec 2020, at 18:01, Dan Stromberg wrote: > > ?On Wed, Dec 2, 2020 at 9:45 AM Mats Wichmann wrote: > >>> On 12/2/20 10:57 AM, Priyankgasree K wrote: >>> Hello, >>> I am Priyankgasree, i am facing problem in installing >> python3.9.0. >>> after i finish download it always says you have to repair or uninstall. I >>> have repaired and uninstalled and reinstalled several times but i can't >> do >>> anything . And also I cant able to download other versions of python. So >>> tell me what`s the problem and the solution >> >> Don't rerun the installer. That's its purpose: to let you install, or >> modify the existing installation. You can remove the downloaded >> installer after you're done with it. >> >> Instead, either run Python from a shell - use the command name py if you >> installed the Python launcher. Or use the Windows search box to look >> for the command named python, the match you want should looke something >> like "Python 3.9 (64-bit) App" >> > This seems to be a common question and answer. > > Perhaps the installer could be named better, or Python could provide a > shortcut for itself? You mean like including the word setup or installer in the file name? That?s what everybody else does isn?t it? Barry > -- > https://mail.python.org/mailman/listinfo/python-list > From shariesk at sundaelectronics.com Wed Dec 2 18:36:40 2020 From: shariesk at sundaelectronics.com (Shari Eskenas) Date: Wed, 2 Dec 2020 15:36:40 -0800 (PST) Subject: A picture book written with Python programs Message-ID: A Day in Code: Python is an educational book that tells a story through Python programs that represent real-life situations. Each program introduces a new Python programming concept. It is currently a Kickstarter project: https://www.kickstarter.com/projects/914595512/a-day-in-code-python From jesterdev at gmail.com Wed Dec 2 22:32:21 2020 From: jesterdev at gmail.com (Michael Baca) Date: Wed, 2 Dec 2020 19:32:21 -0800 (PST) Subject: Converting images to PDF. Final file has blank pages before and after. In-Reply-To: References: <68ed4193-21df-f5c9-f23e-93315ff92574@mrabarnett.plus.com> <8a0c04c4-3704-4c0d-8888-91df28f8e11dn@googlegroups.com> Message-ID: On Monday, November 30, 2020 at 7:15:37 PM UTC-7, MRAB wrote: > 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. Thank you very much for the help. That makes sense, as I remember reading about the image placement, but I didn't think it mattered. My use is very simple, I occasionally need to covert images into to PDF's and this makes it easier than going online. So I figured it was okay to leave that out. I need to go back and read the manual some more. It's a CLI program, it takes a few different arguments and when it's done it just returns to the shell. That's why I have the exit() where I do. Is there a better/safer way to exit the program? From python at mrabarnett.plus.com Thu Dec 3 06:55:13 2020 From: python at mrabarnett.plus.com (MRAB) Date: Thu, 3 Dec 2020 11:55:13 +0000 Subject: Converting images to PDF. Final file has blank pages before and after. In-Reply-To: References: <68ed4193-21df-f5c9-f23e-93315ff92574@mrabarnett.plus.com> <8a0c04c4-3704-4c0d-8888-91df28f8e11dn@googlegroups.com> Message-ID: On 2020-12-03 03:32, Michael Baca wrote: > On Monday, November 30, 2020 at 7:15:37 PM UTC-7, MRAB wrote: >> 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. > > Thank you very much for the help. That makes sense, as I remember reading about the image placement, but I didn't think it mattered. My use is very simple, I occasionally need to covert images into to PDF's and this makes it easier than going online. So I figured it was okay to leave that out. I need to go back and read the manual some more. > > It's a CLI program, it takes a few different arguments and when it's done it just returns to the shell. That's why I have the exit() where I do. Is there a better/safer way to exit the program? > It's best if a function just returns to its caller. That's what you'd expect a function to do, and it's a good practice to follow because it reduces the number of unexpected "surprises" in the long term or if you come back to the code much later. From thomasomea at gmail.com Thu Dec 3 07:13:59 2020 From: thomasomea at gmail.com (A. M. Thomas [PETech MIET MBA]) Date: Thu, 3 Dec 2020 15:13:59 +0300 Subject: Unable to read .xlsx file using pandas Message-ID: Kindly help manage read .xlsx files using pandas, thank you import numpy as np import pandas as pd from pandas import Series, DataFrame excelfile = pd.ExcelFile('C:\Users\THOMAS\Documents/Hash Analytics Internship - DemoS2.xlsx') dframe = excelfile.parse('Sheet10') print (dframe) C:\Users\THOMAS\AppData\Local\Programs\Python\Python39\python.exe "C:/Users/THOMAS/PycharmProjects/Assignment#2/code File.py" File "C:\Users\THOMAS\PycharmProjects\Assignment#2\code File.py", line 5 excelfile = pd.ExcelFile('C:\Users\THOMAS\Documents/Hash Analytics Internship - DemoS2.xlsx') ^ SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape 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 Thu Dec 3 07:54:54 2020 From: python at mrabarnett.plus.com (MRAB) Date: Thu, 3 Dec 2020 12:54:54 +0000 Subject: Unable to read .xlsx file using pandas In-Reply-To: References: Message-ID: <68d2e1a5-d255-2d5c-6f41-9fe5f21ec677@mrabarnett.plus.com> On 2020-12-03 12:13, A. M. Thomas [PETech MIET MBA] wrote: > Kindly help manage read .xlsx files using pandas, thank you > > import numpy as np > import pandas as pd > from pandas import Series, DataFrame > > excelfile = pd.ExcelFile('C:\Users\THOMAS\Documents/Hash Analytics > Internship - DemoS2.xlsx') > dframe = excelfile.parse('Sheet10') > print (dframe) > > > C:\Users\THOMAS\AppData\Local\Programs\Python\Python39\python.exe > "C:/Users/THOMAS/PycharmProjects/Assignment#2/code File.py" > File "C:\Users\THOMAS\PycharmProjects\Assignment#2\code File.py", line 5 > excelfile = pd.ExcelFile('C:\Users\THOMAS\Documents/Hash Analytics > Internship - DemoS2.xlsx') > > ^ > SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in > position 2-3: truncated \UXXXXXXXX escape > > Process finished with exit code 1 > You're giving the path as a plain string that contains \U, which is the start of an escape sequence, but it's not a valid escape sequence, hence the error. You could use a raw string: r'C:\Users\THOMAS\Documents/Hash Analytics Internship - DemoS2.xlsx' or escape the backslashes: 'C:\\Users\\THOMAS\\Documents/Hash Analytics Internship - DemoS2.xlsx' or use slashes instead of backslashes: 'C:/Users/THOMAS/Documents/Hash Analytics Internship - DemoS2.xlsx' From shishaozhong at gmail.com Thu Dec 3 08:10:00 2020 From: shishaozhong at gmail.com (Shaozhong SHI) Date: Thu, 3 Dec 2020 13:10:00 +0000 Subject: Observing long running processes of Jupyter Notebook Message-ID: We have been running Jupyter Notebook processes, which take long time to run. We use nbconvert to run these in commandline. Nbconvert only writes output into a file at the end. We just wonder whether there is a way to observe the progress and printing messages when nbconvert is running. Regards, David From Marco.Sulla.Python at gmail.com Thu Dec 3 11:41:57 2020 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Thu, 3 Dec 2020 17:41:57 +0100 Subject: Observing long running processes of Jupyter Notebook In-Reply-To: References: Message-ID: On Thu, 3 Dec 2020 at 14:12, Shaozhong SHI wrote: > > We have been running Jupyter Notebook processes, which take long time to > run. > > We use nbconvert to run these in commandline. Nbconvert only writes output > into a file at the end. > > We just wonder whether there is a way to observe the progress and printing > messages when nbconvert is running. If you're under linux, you can use `tail -f FILE` in the command line. From pbryan at anode.ca Thu Dec 3 01:37:09 2020 From: pbryan at anode.ca (Paul Bryan) Date: Wed, 02 Dec 2020 22:37:09 -0800 Subject: list[type, type, ...] ?! Message-ID: <957ba706cf549a1e7f94dcbbbfcdd3b259e0b1ba.camel@anode.ca> Using the typing.List generic alias, I can only specify a single type. Example: >>> typing.List[int] typing.List[int] When I try to specify additional types, it fails. Example: >>> typing.List[int, int] Traceback (most recent call last): File "", line 1, in File "/usr/lib/python3.9/typing.py", line 243, in inner return func(*args, **kwds) File "/usr/lib/python3.9/typing.py", line 775, in __getitem__ _check_generic(self, params, self._nparams) File "/usr/lib/python3.9/typing.py", line 197, in _check_generic raise TypeError(f"Too {'many' if alen > elen else 'few'} parameters for {cls};" TypeError: Too many parameters for typing.List; actual 2, expected 1 This makes sense to me. An item has one type, and we use Union if we want variants. What's not making sense to me in Python 3.9: I can use the built-in generic alias in list?in this manner, apparently successfully: >>> list[int, int] list[int, int] In fact, it appears I can specify an indeterminate number of types. Can someone explain what this construct means? I suspect this will fail to be interpreted by type validators, but wonder why it doesn't fail fast when I express it. Thanks, Paul From pbryan at anode.ca Thu Dec 3 12:19:04 2020 From: pbryan at anode.ca (Paul Bryan) Date: Thu, 03 Dec 2020 09:19:04 -0800 Subject: help(list[int]) =?UTF-8?Q?=E2=86=92?= TypeError Message-ID: <29ce2c4e1e0c7421466280efa225d30ba6f4967a.camel@anode.ca> Is this the correct behavior? Python 3.9.0 (default, Oct 7 2020, 23:09:01) [GCC 10.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> help(list[int]) Traceback (most recent call last): File "", line 1, in File "/usr/lib/python3.9/_sitebuiltins.py", line 103, in __call__ return pydoc.help(*args, **kwds) File "/usr/lib/python3.9/pydoc.py", line 2001, in __call__ self.help(request) File "/usr/lib/python3.9/pydoc.py", line 2060, in help else: doc(request, 'Help on %s:', output=self._output) File "/usr/lib/python3.9/pydoc.py", line 1779, in doc pager(render_doc(thing, title, forceload)) File "/usr/lib/python3.9/pydoc.py", line 1772, in render_doc return title % desc + '\n\n' + renderer.document(object, name) File "/usr/lib/python3.9/pydoc.py", line 473, in document if inspect.isclass(object): return self.docclass(*args) File "/usr/lib/python3.9/pydoc.py", line 1343, in docclass (str(cls.__name__) for cls in type.__subclasses__(object) TypeError: descriptor '__subclasses__' for 'type' objects doesn't apply to a 'types.GenericAlias' object >>> I would have expected the output to the identical to help(list). From greg.ewing at canterbury.ac.nz Thu Dec 3 18:15:07 2020 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Fri, 4 Dec 2020 12:15:07 +1300 Subject: list[type, type, ...] ?! In-Reply-To: References: <957ba706cf549a1e7f94dcbbbfcdd3b259e0b1ba.camel@anode.ca> Message-ID: On 3/12/20 7:37 pm, Paul Bryan wrote: >>>> list[int, int] > list[int, int] > > In fact, it appears I can specify an indeterminate number of types. I think the built-in generic alias just provides the minimum necessary to be able to write sometype[arg, ...]. It doesn't know anything about the semantics with respect to particular types -- that's left to the type checkers. -- Greg From greg.ewing at canterbury.ac.nz Thu Dec 3 18:51:39 2020 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Fri, 04 Dec 2020 12:51:39 +1300 Subject: list[type, type, ...] ?! In-Reply-To: References: <957ba706cf549a1e7f94dcbbbfcdd3b259e0b1ba.camel@anode.ca> Message-ID: <951b40ec-b73a-e8d1-e2c0-09e483ad8c73@canterbury.ac.nz> On 4/12/20 12:31 pm, Paul Bryan wrote: > Would it make sense for list's __class_getitem__ > (GenericAlias?) to perform similar checking as > typing._SpecialGenericAlias (nparams)? Maybe. It's a slippery slope -- how much of the typing module do we want to drag into the core of the interpreter? -- Greg From pbryan at anode.ca Thu Dec 3 18:31:30 2020 From: pbryan at anode.ca (Paul Bryan) Date: Thu, 03 Dec 2020 15:31:30 -0800 Subject: list[type, type, ...] ?! In-Reply-To: References: <957ba706cf549a1e7f94dcbbbfcdd3b259e0b1ba.camel@anode.ca> Message-ID: Thanks, Greg. Would it make sense for list's __class_getitem__ (GenericAlias?) to perform similar checking as typing._SpecialGenericAlias (nparams)? On Fri, 2020-12-04 at 12:15 +1300, Greg Ewing wrote: > On 3/12/20 7:37 pm, Paul Bryan wrote: > > > > > list[int, int] > > list[int, int] > > > > In fact, it appears I can specify an indeterminate number of types. > > I think the built-in generic alias just provides the minimum > necessary to be able to write sometype[arg, ...]. It doesn't > know anything about the semantics with respect to particular > types -- that's left to the type checkers. > > -- > Greg From noah-list at enabled.com Fri Dec 4 09:15:33 2020 From: noah-list at enabled.com (Noah) Date: Fri, 4 Dec 2020 06:15:33 -0800 Subject: [osx] dyld: Library not loaded: /usr/local/Cellar/python@3.8/3.8.3_1/Frameworks/Python.framework/Versions/3.8/Python Message-ID: Hi there, Anybody know how to fix this issue on a mac? ? /usr/local/bin/python dyld: Library not loaded: /usr/local/Cellar/python at 3.8/3.8.3_1/Frameworks/Python.framework/Versions/3.8/Python Referenced from: /usr/local/bin/python Reason: image not found [1] 32209 abort /usr/local/bin/python Cheers From julio at diegidio.name Fri Dec 4 10:07:50 2020 From: julio at diegidio.name (Julio Di Egidio) Date: Fri, 4 Dec 2020 07:07:50 -0800 (PST) Subject: =?UTF-8?B?UmU6IGhlbHAobGlzdFtpbnRdKSDihpIgVHlwZUVycm9y?= In-Reply-To: References: <29ce2c4e1e0c7421466280efa225d30ba6f4967a.camel@anode.ca> Message-ID: On Thursday, 3 December 2020 at 19:28:19 UTC+1, Paul Bryan wrote: > Is this the correct behavior? > > Python 3.9.0 (default, Oct 7 2020, 23:09:01) > [GCC 10.2.0] on linux > Type "help", "copyright", "credits" or "license" for more information. > >>> help(list[int]) > Traceback (most recent call last): > File "", line 1, in > File "/usr/lib/python3.9/_sitebuiltins.py", line 103, in __call__ > return pydoc.help(*args, **kwds) > File "/usr/lib/python3.9/pydoc.py", line 2001, in __call__ > self.help(request) > File "/usr/lib/python3.9/pydoc.py", line 2060, in help > else: doc(request, 'Help on %s:', output=self._output) > File "/usr/lib/python3.9/pydoc.py", line 1779, in doc > pager(render_doc(thing, title, forceload)) > File "/usr/lib/python3.9/pydoc.py", line 1772, in render_doc > return title % desc + '\n\n' + renderer.document(object, name) > File "/usr/lib/python3.9/pydoc.py", line 473, in document > if inspect.isclass(object): return self.docclass(*args) > File "/usr/lib/python3.9/pydoc.py", line 1343, in docclass > (str(cls.__name__) for cls in type.__subclasses__(object) > TypeError: descriptor '__subclasses__' for 'type' objects doesn't apply to a 'types.GenericAlias' object > >>> > > I would have expected the output to the identical to help(list). As I get it from the docs (*), these new generics still only work in type hinting contexts, and I'd rather have expected a more useful error message: but, whether that is temporary (possibly a plain bug, as in a forgotten case) or, instead, just "how things are", I wouldn't know... might be a good question for Python developers. (*) As in this one for a starter, but see also PEP 585: "*In type annotations* you can now use ...", my emphasis. Julio From artott at gmail.com Fri Dec 4 13:57:44 2020 From: artott at gmail.com (Arthur R. Ott) Date: Fri, 04 Dec 2020 12:57:44 -0600 Subject: Fw: See example References: Message-ID: Sent from my BlackBerry - the most secure mobile device From: artott at gmail.com Sent: December 4, 2020 10:40 AM To: python-list at python.org Subject: See example Microsoft Windows [Version 10.0.19042.630] (c) 2020 Microsoft Corporation. All rights reserved. I am sure you can help me.... From the Windows10 command line, either in Admin mode or otherwise this is the error message I get. I want to program a Microprocessor?for the first time and I am already stuck. I have spent a lot of time?on both the internet and YouTube following different solutions. This entry worked two days ago and then the next day didn't. The "help" worksand the program appears to be operating normally. What can you suggest???? C:\WINDOWS\system32>python Python 3.9.0a2 (tags/v3.9.0a2:6202d85, Dec 18 2019, 22:54:12) [MSC v.1916 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> pip --version Traceback (most recent call last): ? File "", line 1, in NameError: name 'pip' is not defined >>> python --version Traceback (most recent call last): ? File "", line 1, in NameError: name 'python' is not defined >>> Cheers ? ?? Art To God goes the glory for creation ?? Not to chance From PythonList at DancesWithMice.info Fri Dec 4 15:00:20 2020 From: PythonList at DancesWithMice.info (dn) Date: Sat, 5 Dec 2020 09:00:20 +1300 Subject: Fw: See example In-Reply-To: References: Message-ID: <23637178-3d81-31ea-396d-d3db1cdf50ef@DancesWithMice.info> On 05/12/2020 07:57, Arthur R. Ott wrote: ... > Microsoft Windows [Version 10.0.19042.630] > (c) 2020 Microsoft Corporation. All rights reserved. > I am sure you can help me.... > From the Windows10 command line, either in Admin mode or otherwise this is > the error message I get. I want to program a Microprocessor?for the first > time and I am already stuck. I have spent a lot of time?on both the > internet and YouTube following different solutions. This entry worked two > days ago and then the next day didn't. The "help" worksand the program > appears to be operating normally. > What can you suggest???? > C:\WINDOWS\system32>python > Python 3.9.0a2 (tags/v3.9.0a2:6202d85, Dec 18 2019, 22:54:12) [MSC v.1916 > 64 bit (AMD64)] on win32 > Type "help", "copyright", "credits" or "license" for more information. > >>> pip --version > Traceback (most recent call last): > ? File "", line 1, in > NameError: name 'pip' is not defined > >>> python --version > Traceback (most recent call last): > ? File "", line 1, in > NameError: name 'python' is not defined Try the two commands from the command-line (rather than from within the Python interpreter/REPL). -- Regards =dn From pbryan at anode.ca Fri Dec 4 15:09:21 2020 From: pbryan at anode.ca (Paul Bryan) Date: Fri, 04 Dec 2020 12:09:21 -0800 Subject: help(list[int]) =?UTF-8?Q?=E2=86=92?= TypeError In-Reply-To: References: <29ce2c4e1e0c7421466280efa225d30ba6f4967a.camel@anode.ca> Message-ID: <861bba5dfe981701e59b97571e1dff14f9f76b08.camel@anode.ca> Thanks, will bring it to the dev list. On Fri, 2020-12-04 at 07:07 -0800, Julio Di Egidio wrote: > On Thursday, 3 December 2020 at 19:28:19 UTC+1, Paul Bryan wrote: > > Is this the correct behavior? > > > > Python 3.9.0 (default, Oct 7 2020, 23:09:01) > > [GCC 10.2.0] on linux > > Type "help", "copyright", "credits" or "license" for more > > information. > > > > > help(list[int]) > > Traceback (most recent call last): > > File "", line 1, in > > File "/usr/lib/python3.9/_sitebuiltins.py", line 103, in __call__ > > return pydoc.help(*args, **kwds) > > File "/usr/lib/python3.9/pydoc.py", line 2001, in __call__ > > self.help(request) > > File "/usr/lib/python3.9/pydoc.py", line 2060, in help > > else: doc(request, 'Help on %s:', output=self._output) > > File "/usr/lib/python3.9/pydoc.py", line 1779, in doc > > pager(render_doc(thing, title, forceload)) > > File "/usr/lib/python3.9/pydoc.py", line 1772, in render_doc > > return title % desc + '\n\n' + renderer.document(object, name) > > File "/usr/lib/python3.9/pydoc.py", line 473, in document > > if inspect.isclass(object): return self.docclass(*args) > > File "/usr/lib/python3.9/pydoc.py", line 1343, in docclass > > (str(cls.__name__) for cls in type.__subclasses__(object) > > TypeError: descriptor '__subclasses__' for 'type' objects doesn't > > apply to a 'types.GenericAlias' object > > > > > > > > > I would have expected the output to the identical to help(list). > > As I get it from the docs (*), these new generics still only work in > type hinting contexts, > and I'd rather have expected a more useful error message: but, > whether that is temporary > (possibly a plain bug, as in a forgotten case) or, instead, just "how > things are", I wouldn't > know... might be a good question for Python developers. > > (*) As in this one for a starter, but see also PEP 585: > "*In type annotations* you can now use ...", my emphasis. > > > > Julio From drsalists at gmail.com Fri Dec 4 15:17:03 2020 From: drsalists at gmail.com (Dan Stromberg) Date: Fri, 4 Dec 2020 12:17:03 -0800 Subject: Fw: See example In-Reply-To: <23637178-3d81-31ea-396d-d3db1cdf50ef@DancesWithMice.info> References: <23637178-3d81-31ea-396d-d3db1cdf50ef@DancesWithMice.info> Message-ID: On Fri, Dec 4, 2020 at 12:01 PM dn via Python-list wrote: > On 05/12/2020 07:57, Arthur R. Ott wrote: > ... > > > Microsoft Windows [Version 10.0.19042.630] > > (c) 2020 Microsoft Corporation. All rights reserved. > > I am sure you can help me.... > > From the Windows10 command line, either in Admin mode or otherwise > this is > > the error message I get. I want to program a Microprocessor for the > first > > time and I am already stuck. I have spent a lot of time on both the > > internet and YouTube following different solutions. This entry > worked two > > days ago and then the next day didn't. The "help" worksand the > program > > appears to be operating normally. > > What can you suggest???? > > C:\WINDOWS\system32>python > > Python 3.9.0a2 (tags/v3.9.0a2:6202d85, Dec 18 2019, 22:54:12) [MSC > v.1916 > > 64 bit (AMD64)] on win32 > > Type "help", "copyright", "credits" or "license" for more > information. > > >>> pip --version > > Traceback (most recent call last): > > File "", line 1, in > > NameError: name 'pip' is not defined > > >>> python --version > > Traceback (most recent call last): > > File "", line 1, in > > NameError: name 'python' is not defined > > > Try the two commands from the command-line (rather than from within the > Python interpreter/REPL). > IOW, run pip or python from a command.com or powershell or cygwin bash. From mats at wichmann.us Fri Dec 4 19:21:51 2020 From: mats at wichmann.us (Mats Wichmann) Date: Fri, 4 Dec 2020 17:21:51 -0700 Subject: [osx] dyld: Library not loaded: /usr/local/Cellar/python@3.8/3.8.3_1/Frameworks/Python.framework/Versions/3.8/Python In-Reply-To: References: Message-ID: <3633067d-5613-c9ef-9b0e-55b1373a3e88@wichmann.us> On 12/4/20 7:15 AM, Noah wrote: > Hi there, > > Anybody know how to fix this issue on a mac? > > ? /usr/local/bin/python > dyld: Library not loaded: > /usr/local/Cellar/python at 3.8/3.8.3_1/Frameworks/Python.framework/Versions/3.8/Python > > ? Referenced from: /usr/local/bin/python > ? Reason: image not found > [1]??? 32209 abort????? /usr/local/bin/python Looks like you're using Python installed via Homebrew ('Cellar' being the hint), perhaps hit up that project for ideas? It looks like the install is inconsistent somehow. From PythonList at DancesWithMice.info Fri Dec 4 20:37:02 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Sat, 5 Dec 2020 14:37:02 +1300 Subject: Fw: See example In-Reply-To: References: <23637178-3d81-31ea-396d-d3db1cdf50ef@DancesWithMice.info> Message-ID: On 05/12/2020 09:17, Dan Stromberg wrote: > > On Fri, Dec 4, 2020 at 12:01 PM dn via Python-list > > wrote: > > On 05/12/2020 07:57, Arthur R. Ott wrote: > ... > > >? ? ?Microsoft Windows [Version 10.0.19042.630] > >? ? ?(c) 2020 Microsoft Corporation. All rights reserved. > >? ? ?I am sure you can help me.... > >? ? ?From the Windows10 command line, either in Admin mode or > otherwise this is > >? ? ?the error message I get. I want to program a > Microprocessor?for the first > >? ? ?time and I am already stuck. I have spent a lot of time?on > both the > >? ? ?internet and YouTube following different solutions. This > entry worked two > >? ? ?days ago and then the next day didn't. The "help" worksand > the program > >? ? ?appears to be operating normally. > >? ? ?What can you suggest???? > >? ? ?C:\WINDOWS\system32>python > >? ? ?Python 3.9.0a2 (tags/v3.9.0a2:6202d85, Dec 18 2019, 22:54:12) > [MSC v.1916 > >? ? ?64 bit (AMD64)] on win32 > >? ? ?Type "help", "copyright", "credits" or "license" for more > information. > >? ? ?>>> pip --version > >? ? ?Traceback (most recent call last): > >? ? ?? File "", line 1, in > >? ? ?NameError: name 'pip' is not defined > >? ? ?>>> python --version > >? ? ?Traceback (most recent call last): > >? ? ?? File "", line 1, in > >? ? ?NameError: name 'python' is not defined > > > Try the two commands from the command-line (rather than from within the > Python interpreter/REPL). > > > IOW, run pip or python from a command.com or > powershell or cygwin bash. Yes, thank you @Dan, I don't use MS-Win! The fact that the two (version) commands are being typed in response to a ">>>" prompt indicates that Python is already running, yet they are BASH/Windows command-line/DOS-box commands! -- Regards =dn From bdorestand at example.com Sat Dec 5 12:16:11 2020 From: bdorestand at example.com (Boris Dorestand) Date: Sat, 05 Dec 2020 14:16:11 -0300 Subject: how to plot the FFT of a list of values Message-ID: <86r1o4kwbo.fsf@example.com> I have 16 values of the period sequence 1, 2, 4, 8, 1, 2, 4, 8, ... I compute its fourier transform using >>> from scipy import fft, ifft >>> x = [1,2,4,8,1,2,4,8] >>> fft(x) array([ 30. +0.j, 0. +0.j, -6.+12.j, 0. +0.j, -10. +0.j, 0. +0.j, -6.-12.j, 0. +0.j]) Now how can I plot these values? I would like to plot 16 values. What do I need to do here? Can you show an example? From drsalists at gmail.com Sat Dec 5 13:07:30 2020 From: drsalists at gmail.com (Dan Stromberg) Date: Sat, 5 Dec 2020 10:07:30 -0800 Subject: how to plot the FFT of a list of values In-Reply-To: <86r1o4kwbo.fsf@example.com> References: <86r1o4kwbo.fsf@example.com> Message-ID: On Sat, Dec 5, 2020 at 9:20 AM Boris Dorestand wrote: > I have 16 values of the period sequence 1, 2, 4, 8, 1, 2, 4, 8, ... I > compute its fourier transform using > > >>> from scipy import fft, ifft > >>> x = [1,2,4,8,1,2,4,8] > >>> fft(x) > array([ 30. +0.j, 0. +0.j, -6.+12.j, 0. +0.j, -10. +0.j, 0. +0.j, > -6.-12.j, 0. +0.j]) > > Now how can I plot these values? I would like to plot 16 values. What > do I need to do here? Can you show an example? > Maybe https://stackoverflow.com/questions/17445720/how-to-plot-complex-numbers-argand-diagram-using-matplotlib ? From p_d_a_s_i_l_v_a_ns at nonetnoaddress.pt Sat Dec 5 13:56:46 2020 From: p_d_a_s_i_l_v_a_ns at nonetnoaddress.pt (Paulo da Silva) Date: Sat, 5 Dec 2020 18:56:46 +0000 Subject: Learning tkinter - a grid problem Message-ID: Hi! Why this example does not work? ------------------ from tkinter import * root=Tk() root.geometry("400x200") S=Scrollbar(root) T=Text(root) T.grid(row=0,column=0) S.grid(row=0,column=1) S.config(command=T.yview) T.config(yscrollcommand=S.set) txt="""This is a very big text - - - - - - - - - - - - - - - - Last line """ T.insert(END,txt) mainloop() --------------------- I would like it to work more or less like this --------------------- from tkinter import * root=Tk() root.geometry("400x200") S=Scrollbar(root) T=Text(root) S.pack(side=RIGHT,fill=Y) T.pack(side=LEFT,fill=Y) S.config(command=T.yview) T.config(yscrollcommand=S.set) txt="""This is a very big text - - - - - - - - - - - - - - - - Last line """ T.insert(END,txt) mainloop() --------------------- Thanks for any help Paulo From python at mrabarnett.plus.com Sat Dec 5 15:20:11 2020 From: python at mrabarnett.plus.com (MRAB) Date: Sat, 5 Dec 2020 20:20:11 +0000 Subject: Learning tkinter - a grid problem In-Reply-To: References: Message-ID: <352abde5-7228-f123-e6c6-340a8cd90fe1@mrabarnett.plus.com> On 2020-12-05 18:56, Paulo da Silva wrote: > Hi! > > Why this example does not work? > There are a few bits of configuration missing: > ------------------ > from tkinter import * > > root=Tk() > root.geometry("400x200") Add: root.grid_rowconfigure(0, weight=1) root.grid_columnconfigure(0, weight=1) root.grid_columnconfigure(1, weight=0) > S=Scrollbar(root) > T=Text(root) > T.grid(row=0,column=0) > S.grid(row=0,column=1) Change to: T.grid(row=0, column=0, sticky=NSEW) S.grid(row=0, column=1, sticky=NS) > S.config(command=T.yview) > T.config(yscrollcommand=S.set) > txt="""This is a very big text > - > - > - > - > - > - > - > - > - > - > - > - > - > - > - > - > Last line > """ > T.insert(END,txt) > mainloop() > --------------------- > [snip] From p_d_a_s_i_l_v_a_ns at nonetnoaddress.pt Sat Dec 5 15:45:12 2020 From: p_d_a_s_i_l_v_a_ns at nonetnoaddress.pt (Paulo da Silva) Date: Sat, 5 Dec 2020 20:45:12 +0000 Subject: Learning tkinter - a grid problem References: <352abde5-7228-f123-e6c6-340a8cd90fe1@mrabarnett.plus.com> Message-ID: ?s 20:20 de 05/12/20, MRAB escreveu: > On 2020-12-05 18:56, Paulo da Silva wrote: >> Hi! >> >> Why this example does not work? >> > There are a few bits of configuration missing: > >> ------------------ >> from tkinter import * >> >> root=Tk() >> root.geometry("400x200") > > Add: > > root.grid_rowconfigure(0, weight=1) > root.grid_columnconfigure(0, weight=1) > root.grid_columnconfigure(1, weight=0) > >> S=Scrollbar(root) >> T=Text(root) >> T.grid(row=0,column=0) >> S.grid(row=0,column=1) > > Change to: > > T.grid(row=0, column=0, sticky=NSEW) > S.grid(row=0, column=1, sticky=NS) > >> S.config(command=T.yview) >> T.config(yscrollcommand=S.set) >> txt="""This is a very big text >> - Ok, thank you. From auriocus at gmx.de Sat Dec 5 17:08:45 2020 From: auriocus at gmx.de (Christian Gollwitzer) Date: Sat, 5 Dec 2020 23:08:45 +0100 Subject: how to plot the FFT of a list of values In-Reply-To: <86r1o4kwbo.fsf@example.com> References: <86r1o4kwbo.fsf@example.com> Message-ID: Am 05.12.20 um 18:16 schrieb Boris Dorestand: > I have 16 values of the period sequence 1, 2, 4, 8, 1, 2, 4, 8, ... I > compute its fourier transform using > >>>> from scipy import fft, ifft >>>> x = [1,2,4,8,1,2,4,8] >>>> fft(x) > array([ 30. +0.j, 0. +0.j, -6.+12.j, 0. +0.j, -10. +0.j, 0. +0.j, > -6.-12.j, 0. +0.j]) > > Now how can I plot these values? I would like to plot 16 values. What > do I need to do here? Can you show an example? Usually, for the FFT of real input data, you plot only the magnitude or square of the complex array, and usually on a logscale. So: import pylab import numpy as np fx = fft(x) pylab.semilogy(np.abs(fx)) pylab.show() Christian From sjeik_appie at hotmail.com Sat Dec 5 17:30:25 2020 From: sjeik_appie at hotmail.com (sjeik_appie at hotmail.com) Date: Sat, 05 Dec 2020 23:30:25 +0100 Subject: Bot In-Reply-To: Message-ID: Try Selenium (preferred) or Mechanize. I recently used Selenium with Chrome for automated unittests of a web app, including a login screen. You could fire up the selenium script in a cron job at the desired time. On 1 Dec 2020 09:53, ?lvaro d'Ors wrote: Hi guys, I'm new here, can anyone help me built a bot than can input data in a website? This is not for spam purposes, I just need to reserve a place in the library at the university but they are completed in a matter of minutes and I can't waste time "camping" the website. Thank you Nestares D. ?lvaro -- https://mail.python.org/mailman/listinfo/python-list From sjeik_appie at hotmail.com Sat Dec 5 17:42:11 2020 From: sjeik_appie at hotmail.com (sjeik_appie at hotmail.com) Date: Sat, 05 Dec 2020 23:42:11 +0100 Subject: Regarding Regex timeout behavior to minimize CPU consumption In-Reply-To: Message-ID: Hi, Timeout: no idea. But check out re.compile and re.iterfind as they might speed things up. I often compile a regex once upon import, then use it in functions On 27 Nov 2020 13:33, Shahique Khan wrote: 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, -- https://mail.python.org/mailman/listinfo/python-list From hjp-python at hjp.at Sat Dec 5 18:34:13 2020 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sun, 6 Dec 2020 00:34:13 +0100 Subject: Regarding Regex timeout behavior to minimize CPU consumption In-Reply-To: References: Message-ID: <20201205233413.GB29541@hjp.at> On 2020-12-05 23:42:11 +0100, sjeik_appie at hotmail.com wrote: > Timeout: no idea. But check out re.compile and re.iterfind as they might > speed things up. I doubt that compiling regular expressions helps the OP much. Compiled regular expressions are cached, but more importantly, if a match takes long enough that specifying a timeout is useful, the time is almost certainly not spent compiling, but matching - most likely backtracking from lots of promising but ultimately unsuccessful partial matches. > 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) This part: \s*([\s\S]*?)\s*' looks dangerous from a performance point of view. If that can be rewritten with less potential for backtracking, it might help. Generally, it should be possible to implement a timeout for any operation by either scheduling an alarm with signal.alarm or by executing the operation in a separate thread and killing the thread if it takes too long. 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 nulla.epistola at web.de Sun Dec 6 03:11:51 2020 From: nulla.epistola at web.de (Sibylle Koczian) Date: Sun, 6 Dec 2020 09:11:51 +0100 Subject: Learning tkinter - a grid problem In-Reply-To: References: Message-ID: Am 05.12.2020 um 19:56 schrieb Paulo da Silva: > Hi! > > Why this example does not work? > > ------------------ > from tkinter import * > > root=Tk() > root.geometry("400x200") > S=Scrollbar(root) > T=Text(root) ... > mainloop() > --------------------- > Shouldn't that be root.mainloop() ? From nulla.epistola at web.de Sun Dec 6 03:11:51 2020 From: nulla.epistola at web.de (Sibylle Koczian) Date: Sun, 6 Dec 2020 09:11:51 +0100 Subject: Learning tkinter - a grid problem In-Reply-To: References: Message-ID: Am 05.12.2020 um 19:56 schrieb Paulo da Silva: > Hi! > > Why this example does not work? > > ------------------ > from tkinter import * > > root=Tk() > root.geometry("400x200") > S=Scrollbar(root) > T=Text(root) ... > mainloop() > --------------------- > Shouldn't that be root.mainloop() ? From python at mrabarnett.plus.com Sun Dec 6 09:19:19 2020 From: python at mrabarnett.plus.com (MRAB) Date: Sun, 6 Dec 2020 14:19:19 +0000 Subject: Learning tkinter - a grid problem In-Reply-To: References: Message-ID: On 2020-12-06 08:11, Sibylle Koczian wrote: > Am 05.12.2020 um 19:56 schrieb Paulo da Silva: >> Hi! >> >> Why this example does not work? >> >> ------------------ >> from tkinter import * >> >> root=Tk() >> root.geometry("400x200") >> S=Scrollbar(root) >> T=Text(root) > ... >> mainloop() >> --------------------- >> > > Shouldn't that be > > root.mainloop() > > ? > The function 'mainloop' calls the 'mainloop' method of the root Tk window created by Tk(), so it does work as-is. From nulla.epistola at web.de Sun Dec 6 13:16:55 2020 From: nulla.epistola at web.de (Sibylle Koczian) Date: Sun, 6 Dec 2020 19:16:55 +0100 Subject: Learning tkinter - a grid problem In-Reply-To: References: Message-ID: <8ccace6b-33fe-e0ad-1c90-bb138892e6bb@web.de> Am 06.12.2020 um 15:19 schrieb MRAB: > On 2020-12-06 08:11, Sibylle Koczian wrote: >> Am 05.12.2020 um 19:56 schrieb Paulo da Silva: >>> Hi! >>> >>> Why this example does not work? >>> >>> ------------------ >>> from tkinter import * >>> >>> root=Tk() >>> root.geometry("400x200") >>> S=Scrollbar(root) >>> T=Text(root) >> ... >>> mainloop() >>> --------------------- >>> >> >> Shouldn't that be >> >> root.mainloop() >> >> ? >> > The function 'mainloop' calls the 'mainloop' method of the root Tk > window created by Tk(), so it does work as-is. Didn't know that, thank you! From nulla.epistola at web.de Sun Dec 6 13:16:55 2020 From: nulla.epistola at web.de (Sibylle Koczian) Date: Sun, 6 Dec 2020 19:16:55 +0100 Subject: Learning tkinter - a grid problem In-Reply-To: References: Message-ID: <8ccace6b-33fe-e0ad-1c90-bb138892e6bb@web.de> Am 06.12.2020 um 15:19 schrieb MRAB: > On 2020-12-06 08:11, Sibylle Koczian wrote: >> Am 05.12.2020 um 19:56 schrieb Paulo da Silva: >>> Hi! >>> >>> Why this example does not work? >>> >>> ------------------ >>> from tkinter import * >>> >>> root=Tk() >>> root.geometry("400x200") >>> S=Scrollbar(root) >>> T=Text(root) >> ... >>> mainloop() >>> --------------------- >>> >> >> Shouldn't that be >> >> root.mainloop() >> >> ? >> > The function 'mainloop' calls the 'mainloop' method of the root Tk > window created by Tk(), so it does work as-is. Didn't know that, thank you! From tjreedy at udel.edu Sun Dec 6 05:59:01 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Sun, 6 Dec 2020 05:59:01 -0500 Subject: Learning tkinter - a grid problem In-Reply-To: References: Message-ID: On 12/6/2020 3:11 AM, Sibylle Koczian wrote: > Am 05.12.2020 um 19:56 schrieb Paulo da Silva: >> Why this example does not work? >> ------------------ >> from tkinter import * >> >> root=Tk() >> root.geometry("400x200") >> S=Scrollbar(root) >> T=Text(root) > ... >> mainloop() > Shouldn't that be > root.mainloop() > ? Yes. The * import does not turn method into module functions. -- Terry Jan Reedy From baroldonfire at yahoo.com Sat Dec 5 13:41:16 2020 From: baroldonfire at yahoo.com (Barry Fitzgerald) Date: Sat, 5 Dec 2020 13:41:16 -0500 Subject: Error References: Message-ID: Good day," I purchased a book for my son and followed the directions to a T. (Coding Games in Python) Whenever I got to the point of of moving the "hello" file over to pgzrun is where my trouble began. Its not finding a path because I'm getting this "pgzrun is not recognized as an internal or external command". I've uninstall reinstall and tried to trouble shoot offline. I' believe its a "path" issue but that is a little over my head. At least this is what I've read. Yes I selected all users and the variables options on custom install. Any Suggestions? From PythonList at DancesWithMice.info Sun Dec 6 15:39:09 2020 From: PythonList at DancesWithMice.info (dn) Date: Mon, 7 Dec 2020 09:39:09 +1300 Subject: Error In-Reply-To: References: Message-ID: <8dbc7420-4603-59b8-b131-1735b0f1ebdf@DancesWithMice.info> On 06/12/2020 07:41, Barry Fitzgerald via Python-list wrote: > Good day," > > I purchased a book for my son and followed the directions to a T. (Coding Games in Python) > Whenever I got to the point of of moving the "hello" file over to pgzrun is where my trouble began. > Its not finding a path because I'm getting this "pgzrun is not recognized as an internal or external command". > > I've uninstall reinstall and tried to trouble shoot offline. I' believe its a "path" issue but that is a little over my head. At least this is what I've read. Yes I selected all users and the variables options on custom install. > > Any Suggestions? It would help to have some detail: OpSys, source of Python and pygame, editor/IDE in-use, how executing pygame zero, etc. - please copy-paste relevant code and/or error messages. else: https://duckduckgo.com/?q=pgzrun&ia=web -- Regards =dn From torriem at gmail.com Sun Dec 6 17:32:01 2020 From: torriem at gmail.com (Michael Torrie) Date: Sun, 6 Dec 2020 15:32:01 -0700 Subject: Error In-Reply-To: References: Message-ID: <29e8366d-2ec6-7041-596d-c1aab30e22d5@gmail.com> On 12/5/20 11:41 AM, Barry Fitzgerald via Python-list wrote: > Good day," > > I purchased a book for my son and followed the directions to a T. (Coding Games in Python) > Whenever I got to the point of of moving the "hello" file over to pgzrun is where my trouble began. > Its not finding a path because I'm getting this "pgzrun is not recognized as an internal or external command". > > I've uninstall reinstall and tried to trouble shoot offline. I' believe its a "path" issue but that is a little over my head. At least this is what I've read. Yes I selected all users and the variables options on custom install. I think you're referring to PyGame Zero. Where did you download the installer from? From barry at barrys-emacs.org Sun Dec 6 17:36:25 2020 From: barry at barrys-emacs.org (Barry) Date: Sun, 6 Dec 2020 22:36:25 +0000 Subject: Regarding Regex timeout behavior to minimize CPU consumption In-Reply-To: <20201205233413.GB29541@hjp.at> References: <20201205233413.GB29541@hjp.at> Message-ID: <2678A846-66D9-4A7E-8C4F-5B6D49163958@barrys-emacs.org> > On 5 Dec 2020, at 23:44, Peter J. Holzer wrote: > > ?On 2020-12-05 23:42:11 +0100, sjeik_appie at hotmail.com wrote: >> Timeout: no idea. But check out re.compile and re.iterfind as they might >> speed things up. > > I doubt that compiling regular expressions helps the OP much. Compiled > regular expressions are cached, but more importantly, if a match takes > long enough that specifying a timeout is useful, the time is almost > certainly not spent compiling, but matching - most likely backtracking > from lots of promising but ultimately unsuccessful partial matches. > >> 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) > > This part: > > \s*([\s\S]*?)\s*' > > looks dangerous from a performance point of view. If that can be > rewritten with less potential for backtracking, it might help. > > Generally, it should be possible to implement a timeout for any > operation by either scheduling an alarm with signal.alarm or by > executing the operation in a separate thread and killing the thread if > it takes too long. I think that python ignores signals until the coeval loop is entered. And since the re.match will block that is not going to happen. Killing threads is not safe and if your OS allows it then you end up with the internal state of python messed up. To implement this I think requires the re code to implement the timeout. Better is for the OP to fix the re to not back track so much or to work on the input string in chunks. Barry > > hp > > -- > _ | Peter J. Holzer | Story must make more sense than reality. > |_|_) | | > | | | hjp at hjp.at | -- Charles Stross, "Creative writing > __/ | http://www.hjp.at/ | challenge!" > -- > https://mail.python.org/mailman/listinfo/python-list From torriem at gmail.com Sun Dec 6 18:09:42 2020 From: torriem at gmail.com (Michael Torrie) Date: Sun, 6 Dec 2020 16:09:42 -0700 Subject: Error In-Reply-To: References: Message-ID: On 12/5/20 11:41 AM, Barry Fitzgerald via Python-list wrote: > Good day," > > I purchased a book for my son and followed the directions to a T. > (Coding Games in Python) Whenever I got to the point of of moving the > "hello" file over to pgzrun is where my trouble began. Its not > finding a path because I'm getting this "pgzrun is not recognized as > an internal or external command". > > I've uninstall reinstall and tried to trouble shoot offline. I' > believe its a "path" issue but that is a little over my head. At > least this is what I've read. Yes I selected all users and the > variables options on custom install. Looks to me like you have to do two things to get PyGame Zero going on Windows. First, install the latest stable Python 3 from python.org. Be sure to tell the installer to put Python in the system path so you can get to it from the command prompt. Second, from a command prompt, run: py -m pip install pgzero And then you must put the location pgzrun.exe in your path. See below. For example this is what you'd see: C:\Users\torriem>py -m pip install pgzero Collecting pgzero Using cached https://files.pythonhosted.org/packages/48/e5/e5f14292373cb5fc7539aa01307b184c1e3c954d68945d8c44778669dd82/pgzero-1.2-py3-none-any.whl Collecting numpy (from pgzero) Using cached https://files.pythonhosted.org/packages/40/db/5060f18b0116f00ee73f8365efc9c95bd5496946290b0e7c97b6ee89dffe/numpy-1.19.4-cp38-cp38-win_amd64.whl Collecting pygame<2.0,>=1.9.2 (from pgzero) Using cached https://files.pythonhosted.org/packages/a8/1e/5da797179ce046decc7d6d57a9b1977218103ccfb099b959b7736aff5f73/pygame-1.9.6-cp38-cp38-win_amd64.whl Installing collected packages: numpy, pygame, pgzero WARNING: The script f2py.exe is installed in 'C:\Users\torriem\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\Scripts' which is not on PATH. Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location. WARNING: The script pgzrun.exe is installed in 'C:\Users\torriem\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\Scripts' which is not on PATH. Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location. Successfully installed numpy-1.19.4 pgzero-1.2 pygame-1.9.6 WARNING: You are using pip version 19.2.3, however version 20.3.1 is available. You should consider upgrading via the 'python -m pip install --upgrade pip' command. Note the WARNINGs about the scripts and path. You'll want to take that directory (which will be different on your machine) and add that to the path. See https://www.architectryan.com/2018/03/17/add-to-the-path-on-windows-10/ for an example of how to do that. In my case, the path I need to add is C:\Users\torriem\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\Scripts After that, pgzrun should run as the book says it will. From drsalists at gmail.com Sun Dec 6 23:27:34 2020 From: drsalists at gmail.com (Dan Stromberg) Date: Sun, 6 Dec 2020 20:27:34 -0800 Subject: Regarding Regex timeout behavior to minimize CPU consumption In-Reply-To: <2678A846-66D9-4A7E-8C4F-5B6D49163958@barrys-emacs.org> References: <20201205233413.GB29541@hjp.at> <2678A846-66D9-4A7E-8C4F-5B6D49163958@barrys-emacs.org> Message-ID: On Sun, Dec 6, 2020 at 2:37 PM Barry wrote: > > On 5 Dec 2020, at 23:44, Peter J. Holzer wrote: > > > > ?On 2020-12-05 23:42:11 +0100, sjeik_appie at hotmail.com wrote: > >> Timeout: no idea. But check out re.compile and re.iterfind as they > might > >> speed things up. > > > > I doubt that compiling regular expressions helps the OP much. Compiled > > regular expressions are cached, but more importantly, if a match takes > > long enough that specifying a timeout is useful, the time is almost > > certainly not spent compiling, but matching - most likely backtracking > > from lots of promising but ultimately unsuccessful partial matches. > > > >> 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) > > > > This part: > > > > \s*([\s\S]*?)\s*' > > > > looks dangerous from a performance point of view. If that can be > > rewritten with less potential for backtracking, it might help. > > > > Generally, it should be possible to implement a timeout for any > > operation by either scheduling an alarm with signal.alarm or by > > executing the operation in a separate thread and killing the thread if > > it takes too long. > > I think that python ignores signals until the coeval loop is entered. > And since the re.match will block that is not going to happen. > > Killing threads is not safe and if your OS allows it then you end up with > the internal state of python messed up. > > To implement this I think requires the re code to implement the timeout. > > Better is for the OP to fix the re to not back track so much or to work on > the > input string in chunks. > If the regex is expensive enough to warrant it, you could use a subprocess - they are killable. From h.goebel at crazy-compilers.com Mon Dec 7 05:54:59 2020 From: h.goebel at crazy-compilers.com (Hartmut Goebel) Date: Mon, 7 Dec 2020 11:54:59 +0100 Subject: Best-practice for formatted string literals and localization? In-Reply-To: References: <677f5213-9d52-0289-4152-b2a9190f7fe1@crazy-compilers.com> Message-ID: <81b62b47-6c46-65d1-4cb7-4c8df58c0f4c@crazy-compilers.com> Am 30.11.20 um 19:58 schrieb Chris Angelico: > Not really, no. Thanks for confirming my apprehension. -- Regards Hartmut Goebel | Hartmut Goebel | h.goebel at crazy-compilers.com | | www.crazy-compilers.com | compilers which you thought are impossible | From h.goebel at crazy-compilers.com Mon Dec 7 05:56:43 2020 From: h.goebel at crazy-compilers.com (Hartmut Goebel) Date: Mon, 7 Dec 2020 11:56:43 +0100 Subject: Best-practice for formatted string literals and localization? In-Reply-To: <24518.36381.933046.754777@ixdm.fritz.box> References: <677f5213-9d52-0289-4152-b2a9190f7fe1@crazy-compilers.com> <24518.36381.933046.754777@ixdm.fritz.box> Message-ID: Am 01.12.20 um 19:40 schrieb Dieter Maurer: > Usually, the translation machinery has special ways to > provide parameters for translations. > For example with `zope.i18nmessageid`, you can use > `_(msg, mapping=)` to provide parameters > to the translations -- as in your case `count`). > Check, what parameter support your translation machinery support. Thanks for this hint. I'm using the stdlib, which AFAIU does not support that. (Anyhow it would be easy to implement such a wrapper) -- Regards Hartmut Goebel | Hartmut Goebel | h.goebel at crazy-compilers.com | | www.crazy-compilers.com | compilers which you thought are impossible | From tjol at tjol.eu Mon Dec 7 09:46:47 2020 From: tjol at tjol.eu (Thomas Jollans) Date: Mon, 7 Dec 2020 15:46:47 +0100 Subject: how to plot the FFT of a list of values In-Reply-To: References: <86r1o4kwbo.fsf@example.com> Message-ID: <5a75fd39-c370-f875-2c36-5aa91c8744d8@tjol.eu> On 05/12/2020 23:08, Christian Gollwitzer wrote: > Am 05.12.20 um 18:16 schrieb Boris Dorestand: >> I have 16 values of the period sequence 1, 2, 4, 8, 1, 2, 4, 8, ...? I >> compute its fourier transform using >> >>>>> from scipy import fft, ifft >>>>> x = [1,2,4,8,1,2,4,8] >>>>> fft(x) >> array([ 30. +0.j,?? 0. +0.j,? -6.+12.j,?? 0. +0.j, -10. +0.j, 0. +0.j, >> ???????? -6.-12.j,?? 0. +0.j]) >> >> Now how can I plot these values?? I would like to plot 16 values.? What >> do I need to do here?? Can you show an example? > > > Usually, for the FFT of real input data, you plot only the magnitude > or square of the complex array, and usually on a logscale. So: > > import pylab Don't use pylab. https://matplotlib.org/api/index.html#module-pylab Use matplotlib.pyplot directly instead. "plt" is a popular shorthand: from matplotlib import pyplot as plt #... plt.semilogy(...) # or plt.plot, etc. - Thomas > import numpy as np > > fx = fft(x) > > pylab.semilogy(np.abs(fx)) > pylab.show() > > > > ????Christian > > > From Bischoop at vimart.net Mon Dec 7 10:48:27 2020 From: Bischoop at vimart.net (Bischoop) Date: Mon, 7 Dec 2020 15:48:27 -0000 (UTC) Subject: Letter replacer - suggestions? Message-ID: I worked on my wee script that replaces a letters: https://bpa.st/OYBQ . I would like to have some suggestions about the code from more experienced programmers, the code does work and do its job but perhaps could work in a better way. Thanks From python at mrabarnett.plus.com Mon Dec 7 12:12:02 2020 From: python at mrabarnett.plus.com (MRAB) Date: Mon, 7 Dec 2020 17:12:02 +0000 Subject: Letter replacer - suggestions? In-Reply-To: References: Message-ID: <0d1257d4-f665-dc14-0201-06eaa54c5ddf@mrabarnett.plus.com> On 2020-12-07 15:48, Bischoop wrote: > > I worked on my wee script that replaces a letters: https://bpa.st/OYBQ . > I would like to have some suggestions about the code from more > experienced programmers, the code does work and do its job but perhaps > could work in a better way. > > Thanks > > word = input( f'input word you want to change letters in: ') There's no need for the f prefix. > print(f' Your word to change: ,{word}') Is the comma a typo? > word_list = list(word) > change_this = input(f'Enter the letters you want to change: ') There's no need for the f prefix. > replace_with = input(f'Enter the letters to replace with: ') There's no need for the f prefix. > change_this_list = list(change_this) > replace_with_list = list(replace_with) > > while True: > try: > for element in word_list: > for x in change_this_list: > if element == x: > to = word_list.index(element) > replace = change_this_list.index(x) > word_list[to] = replace_with_list[replace] > new_word = ''.join(word_list) > print(f'{new_word}') The f-string is overkill. You might as well just have: print(new_word) > break > except: Avoid a 'bare' except unless you _really_ mean it, which is virtually never. Catch only those exceptions that you're going to handle. > print(f'nope') You can make it a lot shorter and faster by using a dict. The entire while loop section can be replaced with: replacements = dict(zip(change_this, replace_with)) new_word = ''.join(replacements.get(letter, letter) for letter in word) print(new_word) From torriem at gmail.com Mon Dec 7 13:13:36 2020 From: torriem at gmail.com (Michael Torrie) Date: Mon, 7 Dec 2020 11:13:36 -0700 Subject: Error In-Reply-To: <581499158.4562022.1607364432970@mail.yahoo.com> References: <581499158.4562022.1607364432970@mail.yahoo.com> Message-ID: <10ab5569-2659-a268-f164-b08f7d8d2d2b@gmail.com> On 12/7/20 11:07 AM, Barry Fitzgerald wrote: > I did the pip install I did the pip install pygameThe pip install > pgzero I get this error C:\Users\barol>pip install pgzeroDefaulting > to user installation because normal site-packages is not > writeableCollecting pgzero Using cached pgzero-1.2-py3-none-any.whl > (69 kB)Collecting numpy Using cached > numpy-1.19.4-cp39-cp39-win_amd64.whl (13.0 MB)Collecting > pygame<2.0,>=1.9.2 Using cached pygame-1.9.6.tar.gz (3.2 MB) > ERROR: Command errored out with exit status 1: command: > 'c:\program files\python39\python.exe' -c 'import sys, setuptools, > tokenize; sys.argv[0] = > '"'"'C:\\Users\\barol\\AppData\\Local\\Temp\\pip-install-loo9yev7\\pygame_5aee70f17f294e14b6187b13f07afa31\\setup.py'"'"'; > __file__='"'"'C:\\Users\\barol\\AppData\\Local\\Temp\\pip-install-loo9yev7\\pygame_5aee70f17f294e14b6187b13f07afa31\\setup.py'"'"';f=getattr(tokenize, > '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', > '"'"'\n'"'"');f.close();exec(compile(code, __file__, > '"'"'exec'"'"'))' egg_info --egg-base > 'C:\Users\barol\AppData\Local\Temp\pip-pip-egg-info-rdmw_7gl' > cwd: > C:\Users\barol\AppData\Local\Temp\pip-install-loo9yev7\pygame_5aee70f17f294e14b6187b13f07afa31\ > Complete output (17 lines): > > WARNING, No "Setup" File Exists, Running "buildconfig/config.py" > Using WINDOWS configuration... The problem is there is no pre-compiled PyGame Zero package yet for Python 3.9. So your system is trying to compile it from source. Probably your best bet is to remove Python 3.9 and install Python 3.8. From mats at wichmann.us Mon Dec 7 13:29:21 2020 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 7 Dec 2020 11:29:21 -0700 Subject: Error In-Reply-To: <10ab5569-2659-a268-f164-b08f7d8d2d2b@gmail.com> References: <581499158.4562022.1607364432970@mail.yahoo.com> <10ab5569-2659-a268-f164-b08f7d8d2d2b@gmail.com> Message-ID: <81d35ada-10f0-9ac9-f81b-65107fe11dbc@wichmann.us> On 12/7/20 11:13 AM, Michael Torrie wrote: > On 12/7/20 11:07 AM, Barry Fitzgerald wrote: >> I did the pip install I did the pip install pygameThe pip install >> pgzero I get this error C:\Users\barol>pip install pgzeroDefaulting >> to user installation because normal site-packages is not >> writeableCollecting pgzero Using cached pgzero-1.2-py3-none-any.whl >> (69 kB)Collecting numpy Using cached >> numpy-1.19.4-cp39-cp39-win_amd64.whl (13.0 MB)Collecting >> pygame<2.0,>=1.9.2 Using cached pygame-1.9.6.tar.gz (3.2 MB) >> ERROR: Command errored out with exit status 1: command: >> 'c:\program files\python39\python.exe' -c 'import sys, setuptools, >> tokenize; sys.argv[0] = >> '"'"'C:\\Users\\barol\\AppData\\Local\\Temp\\pip-install-loo9yev7\\pygame_5aee70f17f294e14b6187b13f07afa31\\setup.py'"'"'; >> __file__='"'"'C:\\Users\\barol\\AppData\\Local\\Temp\\pip-install-loo9yev7\\pygame_5aee70f17f294e14b6187b13f07afa31\\setup.py'"'"';f=getattr(tokenize, >> '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', >> '"'"'\n'"'"');f.close();exec(compile(code, __file__, >> '"'"'exec'"'"'))' egg_info --egg-base >> 'C:\Users\barol\AppData\Local\Temp\pip-pip-egg-info-rdmw_7gl' >> cwd: >> C:\Users\barol\AppData\Local\Temp\pip-install-loo9yev7\pygame_5aee70f17f294e14b6187b13f07afa31\ >> Complete output (17 lines): >> >> WARNING, No "Setup" File Exists, Running "buildconfig/config.py" >> Using WINDOWS configuration... > The problem is there is no pre-compiled PyGame Zero package yet for > Python 3.9. So your system is trying to compile it from source. ... which nearly always fails on Windows, unless you're previously ensured your setup exactly matches what that project wants. > Probably your best bet is to remove Python 3.9 and install Python 3.8. You can check the status on pypi by searching for a package and then clicking on "Download files". Doing that in this case shows that pygame 2.0 is indeed available for Python 3.9: https://pypi.org/project/pygame/#files BUT, above it's trying to compile pygame 1.9.2, because *it* presumably doesn't have a Py3.9 version. So the guess is that pgzero is pinned to a particular pygame version, and that version isn't available for 3.9, so this story may be a little more complex than most of them are. Unpacking it shows the requirement indeed excludes pygame 2.0: pygame<2.0,>=1.9.2 From python at mrabarnett.plus.com Mon Dec 7 13:30:39 2020 From: python at mrabarnett.plus.com (MRAB) Date: Mon, 7 Dec 2020 18:30:39 +0000 Subject: Error In-Reply-To: <10ab5569-2659-a268-f164-b08f7d8d2d2b@gmail.com> References: <581499158.4562022.1607364432970@mail.yahoo.com> <10ab5569-2659-a268-f164-b08f7d8d2d2b@gmail.com> Message-ID: <34f710ec-68f1-5105-0b3f-701792a1109d@mrabarnett.plus.com> On 2020-12-07 18:13, Michael Torrie wrote: > On 12/7/20 11:07 AM, Barry Fitzgerald wrote: >> I did the pip install I did the pip install pygameThe pip install >> pgzero I get this error C:\Users\barol>pip install pgzeroDefaulting >> to user installation because normal site-packages is not >> writeableCollecting pgzero Using cached pgzero-1.2-py3-none-any.whl >> (69 kB)Collecting numpy Using cached >> numpy-1.19.4-cp39-cp39-win_amd64.whl (13.0 MB)Collecting >> pygame<2.0,>=1.9.2 Using cached pygame-1.9.6.tar.gz (3.2 MB) >> ERROR: Command errored out with exit status 1: command: >> 'c:\program files\python39\python.exe' -c 'import sys, setuptools, >> tokenize; sys.argv[0] = >> '"'"'C:\\Users\\barol\\AppData\\Local\\Temp\\pip-install-loo9yev7\\pygame_5aee70f17f294e14b6187b13f07afa31\\setup.py'"'"'; >> __file__='"'"'C:\\Users\\barol\\AppData\\Local\\Temp\\pip-install-loo9yev7\\pygame_5aee70f17f294e14b6187b13f07afa31\\setup.py'"'"';f=getattr(tokenize, >> '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', >> '"'"'\n'"'"');f.close();exec(compile(code, __file__, >> '"'"'exec'"'"'))' egg_info --egg-base >> 'C:\Users\barol\AppData\Local\Temp\pip-pip-egg-info-rdmw_7gl' >> cwd: >> C:\Users\barol\AppData\Local\Temp\pip-install-loo9yev7\pygame_5aee70f17f294e14b6187b13f07afa31\ >> Complete output (17 lines): >> >> WARNING, No "Setup" File Exists, Running "buildconfig/config.py" >> Using WINDOWS configuration... > The problem is there is no pre-compiled PyGame Zero package yet for > Python 3.9. So your system is trying to compile it from source. > Probably your best bet is to remove Python 3.9 and install Python 3.8. > There's no need to remove Python 3.9 first; Python 3.8 can be installed alongside it. From python at mrabarnett.plus.com Mon Dec 7 14:31:26 2020 From: python at mrabarnett.plus.com (MRAB) Date: Mon, 7 Dec 2020 19:31:26 +0000 Subject: Error In-Reply-To: <81d35ada-10f0-9ac9-f81b-65107fe11dbc@wichmann.us> References: <581499158.4562022.1607364432970@mail.yahoo.com> <10ab5569-2659-a268-f164-b08f7d8d2d2b@gmail.com> <81d35ada-10f0-9ac9-f81b-65107fe11dbc@wichmann.us> Message-ID: On 2020-12-07 18:29, Mats Wichmann wrote: > On 12/7/20 11:13 AM, Michael Torrie wrote: >> On 12/7/20 11:07 AM, Barry Fitzgerald wrote: >>> I did the pip install I did the pip install pygameThe pip install >>> pgzero I get this error C:\Users\barol>pip install pgzeroDefaulting >>> to user installation because normal site-packages is not >>> writeableCollecting pgzero Using cached pgzero-1.2-py3-none-any.whl >>> (69 kB)Collecting numpy Using cached >>> numpy-1.19.4-cp39-cp39-win_amd64.whl (13.0 MB)Collecting >>> pygame<2.0,>=1.9.2 Using cached pygame-1.9.6.tar.gz (3.2 MB) >>> ERROR: Command errored out with exit status 1: command: >>> 'c:\program files\python39\python.exe' -c 'import sys, setuptools, >>> tokenize; sys.argv[0] = >>> '"'"'C:\\Users\\barol\\AppData\\Local\\Temp\\pip-install-loo9yev7\\pygame_5aee70f17f294e14b6187b13f07afa31\\setup.py'"'"'; >>> __file__='"'"'C:\\Users\\barol\\AppData\\Local\\Temp\\pip-install-loo9yev7\\pygame_5aee70f17f294e14b6187b13f07afa31\\setup.py'"'"';f=getattr(tokenize, >>> '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', >>> '"'"'\n'"'"');f.close();exec(compile(code, __file__, >>> '"'"'exec'"'"'))' egg_info --egg-base >>> 'C:\Users\barol\AppData\Local\Temp\pip-pip-egg-info-rdmw_7gl' >>> cwd: >>> C:\Users\barol\AppData\Local\Temp\pip-install-loo9yev7\pygame_5aee70f17f294e14b6187b13f07afa31\ >>> Complete output (17 lines): >>> >>> WARNING, No "Setup" File Exists, Running "buildconfig/config.py" >>> Using WINDOWS configuration... >> The problem is there is no pre-compiled PyGame Zero package yet for >> Python 3.9. So your system is trying to compile it from source. > > ... which nearly always fails on Windows, unless you're previously > ensured your setup exactly matches what that project wants. > >> Probably your best bet is to remove Python 3.9 and install Python 3.8. > > You can check the status on pypi by searching for a package and then > clicking on "Download files". Doing that in this case shows that pygame > 2.0 is indeed available for Python 3.9: > > https://pypi.org/project/pygame/#files > > BUT, above it's trying to compile pygame 1.9.2, because *it* presumably > doesn't have a Py3.9 version. So the guess is that pgzero is pinned to > a particular pygame version, and that version isn't available for 3.9, > so this story may be a little more complex than most of them are. > Unpacking it shows the requirement indeed excludes pygame 2.0: > > pygame<2.0,>=1.9.2 > Christoph Gohlke's site has wheels for pygame on Python 3.9: https://www.lfd.uci.edu/~gohlke/pythonlibs/#pygame From tjreedy at udel.edu Mon Dec 7 00:59:12 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Mon, 7 Dec 2020 00:59:12 -0500 Subject: Learning tkinter - a grid problem In-Reply-To: References: Message-ID: On 12/6/2020 5:59 AM, Terry Reedy wrote: > On 12/6/2020 3:11 AM, Sibylle Koczian wrote: >> Am 05.12.2020 um 19:56 schrieb Paulo da Silva: > >>> Why this example does not work? >>> ------------------ >>> from tkinter import * >>> >>> root=Tk() >>> root.geometry("400x200") >>> S=Scrollbar(root) >>> T=Text(root) >> ... >>> mainloop() > >> Shouldn't that be >> root.mainloop() >> ? > > Yes.? The * import does not turn method into module functions. But no, sort of. MRAB is correct that there is (an undocumented) module function by the same name. It calls tkinter._default_root.tk.mainloop if _default_root is not None. This is true if tkinter._support_default_root == 1 (the default, but set to 0 in IDLE) and tkinter.Tk has been called at least once. -- Terry Jan Reedy From tsano at tiscali.it Mon Dec 7 11:59:01 2020 From: tsano at tiscali.it (=?iso-8859-1?Q?Tito_San=F2?=) Date: Mon, 7 Dec 2020 17:59:01 +0100 Subject: linear algebric equations Message-ID: <000401d6ccba$43cab5f0$cb6021d0$@tiscali.it> Regarding the solution of linear algebraic equations I noticed a big difference in the computation time in Python compared to the old fortran language. I have compared both the linelg and lapack.dgesv-lapack.zgesv modules with the fortan: dgelg and f04adf. The difference in computation time is enormous: for example for 430 degrees of freedom it is about 24 min in Python versus about 1 sec in fortran. Is it possible to get better performance in Python? Thanks in advance Tito Sano? Roma Italy Cell: 339 6903895 From grant.b.edwards at gmail.com Mon Dec 7 13:36:36 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 7 Dec 2020 18:36:36 -0000 (UTC) Subject: Letter replacer - suggestions? References: <0d1257d4-f665-dc14-0201-06eaa54c5ddf@mrabarnett.plus.com> Message-ID: On 2020-12-07, MRAB wrote: > Avoid a 'bare' except unless you _really_ mean it, which is > virtually never. Catch only those exceptions that you're going to > handle. And sometimes "handling" is just printing some extra stuff and then re-raising the original exception: try: something(): except: print() raise From Joseph.Schachner at Teledyne.com Mon Dec 7 14:48:51 2020 From: Joseph.Schachner at Teledyne.com (Schachner, Joseph) Date: Mon, 7 Dec 2020 19:48:51 +0000 Subject: Letter replacer - suggestions? In-Reply-To: References: Message-ID: The only comment I have is that you didn't check the inputs at all. Suppose the word I type in is "1234". 1234 will turn into an int, not a string. You can't index through an int, it's one thing. So the program will probably throw an error. If the word at least starts with a letter, then it will be a string. If I say I want to replace "?" that may not exist in the string, but that's OK. ---- Joseph S. -----Original Message----- From: Bischoop Sent: Monday, December 7, 2020 10:48 AM To: python-list at python.org Subject: Letter replacer - suggestions? I worked on my wee script that replaces a letters: https://bpa.st/OYBQ . I would like to have some suggestions about the code from more experienced programmers, the code does work and do its job but perhaps could work in a better way. Thanks From rosuav at gmail.com Mon Dec 7 14:53:07 2020 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 8 Dec 2020 06:53:07 +1100 Subject: Letter replacer - suggestions? In-Reply-To: References: <0d1257d4-f665-dc14-0201-06eaa54c5ddf@mrabarnett.plus.com> Message-ID: On Tue, Dec 8, 2020 at 6:41 AM Grant Edwards wrote: > > On 2020-12-07, MRAB wrote: > > > Avoid a 'bare' except unless you _really_ mean it, which is > > virtually never. Catch only those exceptions that you're going to > > handle. > > And sometimes "handling" is just printing some extra stuff and then > re-raising the original exception: > > try: > something(): > except: > print() > raise > Even there, I'd most often use "except BaseException as e:", other than in a very few situations. The only time I have recently used a bare except is when making use of the traceback module: try: ... except: with open("notes.err", "a") as err: traceback.print_exc(file=err) raise since print_exc() can go fetch the exception via sys.exc_info(). ChrisA From rosuav at gmail.com Mon Dec 7 14:54:45 2020 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 8 Dec 2020 06:54:45 +1100 Subject: Letter replacer - suggestions? In-Reply-To: References: Message-ID: On Tue, Dec 8, 2020 at 6:51 AM Schachner, Joseph wrote: > > The only comment I have is that you didn't check the inputs at all. Suppose the word I type in is "1234". 1234 will turn into an int, not a string. > You can't index through an int, it's one thing. So the program will probably throw an error. Not sure what you mean here. The input() function always returns a string, even if it's nothing but decimal digits. (If you're using an ancient version of Python, then it will evaluate the input, which would mean digits turn into an integer, but other things will just error out - they won't be strings. Also, all the f-strings in the OP's code wouldn't work, so that's irrelevant here.) ChrisA From inhahe at gmail.com Mon Dec 7 14:58:45 2020 From: inhahe at gmail.com (inhahe) Date: Mon, 7 Dec 2020 14:58:45 -0500 Subject: Letter replacer - suggestions? In-Reply-To: References: Message-ID: Besides what others have said (especially re using a dict instead), I think it's unpythonic/can result in unexpected behavior to change a list as it's being iterated over. Your modified word_list should be a separate list, I think. Also, if you use enumerate(), you won't have to use .index and it would be more efficient. And I'm not sure what the 'while True' accomplishes. Seems it would put it in an endless loop? If the 'while True' were in the beginning of the program, before the inputs, it would make more sense. (And in that case you'd probably want to break the loop if `word` is empty) On Mon, Dec 7, 2020 at 10:51 AM Bischoop wrote: > > I worked on my wee script that replaces a letters: https://bpa.st/OYBQ . > I would like to have some suggestions about the code from more > experienced programmers, the code does work and do its job but perhaps > could work in a better way. > > Thanks > -- > https://mail.python.org/mailman/listinfo/python-list > From jon+usenet at unequivocal.eu Mon Dec 7 15:07:40 2020 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Mon, 7 Dec 2020 20:07:40 -0000 (UTC) Subject: Letter replacer - suggestions? References: <0d1257d4-f665-dc14-0201-06eaa54c5ddf@mrabarnett.plus.com> Message-ID: On 2020-12-07, Chris Angelico wrote: > On Tue, Dec 8, 2020 at 6:41 AM Grant Edwards wrote: >> On 2020-12-07, MRAB wrote: >> > Avoid a 'bare' except unless you _really_ mean it, which is >> > virtually never. Catch only those exceptions that you're going to >> > handle. >> >> And sometimes "handling" is just printing some extra stuff and then >> re-raising the original exception: >> >> try: >> something(): >> except: >> print() >> raise >> > > Even there, I'd most often use "except BaseException as e:", other > than in a very few situations. The only time I have recently used a > bare except is when making use of the traceback module: > > try: > ... > except: > with open("notes.err", "a") as err: > traceback.print_exc(file=err) > raise > > since print_exc() can go fetch the exception via sys.exc_info(). ... but even if you do think you want "except BaseException:" or "except:", you almost never actually do - you almost certainly want "except Exception:", because the former two will stop sys.exit() from working, or the user from pressing ctrl-C. From rosuav at gmail.com Mon Dec 7 15:24:32 2020 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 8 Dec 2020 07:24:32 +1100 Subject: Letter replacer - suggestions? In-Reply-To: References: <0d1257d4-f665-dc14-0201-06eaa54c5ddf@mrabarnett.plus.com> Message-ID: On Tue, Dec 8, 2020 at 7:11 AM Jon Ribbens via Python-list wrote: > > On 2020-12-07, Chris Angelico wrote: > > On Tue, Dec 8, 2020 at 6:41 AM Grant Edwards wrote: > >> On 2020-12-07, MRAB wrote: > >> > Avoid a 'bare' except unless you _really_ mean it, which is > >> > virtually never. Catch only those exceptions that you're going to > >> > handle. > >> > >> And sometimes "handling" is just printing some extra stuff and then > >> re-raising the original exception: > >> > >> try: > >> something(): > >> except: > >> print() > >> raise > >> > > > > Even there, I'd most often use "except BaseException as e:", other > > than in a very few situations. The only time I have recently used a > > bare except is when making use of the traceback module: > > > > try: > > ... > > except: > > with open("notes.err", "a") as err: > > traceback.print_exc(file=err) > > raise > > > > since print_exc() can go fetch the exception via sys.exc_info(). > > ... but even if you do think you want "except BaseException:" or > "except:", you almost never actually do - you almost certainly want > "except Exception:", because the former two will stop sys.exit() > from working, or the user from pressing ctrl-C. For "log and reraise" handlers, actually I usually *do* want to see those. The goal of these is to report the exception in some different way from the normal one, and maybe figuring out why some subsystem is dying inexplicably; and a KeyboardInterrupt would definitely be of note there. ChrisA From drsalists at gmail.com Mon Dec 7 15:51:34 2020 From: drsalists at gmail.com (Dan Stromberg) Date: Mon, 7 Dec 2020 12:51:34 -0800 Subject: linear algebric equations In-Reply-To: <000401d6ccba$43cab5f0$cb6021d0$@tiscali.it> References: <000401d6ccba$43cab5f0$cb6021d0$@tiscali.it> Message-ID: On Mon, Dec 7, 2020 at 11:36 AM Tito San? wrote: > Regarding the solution of linear algebraic equations I noticed a big > difference in the computation > > time in Python compared to the old fortran language. > > I have compared both the linelg and lapack.dgesv-lapack.zgesv modules with > the fortan: dgelg and f04adf. > > The difference in computation time is enormous: > > for example for 430 degrees of freedom it is about 24 min in Python versus > about 1 sec in fortran. > > Is it possible to get better performance in Python? > Can you make your test code available for examination? If you are using CPython, are you also using numpy? Or numba? If you are using pure Python, have you tried Pypy3? HTH. From larry.martell at gmail.com Mon Dec 7 17:06:39 2020 From: larry.martell at gmail.com (Larry Martell) Date: Mon, 7 Dec 2020 17:06:39 -0500 Subject: list of dictionaries search using kwargs Message-ID: I have a class that has an object that contains a list of dicts. I want to have a class method that takes a variable number of key/value pairs and searches the list and returns the item that matches the arguments. If I know the key value pairs I can do something like this: instance = next(item for item in data] if\ item["appCode"] == 1 and\ item["componentCode"] == "DB" and\ item["environmentEnumID"] == 12 and\ item["serverName"] == 'foo', None) But in my class method if I have: def find_data_row(self, **kwargs): and I call it: find_data_row(appCode=1, componentCode='DB', ...) How can I do the search in a pythonic way? From Marco.Sulla.Python at gmail.com Mon Dec 7 17:16:36 2020 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Mon, 7 Dec 2020 23:16:36 +0100 Subject: Letter replacer - suggestions? In-Reply-To: References: <0d1257d4-f665-dc14-0201-06eaa54c5ddf@mrabarnett.plus.com> Message-ID: Not sure why you want to do this (it's schoolwork)? Anyway, this is my version: word = input('input word you want to change letters in: ') chars = tuple(word) change_this = input('Enter the letters you want to change: ') replace_with = input('Enter the letters to replace with: ') if len(change_this) != len(replace_with): raise RuntimeError( "Letters to replace must be equals in number to letters you want " + "to change" ) change_chars = tuple(change_this) replace_chars = tuple(replace_with) new_chars = [] for ch in chars: try: i = change_chars.index(ch) except ValueError: new_chars.append(ch) else: new_chars.append(replace_chars[i]) From Marco.Sulla.Python at gmail.com Mon Dec 7 17:28:04 2020 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Mon, 7 Dec 2020 23:28:04 +0100 Subject: list of dictionaries search using kwargs In-Reply-To: References: Message-ID: You can return dictionaries that returns True if (a.items() & kwargs.items()) == kwargs.items() when `a` is one of your dicts. From larry.martell at gmail.com Mon Dec 7 17:33:06 2020 From: larry.martell at gmail.com (Larry Martell) Date: Mon, 7 Dec 2020 17:33:06 -0500 Subject: list of dictionaries search using kwargs In-Reply-To: References: Message-ID: On Mon, Dec 7, 2020 at 5:29 PM Marco Sulla wrote: > > You can return dictionaries that returns True if > > (a.items() & kwargs.items()) == kwargs.items() > > when `a` is one of your dicts. But what is passed in kwargs will not necessarily have values for all of the keys and I only want to check for matches with the ones passed in. From m at funkyhat.org Mon Dec 7 17:42:30 2020 From: m at funkyhat.org (Matt Wheeler) Date: Mon, 7 Dec 2020 22:42:30 +0000 Subject: list of dictionaries search using kwargs In-Reply-To: References: Message-ID: for item in self.data: ?? ?if all(item[k] == v for k,v in kwargs.items()): ?? ? ? ?return item Or return [item for item in self.data if all(item[k] == v for k,v in kwargs.items())] to return all matches Beware though that either of these will be slow if your list of dicts is large. If the list is large enough that this becomes slow, consider using a database (e.g. sqlite or other SQL DB) instead. On 7 Dec 2020, 22:06 +0000, Larry Martell , wrote: > I have a class that has an object that contains a list of dicts. I > want to have a class method that takes a variable number of key/value > pairs and searches the list and returns the item that matches the > arguments. > > If I know the key value pairs I can do something like this: > > instance = next(item for item in data] if\ > item["appCode"] == 1 and\ > item["componentCode"] == "DB" and\ > item["environmentEnumID"] == 12 and\ > item["serverName"] == 'foo', None) > > But in my class method if I have: > > def find_data_row(self, **kwargs): > > and I call it: > > find_data_row(appCode=1, componentCode='DB', ...) > > How can I do the search in a pythonic way? > -- > https://mail.python.org/mailman/listinfo/python-list From larry.martell at gmail.com Mon Dec 7 17:53:37 2020 From: larry.martell at gmail.com (Larry Martell) Date: Mon, 7 Dec 2020 17:53:37 -0500 Subject: list of dictionaries search using kwargs In-Reply-To: References: Message-ID: On Mon, Dec 7, 2020 at 5:42 PM Matt Wheeler wrote: > > for item in self.data: > if all(item[k] == v for k,v in kwargs.items()): > return item > > Or > > return [item for item in self.data if all(item[k] == v for k,v in kwargs.items())] > > to return all matches > > Beware though that either of these will be slow if your list of dicts is large. > If the list is large enough that this becomes slow, consider using a database (e.g. sqlite or other SQL DB) instead. Thanks! Works perfectly. > On 7 Dec 2020, 22:06 +0000, Larry Martell , wrote: > > I have a class that has an object that contains a list of dicts. I > > want to have a class method that takes a variable number of key/value > > pairs and searches the list and returns the item that matches the > > arguments. > > > If I know the key value pairs I can do something like this: > > > instance = next(item for item in data] if\ > > item["appCode"] == 1 and\ > > item["componentCode"] == "DB" and\ > > item["environmentEnumID"] == 12 and\ > > item["serverName"] == 'foo', None) > > > But in my class method if I have: > > > def find_data_row(self, **kwargs): > > > and I call it: > > > find_data_row(appCode=1, componentCode='DB', ...) > > > How can I do the search in a pythonic way? > > -- > > https://mail.python.org/mailman/listinfo/python-list From torriem at gmail.com Mon Dec 7 18:00:40 2020 From: torriem at gmail.com (Michael Torrie) Date: Mon, 7 Dec 2020 16:00:40 -0700 Subject: Error In-Reply-To: <34f710ec-68f1-5105-0b3f-701792a1109d@mrabarnett.plus.com> References: <581499158.4562022.1607364432970@mail.yahoo.com> <10ab5569-2659-a268-f164-b08f7d8d2d2b@gmail.com> <34f710ec-68f1-5105-0b3f-701792a1109d@mrabarnett.plus.com> Message-ID: <7a51b88e-7d68-3c88-5344-f3eed6c6808f@gmail.com> On 12/7/20 11:30 AM, MRAB wrote: > There's no need to remove Python 3.9 first; Python 3.8 can be installed > alongside it. Since the original poster is invoking python.exe directly, probably as per the instructions in the book he's following, I fear having two versions of python installed will just lead to confusion. In his case, I think it's best to just have Python 3.8 installed. Although pgzrun.exe will almost certainly execute the correct version of Python, so probably wouldn't matter either way. From python at mrabarnett.plus.com Mon Dec 7 18:06:47 2020 From: python at mrabarnett.plus.com (MRAB) Date: Mon, 7 Dec 2020 23:06:47 +0000 Subject: list of dictionaries search using kwargs In-Reply-To: References: Message-ID: <34eddbe0-67b4-48c3-d043-1347e3955700@mrabarnett.plus.com> On 2020-12-07 22:06, Larry Martell wrote: > I have a class that has an object that contains a list of dicts. I > want to have a class method that takes a variable number of key/value > pairs and searches the list and returns the item that matches the > arguments. > > If I know the key value pairs I can do something like this: > > instance = next(item for item in data] if\ > item["appCode"] == 1 and\ > item["componentCode"] == "DB" and\ > item["environmentEnumID"] == 12 and\ > item["serverName"] == 'foo', None) > > But in my class method if I have: > > def find_data_row(self, **kwargs): > > and I call it: > > find_data_row(appCode=1, componentCode='DB', ...) > > How can I do the search in a pythonic way? > An item is a match if: all(item[key] == value for key, value in kwargs.items()) or possibly: MISSING = object() all(item.get(key, MISSING) == value for key, value in kwargs.items()) Just iterate over the list of dicts until you find a match. From PythonList at DancesWithMice.info Mon Dec 7 18:08:28 2020 From: PythonList at DancesWithMice.info (dn) Date: Tue, 8 Dec 2020 12:08:28 +1300 Subject: Letter replacer - suggestions? In-Reply-To: References: <0d1257d4-f665-dc14-0201-06eaa54c5ddf@mrabarnett.plus.com> Message-ID: <800c3598-4d75-5681-65f1-04f3b5814201@DancesWithMice.info> > word = input('input word you want to change letters in: ') > > chars = tuple(word) > change_this = input('Enter the letters you want to change: ') > replace_with = input('Enter the letters to replace with: ') > > if len(change_this) != len(replace_with): > raise RuntimeError( > "Letters to replace must be equals in number to letters you want " + > "to change" > ) > > change_chars = tuple(change_this) > replace_chars = tuple(replace_with) > > new_chars = [] > > for ch in chars: > try: > i = change_chars.index(ch) > except ValueError: > new_chars.append(ch) > else: > new_chars.append(replace_chars[i]) There are two 'phases' to this program: 1 collecting the input-data, and 2 performing a translation. The second and third inputs must be the same length - hence the first if-condition (above). Phase 1: More user-friendly (considerate) ways to do this include: - (if short strings) input the character-pairs as a unit:- while ... # decide upon a sentinel/loop-terminator in = input( "A character and its replacement" ) source_character, replacement_character = in.split( ... ) # insert appropriate criteria as ... source_list.append( source_character ) replacement_list.append( replacement_character ) - (existing practice) alter the input() "prompt-strings" to be the same length, and thus assist the user to *see* that his/her two inputs [must] also 'match' in length! eg Source characters? abcdef? Encoded characters? zyxwuv? Phase 2: The translation phase is most easily achieved with the built-in str.translate() - and likely faster! First the translation-table must be built, then the source-text(s) translated: source_str = "".join( source_list ) replacement_str = "".join( replacement_list ) # have to join (above) lists into strings for next line translation_table = str.maketrans( source_str, replacement_str ) translation = word.translate( translation_table ) NB because maketrans() is a static method (of the str[ing] class) we must use the "str.". NBB because str.maketrans() checks the length of the two translation-strings, wrapping that with try...except might be considered more 'pythonic' than the "first if-condition" (although "explicit is better...", Zen of Python) For extra credit/re-factoring further: (after learning the above 'straight-line' approaches and code constructs) str.maketrans() will accept a single dict[ionary]. Accordingly, instead of collecting the translation data as two lists - which must then be converted into strings; (no matter which approach to 'phase 1' is preferred); consider building a translation-dictionary wherein each entry has the 'letter to be changed' as its "key", and its "data" is 'the letter to replace [it] with'. Refactoring from the above: source_character, replacement_character = in.split( ... ) translation_dict[ source_character ] = replacement_character translation_table = str.maketrans( translation_dict ) translation = word.translate( translation_table ) Trust this adds to your 'adventures' in learning Python! Web.Refs: https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str https://www.askpython.com/python/string/python-string-translate -- Regards =dn From Marco.Sulla.Python at gmail.com Mon Dec 7 18:15:57 2020 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Tue, 8 Dec 2020 00:15:57 +0100 Subject: Letter replacer - suggestions? In-Reply-To: <800c3598-4d75-5681-65f1-04f3b5814201@DancesWithMice.info> References: <0d1257d4-f665-dc14-0201-06eaa54c5ddf@mrabarnett.plus.com> <800c3598-4d75-5681-65f1-04f3b5814201@DancesWithMice.info> Message-ID: On Tue, 8 Dec 2020 at 00:10, dn via Python-list wrote: > The translation phase is most easily achieved with the built-in > str.translate() I forgot it :-) From Marco.Sulla.Python at gmail.com Mon Dec 7 18:19:15 2020 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Tue, 8 Dec 2020 00:19:15 +0100 Subject: list of dictionaries search using kwargs In-Reply-To: References: Message-ID: On Mon, 7 Dec 2020 at 23:35, Larry Martell wrote: > > On Mon, Dec 7, 2020 at 5:29 PM Marco Sulla wrote: > > > > You can return dictionaries that returns True if > > > > (a.items() & kwargs.items()) == kwargs.items() > > > > when `a` is one of your dicts. > > But what is passed in kwargs will not necessarily have values for all > of the keys That's why I used the operator `&`. Anyway you already made your choice :-) From PythonList at DancesWithMice.info Mon Dec 7 20:02:45 2020 From: PythonList at DancesWithMice.info (dn) Date: Tue, 8 Dec 2020 14:02:45 +1300 Subject: Letter replacer - suggestions? In-Reply-To: References: <0d1257d4-f665-dc14-0201-06eaa54c5ddf@mrabarnett.plus.com> <800c3598-4d75-5681-65f1-04f3b5814201@DancesWithMice.info> Message-ID: <21898357-3436-b513-0408-51cd19e11614@DancesWithMice.info> On 08/12/2020 12:15, Marco Sulla wrote: > On Tue, 8 Dec 2020 at 00:10, dn via Python-list wrote: >> The translation phase is most easily achieved with the built-in >> str.translate() > > I forgot it :-) That's down to the rich-ness of the Python eco-system! IIRC (from previous posts) the OP is teaching him-/her-self Python. Thus, learning one-step at a time, building complexity in-line with confidence, is the way (s)he's going. Accordingly, each answer, building on the previous shows the way forward (as well as, the process of re-factoring)! BTW his/her learn-by-doing approach is also the reason why I didn't write a complete-code answer. Interestingly (at least, to me), the earlier response was me taking a break from writing a short paper (nothing-much to do with Python). Herewith some overlap of ideas:- The aphorism claiming "two heads are better than one" is also the basis for what business-groups commonly call "brain-storming" (or "spit-balling", if you're 'in' marketing). However, did you know that "brain-storming" (in-person) seldom reaches the aspiration of finding 'the best possible answer'? Further, that if team-members work remotely, (first) 'attacking' a problem individually, and only after that, pooling their ideas to produce a plan; the chosen 'answer' will (likely) be much better! Reasons: stated opinion of the "highest paid [wo]man in the room", dominant personalities, extrovert behavior, introvert behavior, I'd rather be sailing, ... Thus: "Planning Poker" as a 'bottom-up', Agile, method for story/task (length) estimation! -- Regards =dn From pablogsal at gmail.com Mon Dec 7 20:33:11 2020 From: pablogsal at gmail.com (Pablo Galindo Salgado) Date: Tue, 8 Dec 2020 01:33:11 +0000 Subject: [RELEASE] Python 3.9.1 is now available, together with 3.10.0a3 and 3.8.7rc1 Message-ID: It's starting to get very cold (at least on the Northern hemisphere) so we have been carefully packaging a total of three new Python releases to keep you warm these days! Python 3.9.1 is the first maintenance release of Python 3.9, and also the first version of Python to support macOS 11 Big Sur natively on Apple Silicon. Go get it here: https://www.python.org/downloads/release/python-391/ Maintenance releases for the 3.9 series will continue at regular bi-monthly intervals, with **3.9.2** planned for Monday, 2021-02-08. Python 3.10a3 is the third alpha release of Python 3.10. You can get it here: https://www.python.org/downloads/release/python-3100a3/ Python 3.10a3 is the release preview of the next maintenance release of Python 3.8. You can get it here: https://www.python.org/downloads/release/python-387rc1/ Assuming no critical problems are found prior to **2020-12-21** , the currently scheduled release date for **3.8.7** , 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.8.7 and as such its main purpose is testing. Your friendly release team, Ned Deily, Steve Dower, Pablo Galindo, ?ukasz Langa From tjol at tjol.eu Mon Dec 7 11:22:16 2020 From: tjol at tjol.eu (Thomas Jollans) Date: Mon, 7 Dec 2020 17:22:16 +0100 Subject: Letter replacer - suggestions? In-Reply-To: References: Message-ID: <9a9093ba-ca6c-6236-64d1-8db2b6df4a8e@tjol.eu> On 07/12/2020 16:48, Bischoop wrote: > I worked on my wee script that replaces a letters: https://bpa.st/OYBQ . > I would like to have some suggestions about the code from more > experienced programmers, the code does work and do its job but perhaps > could work in a better way. > > Thanks Sure! First of all, the code could be simplified by using the replace() method of the str class (https://docs.python.org/3/library/stdtypes.html#str.replace). Now a few comments on the code specifically: ??? while True: What is this for? It looks like all it does is cause the program to get caught in an infinite loop if there's an exception... ??????? for element in word_list: ??????????? for x in change_this_list: You can loop over strings as well - there's no need to convert them to lists. ??????? to = word_list.index(element) There's a nice trick to get the index while looping: write ??????? for (idx, character) in enumerate(word): then you don't have to use the index method. This also works if a character appears multiple times in the word, in which case I think your code will fail (but I haven't tried it) (Obviously apply this to the other loop as well, mutadis mutandis, to get rid of both index() calls) ??????? word_list[to] = replace_with_list[replace] Okay, this is something you can't do with a str because they're immutable. Generally I'd avoid modifying the thing you're looping over; it works in this case when you're replacing elements of a list, but it probably won't do what you want if you're deleting or adding items. I'd put new_word_list = [] somewhere at the top, and build it up element by element with new_word_list.append(). But what you're doing is fine too as long as you keep in mind that changing the thing you're looping over can be dangerous in other cases. Hope this helps Thomas From tjreedy at udel.edu Tue Dec 8 09:09:53 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Tue, 8 Dec 2020 09:09:53 -0500 Subject: [RELEASE] Python 3.9.1 is now available, together with 3.10.0a3 and 3.8.7rc1 In-Reply-To: References: Message-ID: On 12/7/2020 8:33 PM, Pablo Galindo Salgado wrote: > It's starting to get very cold (at least on the Northern hemisphere) so we > have been carefully packaging a total of three new Python releases to keep > you warm these days! > > Python 3.9.1 is the first maintenance release of Python 3.9, and also the > first version of Python to support macOS 11 Big Sur natively on Apple > Silicon. Go get it here: > > https://www.python.org/downloads/release/python-391/ On my Windows 10 machine, only test_locale failed. https://bugs.python.org/issue37945 has not come to a conclusion yet. > Maintenance releases for the 3.9 series will continue at regular bi-monthly > intervals, with **3.9.2** planned for Monday, 2021-02-08. > > Python 3.10a3 is the third alpha release of Python 3.10. You can get it > here: > > https://www.python.org/downloads/release/python-3100a3/ test_os test_pydoc test_webbrowser also fail for me > Python 3.10a3 is the release preview of the next maintenance release of This should be 3.8.7rc1 ... > Python 3.8. You can get it here: > > https://www.python.org/downloads/release/python-387rc1/ test_compileall also fails for me > Assuming no critical problems are found prior to **2020-12-21** , the > currently scheduled release date for **3.8.7** , 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.8.7 and as such > its main purpose is testing -- Terry Jan Reedy From fabiofz at gmail.com Tue Dec 8 13:57:15 2020 From: fabiofz at gmail.com (Fabio Zadrozny) Date: Tue, 8 Dec 2020 15:57:15 -0300 Subject: PyDev 8.1.0 Released Message-ID: PyDev 8.1.0 Release Highlights - *Interactive Console* - The selection for which console to open may be saved. (*#PyDev-1112*) - When the *current editor* option is selected, the related interpreter is no longer asked. (*#PyDev-1112*) - *Debugger* (updated to pydevd 2.2.0) - Better support for Python flags when auto-attaching to subprocesses. - Fixes to path translation (when debugging in a different machine). - Catch warnings related to *imp* import from *pkg_resources*. - No longer crashing when running with *Pyjion* (patch by Anthony Shaw). - *Others* - Code analysis now supports *from __future__ import anotations*. ( *#PyDev-1040*) - AST pretty-printing supports printing slices. (*#PyDev-1106*) - Code-completion with auto imports for the builtin module is no longer shown. (*#PyDev-1117*) - MyPy messages from a different file are no longer shown in the current editor. (*#PyDev-1114*) About PyDev PyDev is an open-source Python IDE on top of Eclipse for Python, Jython and IronPython development, now also available for Python on Visual Studio Code. It comes with goodies such as code completion, syntax highlighting, syntax analysis, code analysis, refactor, debug, interactive console, etc. It is also available as a standalone through LiClipse with goodies such as multiple cursors, theming and support for many other languages, such as Django Templates, Jinja2, Html, JavaScript, etc. Links: PyDev: http://pydev.org PyDev Blog: http://pydev.blogspot.com PyDev on VSCode: http://pydev.org/vscode LiClipse: http://www.liclipse.com PyVmMonitor - Python Profiler: http://www.pyvmmonitor.com/ Cheers, Fabio Zadrozny From Joseph.Schachner at Teledyne.com Tue Dec 8 14:07:57 2020 From: Joseph.Schachner at Teledyne.com (Schachner, Joseph) Date: Tue, 8 Dec 2020 19:07:57 +0000 Subject: linear algebric equations In-Reply-To: <000401d6ccba$43cab5f0$cb6021d0$@tiscali.it> References: <000401d6ccba$43cab5f0$cb6021d0$@tiscali.it> Message-ID: Yes. Import os, and use os.system( ) to call your Fortran (or C) executable. If the executable saves results in a file or files, Python can read them in an format a nice overall report. In html or xml, if you like. Using Python as glue, the execution time will be exactly what it was for your executable, because Python will call it; and in a second of so after it finishes Python can read in results and format whatever report you like. --- Joseph S. -----Original Message----- From: Tito San? Sent: Monday, December 7, 2020 11:59 AM To: python-list at python.org Subject: linear algebric equations Regarding the solution of linear algebraic equations I noticed a big difference in the computation time in Python compared to the old fortran language. I have compared both the linelg and lapack.dgesv-lapack.zgesv modules with the fortan: dgelg and f04adf. The difference in computation time is enormous: for example for 430 degrees of freedom it is about 24 min in Python versus about 1 sec in fortran. Is it possible to get better performance in Python? Thanks in advance Tito Sano' Roma Italy Cell: 339 6903895 From Marco.Sulla.Python at gmail.com Tue Dec 8 15:06:39 2020 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Tue, 8 Dec 2020 21:06:39 +0100 Subject: linear algebric equations In-Reply-To: <000401d6ccba$43cab5f0$cb6021d0$@tiscali.it> References: <000401d6ccba$43cab5f0$cb6021d0$@tiscali.it> Message-ID: On Mon, 7 Dec 2020 at 20:38, Tito San? wrote: > Is it possible to get better performance in Python? Have you installed BLAS for Scipy? What OS do you have? From auriocus at gmx.de Tue Dec 8 15:05:54 2020 From: auriocus at gmx.de (Christian Gollwitzer) Date: Tue, 8 Dec 2020 21:05:54 +0100 Subject: linear algebric equations In-Reply-To: References: <000401d6ccba$43cab5f0$cb6021d0$@tiscali.it> Message-ID: Am 07.12.20 um 17:59 schrieb Tito San?: > Regarding the solution of linear algebraic equations I noticed a big > difference in the computation > > time in Python compared to the old fortran language. > > I have compared both the linelg and lapack.dgesv-lapack.zgesv modules with > the fortan: dgelg and f04adf. > > The difference in computation time is enormous: > > for example for 430 degrees of freedom it is about 24 min in Python versus > about 1 sec in fortran. There must be something seriously wrong. If I understand correctly, you want to solve an 430x430 matrix with LU decompositino (that is what dgesv from LAPACK does). The following code takes less than a second on my machine: ==============430.py============== import numpy as np # create a 430x430 random matrix A = np.random.randn(430,430) # right hand side b = np.ones(430) # solve it x = np.linalg.solve(A, b) print(x) ==================================== time python3 430.py real 0m0.318s user 0m0.292s sys 0m0.046s If it takes longer than 1s, there is something wrong with your system. Christian From pbryan at anode.ca Tue Dec 8 19:17:24 2020 From: pbryan at anode.ca (Paul Bryan) Date: Tue, 08 Dec 2020 16:17:24 -0800 Subject: Property type hints? Message-ID: Would this be a reasonably correct way to annotate a property with a type hint? >>> class Foo: ... bar: int ... @property ... def bar(self): ... return 1 ... >>> foo = Foo() >>> import typing >>> typing.get_type_hints(foo) {'bar': } I could also decorate the property method return value: ... def bar(self) -> int: I don't see the point though, because you can't access it with get_type_hints. From p_d_a_s_i_l_v_a_ns at nonetnoaddress.pt Wed Dec 9 00:55:29 2020 From: p_d_a_s_i_l_v_a_ns at nonetnoaddress.pt (Paulo da Silva) Date: Wed, 9 Dec 2020 05:55:29 +0000 Subject: numpy/python (image) problem Message-ID: Hi! I am looking at some code, that I found somewhere in the internet, to compute DCT for each 8x8 block in an gray (2D) image (512x512). This is the code: def dct2(a): return scipy.fft.dct(scipy.fft.dct(a,axis=0,norm='ortho'),axis=1,norm='ortho') imsize=im.shape dct=np.zeros(imsize) # Do 8x8 DCT on image (in-place) for i in r_[:imsize[0]:8]: # Seems the same as "for i in np.arange(0,imsize[0],8)"! for j in r_[:imsize[1]:8]: dct[i:(i+8),j:(j+8)]=dct2(im[i:(i+8),j:(j+8)]) I tried to do the same thing with: imsize=im.shape im8=im.reshape(imsize[0]*imsize[1]//8//8,8,8) dct_test=np.asarray([dct2(im8x) for im8x in im8]) dct_test=dct_test.reshape(imsize) so that dct_test should be equal to (previous) dct. But they are completely different. What am I doing wrong? Thanks a lot. From avianshgaur at gmail.com Wed Dec 9 11:08:46 2020 From: avianshgaur at gmail.com (avinash gaur) Date: Wed, 9 Dec 2020 21:38:46 +0530 Subject: Python idle did not open even after trying many times Message-ID: Dear Sir/Mam, I am facing a problem with Python Idle. I am unable to open python idle even after clicking on it so many times. I am using Python 3.7 on Windows. I have already installed and uninstalled python 3.7 so many times. But it is not working Any help will be appreciated Thanking you From siddarthadiga at gmail.com Wed Dec 9 00:34:03 2020 From: siddarthadiga at gmail.com (Siddarth Adiga) Date: Wed, 9 Dec 2020 11:04:03 +0530 Subject: Unable to download Message-ID: Hello. I wanted to download the Python Version 3.9.1 but it said there was already another version of Python already installed. But I have deleted the program from the ADD OR REMOVE PROGRAMS option. But still I am unable to download it. Please help... From p_d_a_s_i_l_v_a_ns at nonetnoaddress.pt Wed Dec 9 13:21:13 2020 From: p_d_a_s_i_l_v_a_ns at nonetnoaddress.pt (Paulo da Silva) Date: Wed, 9 Dec 2020 18:21:13 +0000 Subject: numpy/python (image) problem References: Message-ID: ?s 05:55 de 09/12/20, Paulo da Silva escreveu: > Hi! > > I am looking at some code, that I found somewhere in the internet, to > compute DCT for each 8x8 block in an gray (2D) image (512x512). > > This is the code: > > def dct2(a): > return > scipy.fft.dct(scipy.fft.dct(a,axis=0,norm='ortho'),axis=1,norm='ortho') > > imsize=im.shape > dct=np.zeros(imsize) > > # Do 8x8 DCT on image (in-place) > for i in r_[:imsize[0]:8]: # Seems the same as "for i in > np.arange(0,imsize[0],8)"! > for j in r_[:imsize[1]:8]: > dct[i:(i+8),j:(j+8)]=dct2(im[i:(i+8),j:(j+8)]) > > I tried to do the same thing with: > > imsize=im.shape > im8=im.reshape(imsize[0]*imsize[1]//8//8,8,8) > dct_test=np.asarray([dct2(im8x) for im8x in im8]) > dct_test=dct_test.reshape(imsize) > > so that dct_test should be equal to (previous) dct. > But they are completely different. > > What am I doing wrong? > This was silly :-) The first code splits the image in 8x8 squares. The last one builds 8x8 squares from each line in sequence! Forget this please. Thanks. From bgailer at gmail.com Wed Dec 9 13:34:47 2020 From: bgailer at gmail.com (Bob Gailer) Date: Wed, 9 Dec 2020 13:34:47 -0500 Subject: Unable to download In-Reply-To: References: Message-ID: On Wed, Dec 9, 2020, 11:46 AM Siddarth Adiga wrote: > Hello. I wanted to download the Python Version 3.9.1 but it said there was > already another version of Python already installed. But I have deleted the > program from the ADD OR REMOVE PROGRAMS option. But still I am unable to > download it. Please help. What OS are you using? Exactly what did you do to download? Exactly what did the error.message say? Bob Gailer > From PythonList at DancesWithMice.info Wed Dec 9 13:49:31 2020 From: PythonList at DancesWithMice.info (dn) Date: Thu, 10 Dec 2020 07:49:31 +1300 Subject: Property type hints? In-Reply-To: References: Message-ID: <3802dbe9-3783-ae69-4e71-84a4be00edb2@DancesWithMice.info> On 09/12/2020 13:17, Paul Bryan wrote: > Would this be a reasonably correct way to annotate a property with a > type hint? > >>>> class Foo: > ... bar: int If we build a class with (only) the above two lines, Python's help lookup offers the following documentation: <<< Help on Foo in module __main__ object: class Foo(builtins.object) | Data descriptors defined here: | | __dict__ | dictionary for instance variables (if defined) | | __weakref__ | list of weak references to the object (if defined) | | ---------------------------------------------------------------------- | Data and other attributes defined here: | | __annotations__ = {'bar': } >>> Note the last line identifying 'bar' as having integer-type. However, when we continue, by adding a property/lookup-method called 'bar'. > ... @property > ... def bar(self): > ... return 1 ...the help lookup becomes: <<< class Foo(builtins.object) | Readonly properties defined here: | | bar | | ---------------------------------------------------------------------- | Data descriptors defined here: | | __dict__ | dictionary for instance variables (if defined) | | __weakref__ | list of weak references to the object (if defined) | | ---------------------------------------------------------------------- | Data and other attributes defined here: | | __annotations__ = {'bar': } >>> Note that 'bar' has now been listed as a read-only property. Further, if we remove the explicit typing (int) of 'bar', the help listing doesn't change. <<< class Foo(builtins.object) | Readonly properties defined here: | | bar | | ---------------------------------------------------------------------- | Data descriptors defined here: | | __dict__ | dictionary for instance variables (if defined) | | __weakref__ | list of weak references to the object (if defined) >>> Except that the annotation documentation has disappeared! Hence, one assumes, the question! The problem is that the help system appears to be talking about two different things: 'bar' the class int, and 'bar' the method/property. At run-time however, there cannot be two uses of the same name, and the last-defined 'wins'. Continuing:- > ... >>>> foo = Foo() >>>> import typing >>>> typing.get_type_hints(foo) > {'bar': } > > I could also decorate the property method return value: > ... def bar(self) -> int: ...and when the typing-hint is added to the property's def, the help listing still doesn't change/improve. That said, I've been following this last convention since moving to typing. Putting a separate description at the beginning of the class invites the reader to think of 'foo' as an integer. That's not 'wrong', in the sense that a property is/produces an attribute in the same dotted-notation from the object-name. However,there could be quite a lot of code between this 'declaration' line and the property def! However, there is another line of logic built upon the idea that all class-attributes should be defined in the class 'header' and all instance-attributes in __init__() or __post_init__(). Does this underlie the discussion? > I don't see the point though, because you can't access it with get_type_hints. Correct: if one codes (only) the property-bar, then: >>> get_type_hints( Foo ) {} However, reverting back to the first class-definition, we do see something for our money: >>> get_type_hints( foo ) {'bar': } Unfortunately, as mentioned above, there is this confusion between the two 'bar's... Proof? If we change things, the result is not what (it would appear) is desired: >>> class Foo: ... bar:str ... @property ... def bar( self ): ... return 1 ... >>> get_type_hints( Foo ) {'bar': } Yet the 'bar' property will return an int! ...and this is proven/made worse when we add explicit typing to the property definition: >>> class Foo: ... bar:str ... @property ... def bar( self )->int: ... return 1 ... >>> get_type_hints( Foo ) {'bar': } Our documentation entries don't agree, and don't match 'reality'. Ouch! Beyond that, I won't hazard a guess at the minds of the 'Python gods' who design and implement these things. However, please remember that in this discussion we have been using Python itself, whereas the docs and PEP-justifications for typing clearly say: <<< Note The Python runtime does not enforce function and variable type annotations. They can be used by third party tools such as type checkers, IDEs, linters, etc. >>> which may stump whatever the aim in using get-type-hints() may have been. If we're only talking about code-review, then (personal) comment of 'documenting' the method-definition applies. -- Regards =dn From pbryan at anode.ca Wed Dec 9 19:06:03 2020 From: pbryan at anode.ca (Paul Bryan) Date: Wed, 09 Dec 2020 16:06:03 -0800 Subject: Property type hints? In-Reply-To: <3802dbe9-3783-ae69-4e71-84a4be00edb2@DancesWithMice.info> References: <3802dbe9-3783-ae69-4e71-84a4be00edb2@DancesWithMice.info> Message-ID: <5b5dc1a35ca16d061468abfcb5e0c87d2b2dc33d.camel@anode.ca> Thanks for the comprehensive response, dn! I guess I'm influenced by data classes here, where the object's attribute type hints are represented by class variable annotations. On Thu, 2020-12-10 at 07:49 +1300, dn via Python-list wrote: > On 09/12/2020 13:17, Paul Bryan wrote: > > Would this be a reasonably correct way to annotate a property with > > a > > type hint? > > > > > > > class Foo: > > ...???? bar: int > > > If we build a class with (only) the above two lines, Python's help > lookup offers the following documentation: > > <<< > Help on Foo in module __main__ object: > > class Foo(builtins.object) > ? |? Data descriptors defined here: > ? | > ? |? __dict__ > ? |????? dictionary for instance variables (if defined) > ? | > ? |? __weakref__ > ? |????? list of weak references to the object (if defined) > ? | > ? |? ---------------------------------------------------------------- > ------ > ? |? Data and other attributes defined here: > ? | > ? |? __annotations__ = {'bar': } > ?>>> > > Note the last line identifying 'bar' as having integer-type. > > However, when we continue, by adding a property/lookup-method called > 'bar'. > > > ...???? @property > > ...???? def bar(self): > > ...???????? return 1 > > > ...the help lookup becomes: > > <<< > class Foo(builtins.object) > ? |? Readonly properties defined here: > ? | > ? |? bar > ? | > ? |? ---------------------------------------------------------------- > ------ > ? |? Data descriptors defined here: > ? | > ? |? __dict__ > ? |????? dictionary for instance variables (if defined) > ? | > ? |? __weakref__ > ? |????? list of weak references to the object (if defined) > ? | > ? |? ---------------------------------------------------------------- > ------ > ? |? Data and other attributes defined here: > ? | > ? |? __annotations__ = {'bar': } > ?>>> > > Note that 'bar' has now been listed as a read-only property. > > Further, if we remove the explicit typing (int) of 'bar', the help > listing doesn't change. > > > <<< > class Foo(builtins.object) > ? |? Readonly properties defined here: > ? | > ? |? bar > ? | > ? |? ---------------------------------------------------------------- > ------ > ? |? Data descriptors defined here: > ? | > ? |? __dict__ > ? |????? dictionary for instance variables (if defined) > ? | > ? |? __weakref__ > ? |????? list of weak references to the object (if defined) > ?>>> > > Except that the annotation documentation has disappeared! > > Hence, one assumes, the question! > > The problem is that the help system appears to be talking about two > different things: 'bar' the class int, and 'bar' the method/property. > At > run-time however, there cannot be two uses of the same name, and the > last-defined 'wins'. > > Continuing:- > > > ... > > > > > foo = Foo() > > > > > import typing > > > > > typing.get_type_hints(foo) > > {'bar': } > > > > I could also decorate the property method return value: > > ...???? def bar(self) -> int: > > ...and when the typing-hint is added to the property's def, the help > listing still doesn't change/improve. > > > That said, I've been following this last convention since moving to > typing. > > Putting a separate description at the beginning of the class invites > the > reader to think of 'foo' as an integer. That's not 'wrong', in the > sense > that a property is/produces an attribute in the same dotted-notation > from the object-name. However,there could be quite a lot of code > between > this 'declaration' line and the property def! > > However, there is another line of logic built upon the idea that all > class-attributes should be defined in the class 'header' and all > instance-attributes in __init__() or __post_init__(). Does this > underlie > the discussion? > > > > I don't see the point though, because you can't access it with > > get_type_hints. > > Correct: if one codes (only) the property-bar, then: > > ?>>> get_type_hints( Foo ) > {} > > However, reverting back to the first class-definition, we do see > something for our money: > > ?>>> get_type_hints( foo ) > {'bar': } > > Unfortunately, as mentioned above, there is this confusion between > the > two 'bar's... > > Proof? > > If we change things, the result is not what (it would appear) is > desired: > > ?>>> class Foo: > ...?? bar:str > ...?? @property > ...?? def bar( self ): > ...???? return 1 > ... > ?>>> get_type_hints( Foo ) > {'bar': } > > Yet the 'bar' property will return an int! > > ...and this is proven/made worse when we add explicit typing to the > property definition: > > ?>>> class Foo: > ...?? bar:str > ...?? @property > ...?? def bar( self )->int: > ...???? return 1 > ... > ?>>> get_type_hints( Foo ) > {'bar': } > > Our documentation entries don't agree, and don't match 'reality'. > Ouch! > > Beyond that, I won't hazard a guess at the minds of the 'Python gods' > who design and implement these things. However, please remember that > in > this discussion we have been using Python itself, whereas the docs > and > PEP-justifications for typing clearly say: > > <<< > Note The Python runtime does not enforce function and variable type > annotations. They can be used by third party tools such as type > checkers, IDEs, linters, etc. > ?>>> > > which may stump whatever the aim in using get-type-hints() may have > been. > > > If we're only talking about code-review, then (personal) comment of > 'documenting' the method-definition applies. > -- > Regards =dn From siddarthadiga at gmail.com Wed Dec 9 20:35:20 2020 From: siddarthadiga at gmail.com (Siddarth Adiga) Date: Thu, 10 Dec 2020 07:05:20 +0530 Subject: Unable to download In-Reply-To: References: Message-ID: Thank you for your concern. I use windows 10. But I was able to download it. The fifth time I tried, it worked. But then I had a prolem opening Jupyter Notebook, it said "Fatal error in launcher: unable to create process using. The system cannot find the file specified." So I had to download Anaconda. So thank you. I was able to open Python. On Thu, 10 Dec 2020, 00:04 Bob Gailer, wrote: > > > On Wed, Dec 9, 2020, 11:46 AM Siddarth Adiga > wrote: > >> Hello. I wanted to download the Python Version 3.9.1 but it said there was >> already another version of Python already installed. But I have deleted >> the >> program from the ADD OR REMOVE PROGRAMS option. But still I am unable to >> download it. Please help. > > > What OS are you using? > > Exactly what did you do to download? > Exactly what did the error.message say? > > Bob Gailer > >> From tjreedy at udel.edu Wed Dec 9 21:13:44 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Wed, 9 Dec 2020 21:13:44 -0500 Subject: Python idle did not open even after trying many times In-Reply-To: References: Message-ID: On 12/9/2020 11:08 AM, avinash gaur wrote: > Dear Sir/Mam, > I am facing a problem with Python Idle. I am unable to open python idle > even after clicking on it so many times. I am using Python 3.7 on Windows. What are you clicking on? Did IDLE work before? (If you just installed 3.7, why?) Can you start interactive Python? and get >>> prompt? Does 'import tkinter' work? Does 'import idlelib.idle' work? -- Terry Jan Reedy From PythonList at DancesWithMice.info Thu Dec 10 01:13:08 2020 From: PythonList at DancesWithMice.info (dn) Date: Thu, 10 Dec 2020 19:13:08 +1300 Subject: Property type hints? In-Reply-To: <5b5dc1a35ca16d061468abfcb5e0c87d2b2dc33d.camel@anode.ca> References: <3802dbe9-3783-ae69-4e71-84a4be00edb2@DancesWithMice.info> <5b5dc1a35ca16d061468abfcb5e0c87d2b2dc33d.camel@anode.ca> Message-ID: On 10/12/2020 13:06, Paul Bryan wrote: > Thanks for the comprehensive response, dn! > > I guess I'm influenced by data classes here, where the object's > attribute type hints are represented by class variable annotations. I'm a great fan of them too - the saving of 'boilerplate code' does it for me; but yes, the typing benefits come for-free! Just in case it needs to be said: there's no need to 'declare' properties (or any other methods) as if they are class-attributes - either when using data-classes or rolling-your-own! Also, remember that class-attributes will become (actually be 'hidden' by) instance-attributes if used on the LHS of an expression within the class (replicating the 'two' entity problem, discussed earlier). -- Regards =dn From PythonList at DancesWithMice.info Fri Dec 11 13:22:21 2020 From: PythonList at DancesWithMice.info (dn) Date: Sat, 12 Dec 2020 07:22:21 +1300 Subject: Planet Python Message-ID: <76980276-ee36-47e2-5310-84211547cf70@etelligence.info> Has something happened to the Planet Python feed? - Last update: December 07, 2020 04:48 PM UTC -- Regards, =dn From Bischoop at vimart.net Fri Dec 11 20:25:12 2020 From: Bischoop at vimart.net (Bischoop) Date: Sat, 12 Dec 2020 01:25:12 -0000 (UTC) Subject: Function returns old value Message-ID: I've function asking question and comparing it, if is not matching 'yes' it does call itself to ask question again. The problem is that when function is called second time it returns old value or with additional else statement it returns none. Code: https://bpa.st/KVGA How this functions should look properly? -- Thanks in advance From PythonList at DancesWithMice.info Fri Dec 11 20:41:19 2020 From: PythonList at DancesWithMice.info (dn) Date: Sat, 12 Dec 2020 14:41:19 +1300 Subject: Function returns old value In-Reply-To: References: Message-ID: <68064583-3a43-2664-30fe-41093feabf9e@DancesWithMice.info> On 12/12/2020 14:25, Bischoop wrote: > > > > I've function asking question and comparing it, if is not matching 'yes' > it does call itself to ask question again. The problem is that when > function is called second time it returns old value or with additional > else statement it returns none. > > Code: https://bpa.st/KVGA > > How this functions should look properly? In the event of "yes" the function returns a value (return ask). When the function calls itself, what happens to the return-ed value? -- Regards =dn From Bischoop at vimart.net Fri Dec 11 20:48:45 2020 From: Bischoop at vimart.net (Bischoop) Date: Sat, 12 Dec 2020 01:48:45 -0000 (UTC) Subject: Letter replacer - suggestions? References: <0d1257d4-f665-dc14-0201-06eaa54c5ddf@mrabarnett.plus.com> Message-ID: On 2020-12-07, MRAB wrote: > > word = input( f'input word you want to change letters in: ') Yes, I've learn already that should use only when want to use variables I just started using this new f' string method. > > There's no need for the f prefix. > > > print(f' Your word to change: ,{word}') > > Is the comma a typo? > lol mixing old and new methods, just old habit. > > > change_this_list = list(change_this) > > replace_with_list = list(replace_with) > > > > while True: > > try: > > for element in word_list: > > for x in change_this_list: > > if element == x: > > to = word_list.index(element) > > replace = change_this_list.index(x) > > word_list[to] = replace_with_list[replace] > > new_word = ''.join(word_list) > > print(f'{new_word}') > > > You can make it a lot shorter and faster by using a dict. The entire > while loop section can be replaced with: > > replacements = dict(zip(change_this, replace_with)) > new_word = ''.join(replacements.get(letter, letter) for letter in word) > print(new_word Simply and nice, I wouldn't come with that yet at all, beyond my knowledge. Thanks a lot for feedback and suggestions. From pfeiffer at cs.nmsu.edu Fri Dec 11 20:55:43 2020 From: pfeiffer at cs.nmsu.edu (Joe Pfeiffer) Date: Fri, 11 Dec 2020 18:55:43 -0700 Subject: Function returns old value References: Message-ID: <1bblezokio.fsf@pfeifferfamily.net> Bischoop writes: > I've function asking question and comparing it, if is not matching 'yes' > it does call itself to ask question again. The problem is that when > function is called second time it returns old value or with additional > else statement it returns none. > > Code: https://bpa.st/KVGA It calls itself again, but what does it return in that case? From Bischoop at vimart.net Fri Dec 11 21:00:01 2020 From: Bischoop at vimart.net (Bischoop) Date: Sat, 12 Dec 2020 02:00:01 -0000 (UTC) Subject: Letter replacer - suggestions? References: <0d1257d4-f665-dc14-0201-06eaa54c5ddf@mrabarnett.plus.com> Message-ID: On 2020-12-07, Marco Sulla wrote: > Not sure why you want to do this (it's schoolwork)? >Anyway, this is my version: > Thanks, seems nicer I think not to mention those exceptions. So far I'm just learning and doing everythin only for myself so do not think on others users but I know it's good to make a habit. -- Thanks From pbryan at anode.ca Fri Dec 11 21:07:21 2020 From: pbryan at anode.ca (Paul Bryan) Date: Fri, 11 Dec 2020 18:07:21 -0800 Subject: Function returns old value In-Reply-To: <1bblezokio.fsf@pfeifferfamily.net> References: <1bblezokio.fsf@pfeifferfamily.net> Message-ID: <5b86074c9b1c34752373493add07136a62cba8b2.camel@anode.ca> It won't return until the inner call to question (and it's not using the return value on inner call). Eventually, (and not until you answer yes) it will return the first answer. On Fri, 2020-12-11 at 18:55 -0700, Joe Pfeiffer wrote: > Bischoop writes: > > > I've function asking question and comparing it, if is not matching > > 'yes' > > it does call itself to ask question again. The problem is that when > > function is called second time it returns old value or with > > additional > > else statement it returns none. > > > > Code: https://bpa.st/KVGA > > It calls itself again, but what does it return in that case? From pbryan at anode.ca Fri Dec 11 21:09:35 2020 From: pbryan at anode.ca (Paul Bryan) Date: Fri, 11 Dec 2020 18:09:35 -0800 Subject: Function returns old value In-Reply-To: <1bblezokio.fsf@pfeifferfamily.net> References: <1bblezokio.fsf@pfeifferfamily.net> Message-ID: Sorry, actually, if you do not answer yes, will always return None, not the first answer as I suggested. On Fri, 2020-12-11 at 18:55 -0700, Joe Pfeiffer wrote: > Bischoop writes: > > > I've function asking question and comparing it, if is not matching > > 'yes' > > it does call itself to ask question again. The problem is that when > > function is called second time it returns old value or with > > additional > > else statement it returns none. > > > > Code: https://bpa.st/KVGA > > It calls itself again, but what does it return in that case? From Bischoop at vimart.net Fri Dec 11 21:09:15 2020 From: Bischoop at vimart.net (Bischoop) Date: Sat, 12 Dec 2020 02:09:15 -0000 (UTC) Subject: Function returns old value References: <68064583-3a43-2664-30fe-41093feabf9e@DancesWithMice.info> Message-ID: On 2020-12-12, dn wrote: > On 12/12/2020 14:25, Bischoop wrote: >> >> >> >> I've function asking question and comparing it, if is not matching 'yes' >> it does call itself to ask question again. The problem is that when >> function is called second time it returns old value or with additional >> else statement it returns none. >> >> Code: https://bpa.st/KVGA >> >> How this functions should look properly? > > > In the event of "yes" the function returns a value (return ask). > When the function calls itself, what happens to the return-ed value? Well I've put the output in a paste as well, anyway here is what is in a paste: def question(): ask = input("Are you OK?:").lower() if ask != 'yes': question() return ask print (question()) #output: Are you OK?:no Are you OK?:no Are you OK?:yes no --------------------------------------- #Another way with 'elif' statment returns none def question(): ask = input("Are you OK?:").lower() if ask != 'yes': question() elif ask == 'yes': return ask print (question()) #output: Are you OK?:no Are you OK?:yes None #Tried also nested functions, same results: def question(): ask = input("Are you OK?:").lower() def check_question(n): if ask != 'yes': question() else: return ask m = check_question(ask) print (m) question() #output: Are you OK?:no Are you OK?:yes None Process finished with exit code 0 From Bischoop at vimart.net Fri Dec 11 21:13:06 2020 From: Bischoop at vimart.net (Bischoop) Date: Sat, 12 Dec 2020 02:13:06 -0000 (UTC) Subject: Function returns old value References: <1bblezokio.fsf@pfeifferfamily.net> Message-ID: On 2020-12-12, Joe Pfeiffer wrote: > Bischoop writes: > >> I've function asking question and comparing it, if is not matching 'yes' >> it does call itself to ask question again. The problem is that when >> function is called second time it returns old value or with additional >> else statement it returns none. >> >> Code: https://bpa.st/KVGA > > It calls itself again, but what does it return in that case? I've stated it returns old value that I've input first time, anyway output is also inluded in a paste but since you've asked: def question(): ask = input("Are you OK?:").lower() if ask != 'yes': question() return ask print (question()) #output: Are you OK?:no Are you OK?:no Are you OK?:yes no --------------------------------------- #Another way with 'elif' statment returns none def question(): ask = input("Are you OK?:").lower() if ask != 'yes': question() elif ask == 'yes': return ask print (question()) #output: Are you OK?:no Are you OK?:yes None #Tried also nested functions, same results: def question(): ask = input("Are you OK?:").lower() def check_question(n): if ask != 'yes': question() else: return ask m = check_question(ask) print (m) question() #output: Are you OK?:no Are you OK?:yes None Process finished with exit code 0 From PythonList at DancesWithMice.info Fri Dec 11 21:21:29 2020 From: PythonList at DancesWithMice.info (dn) Date: Sat, 12 Dec 2020 15:21:29 +1300 Subject: Function returns old value In-Reply-To: References: <68064583-3a43-2664-30fe-41093feabf9e@DancesWithMice.info> Message-ID: <39e7a344-168b-ee2e-45ec-c5ead771fbdc@DancesWithMice.info> On 12/12/2020 15:09, Bischoop wrote: > On 2020-12-12, dn wrote: >> On 12/12/2020 14:25, Bischoop wrote: >>> >>> >>> >>> I've function asking question and comparing it, if is not matching 'yes' >>> it does call itself to ask question again. The problem is that when >>> function is called second time it returns old value or with additional >>> else statement it returns none. >>> >>> Code: https://bpa.st/KVGA >>> >>> How this functions should look properly? >> >> >> In the event of "yes" the function returns a value (return ask). >> When the function calls itself, what happens to the return-ed value? Apologies, the question was for you to ask yourself; not me asking for me! When you read the code, to where are the results of the 'inner call' assigned? If you can answer this question, you will solve 'the problem'! (and have learned an approach to solving problems in-future) > Well I've put the output in a paste as well, anyway here is what is in a > paste: Thank you. Speaking personally, I prefer the code to be included in the email. However, it would be better to use spaces rather than tabs (Python's preferred style, per PEP-8) because many email packages implement tab-stops as eight-spaces apart. -- Regards =dn From rosuav at gmail.com Fri Dec 11 21:25:26 2020 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 12 Dec 2020 13:25:26 +1100 Subject: Function returns old value In-Reply-To: <39e7a344-168b-ee2e-45ec-c5ead771fbdc@DancesWithMice.info> References: <68064583-3a43-2664-30fe-41093feabf9e@DancesWithMice.info> <39e7a344-168b-ee2e-45ec-c5ead771fbdc@DancesWithMice.info> Message-ID: On Sat, Dec 12, 2020 at 1:23 PM dn via Python-list wrote: > > Speaking personally, I prefer the code to be included in the email. > However, it would be better to use spaces rather than tabs (Python's > preferred style, per PEP-8) because many email packages implement > tab-stops as eight-spaces apart. > Be careful of wording here. PEP 8 does not specify that all Python code should use spaces rather than tabs. Tabs are absolutely fine for your code. ChrisA From PythonList at DancesWithMice.info Fri Dec 11 21:38:06 2020 From: PythonList at DancesWithMice.info (dn) Date: Sat, 12 Dec 2020 15:38:06 +1300 Subject: Function returns old value In-Reply-To: References: <68064583-3a43-2664-30fe-41093feabf9e@DancesWithMice.info> <39e7a344-168b-ee2e-45ec-c5ead771fbdc@DancesWithMice.info> Message-ID: <4733a888-bd34-9528-293c-7b640b2c014e@DancesWithMice.info> On 12/12/2020 15:25, Chris Angelico wrote: > On Sat, Dec 12, 2020 at 1:23 PM dn via Python-list > wrote: >> >> Speaking personally, I prefer the code to be included in the email. >> However, it would be better to use spaces rather than tabs (Python's >> preferred style, per PEP-8) because many email packages implement >> tab-stops as eight-spaces apart. >> > > Be careful of wording here. PEP 8 does not specify that all Python > code should use spaces rather than tabs. Tabs are absolutely fine for > your code. Hence "preferred", cf "prescribed" or "required". My personal reaction when ppl do make such a demand, is to use the facility built-in to decent editors/IDEs to change from one to the other - no fuss, no muss; peace reigns amongst the team once again...! Wish could do that with such ease in other applications! Nevertheless, email-client observation applies... -- Regards =dn From rosuav at gmail.com Fri Dec 11 21:47:54 2020 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 12 Dec 2020 13:47:54 +1100 Subject: Function returns old value In-Reply-To: <4733a888-bd34-9528-293c-7b640b2c014e@DancesWithMice.info> References: <68064583-3a43-2664-30fe-41093feabf9e@DancesWithMice.info> <39e7a344-168b-ee2e-45ec-c5ead771fbdc@DancesWithMice.info> <4733a888-bd34-9528-293c-7b640b2c014e@DancesWithMice.info> Message-ID: On Sat, Dec 12, 2020 at 1:39 PM dn via Python-list wrote: > > On 12/12/2020 15:25, Chris Angelico wrote: > > On Sat, Dec 12, 2020 at 1:23 PM dn via Python-list > > wrote: > >> > >> Speaking personally, I prefer the code to be included in the email. > >> However, it would be better to use spaces rather than tabs (Python's > >> preferred style, per PEP-8) because many email packages implement > >> tab-stops as eight-spaces apart. > >> > > > > Be careful of wording here. PEP 8 does not specify that all Python > > code should use spaces rather than tabs. Tabs are absolutely fine for > > your code. > > Hence "preferred", cf "prescribed" or "required". It's not even that. It's required for the standard library, and not at all a language recommendation elsewhere. > My personal reaction when ppl do make such a demand, is to use the > facility built-in to decent editors/IDEs to change from one to the other > - no fuss, no muss; peace reigns amongst the team once again...! > > Wish could do that with such ease in other applications! Ah yes, and then you have these massive source control diffs when you do a meaningless conversion over large slabs of the code! Perfect, just what we wanted. For teams that disagree on the correct width of indentation levels, why not standardize on a single token meaning "indentation level", and then allow everyone to configure their editors to show it at whatever width they prefer? > Nevertheless, email-client observation applies... Yes. Make sure you use an email client that supports leading whitespace of all forms. Otherwise you're not going to have a good time of it. ChrisA From Bischoop at vimart.net Fri Dec 11 20:49:58 2020 From: Bischoop at vimart.net (Bischoop) Date: Sat, 12 Dec 2020 01:49:58 -0000 (UTC) Subject: Letter replacer - suggestions? References: <0d1257d4-f665-dc14-0201-06eaa54c5ddf@mrabarnett.plus.com> Message-ID: On 2020-12-07, Grant Edwards wrote: > On 2020-12-07, MRAB wrote: > >> Avoid a 'bare' except unless you _really_ mean it, which is >> virtually never. Catch only those exceptions that you're going to >> handle. > > And sometimes "handling" is just printing some extra stuff and then > re-raising the original exception: > > try: > something(): > except: > print() > raise > > Noted, thanks. From tjreedy at udel.edu Fri Dec 11 20:59:07 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Fri, 11 Dec 2020 20:59:07 -0500 Subject: Function returns old value In-Reply-To: References: Message-ID: On 12/11/2020 8:25 PM, Bischoop wrote: > I've function asking question and comparing it, if is not matching 'yes' > it does call itself to ask question again. The problem is that when > function is called second time it returns old value or with additional > else statement it returns none. > > Code: https://bpa.st/?????? Don't post links to unknown sites. Reduce it to the minimum needed to exhibit the questionable behavior and include inline with the question. > How this functions should look properly? -- Terry Jan Reedy From ast at invalid Sat Dec 12 01:39:49 2020 From: ast at invalid (ast) Date: Sat, 12 Dec 2020 07:39:49 +0100 Subject: Returning from a multiple stacked call at once Message-ID: <5fd465b5$0$8956$426a74cc@news.free.fr> Hello In case a function recursively calls itself many times, is there a way to return a data immediately without unstacking all functions ? From cs at cskk.id.au Sat Dec 12 03:18:25 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Sat, 12 Dec 2020 19:18:25 +1100 Subject: Returning from a multiple stacked call at once In-Reply-To: <5fd465b5$0$8956$426a74cc@news.free.fr> References: <5fd465b5$0$8956$426a74cc@news.free.fr> Message-ID: <20201212081825.GA17222@cskk.homeip.net> On 12Dec2020 07:39, ast wrote: >In case a function recursively calls itself many times, >is there a way to return a data immediately without >unstacking all functions ? Not really. Do you have an example where this is inconvenient? There are alternatives, for example passing in a Queue and put()ing the data onto the queue. It's quite dependent on what you're trying to do though. Cheers, Cameron Simpson From cs at cskk.id.au Sat Dec 12 03:51:52 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Sat, 12 Dec 2020 19:51:52 +1100 Subject: Letter replacer - suggestions? In-Reply-To: References: Message-ID: <20201212085152.GA23786@cskk.homeip.net> On 12Dec2020 01:49, Bischoop wrote: >On 2020-12-07, Grant Edwards wrote: >> On 2020-12-07, MRAB wrote: >>> Avoid a 'bare' except unless you _really_ mean it, which is >>> virtually never. Catch only those exceptions that you're going to >>> handle. >> >> And sometimes "handling" is just printing some extra stuff and then >> re-raising the original exception: >> >> try: >> something(): >> except: >> print() >> raise > >Noted, thanks. Also note that the exception itself is very interesting. So: except Exception as e: print(, e) raise Cheers, Cameron Simpson From jornws200602 at xs4all.nl Sat Dec 12 10:59:31 2020 From: jornws200602 at xs4all.nl (Oscar) Date: 12 Dec 2020 15:59:31 GMT Subject: To check if number is in range(x,y) References: Message-ID: <5fd4e8e3$0$301$e4fe514c@news.xs4all.nl> In article , Bischoop wrote: >I've also convert the choice to int() but doesn't help. Oh.. did not read this yet. How did you do this? In both places after the input or during the comparison? If so, in which version? Only the first version would work. The other two are just plain wrong. -- [J|O|R] <- .signature.gz From Bischoop at vimart.net Sat Dec 12 11:03:07 2020 From: Bischoop at vimart.net (Bischoop) Date: Sat, 12 Dec 2020 16:03:07 -0000 (UTC) Subject: To check if number is in range(x,y) References: <5fd4e8e3$0$301$e4fe514c@news.xs4all.nl> Message-ID: On 2020-12-12, Oscar wrote: > In article , > Bischoop wrote: >>I've also convert the choice to int() but doesn't help. > > Oh.. did not read this yet. How did you do this? In both places after > the input or during the comparison? If so, in which version? Only the > first version would work. The other two are just plain wrong. after the input, https://bpa.st/BFJA From jornws200602 at xs4all.nl Sat Dec 12 11:10:46 2020 From: jornws200602 at xs4all.nl (Oscar) Date: 12 Dec 2020 16:10:46 GMT Subject: Returning from a multiple stacked call at once References: <5fd465b5$0$8956$426a74cc@news.free.fr> Message-ID: <5fd4eb86$0$301$e4fe514c@news.xs4all.nl> In article <5fd465b5$0$8956$426a74cc at news.free.fr>, ast wrote: >Hello > >In case a function recursively calls itself many times, >is there a way to return a data immediately without >unstacking all functions ? If you are referring to your "are you ok?" problem, please read up on recursion and when and how to use it. You were doing it completely wrong. You only call a function from *whitin itself* if you need recursion. It's quite hard to explain in a few words, so just google it. I'm sure there are many great explanations around. -- [J|O|R] <- .signature.gz From Bischoop at vimart.net Sat Dec 12 10:12:25 2020 From: Bischoop at vimart.net (Bischoop) Date: Sat, 12 Dec 2020 15:12:25 -0000 (UTC) Subject: To check if number is in range(x,y) Message-ID: I need to check if input number is 1-5. Whatever I try it's not working. Here are my aproaches to the problem: https://bpa.st/H62A What I'm doing wrong and how I should do it? -- Thanks From Bischoop at vimart.net Sat Dec 12 10:37:17 2020 From: Bischoop at vimart.net (Bischoop) Date: Sat, 12 Dec 2020 15:37:17 -0000 (UTC) Subject: To check if number is in range(x,y) References: Message-ID: I've also convert the choice to int() but doesn't help. From jornws200602 at xs4all.nl Sat Dec 12 10:57:42 2020 From: jornws200602 at xs4all.nl (Oscar) Date: 12 Dec 2020 15:57:42 GMT Subject: To check if number is in range(x,y) References: Message-ID: <5fd4e876$0$301$e4fe514c@news.xs4all.nl> In article , Bischoop wrote: > >I need to check if input number is 1-5. Whatever I try it's not working. >Here are my aproaches to the problem: https://bpa.st/H62A > >What I'm doing wrong and how I should do it? You need to learn about types. ;-) Input returns a string. That string is not in the range you compare it to. You need to convert it to an int: choice = int(input.. ) This is assuming you want a whole number. You compare it against the list of numbers [1, 2, 3, 4, 5]. If 2.4 is also a valid number, you need a different comparison. 2.4 is not in this list. So first you should get your requirements straight.. ;-) -- [J|O|R] <- .signature.gz From Bischoop at vimart.net Sat Dec 12 11:02:02 2020 From: Bischoop at vimart.net (Bischoop) Date: Sat, 12 Dec 2020 16:02:02 -0000 (UTC) Subject: To check if number is in range(x,y) References: Message-ID: Got it solved here: https://bpa.st/BFJA From ast at invalid Sat Dec 12 11:46:33 2020 From: ast at invalid (ast) Date: Sat, 12 Dec 2020 17:46:33 +0100 Subject: Returning from a multiple stacked call at once In-Reply-To: References: <5fd465b5$0$8956$426a74cc@news.free.fr> <20201212081825.GA17222@cskk.homeip.net> Message-ID: <5fd4f3ea$0$6469$426a74cc@news.free.fr> Le 12/12/2020 ? 09:18, Cameron Simpson a ?crit?: > On 12Dec2020 07:39, ast wrote: >> In case a function recursively calls itself many times, >> is there a way to return a data immediately without >> unstacking all functions ? > > Not really. Do you have an example where this is inconvenient? > > There are alternatives, for example passing in a Queue and put()ing the > data onto the queue. It's quite dependent on what you're trying to do > though. > > Cheers, > Cameron Simpson > I don't really need it. I was just wondering and guessed it was not feasible. Here is a code where it would be useful. This code looks for a path in a graph. If the found path is long, say 100 nodes, then path_finder calls itself recursively 100 times, and has to unstack 100 times to provide the found path. It could be returned immediately. def path_finder(graph, start, end, path=[]): if start in path: return None if start == end: return path + [start] # Found ! if start not in graph: return None path = path + [start] for node in graph[start]: found_path = path_finder(graph, node, end, path) if found_path: return found_path return None graph = {'A': ['B', 'C'], 'B': ['C', 'D'], 'C': ['D'], 'D': ['C'], 'E': ['F'], 'F': ['C']} path_finder(graph, 'A', 'D') From ast at invalid Sat Dec 12 11:49:56 2020 From: ast at invalid (ast) Date: Sat, 12 Dec 2020 17:49:56 +0100 Subject: Returning from a multiple stacked call at once In-Reply-To: <5fd4eb86$0$301$e4fe514c@news.xs4all.nl> References: <5fd465b5$0$8956$426a74cc@news.free.fr> <5fd4eb86$0$301$e4fe514c@news.xs4all.nl> Message-ID: <5fd4f4b5$0$8928$426a74cc@news.free.fr> Le 12/12/2020 ? 17:10, Oscar a ?crit?: > In article <5fd465b5$0$8956$426a74cc at news.free.fr>, ast wrote: >> Hello >> >> In case a function recursively calls itself many times, >> is there a way to return a data immediately without >> unstacking all functions ? > > If you are referring to your "are you ok?" problem, please read up on > recursion and when and how to use it. You were doing it completely > wrong. You only call a function from *whitin itself* if you need > recursion. It's quite hard to explain in a few words, so just google it. > I'm sure there are many great explanations around. > not understood. From python.list at tim.thechases.com Sat Dec 12 11:37:50 2020 From: python.list at tim.thechases.com (Tim Chase) Date: Sat, 12 Dec 2020 10:37:50 -0600 Subject: Returning from a multiple stacked call at once In-Reply-To: <5fd465b5$0$8956$426a74cc@news.free.fr> References: <5fd465b5$0$8956$426a74cc@news.free.fr> Message-ID: <20201212103750.52069d42@bigbox.attlocal.net> On 2020-12-12 07:39, ast wrote: > In case a function recursively calls itself many times, > is there a way to return a data immediately without > unstacking all functions ? Not that I'm aware of. If you use recursion (and AFAIK, Python doesn't support tail-recursion), you pay all the pushes & pay all the pops. If you convert it to an iterative algorithm, you can bail early with items still in the work queue: while queue: item = queue.get() if test(item): print(f"Found it, bailing early with {len(queue)} item(s)") break more = process(item) if more: queue.extend(more) -tkc From python.list at tim.thechases.com Sat Dec 12 11:51:00 2020 From: python.list at tim.thechases.com (Tim Chase) Date: Sat, 12 Dec 2020 10:51:00 -0600 Subject: To check if number is in range(x,y) In-Reply-To: References: Message-ID: <20201212105100.68a7568e@bigbox.attlocal.net> On 2020-12-12 15:12, Bischoop wrote: > I need to check if input number is 1-5. Whatever I try it's not > working. Here are my aproaches to the problem: https://bpa.st/H62A > > What I'm doing wrong and how I should do it? A range is similar to a list in that it contains just the numbers listed: >>> r = range(10) >>> 2 in r True >>> 2.5 in r False >>> r = range(1, 10, 2) >>> 2 in r False >>> list(r) [1, 3, 5, 7, 9] It also doesn't automatically convert from the string inputs you're getting from the input() function: >>> s = "5" >>> s in r False >>> int(s) in r True Additionally, note that the endpoint of the range is exclusive so >>> r = range(1, 10) >>> 10 in r False >>> list(r) [1, 2, 3, 4, 5, 6, 7, 8, 9] If you want numeric-range checks, Python provides the lovely double-comparison syntax: >>> x = 5 >>> 2 < x < 10 True >>> x = 5.5 >>> 2 < x < 10 True >>> s = "5" >>> 2 < s < 10 Traceback? >>> 2 < int(s) < 10 True Hopefully this gives you the hints that you need to troubleshoot. -tkc From dieter at handshake.de Sat Dec 12 12:20:17 2020 From: dieter at handshake.de (Dieter Maurer) Date: Sat, 12 Dec 2020 18:20:17 +0100 Subject: Returning from a multiple stacked call at once In-Reply-To: <5fd465b5$0$8956$426a74cc@news.free.fr> References: <5fd465b5$0$8956$426a74cc@news.free.fr> Message-ID: <24532.64465.213850.33597@ixdm.fritz.box> ast wrote at 2020-12-12 07:39 +0100: >In case a function recursively calls itself many times, >is there a way to return a data immediately without >unstacking all functions ? Python does not have "long jump"s (out of many functions, many loop incarnations). In some cases, you can use exceptions to emulate "long jump"s. From avigross at verizon.net Sat Dec 12 13:21:02 2020 From: avigross at verizon.net (Avi Gross) Date: Sat, 12 Dec 2020 13:21:02 -0500 Subject: Returning from a multiple stacked call at once In-Reply-To: <24532.64465.213850.33597@ixdm.fritz.box> References: <5fd465b5$0$8956$426a74cc@news.free.fr> <24532.64465.213850.33597@ixdm.fritz.box> Message-ID: <012901d6d0b3$8ccf5650$a66e02f0$@verizon.net> As always, it may be useful to know WHY the questioner wants to skip intermediate functions already in progress and jump back to some unspecified earlier level. There is a reason why functions are "stacked" and there are data structures that really may need to be unwound. But if the question is not about some sort of "efficiency" or speed but about ways to write the code so once something has been found, it can fairly directly return, that does have answers. Tail recursion is an example, sometimes real as in the function is overlaid and there is no need to return and sometimes sort of simulated with overhead remaining but it looks like it returned. If all the functions written are your own, then simply calling your next function that you want to be the return value (from anywhere applicable in the function, not just the end, is easy enough to write as: return(next_function(args)) It will still unwind but logically will act as if it just returns without the need for the functions to be written with lots of if statements or twisted logic so nothing much gets done after the right result is obtained. And, of course, there are exceptions. If you raise an exception that you know will not be caught until you reach the level where you do catch it, you can sort of sail through any of the functions between and bypass any logic that might otherwise be there for a normal return. Arguably it might be better to write your code carefully so upon success, it unwinds easily and only in low probability cases look for an abrupt exit. And for a really abrupt exit, there is a way to shut down the program very abruptly perhaps even too abruptly. -----Original Message----- From: Python-list On Behalf Of Dieter Maurer Sent: Saturday, December 12, 2020 12:20 PM To: ast Cc: python-list at python.org Subject: Re: Returning from a multiple stacked call at once ast wrote at 2020-12-12 07:39 +0100: >In case a function recursively calls itself many times, is there a way >to return a data immediately without unstacking all functions ? Python does not have "long jump"s (out of many functions, many loop incarnations). In some cases, you can use exceptions to emulate "long jump"s. -- https://mail.python.org/mailman/listinfo/python-list Scanned by McAfee and confirmed virus-free. Find out more here: https://bit.ly/2zCJMrO From 2QdxY4RzWzUUiLuE at potatochowder.com Sat Dec 12 13:13:55 2020 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Sat, 12 Dec 2020 12:13:55 -0600 Subject: To check if number is in range(x,y) In-Reply-To: <20201212105100.68a7568e@bigbox.attlocal.net> References: <20201212105100.68a7568e@bigbox.attlocal.net> Message-ID: On 2020-12-12 at 10:51:00 -0600, Tim Chase wrote: > If you want numeric-range checks, Python provides the lovely > double-comparison syntax: > > >>> x = 5 > >>> 2 < x < 10 > True Not just numbers: >>> 'm' < 'n' < 'o' True >>> 'one' < 'one point five' < 'two' True Okay, so the second one is a trap, but you get the idea. ;-) From pfeiffer at cs.nmsu.edu Sat Dec 12 14:51:50 2020 From: pfeiffer at cs.nmsu.edu (Joe Pfeiffer) Date: Sat, 12 Dec 2020 12:51:50 -0700 Subject: Function returns old value References: <1bblezokio.fsf@pfeifferfamily.net> Message-ID: <1beejuby5l.fsf@pfeifferfamily.net> Bischoop writes: > On 2020-12-12, Joe Pfeiffer wrote: >> Bischoop writes: >> >>> I've function asking question and comparing it, if is not matching 'yes' >>> it does call itself to ask question again. The problem is that when >>> function is called second time it returns old value or with additional >>> else statement it returns none. >>> >>> Code: https://bpa.st/KVGA >> >> It calls itself again, but what does it return in that case? > > I've stated it returns old value that I've input first time, anyway > output is also inluded in a paste but since you've asked: Sorry, my question wasn't clear. What I meant was, "in your return statement, what are you returning"? You need to be returning the value from the recursive call. > def question(): > ask = input("Are you OK?:").lower() > if ask != 'yes': > question() > return ask > > print (question()) > > #output: > Are you OK?:no > Are you OK?:no > Are you OK?:yes > no > > --------------------------------------- > #Another way with 'elif' statment returns none > > > def question(): > ask = input("Are you OK?:").lower() > if ask != 'yes': > question() > elif ask == 'yes': > return ask > > print (question()) > > #output: > Are you OK?:no > Are you OK?:yes > None > > #Tried also nested > functions, same results: > > def question(): > ask = input("Are you > OK?:").lower() > > def > check_question(n): > if ask > != > 'yes': > question() > else: > return > ask > > m > = > check_question(ask) > print > (m) > question() > > #output: > Are > you > OK?:no > Are > you > OK?:yes > None > > Process > finished > with > exit > code > 0 From PythonList at DancesWithMice.info Sat Dec 12 15:33:18 2020 From: PythonList at DancesWithMice.info (dn) Date: Sun, 13 Dec 2020 09:33:18 +1300 Subject: Returning from a multiple stacked call at once In-Reply-To: <5fd4f3ea$0$6469$426a74cc@news.free.fr> References: <5fd465b5$0$8956$426a74cc@news.free.fr> <20201212081825.GA17222@cskk.homeip.net> <5fd4f3ea$0$6469$426a74cc@news.free.fr> Message-ID: On 13/12/2020 05:46, ast wrote: > Le 12/12/2020 ? 09:18, Cameron Simpson a ?crit?: >> On 12Dec2020 07:39, ast wrote: >>> In case a function recursively calls itself many times, >>> is there a way to return a data immediately without >>> unstacking all functions ? >> >> Not really. Do you have an example where this is inconvenient? >> >> There are alternatives, for example passing in a Queue and put()ing the >> data onto the queue. It's quite dependent on what you're trying to do >> though. > > I don't really need it. I was just wondering and guessed it was > not feasible. [somewhat simplified] The way Python handles recursion is to add a "frame" every time the function is called. The "frame" contains all the data-items for the function. Think of the frames as stacked on top of each other: frame n frame n+1 frame n+2 ... NB you can 'see' this when viewing an exception tracing its way from a deeply-nested function, to the function which called it, to the function which called that, etc. This is how node-1's attributes are kept separate from node-2's. If you think that only the 'current frame' as being visible at any stage of the program's execution, it will suit our purposes for-now. One effect of a "return" is to close the current frame (and to carry any return-value 'back' to the previous frame). Per comment (below), if this function recurses 100 times, then there will be 100 frames. Accordingly, there need to be 100 returns to close each of those frames. NB Python offers reflective facilities to inspect all of this, if you really want to see what happens 'under the hood/bonnet'. > Here is a code where it would be useful. This code looks for a > path in a graph. > If the found path is long, say 100 nodes, then path_finder calls > itself recursively 100 times, and has to unstack 100 times to > provide the found path. It could be returned immediately. > ... Recursion may not be the best tool/tactic here. As you observe, it has to be 'unwound'! Assuming the objectives are: 1 trace through a graph 2 locate an identified node 3 note (and make available 'later') the path through the graph to reach said node. The logic for (1) and (2) has been done. For (3), consider using a "stack". This is a ComSc term (in case you've not studied such), and is the same concept as the 'stack of frames' (above). 1 Create a list "stack". 2 Walk the network. 3 Upon 'arrival' at a node, add the node to the 'stack' by appending relevant detail(s) to the list. 4 If the node is 'the end', stop walking. If the 'walk' is a loop (cf recursion), the 'stop' becomes a (single) "break". If the identified node is found 50-nodes 'in', or 100-nodes, that will be the length of the list/stack. (which BTW will require less storage than the same number of recursion-frames) Now, back to ComSc (again, with apologies for appearing to 'talk-down', if you've studied this stuff but let's help anyone else 'following along at home'), when it comes to using the list/stack, if you start with the found-node and work your way 'back' to the start-node, this will require working from the list[ -1 ] element, back to the zero-th element. Accessing each element is known as "popping the stack", and you will find a Python list.method() enacting such - but be careful about the working-backwards logic! Conversely, if the ensuing functionality wants to 'start' from the start-node and walk 'forward' through the graph to the found-node; then that process will start at list[ 0 ], per most collection-processing. In which case, rather than a "stack", we are looking at a "queue" (per @Cameron). Thus, a "stack" accepts additions to 'the end', and "pops" data from the same 'end' ("LIFO" = last-in, first-out). Whereas a "queue" also adds to 'the end', but processes/pops from the beginning ("FIFO" = first-in, first-out). If this ComSc-stuff is 'new', then plenty of books and web-sites discuss such data-structures... -- Regards =dn From cs at cskk.id.au Sat Dec 12 16:37:42 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Sun, 13 Dec 2020 08:37:42 +1100 Subject: Returning from a multiple stacked call at once In-Reply-To: <5fd4f3ea$0$6469$426a74cc@news.free.fr> References: <5fd4f3ea$0$6469$426a74cc@news.free.fr> Message-ID: <20201212213742.GA67229@cskk.homeip.net> On 12Dec2020 17:46, ast wrote: >Le 12/12/2020 ? 09:18, Cameron Simpson a ?crit?: >>On 12Dec2020 07:39, ast wrote: >>>In case a function recursively calls itself many times, >>>is there a way to return a data immediately without >>>unstacking all functions ? >> >>Not really. Do you have an example where this is inconvenient? >>There are alternatives, for example passing in a Queue and put()ing >>the data onto the queue. [...] > >I don't really need it. I was just wondering and guessed it was >not feasible. Well, it is feasible. Kinda. Regardless, the stack need to unwind. You _could_ abuse exceptions to do that in a single go: class CompletedOperation(Exception): def __init__(self, value): self.value = value ... in your function ... raise CompletedOperation(the_value) ... at the calling end ... try: call_the_function(....) except CompletedOperation as e: value = e.value else: ... value not found ... or obvious variations where that try/except it done by the outermost function invocation, concealing it from users. But usually you just return the value from the innermost call and return that in turn: def f(....): for subpart in ... stuff ...: value = f(subpart) if value is not None: return value return None which searches some data structure and returns nonNone on finding something, None if not found. >Here is a code where it would be useful. This code looks for a >path in a graph. >If the found path is long, say 100 nodes, then path_finder calls >itself recursively 100 times, and has to unstack 100 times to >provide the found path. It could be returned immediately. The above code returns efficiently. But there's a cascade of returns. WRT to the below code, I thought I'd restate what DL Neil has said: you can often make these things nonrecursive by maintaining a queue or stack of pending tasks. A recursive function keeps it state in the call stack, but you needn't do that: def f(node,...): pending = [node] while pending: node = pending.pop(0) if node is the one you're looking for: return node pending.extend(children of the node here ...) return None This keeps a queue of unexamined nodes in pending. You could make that a stack by replacing the .pop(0) with .pop(). That will be more efficient (remove the leading element of a list is comparatively expensive) but changes the search order. Anyway, this is what DL Neil is referring to: a nonrecursive function with a data structure to hold the coming work, which a recursive function would process by calling itself instead of saving the undone task (chid nodes, here). Cheers, Cameron Simpson From greg.ewing at canterbury.ac.nz Sat Dec 12 18:52:50 2020 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Sun, 13 Dec 2020 12:52:50 +1300 Subject: Returning from a multiple stacked call at once In-Reply-To: <5fd4f3ea$0$6469$426a74cc@news.free.fr> References: <5fd465b5$0$8956$426a74cc@news.free.fr> <20201212081825.GA17222@cskk.homeip.net> <5fd4f3ea$0$6469$426a74cc@news.free.fr> Message-ID: On 13/12/20 5:46 am, ast wrote: > Here is a code where it would be useful. This code looks for a > path in a graph. Recursion is probably not the best way to solve this problem in CPython, because it imposes a limit on the number of nested calls (in order to detect runaway recursion). By default the limit is about 1000. So if you have a large graph with a path more than 1000 steps long, you can hit the recursion limit. -- Greg From Bischoop at vimart.net Sat Dec 12 19:01:43 2020 From: Bischoop at vimart.net (Bischoop) Date: Sun, 13 Dec 2020 00:01:43 -0000 (UTC) Subject: Unable to pass dict from json. Message-ID: Here https://bpa.st/YBVA I've working code with dictionary only if used dict from the code (it's commented now) but when I load it I can print it from load function (line 14) but at all have not a clue how to pass the data so could use them. I've learnt a lot when making it but here I'm completetly stuck, was trying do solve it for a whole day and it's just a death wall for me. -- Thanks From Bischoop at vimart.net Sat Dec 12 17:57:48 2020 From: Bischoop at vimart.net (Bischoop) Date: Sat, 12 Dec 2020 22:57:48 -0000 (UTC) Subject: To check if number is in range(x,y) References: <20201212105100.68a7568e@bigbox.attlocal.net> Message-ID: On 2020-12-12, Tim Chase wrote: > > Hopefully this gives you the hints that you need to troubleshoot. > > -tkc > > > > Yes it explains a lot. Thanks From drsalists at gmail.com Sat Dec 12 19:44:30 2020 From: drsalists at gmail.com (Dan Stromberg) Date: Sat, 12 Dec 2020 16:44:30 -0800 Subject: Unable to pass dict from json. In-Reply-To: References: Message-ID: On Sat, Dec 12, 2020 at 4:05 PM Bischoop wrote: > > Here https://bpa.st/YBVA I've working code with dictionary only if used > dict from the code > (it's commented now) but when I load it I can print it from load > function (line 14) but at all have not a > clue how to pass the data so could use them. > I've learnt a lot when making it but here I'm completetly stuck, was > trying do solve it for a whole day and it's just a death wall for me. > I too recommend cutting and pasting minimal code into your e-mail, instead of referring to a URL; URL's used this way are a common attack vector. From python at mrabarnett.plus.com Sat Dec 12 19:54:09 2020 From: python at mrabarnett.plus.com (MRAB) Date: Sun, 13 Dec 2020 00:54:09 +0000 Subject: Unable to pass dict from json. In-Reply-To: References: Message-ID: On 2020-12-13 00:01, Bischoop wrote: > > Here https://bpa.st/YBVA I've working code with dictionary only if used dict from the code > (it's commented now) but when I load it I can print it from load > function (line 14) but at all have not a > clue how to pass the data so could use them. > I've learnt a lot when making it but here I'm completetly stuck, was > trying do solve it for a whole day and it's just a death wall for me. > It would be better to use a loop instead of recursion in load_options when asking for the choice. load_json returns the data, so just have load_options return it and then pass it in to the functions that need it. There's no need to make 'load_json' and the others local to 'load_from_file', and similarly for save_tofile. From jfong at ms4.hinet.net Sat Dec 12 21:17:40 2020 From: jfong at ms4.hinet.net (Jach Feng) Date: Sat, 12 Dec 2020 18:17:40 -0800 (PST) Subject: To whom he want to set breakpoint on negative line number in pdb Message-ID: <32c60cb3-8fdd-4c4b-b271-f05363440c2an@googlegroups.com> I use .pdbrc file to help debugging. To avoid editing this file frequently when source was modified, I need this feature. I modify the checkline function in pdb.py from ... line = linecache.getline(filename, lineno, globs) if not line: .... to ... lines = linecache.getlines(filename, globs) if lineno < 0: lineno = len(lines) + lineno + 1 # change to a valid positive number, or not if 1 <= lineno <= len(lines): line = lines[lineno-1] else: line = '' if not line: ... This modification is mostly the copy of the getline function body except the added line. It will not influence the original pdb usage in anyway. --Jach From grant.b.edwards at gmail.com Sat Dec 12 19:46:12 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Sun, 13 Dec 2020 00:46:12 -0000 (UTC) Subject: Unable to pass dict from json. References: Message-ID: On 2020-12-13, Bischoop wrote: > Here https://bpa.st/YBVA Don't do that. Include in your post a short example that illustrates your questions. > I've working code with dictionary only if used dict from the code > [...] From ethan at stoneleaf.us Sun Dec 13 12:54:20 2020 From: ethan at stoneleaf.us (Ethan Furman) Date: Sun, 13 Dec 2020 09:54:20 -0800 Subject: Fwd: Fwd: How to specify JSON parameters in CallBack? In-Reply-To: References: Message-ID: From: Caleb Gattegno Date: Fri, Dec 11, 2020 at 5:02 PM Subject: How to specify JSON parameters in CallBack? Please can you suggest where should I look for advice on converting a old style web app which vends whole pages of html with a cgi-bin/python script invoked bypython3 server.py, into one that only serves callbacks to this Javascript AJAX async RPC call: $('#compute').click(function() { ? ? $('#poly').val('Waiting...'); ? ? var seq = $('#seq').val(); ? ? console.log(seq); ? ? $.post('/compute', seq, function(result) { ? ? ? ? $('#poly').val(result.poly); ? ? }, 'json'); }); I don?t want to touch the html/javascript, but I?d like to update the python cgi code module to respond to the RPC call in the post by returning a json data structure. Poly is a string of variable length. Many thanks gattegnPython From rosuav at gmail.com Sun Dec 13 13:25:02 2020 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 14 Dec 2020 05:25:02 +1100 Subject: Fwd: How to specify JSON parameters in CallBack? In-Reply-To: References: Message-ID: On Mon, Dec 14, 2020 at 4:57 AM Ethan Furman wrote: > > From: Caleb Gattegno > Date: Fri, Dec 11, 2020 at 5:02 PM > Subject: How to specify JSON parameters in CallBack? > > > Please can you suggest where should I look for advice on converting a old style web app which vends whole pages of html > with a cgi-bin/python script invoked bypython3 server.py, into one that only serves callbacks to this Javascript AJAX > async RPC call: > > $('#compute').click(function() { > $('#poly').val('Waiting...'); > > var seq = $('#seq').val(); > console.log(seq); > $.post('/compute', seq, function(result) { > $('#poly').val(result.poly); > }, 'json'); > }); > > I don?t want to touch the html/javascript, but I?d like to update the python cgi code module to respond to the RPC call > in the post by returning a json data structure. Poly is a string of variable length. > First place to look would be a well-known server framework. I use Flask, but there are others. Figure out exactly what your front end is sending; use your web browser's developer tools to inspect the requests, and then code your back end to match. Writing a JSON-based API in Flask is pretty straight-forward. Here's an example: @app.route("/api/widgets") def list_setups(): return jsonify(database.list_widgets()) @app.route("/api/widgets/") def get_widget(id): return jsonify(database.get_widget(id)) @app.route("/api/widgets", methods=["POST"]) def create_widget(): if not request.json: return jsonify({}), 400 missing = {"name", "purpose"} - set(request.json) if missing: return jsonify({"error": "Missing: " + ", ".join(sorted(missing))}), 400 widget = database.create_widget(request.json["name"], request.json["purpose"]) return jsonify(widget) (For a real example, see https://github.com/Rosuav/MustardMine/blob/master/mustard.py#L643 - although that has a lot of other complexities.) ChrisA From sh at changeset.nyc Sun Dec 13 16:22:39 2020 From: sh at changeset.nyc (Sumana Harihareswara) Date: Sun, 13 Dec 2020 16:22:39 -0500 Subject: pip 20.3 release (heads-up for potential disruption) In-Reply-To: <5d8a1134-82a0-6c81-03f9-c8d9de9b21f4@changeset.nyc> References: <5d8a1134-82a0-6c81-03f9-c8d9de9b21f4@changeset.nyc> Message-ID: On 11/30/20 8:33 AM, Sumana Harihareswara wrote: > 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 Incidentally, I should have mentioned in my previous email: pip 20.3 turned the new resolver on by default for Python 3 users. When users use pip 20.3 in a Python 2 environment, the old dependency resolver is still the default. Python 2 users should also note that pip 21.0 in January will remove Python 2 support: https://pip.pypa.io/en/latest/development/release-process/#python-2-support . -- Sumana Harihareswara From jornws200602 at xs4all.nl Sun Dec 13 16:41:41 2020 From: jornws200602 at xs4all.nl (Oscar) Date: 13 Dec 2020 21:41:41 GMT Subject: Returning from a multiple stacked call at once References: <5fd465b5$0$8956$426a74cc@news.free.fr> <5fd4eb86$0$301$e4fe514c@news.xs4all.nl> <5fd4f4b5$0$8928$426a74cc@news.free.fr> Message-ID: <5fd68a95$0$305$e4fe514c@news.xs4all.nl> In article <5fd4f4b5$0$8928$426a74cc at news.free.fr>, ast wrote: >Le 12/12/2020 ?? 17:10, Oscar a ??crit??: >> In article <5fd465b5$0$8956$426a74cc at news.free.fr>, ast wrote: >>> Hello >>> >>> In case a function recursively calls itself many times, >>> is there a way to return a data immediately without >>> unstacking all functions ? >> >> If you are referring to your "are you ok?" problem, please read up on >> recursion and when and how to use it. You were doing it completely >> wrong. You only call a function from *whitin itself* if you need >> recursion. It's quite hard to explain in a few words, so just google it. >> I'm sure there are many great explanations around. >> > >not understood. I understand! Sorry... Somehow I mixed you up with another poster that was clearly beginning with programming and wrote an input function that called itself recursively when it received invalid input. Then he was suprised the calling function got the very first (invalid) value. You clearly know your way around recursion. Sorry again! ;-) -- [J|O|R] <- .signature.gz From PythonList at DancesWithMice.info Mon Dec 14 13:08:30 2020 From: PythonList at DancesWithMice.info (dn) Date: Tue, 15 Dec 2020 07:08:30 +1300 Subject: Planet Python In-Reply-To: <76980276-ee36-47e2-5310-84211547cf70@etelligence.info> References: <76980276-ee36-47e2-5310-84211547cf70@etelligence.info> Message-ID: On 12/12/2020 07:22, dn via Python-list wrote: > Has something happened to the Planet Python feed? > - Last update: December 07, 2020 04:48 PM UTC Fixed! (Thanks!) Although, still reported as an 'open' issue https://github.com/python/planet/issues/446 -- Regards =dn From Joseph.Schachner at Teledyne.com Mon Dec 14 16:21:43 2020 From: Joseph.Schachner at Teledyne.com (Schachner, Joseph) Date: Mon, 14 Dec 2020 21:21:43 +0000 Subject: To check if number is in range(x,y) In-Reply-To: <20201212105100.68a7568e@bigbox.attlocal.net> References: <20201212105100.68a7568e@bigbox.attlocal.net> Message-ID: >>> r = range(10) So r is a list containing 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 >>> 2 in r True As expected. >>> 2.5 in r False Also as expected. If you did int(floor(2.5)) in 5 that would be true. >>> r = range(1, 10, 2) >>> 2 in r False >>> list(r) [1, 3, 5, 7, 9] Well, yes, because you started the range at 1. Start at 0 and you'd get 0, 2, 4, 6, 8. "It also doesn't automatically convert from the string inputs you're getting from the input() function: >>> s = "5" >>> s in r False >>> int(s) in r True" You have just discovered that Python, although it is dynamically typed, is STRICTLY typed. Another way to say this: you have discovered that Python isn't the same as BASIC. Yes, you have to convert strings to int or float, Python does not assume you want to if you did not do it. Similarly, you have to do something to convert int or float to text. Python makes it very simple, but you have to do it. "Additionally, note that the endpoint of the range is exclusive so >>> r = range(1, 10) >>> 10 in r False" I don't have to note that, I KNOW that (as I've demonstrated above), because I read a couple of books on Python. Python range starts on the number you specify and does NOT include the end number. So: range(0,10) is 0 to 9 (note that this is 10 integers) range(10,20) is 10 to 19 (also 10 integers) range(20,30) is 20 to 29 (another 10 integers) Now suppose that the end integer was not excluded. Each range call would produce 11 integers. 10, 20, and 30 would occur twice. Or you'd have to set the range limits differently. I recommend you read Python 101 and when you've done that, read Python 201. I think they are very good "learn Python" books. If you're surprised that the end point is not included in range, you need to read Python 101. --- Joseph S. -----Original Message----- From: Tim Chase Sent: Saturday, December 12, 2020 11:51 AM To: Bischoop Cc: Bischoop ; python-list at python.org Subject: Re: To check if number is in range(x,y) On 2020-12-12 15:12, Bischoop wrote: > I need to check if input number is 1-5. Whatever I try it's not > working. Here are my aproaches to the problem: https://bpa.st/H62A > > What I'm doing wrong and how I should do it? A range is similar to a list in that it contains just the numbers listed: >>> r = range(10) >>> 2 in r True >>> 2.5 in r False >>> r = range(1, 10, 2) >>> 2 in r False >>> list(r) [1, 3, 5, 7, 9] It also doesn't automatically convert from the string inputs you're getting from the input() function: >>> s = "5" >>> s in r False >>> int(s) in r True Additionally, note that the endpoint of the range is exclusive so >>> r = range(1, 10) >>> 10 in r False >>> list(r) [1, 2, 3, 4, 5, 6, 7, 8, 9] If you want numeric-range checks, Python provides the lovely double-comparison syntax: >>> x = 5 >>> 2 < x < 10 True >>> x = 5.5 >>> 2 < x < 10 True >>> s = "5" >>> 2 < s < 10 Traceback? >>> 2 < int(s) < 10 True Hopefully this gives you the hints that you need to troubleshoot. -tkc From 2QdxY4RzWzUUiLuE at potatochowder.com Mon Dec 14 17:37:13 2020 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Mon, 14 Dec 2020 16:37:13 -0600 Subject: To check if number is in range(x,y) In-Reply-To: References: <20201212105100.68a7568e@bigbox.attlocal.net> Message-ID: On 2020-12-14 at 21:21:43 +0000, "Schachner, Joseph" wrote: > >>> r = range(10) > So r is a list containing 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 In a number of ways, r behaves as if it were that list, but r is definitely not that list: >>> r = range(10) >>> type(r) >>> l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> type(l) >>> r == l False > You have just discovered that Python, although it is dynamically > typed, is STRICTLY typed. Another way to say this: you have > discovered that Python isn't the same as BASIC ... Citation needed? I can't speak for every version of BASIC ever, but the ones I used had separate namespaces for numeric variables and string variables: A was a number, A$ was a string, and never the twain shall meet. That's strict typing. From drsalists at gmail.com Mon Dec 14 18:07:33 2020 From: drsalists at gmail.com (Dan Stromberg) Date: Mon, 14 Dec 2020 15:07:33 -0800 Subject: To check if number is in range(x,y) In-Reply-To: References: <20201212105100.68a7568e@bigbox.attlocal.net> Message-ID: On Mon, Dec 14, 2020 at 1:23 PM Schachner, Joseph < Joseph.Schachner at teledyne.com> wrote: > >>> r = range(10) > So r is a list containing 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 > To get a list of consecutive int's, you can use, for EG: r = list(range(10)) From drsalists at gmail.com Mon Dec 14 18:37:27 2020 From: drsalists at gmail.com (Dan Stromberg) Date: Mon, 14 Dec 2020 15:37:27 -0800 Subject: To check if number is in range(x,y) In-Reply-To: References: <20201212105100.68a7568e@bigbox.attlocal.net> Message-ID: On Mon, Dec 14, 2020 at 3:07 PM Dan Stromberg wrote: > > On Mon, Dec 14, 2020 at 1:23 PM Schachner, Joseph < > Joseph.Schachner at teledyne.com> wrote: > >> >>> r = range(10) >> So r is a list containing 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 >> > To get a list of consecutive int's, you can use, for EG: > r = list(range(10)) > Oh, and range() returning a (lazy) range is a new thing. In Python 2.x, range returned a list and you had to use xrange to get laziness. From python.list at tim.thechases.com Mon Dec 14 20:50:56 2020 From: python.list at tim.thechases.com (Tim Chase) Date: Mon, 14 Dec 2020 19:50:56 -0600 Subject: To check if number is in range(x,y) In-Reply-To: References: <20201212105100.68a7568e@bigbox.attlocal.net> Message-ID: <20201214195056.5b3a198f@bigbox.attlocal.net> On 2020-12-14 21:21, Schachner, Joseph wrote: > >>> r = range(10) > So r is a list containing 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 In Python 3.x, r is *not* a list. It is a custom object/class. > >>> 2 in r > True > As expected. I'm not sure what your replies are suggesting here. I demonstrated the OP's edge-cases, especially cases that one might experience coming from other languages. > >>> r = range(1, 10, 2) > >>> 2 in r > False > >>> list(r) > [1, 3, 5, 7, 9] > Well, yes, because you started the range at 1. Start at 0 and > you'd get 0, 2, 4, 6, 8. Had I done this, for pedagogical value I would have checked for 3 then: >>> r = range(0, 10, 2) >>> 3 in r False The goal was to demonstrate that the resulting range object, when given a step-size of something than the default 1, will have holes in it, and as such, testing for membership in one of those holes would fail. Showing successful membership wouldn't add any value. > "It also doesn't automatically convert from the string inputs > you're getting from the input() function: > > >>> s = "5" > >>> s in r > False > >>> int(s) in r > True" > You have just discovered that Python, although it is dynamically > typed, is STRICTLY typed. No, not just now discovered something I've long known. The goal was to provide an example for the OP of this exact case since their original code attempted to use the string returned from input() and used it as-is (without converting to int) for this exact sort of comparison. > Another way to say this: you have discovered that Python isn't the > same as BASIC. Additionally, (many? all? some?) BASICs have similarly strict typing. For example, reaching for the BASIC that I used in the 80s: ] S$ = "HELLO" ] I = 42 ] PRINT S$ + I ?TYPE MISMATCH ERROR > "Additionally, note that the endpoint of the range is exclusive so > >>> r = range(1, 10) > >>> 10 in r > False" > > I don't have to note that My comment was directed at the OP. Unless you are Bischoop, that's not you. > Now suppose that the end integer was not excluded. Each range call > would produce 11 integers. The goal was to show the OP that while some languages (such as the aforementioned BASIC) have *inclusive* ranges: ] FOR I = 1 to 3 : PRINT I : NEXT 1 2 3 Python's ranges are exclusive. Because a language could have either, the example demonstrated Python's choice. > I recommend you read Python 101 and when you've done that, read > Python 201. I think they are very good "learn Python" books. If > you're surprised that the end point is not included in range, you > need to read Python 101. Your condescending replies bark up the wrong tree. -tkc From nospam at please.ty Tue Dec 15 04:41:24 2020 From: nospam at please.ty (jak) Date: Tue, 15 Dec 2020 10:41:24 +0100 Subject: Returning from a multiple stacked call at once References: <5fd465b5$0$8956$426a74cc@news.free.fr> <24532.64465.213850.33597@ixdm.fritz.box> Message-ID: Il 12/12/2020 18:20, Dieter Maurer ha scritto: > ast wrote at 2020-12-12 07:39 +0100: >> In case a function recursively calls itself many times, >> is there a way to return a data immediately without >> unstacking all functions ? > > Python does not have "long jump"s (out of many functions, many loop > incarnations). > In some cases, you can use exceptions to emulate "long jump"s. > I don't know what you mean by 'emulating' because using the exception handler you simply defer unstacking to it. The real problem is that if you write a function that ends by calling itself and does not take advantage of the branch of code following the recursive call, then it is a wrong way to use a recursive function which should be replaced with a simple one containing a loop where you can insert a break statement wherever you like. IMHO Greetings. From nospam at please.ty Tue Dec 15 05:52:00 2020 From: nospam at please.ty (jak) Date: Tue, 15 Dec 2020 11:52:00 +0100 Subject: Returning from a multiple stacked call at once References: <5fd465b5$0$8956$426a74cc@news.free.fr> <24532.64465.213850.33597@ixdm.fritz.box> Message-ID: Il 15/12/2020 10:41, jak ha scritto: > Il 12/12/2020 18:20, Dieter Maurer ha scritto: >> ast wrote at 2020-12-12 07:39 +0100: >>> In case a function recursively calls itself many times, >>> is there a way to return a data immediately without >>> unstacking all functions ? >> >> Python does not have "long jump"s (out of many functions, many loop >> incarnations). >> In some cases, you can use exceptions to emulate "long jump"s. >> > > I don't know what you mean by 'emulating' because using the exception > handler you simply defer unstacking to it. The real problem is that if > you write a function that ends by calling itself and does not take > advantage of the branch of code following the recursive call, then it is > a wrong way to use a recursive function which should be replaced with a > simple one containing a loop where you can insert a break statement > wherever you like. IMHO > > Greetings. this could be a way to emulate a long_jump: def f(i): if i < 10: i += 1 yield from f(i) else: yield i i = 0 retult = 0 for n in f(i): result = n break print(result) From rosuav at gmail.com Tue Dec 15 06:25:58 2020 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 15 Dec 2020 22:25:58 +1100 Subject: Returning from a multiple stacked call at once In-Reply-To: References: <5fd465b5$0$8956$426a74cc@news.free.fr> <24532.64465.213850.33597@ixdm.fritz.box> Message-ID: On Tue, Dec 15, 2020 at 9:56 PM jak wrote: > > this could be a way to emulate a long_jump: > > def f(i): > if i < 10: > i += 1 > yield from f(i) > else: > yield i > > i = 0 > retult = 0 > for n in f(i): > result = n > break > print(result) > Note that this requires just as much cooperation as this version does: def f(i): if i < 10: return f(i + 1) return i result = f(0) The only difference is that "yield from" sorta kinda gives you a "maybe return", but you're not actually using that in your example, so it doesn't showcase that. But let's say you're searching a complex data structure for something: def find(obj, pred): if pred(obj): yield obj if isinstance(obj, list): for elem in obj: yield from find(elem, pred) if isinstance(obj, dict): for elem in obj.values(): yield from find(elem, pred) Taking the first matching element could be done without worrying too much about whether any subsequent elements would match. I wouldn't really call this a "long jump", though; this is a lazy filter that can be efficiently used to locate the first few results without calculating them all. ChrisA From nospam at please.ty Tue Dec 15 06:31:21 2020 From: nospam at please.ty (jak) Date: Tue, 15 Dec 2020 12:31:21 +0100 Subject: Returning from a multiple stacked call at once References: <5fd465b5$0$8956$426a74cc@news.free.fr> Message-ID: Il 12/12/2020 07:39, ast ha scritto: > Hello > > In case a function recursively calls itself many times, > is there a way to return a data immediately without > unstacking all functions ? > try this way: def path_finder(graph, start, end, path=[]): if start in path: yield None if start == end: yield path + [start] # Found ! if start not in graph: yield None path = path + [start] for node in graph[start]: found_path = yield from path_finder(graph, node, end, path) if found_path: yield found_path yield None graph = {'A': ['B', 'C'], 'B': ['C', 'D'], 'C': ['D'], 'D': ['C'], 'E': ['F'], 'F': ['C']} result = [] for r in path_finder(graph, 'A', 'D'): result = r break print(result) From nospam at please.ty Tue Dec 15 06:39:29 2020 From: nospam at please.ty (jak) Date: Tue, 15 Dec 2020 12:39:29 +0100 Subject: Returning from a multiple stacked call at once References: <5fd465b5$0$8956$426a74cc@news.free.fr> <24532.64465.213850.33597@ixdm.fritz.box> Message-ID: Il 15/12/2020 12:25, Chris Angelico ha scritto: > On Tue, Dec 15, 2020 at 9:56 PM jak wrote: >> >> this could be a way to emulate a long_jump: >> >> def f(i): >> if i < 10: >> i += 1 >> yield from f(i) >> else: >> yield i >> >> i = 0 >> retult = 0 >> for n in f(i): >> result = n >> break >> print(result) >> > > Note that this requires just as much cooperation as this version does: > > def f(i): > if i < 10: > return f(i + 1) > return i > > result = f(0) > > The only difference is that "yield from" sorta kinda gives you a > "maybe return", but you're not actually using that in your example, so > it doesn't showcase that. But let's say you're searching a complex > data structure for something: > > def find(obj, pred): > if pred(obj): yield obj > if isinstance(obj, list): > for elem in obj: yield from find(elem, pred) > if isinstance(obj, dict): > for elem in obj.values(): yield from find(elem, pred) > > Taking the first matching element could be done without worrying too > much about whether any subsequent elements would match. I wouldn't > really call this a "long jump", though; this is a lazy filter that can > be efficiently used to locate the first few results without > calculating them all. > > ChrisA > You are right. In fact I used the word 'emulate' to mean that this is what (IMO) comes closest to a long jump. Cheers. From phd at phdru.name Tue Dec 15 09:22:43 2020 From: phd at phdru.name (Oleg Broytman) Date: Tue, 15 Dec 2020 15:22:43 +0100 Subject: SQLObject 3.9.0 Message-ID: <20201215142243.GA30282@phdru.name> Hello! I'm pleased to announce version 3.9.0, the first release of branch 3.9 of SQLObject. What's new in SQLObject ======================= Contributors for this release are: + Michael S. Root, Ameya Bapat - ``JSONCol``; + Jerry Nance - reported a bug with ``DateTime`` from ``Zope``. Features -------- * Add ``JSONCol``: a universal json column that converts simple Python objects (None, bool, int, float, long, dict, list, str/unicode to/from JSON using json.dumps/loads. A subclass of StringCol. Requires ``VARCHAR``/``TEXT`` columns at backends, doesn't work with ``JSON`` columns. * Extend/fix support for ``DateTime`` from ``Zope``. * Drop support for very old version of ``mxDateTime`` without ``mx.`` namespace. Drivers ------- * Support `mariadb `_. CI -- * Run tests with Python 3.9 at Travis and AppVeyor. For a more complete list, please see the news: http://sqlobject.org/News.html What is SQLObject ================= SQLObject is an object-relational mapper. Your database tables are described as classes, and rows are instances of those classes. SQLObject is meant to be easy to use and quick to get started with. It currently supports MySQL, PostgreSQL and SQLite; connections to other backends - Firebird, Sybase, MSSQL and MaxDB (also known as SAPDB) - are lesser debugged). Python 2.7 or 3.4+ is required. Where is SQLObject ================== Site: http://sqlobject.org Development: http://sqlobject.org/devel/ Mailing list: https://lists.sourceforge.net/mailman/listinfo/sqlobject-discuss Download: https://pypi.org/project/SQLObject/3.9.0 News and changes: http://sqlobject.org/News.html StackOverflow: https://stackoverflow.com/questions/tagged/sqlobject Example ======= Create a simple class that wraps a table:: >>> from sqlobject import * >>> >>> sqlhub.processConnection = connectionForURI('sqlite:/:memory:') >>> >>> class Person(SQLObject): ... fname = StringCol() ... mi = StringCol(length=1, default=None) ... lname = StringCol() ... >>> Person.createTable() Use the object:: >>> p = Person(fname="John", lname="Doe") >>> p >>> p.fname 'John' >>> p.mi = 'Q' >>> p2 = Person.get(1) >>> p2 >>> p is p2 True Queries:: >>> p3 = Person.selectBy(lname="Doe")[0] >>> p3 >>> pc = Person.select(Person.q.lname=="Doe").count() >>> pc 1 Oleg. -- Oleg Broytman https://phdru.name/ phd at phdru.name Programmers don't die, they just GOSUB without RETURN. From lists at mostrom.pp.se Tue Dec 15 10:04:55 2020 From: lists at mostrom.pp.se (Jan Erik =?utf-8?q?Mostr=C3=B6m?=) Date: Tue, 15 Dec 2020 16:04:55 +0100 Subject: Library for text substitutions with calculations? Message-ID: I want to do some text substitutions but a bit more advanced than what string.Template class can do. I addition to plain text substitution I would like to be able to do some calculations: $value+1 - If value is 16 this would insert 17 in the text. I would also like to subtract. $value+1w - In this case value would be a date, this would add a week to that date, similar for year, month, hours. Also subtract. The exact syntax isn't important. In other words I would like to define example1 = 12 example2 = 2020-12-15 and then some text: Hello world $example1+10 and a date $example+1w would result in Hello world 22 and a date 2020-12-22 Is there some library that can do something like this? I probably searching using the wrong keywords because I can't find anything. = jem From 2QdxY4RzWzUUiLuE at potatochowder.com Tue Dec 15 10:41:56 2020 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Tue, 15 Dec 2020 09:41:56 -0600 Subject: Library for text substitutions with calculations? In-Reply-To: References: Message-ID: On 2020-12-15 at 16:04:55 +0100, Jan Erik Mostr?m wrote: > I want to do some text substitutions but a bit more advanced than what > string.Template class can do. I addition to plain text substitution I would > like to be able to do some calculations: > > $value+1 - If value is 16 this would insert 17 in the text. I would also > like to subtract. [...] A lot of libraries for making web pages can do things like that; a starting point is . HTH, Dan From rshepard at appl-ecosys.com Tue Dec 15 10:52:31 2020 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Tue, 15 Dec 2020 07:52:31 -0800 (PST) Subject: Python3 change logs Message-ID: I've upgraded from Python-3.7.x to Python-3.9.x and want to learn about differences (if any) in tkinter between the two versions. Looking on the python.org web site I did not find change logs with the sources or under the other menus I checked. Please point me to any available logs. Regards, Rich From bgailer at gmail.com Tue Dec 15 11:25:13 2020 From: bgailer at gmail.com (Bob Gailer) Date: Tue, 15 Dec 2020 11:25:13 -0500 Subject: Library for text substitutions with calculations? In-Reply-To: References: Message-ID: On Tue, Dec 15, 2020, 10:42 AM <2QdxY4RzWzUUiLuE at potatochowder.com> wrote: > On 2020-12-15 at 16:04:55 +0100, > Jan Erik Mostr?m wrote: > > > I want to do some text substitutions but a bit more advanced than what > > string.Template class can do. I addition to plain text substitution I > would > > like to be able to do some calculations: > > > > $value+1 - If value is 16 this would insert 17 in the text. I would also > > like to subtract. > > val = 2 print(f'{val+3}') 5 Bob Gailer From markpolesky at yahoo.com Tue Dec 15 12:07:16 2020 From: markpolesky at yahoo.com (Mark Polesky) Date: Tue, 15 Dec 2020 17:07:16 +0000 (UTC) Subject: dict.get(key, default) evaluates default even if key exists References: <263519400.745131.1608052036522.ref@mail.yahoo.com> Message-ID: <263519400.745131.1608052036522@mail.yahoo.com> Hi. # Running this script.... D = {'a':1} def get_default(): ??? print('Nobody expects this') ??? return 0 print(D.get('a', get_default())) # ...generates this output: Nobody expects this 1 ### Since I'm brand new to this community, I thought I'd ask here first... Is this worthy of a bug report?? This behavior is definitely unexpected to me, and I accidentally coded an endless loop in a mutual recursion situation because of it.? Calling dict.get.__doc__ only gives this short sentence: Return the value for key if key is in the dictionary, else default.? Nothing in that docstring suggests that the default value is evaluated even if the key exists, and I can't think of any good reason to do so. Am I missing something? Thanks, Mark From skip.montanaro at gmail.com Tue Dec 15 13:35:19 2020 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Tue, 15 Dec 2020 12:35:19 -0600 Subject: Python3 change logs In-Reply-To: References: Message-ID: Change logs are kept as part of the source, I believe. Try browsing the cpython GitHub repo: https://github.com/python/cpython Skip On Tue, Dec 15, 2020, 10:05 AM Rich Shepard wrote: > I've upgraded from Python-3.7.x to Python-3.9.x and want to learn about > differences (if any) in tkinter between the two versions. > > Looking on the python.org web site I did not find change logs with the > sources or under the other menus I checked. Please point me to any > available > logs. > > Regards, > > Rich > -- > https://mail.python.org/mailman/listinfo/python-list > From skip.montanaro at gmail.com Tue Dec 15 13:39:36 2020 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Tue, 15 Dec 2020 12:39:36 -0600 Subject: Python3 change logs In-Reply-To: References: Message-ID: Also, check www.python.org for "What's New" pages. I believe one is generated for every release. It will be less detailed than change logs in GitHub, but more reader friendly. Skip From skip.montanaro at gmail.com Tue Dec 15 13:42:04 2020 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Tue, 15 Dec 2020 12:42:04 -0600 Subject: Python3 change logs In-Reply-To: References: Message-ID: Dang... I'm having very incomplete thoughts. Apologies for the multiple replies when one would have sufficed. https://docs.python.org/3/whatsnew/3.9.html Skip From drsalists at gmail.com Tue Dec 15 13:52:42 2020 From: drsalists at gmail.com (Dan Stromberg) Date: Tue, 15 Dec 2020 10:52:42 -0800 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: <263519400.745131.1608052036522@mail.yahoo.com> References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> Message-ID: On Tue, Dec 15, 2020 at 9:57 AM Mark Polesky via Python-list < python-list at python.org> wrote: > Hi. > > # Running this script.... > > D = {'a':1} > def get_default(): > print('Nobody expects this') > return 0 > print(D.get('a', get_default())) > > # ...generates this output: > > Nobody expects this > 1 > > ### > > Since I'm brand new to this community, I thought I'd ask here first... Is > this worthy of a bug report? This behavior is definitely unexpected to me, > and I accidentally coded an endless loop in a mutual recursion situation > because of it. Calling dict.get.__doc__ only gives this short sentence: > Return the value for key if key is in the dictionary, else default. > Nothing in that docstring suggests that the default value is evaluated even > if the key exists, and I can't think of any good reason to do so. > Python isn't a lazy language. It's evaluating get_default() unconditionally, prior to executing the D.get(). I don't think it's a Python bug. BTW, I tend to prefer collections.defaultdict over the two argument D.get or setdefault. From rosuav at gmail.com Tue Dec 15 13:57:06 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 16 Dec 2020 05:57:06 +1100 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: <263519400.745131.1608052036522@mail.yahoo.com> References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> Message-ID: On Wed, Dec 16, 2020 at 4:58 AM Mark Polesky via Python-list wrote: > > Hi. > > # Running this script.... > > D = {'a':1} > def get_default(): > print('Nobody expects this') > return 0 > print(D.get('a', get_default())) > > # ...generates this output: > > Nobody expects this > 1 > > ### > > Since I'm brand new to this community, I thought I'd ask here first... Is this worthy of a bug report? This behavior is definitely unexpected to me, and I accidentally coded an endless loop in a mutual recursion situation because of it. Calling dict.get.__doc__ only gives this short sentence: Return the value for key if key is in the dictionary, else default. Nothing in that docstring suggests that the default value is evaluated even if the key exists, and I can't think of any good reason to do so. > > Am I missing something? > Seems what you want is the __missing__ method. Look into it - I think it will do what you're expecting here. ChrisA From storchaka at gmail.com Tue Dec 15 13:57:15 2020 From: storchaka at gmail.com (Serhiy Storchaka) Date: Tue, 15 Dec 2020 20:57:15 +0200 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: <263519400.745131.1608052036522@mail.yahoo.com> References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> Message-ID: 15.12.20 19:07, Mark Polesky via Python-list ????: > # Running this script.... > > D = {'a':1} > def get_default(): > ??? print('Nobody expects this') > ??? return 0 > print(D.get('a', get_default())) > > # ...generates this output: > > Nobody expects this > 1 > > ### > > Since I'm brand new to this community, I thought I'd ask here first... Is this worthy of a bug report?? This behavior is definitely unexpected to me, and I accidentally coded an endless loop in a mutual recursion situation because of it.? Calling dict.get.__doc__ only gives this short sentence: Return the value for key if key is in the dictionary, else default.? Nothing in that docstring suggests that the default value is evaluated even if the key exists, and I can't think of any good reason to do so. > > Am I missing something? You are missed that expressions for function arguments are always evaluated before passing their values to a function. This is expected behavior, and I can't remember any programming language in which it's different. So dict.get() returns the value of argument default, which is computed by calling function get_default() before calling dict.get(). From rshepard at appl-ecosys.com Tue Dec 15 14:17:19 2020 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Tue, 15 Dec 2020 11:17:19 -0800 (PST) Subject: Python3 change logs In-Reply-To: References: Message-ID: On Tue, 15 Dec 2020, Skip Montanaro wrote: > Change logs are kept as part of the source, I believe. Try browsing the > cpython GitHub repo: > https://github.com/python/cpython Skip, Thanks, I will. Stay well, Rich From rshepard at appl-ecosys.com Tue Dec 15 14:22:41 2020 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Tue, 15 Dec 2020 11:22:41 -0800 (PST) Subject: Python3 change logs In-Reply-To: References: Message-ID: On Tue, 15 Dec 2020, Skip Montanaro wrote: > Also, check www.python.org for "What's New" pages. I believe one is > generated for every release. It will be less detailed than change logs in > GitHub, but more reader friendly. Skip, I don't find a "What's New" page, but under Download -> All Releases (rather than Source code) there's a column of Release Notes for each version. I'll check github, too. Thanks, Rich From rshepard at appl-ecosys.com Tue Dec 15 14:24:31 2020 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Tue, 15 Dec 2020 11:24:31 -0800 (PST) Subject: Python3 change logs In-Reply-To: References: Message-ID: On Tue, 15 Dec 2020, Skip Montanaro wrote: > Dang... I'm having very incomplete thoughts. Apologies for the multiple > replies when one would have sufficed. > https://docs.python.org/3/whatsnew/3.9.html Skip, No apologies needed. That page looks like a reformatted Release Notes. Thanks again, Rich From markpolesky at yahoo.com Tue Dec 15 15:08:53 2020 From: markpolesky at yahoo.com (Mark Polesky) Date: Tue, 15 Dec 2020 20:08:53 +0000 (UTC) Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> Message-ID: <1823740026.830499.1608062933098@mail.yahoo.com> I see. Perhaps counterintuitive, but implemented consistently. Add it to the list of gotchas, I guess. By the way... four helpful responses in under an hour, very impressive. Nice community here. Thanks to all who answered. Mark On Tuesday, December 15, 2020, 11:05:10 AM PST, Serhiy Storchaka wrote: 15.12.20 19:07, Mark Polesky via Python-list ????: > # Running this script.... > > D = {'a':1} > def get_default(): > ??? print('Nobody expects this') > ??? return 0 > print(D.get('a', get_default())) > > # ...generates this output: > > Nobody expects this > 1 > > ### > > Since I'm brand new to this community, I thought I'd ask here first... Is this worthy of a bug report?? This behavior is definitely unexpected to me, and I accidentally coded an endless loop in a mutual recursion situation because of it.? Calling dict.get.__doc__ only gives this short sentence: Return the value for key if key is in the dictionary, else default.? Nothing in that docstring suggests that the default value is evaluated even if the key exists, and I can't think of any good reason to do so. > > Am I missing something? You are missed that expressions for function arguments are always evaluated before passing their values to a function. This is expected behavior, and I can't remember any programming language in which it's different. So dict.get() returns the value of argument default, which is computed by calling function get_default() before calling dict.get(). -- https://mail.python.org/mailman/listinfo/python-list From grant.b.edwards at gmail.com Tue Dec 15 15:26:23 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Tue, 15 Dec 2020 20:26:23 -0000 (UTC) Subject: dict.get(key, default) evaluates default even if key exists References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <1823740026.830499.1608062933098@mail.yahoo.com> Message-ID: On 2020-12-15, Mark Polesky via Python-list wrote: > I see. Perhaps counterintuitive, I guess that depends on what programming language you normally think in. Python's handling of function parameters is exactly what I expected, because all of the previous languages I used did the same thing. Purely out of curiosity, what language had you been using that behaved otherwise? From ethan at stoneleaf.us Tue Dec 15 16:07:25 2020 From: ethan at stoneleaf.us (Ethan Furman) Date: Tue, 15 Dec 2020 13:07:25 -0800 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: <263519400.745131.1608052036522@mail.yahoo.com> References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> Message-ID: <3f9bf105-1909-3b3a-4823-eaa450a1a2ec@stoneleaf.us> On 12/15/20 9:07 AM, Mark Polesky via Python-list wrote: > D = {'a':1} > > def get_default(): > print('Nobody expects this') > return 0 > > print(D.get('a', get_default())) Python has short-circuiting logical operations, so one way to get the behavior you're looking for is: D.get('a') or get_default() -- ~Ethan~ From drsalists at gmail.com Tue Dec 15 16:10:42 2020 From: drsalists at gmail.com (Dan Stromberg) Date: Tue, 15 Dec 2020 13:10:42 -0800 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> Message-ID: On Tue, Dec 15, 2020 at 11:05 AM Serhiy Storchaka wrote: > 15.12.20 19:07, Mark Polesky via Python-list ????: > > # Running this script.... > > > > D = {'a':1} > > def get_default(): > > print('Nobody expects this') > > return 0 > > print(D.get('a', get_default())) > > > > # ...generates this output: > > > > Nobody expects this > > 1 > > > > ### > > > > Since I'm brand new to this community, I thought I'd ask here first... > Is this worthy of a bug report? This behavior is definitely unexpected to > me, and I accidentally coded an endless loop in a mutual recursion > situation because of it. Calling dict.get.__doc__ only gives this short > sentence: Return the value for key if key is in the dictionary, else > default. Nothing in that docstring suggests that the default value is > evaluated even if the key exists, and I can't think of any good reason to > do so. > > > > Am I missing something? > > You are missed that expressions for function arguments are always > evaluated before passing their values to a function. This is expected > behavior, and I can't remember any programming language in which it's > different. > I think Haskell might be different. It's a lazy language. So its '&&' and '||' operators aren't specialcased by the language implementation to be short-circuit - everything is just lazy naturally. It's a neat idea, but it's kind of hard to reason about its performance characteristics. Python has laziness in its 'and' and 'or', as well as in its generators - this gives laziness where you tend to need it the most, without Python's performance becoming hard to reason about (modulo the garbage collector). One of the coolest things about Haskell is if you write a sort function in it, then you can get a "give me the n lowest values" function for free. That's lazy. From PythonList at DancesWithMice.info Tue Dec 15 18:01:01 2020 From: PythonList at DancesWithMice.info (dn) Date: Wed, 16 Dec 2020 12:01:01 +1300 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: <263519400.745131.1608052036522@mail.yahoo.com> References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> Message-ID: <3dd7380c-8998-c42f-52d1-192787314366@DancesWithMice.info> > On Tue, Dec 15, 2020 at 9:57 AM Mark Polesky via Python-list < > python-list at python.org> wrote: > >> Hi. >> >> # Running this script.... >> >> D = {'a':1} >> def get_default(): >> print('Nobody expects this') >> return 0 >> print(D.get('a', get_default())) >> >> # ...generates this output: >> >> Nobody expects this >> 1 >> >> ### >> >> Since I'm brand new to this community, I thought I'd ask here first... Is >> this worthy of a bug report? This behavior is definitely unexpected to me, >> and I accidentally coded an endless loop in a mutual recursion situation >> because of it. Calling dict.get.__doc__ only gives this short sentence: >> Return the value for key if key is in the dictionary, else default. >> Nothing in that docstring suggests that the default value is evaluated even >> if the key exists, and I can't think of any good reason to do so. Hey this is fun! A quick search reveals that I've (mea culpa) always thought of dict.get() as providing a default *value* and not used a function in there to provide said value. That said, the function's name says it all: get_default(). Is it 'getting' a default value? No, it's (also) reporting-back. Thus a "side-effect". Undesirable, as you say. Were it appropriate to report that a default value was necessary, maybe something like: try: print( d[ 'a' ] ) except KeyError: print( "Nobody expects this" ) d[ 'a' ] = 0 -- Regards =dn From PythonList at DancesWithMice.info Tue Dec 15 18:02:14 2020 From: PythonList at DancesWithMice.info (dn) Date: Wed, 16 Dec 2020 12:02:14 +1300 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> Message-ID: <06f87dd0-4618-b7ed-45a5-e55fad2b2d5a@DancesWithMice.info> On 16/12/2020 07:52, Dan Stromberg wrote: ...> BTW, I tend to prefer collections.defaultdict over the two argument D.get > or setdefault. Contrarily, dict.get() seems 'better', unless (a) the dict's values are all to be initialised to the same value, eg all None, int 0, or empty list []; or (b) my fingers will be tired by the number of dict.get() calls to be typed. This thought partly because it may be some 'distance' between the definition of the 'dict' as a defaultdict cf the built-in 'original', and therefore a simple boy (like me) finds it easy to forget or 'lose track'. Also, because it is unusual to come-across a default-factory which initialises values to the defaultdict other than uniformly. Have you seen any application of defaultdict with some more-complex and cleverly-designed default-factory function? Other than personal-preference (which should be respected), and a uniform default-value, what is the rationale for defaultdict over dict.get()? -- Regards =dn From rosuav at gmail.com Tue Dec 15 18:10:36 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 16 Dec 2020 10:10:36 +1100 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: <06f87dd0-4618-b7ed-45a5-e55fad2b2d5a@DancesWithMice.info> References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <06f87dd0-4618-b7ed-45a5-e55fad2b2d5a@DancesWithMice.info> Message-ID: On Wed, Dec 16, 2020 at 10:03 AM dn via Python-list wrote: > > On 16/12/2020 07:52, Dan Stromberg wrote: > ...> BTW, I tend to prefer collections.defaultdict over the two argument > D.get > > or setdefault. > > > Contrarily, dict.get() seems 'better', unless (a) the dict's values are > all to be initialised to the same value, eg all None, int 0, or empty > list []; or (b) my fingers will be tired by the number of dict.get() > calls to be typed. > > This thought partly because it may be some 'distance' between the > definition of the 'dict' as a defaultdict cf the built-in 'original', > and therefore a simple boy (like me) finds it easy to forget or 'lose > track'. > > Also, because it is unusual to come-across a default-factory which > initialises values to the defaultdict other than uniformly. > > Have you seen any application of defaultdict with some more-complex and > cleverly-designed default-factory function? > > Other than personal-preference (which should be respected), and a > uniform default-value, what is the rationale for defaultdict over > dict.get()? It depends on use-case. Using dict.get() is appropriate when you want to know if something's there without prepopulating it; but if your entire purpose is to then stash something into the dict, and you'll ALWAYS be following the same pattern, then it's often more convenient to use __missing__. And if your __missing__ method is, as it commonly will be, constructing a brand new object, then it's easiest to use defaultdict. But a defaultdict for integers might be better written as a Counter instead. There are a lot of similar options, and you take whatever's easiest for this particular job. One VERY common use-case is gathering things together into lists based on some sort of lookup key. This one is perfect for defaultdict: messages = defaultdict(list) for msg in get_messages(): messages[msg["author"]].append(msg) That'll quickly and easily group the messages by their authors. The first time an author is found, a new list is created, and then you append them all. (In digging for examples, I actually found a place where I'd used defaultdict(collections.Counter) to create a nested structure very easily. Worked out well. Pretty unusual thing to want though!) ChrisA From tjreedy at udel.edu Tue Dec 15 21:47:13 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Tue, 15 Dec 2020 21:47:13 -0500 Subject: Library for text substitutions with calculations? In-Reply-To: References: Message-ID: On 12/15/2020 11:25 AM, Bob Gailer wrote: > On Tue, Dec 15, 2020, 10:42 AM <2QdxY4RzWzUUiLuE at potatochowder.com> wrote: > >> On 2020-12-15 at 16:04:55 +0100, >> Jan Erik Mostr?m wrote: >> >>> I want to do some text substitutions but a bit more advanced than what >>> string.Template class can do. I addition to plain text substitution I >> would >>> like to be able to do some calculations: >>> >>> $value+1 - If value is 16 this would insert 17 in the text. I would also >>> like to subtract. >> >> val = 2 > > print(f'{val+3}') > > 5 For more, see https://docs.python.org/3/reference/lexical_analysis.html#f-strings -- Terry Jan Reedy From tjreedy at udel.edu Tue Dec 15 21:52:07 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Tue, 15 Dec 2020 21:52:07 -0500 Subject: Python3 change logs In-Reply-To: References: Message-ID: On 12/15/2020 1:42 PM, Skip Montanaro wrote: > Dang... I'm having very incomplete thoughts. Apologies for the multiple > replies when one would have sufficed. > > https://docs.python.org/3/whatsnew/3.9.html In particular, for latest release (now 3.9) you would want tkinter in https://docs.python.org/3/whatsnew/3.9.html#improved-modules but nothing there. However, https://docs.python.org/3.8/whatsnew/3.8.html#tkinter -- Terry Jan Reedy From 2QdxY4RzWzUUiLuE at potatochowder.com Tue Dec 15 22:23:59 2020 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Tue, 15 Dec 2020 21:23:59 -0600 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: <3dd7380c-8998-c42f-52d1-192787314366@DancesWithMice.info> References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <3dd7380c-8998-c42f-52d1-192787314366@DancesWithMice.info> Message-ID: On 2020-12-16 at 12:01:01 +1300, dn via Python-list wrote: > > On Tue, Dec 15, 2020 at 9:57 AM Mark Polesky via Python-list < > > python-list at python.org> wrote: > > > >> Hi. > >> > >> # Running this script.... > >> > >> D = {'a':1} > >> def get_default(): > >> print('Nobody expects this') > >> return 0 > >> print(D.get('a', get_default())) > >> > >> # ...generates this output: > >> > >> Nobody expects this > >> 1 > >> > >> ### > >> > >> Since I'm brand new to this community, I thought I'd ask here first... Is > >> this worthy of a bug report? This behavior is definitely unexpected to > me, > >> and I accidentally coded an endless loop in a mutual recursion situation > >> because of it. Calling dict.get.__doc__ only gives this short sentence: > >> Return the value for key if key is in the dictionary, else default. > >> Nothing in that docstring suggests that the default value is evaluated > even > >> if the key exists, and I can't think of any good reason to do so. > > > Hey this is fun! A quick search reveals that I've (mea culpa) always thought > of dict.get() as providing a default *value* and not used a function in > there to provide said value. > > That said, the function's name says it all: get_default(). Is it 'getting' a > default value? No, it's (also) reporting-back. Thus a "side-effect". > Undesirable, as you say. > > Were it appropriate to report that a default value was necessary, maybe > something like: > > try: > print( d[ 'a' ] ) > except KeyError: > print( "Nobody expects this" ) > d[ 'a' ] = 0 Be careful: that mutates d in the except clause, whereas calling d.get('a', 0) doesn't, which may or may not be okay. From mruffalo at cs.cmu.edu Tue Dec 15 23:23:51 2020 From: mruffalo at cs.cmu.edu (Matt Ruffalo) Date: Tue, 15 Dec 2020 23:23:51 -0500 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <1823740026.830499.1608062933098@mail.yahoo.com> Message-ID: <08a7c04b-e8c0-a2a4-807e-41378985b3dc@cs.cmu.edu> On 15/12/20 15:26, Grant Edwards wrote: > On 2020-12-15, Mark Polesky via Python-list wrote: > >> I see. Perhaps counterintuitive, > I guess that depends on what programming language you normally think > in. Python's handling of function parameters is exactly what I > expected, because all of the previous languages I used did the same > thing. > > Purely out of curiosity, what language had you been using that behaved > otherwise? > R comes to mind; arguments can even be defined as functions of other arguments, and this is evaluated symbolically at call time: """ > f = function(x, y = 2 * x) { y } > f(1) [1] 2 > f(2) [1] 4 > f(y = 3) [1] 3 """ MMR... From loris.bennett at fu-berlin.de Wed Dec 16 02:59:02 2020 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Wed, 16 Dec 2020 08:59:02 +0100 Subject: dict.get(key, default) evaluates default even if key exists References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> Message-ID: <87bleu18s9.fsf@hornfels.zedat.fu-berlin.de> Serhiy Storchaka writes: > 15.12.20 19:07, Mark Polesky via Python-list ????: >> # Running this script.... >> >> D = {'a':1} >> def get_default(): >> ??? print('Nobody expects this') >> ??? return 0 >> print(D.get('a', get_default())) >> >> # ...generates this output: >> >> Nobody expects this >> 1 >> >> ### >> >> Since I'm brand new to this community, I thought I'd ask here first... Is this >> worthy of a bug report?? This behavior is definitely unexpected to me, and I >> accidentally coded an endless loop in a mutual recursion situation because of >> it.? Calling dict.get.__doc__ only gives this short sentence: Return the value >> for key if key is in the dictionary, else default.? Nothing in that docstring >> suggests that the default value is evaluated even if the key exists, and I >> can't think of any good reason to do so. >> >> Am I missing something? > > You are missed that expressions for function arguments are always > evaluated before passing their values to a function. This is expected > behavior, and I can't remember any programming language in which it's > different. > > So dict.get() returns the value of argument default, which is computed > by calling function get_default() before calling dict.get(). Isn't the second argument to D.get() the value to be return if the first argument is not a valid key? In that case, why does it make any difference here what the second argument of D.get() is since the key 'a' does exist? Thus, I would indeed expect the code above to print '1'. I am obviously missing something here. Cheers, Loris -- This signature is currently under construction. From pbryan at anode.ca Wed Dec 16 03:41:53 2020 From: pbryan at anode.ca (Paul Bryan) Date: Wed, 16 Dec 2020 00:41:53 -0800 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: <87bleu18s9.fsf@hornfels.zedat.fu-berlin.de> References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <87bleu18s9.fsf@hornfels.zedat.fu-berlin.de> Message-ID: <92ed36a3e1fe6a3d3aaf5c935da1dc75402b172b.camel@anode.ca> On Wed, 2020-12-16 at 08:59 +0100, Loris Bennett wrote: > Isn't the second argument to D.get() the value to be return if the > first > argument is not a valid key?? In that case, why does it make any > difference here what the second argument of D.get() is since the key > 'a' > does exist? > > Thus, I would indeed expect the code above to print '1'.? I am > obviously > missing something here. Yes, the second argument is what to return if there is no valid key. The second argument is evaluated before the call to the get function. It's return value is being supplied as an argument to the get function. Let's write a couple of quick functions to demonstrate... >>> def get(key, default): ... print(f"{key=} {default=}") ... >>> def generate_a_default_value(): ... return 1 ... >>> get("a", generate_a_default_value()) key='a' default=1 >>> The generate_a_default_value function was called before the call to get. It was called so it could produce a value that is actually passed in as an argument to the get function. Paul From loris.bennett at fu-berlin.de Wed Dec 16 04:01:21 2020 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Wed, 16 Dec 2020 10:01:21 +0100 Subject: dict.get(key, default) evaluates default even if key exists References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <87bleu18s9.fsf@hornfels.zedat.fu-berlin.de> <92ed36a3e1fe6a3d3aaf5c935da1dc75402b172b.camel@anode.ca> Message-ID: <87pn3ayvj2.fsf@hornfels.zedat.fu-berlin.de> Paul Bryan writes: > On Wed, 2020-12-16 at 08:59 +0100, Loris Bennett wrote: > >> Isn't the second argument to D.get() the value to be return if the >> first >> argument is not a valid key?? In that case, why does it make any >> difference here what the second argument of D.get() is since the key >> 'a' >> does exist? >> >> Thus, I would indeed expect the code above to print '1'.? I am >> obviously >> missing something here. > > Yes, the second argument is what to return if there is no valid key. > The second argument is evaluated before the call to the get function. > It's return value is being supplied as an argument to the get function. > > Let's write a couple of quick functions to demonstrate... > >>>> def get(key, default): > ... print(f"{key=} {default=}") > ... >>>> def generate_a_default_value(): > ... return 1 > ... >>>> get("a", generate_a_default_value()) > key='a' default=1 >>>> > > The generate_a_default_value function was called before the call to > get. It was called so it could produce a value that is actually passed > in as an argument to the get function. OK, I get the point about when the default value is generated and that potentially being surprising, but in the example originally given, the key 'a' exists and has a value of '1', so the default value is not needed. Thus, I am still unsurprised when dict.get returns the value of an existing key. What am I missing? Cheers, Loris -- This signature is currently under construction. From pbryan at anode.ca Wed Dec 16 04:12:28 2020 From: pbryan at anode.ca (Paul Bryan) Date: Wed, 16 Dec 2020 01:12:28 -0800 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: <87pn3ayvj2.fsf@hornfels.zedat.fu-berlin.de> References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <87bleu18s9.fsf@hornfels.zedat.fu-berlin.de> <92ed36a3e1fe6a3d3aaf5c935da1dc75402b172b.camel@anode.ca> <87pn3ayvj2.fsf@hornfels.zedat.fu-berlin.de> Message-ID: <05df3a5f53b4d92a34f8399265a84b27f630da96.camel@anode.ca> On Wed, 2020-12-16 at 10:01 +0100, Loris Bennett wrote: > OK, I get the point about when the default value is generated and > that > potentially being surprising, but in the example originally given, > the > key 'a' exists and has a value of '1', so the default value is not > needed. But the function is still called. The get method just doesn't use (or return) the value it generates because the key exists. Nevertheless, you're passing the return value of the get_default function as an argument. > Thus, I am still unsurprised when dict.get returns the value of an > existing key. As am I. > What am I missing? You'll need to tell me at this point. Paul From pbryan at anode.ca Wed Dec 16 04:38:02 2020 From: pbryan at anode.ca (Paul Bryan) Date: Wed, 16 Dec 2020 01:38:02 -0800 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: <92ed36a3e1fe6a3d3aaf5c935da1dc75402b172b.camel@anode.ca> References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <87bleu18s9.fsf@hornfels.zedat.fu-berlin.de> <92ed36a3e1fe6a3d3aaf5c935da1dc75402b172b.camel@anode.ca> Message-ID: <8a377abadf168527e5df700b863ff558f3087c85.camel@anode.ca> Maybe this will help: >>> def get(key, default): ... print("entering get") ... print(f"{key=} {default=}") ... print("exiting get") ... >>> def generate_default(): ... print("entering generate_default") ... print("exiting generate_default") ... return 1 ... >>> get("a", generate_default()) entering generate_default exiting generate_default entering get key='a' default=1 exiting get >>> From loris.bennett at fu-berlin.de Wed Dec 16 04:36:34 2020 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Wed, 16 Dec 2020 10:36:34 +0100 Subject: dict.get(key, default) evaluates default even if key exists References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <87bleu18s9.fsf@hornfels.zedat.fu-berlin.de> <92ed36a3e1fe6a3d3aaf5c935da1dc75402b172b.camel@anode.ca> <87pn3ayvj2.fsf@hornfels.zedat.fu-berlin.de> <05df3a5f53b4d92a34f8399265a84b27f630da96.camel@anode.ca> Message-ID: <87lfdyytwd.fsf@hornfels.zedat.fu-berlin.de> Paul Bryan writes: > On Wed, 2020-12-16 at 10:01 +0100, Loris Bennett wrote: > >> OK, I get the point about when the default value is generated and >> that >> potentially being surprising, but in the example originally given, >> the >> key 'a' exists and has a value of '1', so the default value is not >> needed. > > But the function is still called. The get method just doesn't use (or > return) the value it generates because the key exists. Nevertheless, > you're passing the return value of the get_default function as an > argument. > >> Thus, I am still unsurprised when dict.get returns the value of an >> existing key. > > As am I. > >> What am I missing? > > You'll need to tell me at this point. I was just slow and confused, but you helped me get there in the end. I now realise that issue is not about the result of the dict.get(), but rather about the fact that the method which generates the default value is called, whether or not it is needed. I shall remember that next time I think it might be a good idea to define a computationally massively expensive value as a rarely needed default :-) Cheers, Loris -- This signature is currently under construction. From rosuav at gmail.com Wed Dec 16 04:44:11 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 16 Dec 2020 20:44:11 +1100 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: <87lfdyytwd.fsf@hornfels.zedat.fu-berlin.de> References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <87bleu18s9.fsf@hornfels.zedat.fu-berlin.de> <92ed36a3e1fe6a3d3aaf5c935da1dc75402b172b.camel@anode.ca> <87pn3ayvj2.fsf@hornfels.zedat.fu-berlin.de> <05df3a5f53b4d92a34f8399265a84b27f630da96.camel@anode.ca> <87lfdyytwd.fsf@hornfels.zedat.fu-berlin.de> Message-ID: On Wed, Dec 16, 2020 at 8:43 PM Loris Bennett wrote: > > Paul Bryan writes: > > > On Wed, 2020-12-16 at 10:01 +0100, Loris Bennett wrote: > > > >> OK, I get the point about when the default value is generated and > >> that > >> potentially being surprising, but in the example originally given, > >> the > >> key 'a' exists and has a value of '1', so the default value is not > >> needed. > > > > But the function is still called. The get method just doesn't use (or > > return) the value it generates because the key exists. Nevertheless, > > you're passing the return value of the get_default function as an > > argument. > > > >> Thus, I am still unsurprised when dict.get returns the value of an > >> existing key. > > > > As am I. > > > >> What am I missing? > > > > You'll need to tell me at this point. > > I was just slow and confused, but you helped me get there in the end. I > now realise that issue is not about the result of the dict.get(), but > rather about the fact that the method which generates the default value > is called, whether or not it is needed. > > I shall remember that next time I think it might be a good idea to > define a computationally massively expensive value as a rarely needed > default :-) > Yep! That's what defaultdict can do - or if you need more flexibility, subclass dict and add a __missing__ method. ChrisA From loris.bennett at fu-berlin.de Wed Dec 16 04:54:39 2020 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Wed, 16 Dec 2020 10:54:39 +0100 Subject: dict.get(key, default) evaluates default even if key exists References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <87bleu18s9.fsf@hornfels.zedat.fu-berlin.de> <92ed36a3e1fe6a3d3aaf5c935da1dc75402b172b.camel@anode.ca> <8a377abadf168527e5df700b863ff558f3087c85.camel@anode.ca> Message-ID: <87a6ueyt28.fsf@hornfels.zedat.fu-berlin.de> Paul Bryan writes: > Maybe this will help: > >>>> def get(key, default): > ... print("entering get") > ... print(f"{key=} {default=}") > ... print("exiting get") > ... >>>> def generate_default(): > ... print("entering generate_default") > ... print("exiting generate_default") > ... return 1 > ... >>>> get("a", generate_default()) > entering generate_default > exiting generate_default > entering get > key='a' default=1 > exiting get >>>> OK, so it even has nothing to do with dict.get(). It is just about the way function arguments are evaluated. Your example above illustrates nicely that Python does what I would expect, although from the examples others have given, I might have to adjust my expectations when using other languages. Cheers, Loris -- This signature is currently under construction. From hjp-python at hjp.at Wed Dec 16 06:08:23 2020 From: hjp-python at hjp.at (Peter J. Holzer) Date: Wed, 16 Dec 2020 12:08:23 +0100 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: <3f9bf105-1909-3b3a-4823-eaa450a1a2ec@stoneleaf.us> References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <3f9bf105-1909-3b3a-4823-eaa450a1a2ec@stoneleaf.us> Message-ID: <20201216110823.GA27513@hjp.at> On 2020-12-15 13:07:25 -0800, Ethan Furman wrote: > On 12/15/20 9:07 AM, Mark Polesky via Python-list wrote: > > > D = {'a':1} > > > > def get_default(): > > print('Nobody expects this') > > return 0 > > > > print(D.get('a', get_default())) > > Python has short-circuiting logical operations, so one way to get the behavior you're looking for is: > > D.get('a') or get_default() That will call get_default for any falsey value (0, "", an empty list ...), not just for missing values. Which may or may not be what the OP wants. 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 Wed Dec 16 06:26:52 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 16 Dec 2020 22:26:52 +1100 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: <20201216110823.GA27513@hjp.at> References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <3f9bf105-1909-3b3a-4823-eaa450a1a2ec@stoneleaf.us> <20201216110823.GA27513@hjp.at> Message-ID: On Wed, Dec 16, 2020 at 10:17 PM Peter J. Holzer wrote: > > On 2020-12-15 13:07:25 -0800, Ethan Furman wrote: > > On 12/15/20 9:07 AM, Mark Polesky via Python-list wrote: > > > > > D = {'a':1} > > > > > > def get_default(): > > > print('Nobody expects this') > > > return 0 > > > > > > print(D.get('a', get_default())) > > > > Python has short-circuiting logical operations, so one way to get the behavior you're looking for is: > > > > D.get('a') or get_default() > > That will call get_default for any falsey value (0, "", an empty list ...), > not just for missing values. > > Which may or may not be what the OP wants. > D['a'] if 'a' in D else get_default() ChrisA From rshepard at appl-ecosys.com Wed Dec 16 08:39:06 2020 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Wed, 16 Dec 2020 05:39:06 -0800 (PST) Subject: Python3 change logs In-Reply-To: References: Message-ID: On Tue, 15 Dec 2020, Terry Reedy wrote: > In particular, for latest release (now 3.9) you would want tkinter in > https://docs.python.org/3/whatsnew/3.9.html#improved-modules but nothing > there. However, https://docs.python.org/3.8/whatsnew/3.8.html#tkinter Thanks, Terry. Stay well, Rich From robert.rosengard at gmail.com Wed Dec 16 11:04:11 2020 From: robert.rosengard at gmail.com (Rob Rosengard) Date: Wed, 16 Dec 2020 08:04:11 -0800 (PST) Subject: Python concurrent.futures.ProcessPoolExecutor Message-ID: Warning: I am new to this group Warning: I am not an expert at Python, I've written a few small programs, and spend 20 hours of online classes, and maybe a book or two. Warning: I am new to trying to use concurrent.futures.ProcessPoolExecutor - Prior to writing this question I updated to Python 3.9 and PyCharm 2020.3. And confirmed the problem still exists. - Running on Windows 10 Professional - I've been trying to run a simple piece of code to exactly match what I have seen done in various training videos. By I am getting a different and unexpected set of results. I.e. the instructor got different results than I did on my computer. My code is very simple: import concurrent.futures import time start = time.perf_counter() def task(myarg): print(f'Sleeping one second...{myarg}') time.sleep(1) return 'Done sleeping...' if __name__ == '__main__': with concurrent.futures.ProcessPoolExecutor() as executor: future1 = executor.submit(task, 1) future2 = executor.submit(task, 2) finish = time.perf_counter() print(f'Finished in {round(finish-start,2)} seconds') And the output is: Finished in 0.0 seconds Finished in 0.0 seconds Sleeping one second...1 Sleeping one second...2 Finished in 1.14 seconds Process finished with exit code 0 --- QUESTIONS and CONCERNS that I have... It seems that both calls to task not only runs that function, but then keeps executing the rest of the main line code. I only expected it to run the function and then immediately quit/disappear. That is, I expect the output to look like (i.e. not having the three lines of "Finished in x.x seconds", rather, just one line like that): Sleeping one second...1 Sleeping one second...2 Finished in 1.14 seconds Goal: I need the executor tasks to only run that one function, and then completely go away and stop. Not keep executing more code that doesn't belong to the task function. I've tried many iterations of this issue, and placed PRINT statements all over to try to track what is going on. And I used if/else statements in the main code, which caused even more problems. I.e. both the IF and the ELSE was executed each time through the code. Which completely blows my mind. Any thoughts on this? Thanks for your time and help! R From ethan at stoneleaf.us Wed Dec 16 11:59:31 2020 From: ethan at stoneleaf.us (Ethan Furman) Date: Wed, 16 Dec 2020 08:59:31 -0800 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <87bleu18s9.fsf@hornfels.zedat.fu-berlin.de> <92ed36a3e1fe6a3d3aaf5c935da1dc75402b172b.camel@anode.ca> <87pn3ayvj2.fsf@hornfels.zedat.fu-berlin.de> <05df3a5f53b4d92a34f8399265a84b27f630da96.camel@anode.ca> <87lfdyytwd.fsf@hornfels.zedat.fu-berlin.de> Message-ID: <09aee7aa-146c-1c7f-1d0e-b800d7f4eac5@stoneleaf.us> On 12/16/20 1:44 AM, Chris Angelico wrote: > On Wed, Dec 16, 2020 at 8:43 PM Loris Bennett > wrote: >> >> Paul Bryan writes: >> >>> On Wed, 2020-12-16 at 10:01 +0100, Loris Bennett wrote: >>> >>>> OK, I get the point about when the default value is generated and >>>> that >>>> potentially being surprising, but in the example originally given, >>>> the >>>> key 'a' exists and has a value of '1', so the default value is not >>>> needed. >>> >>> But the function is still called. The get method just doesn't use (or >>> return) the value it generates because the key exists. Nevertheless, >>> you're passing the return value of the get_default function as an >>> argument. >>> >>>> Thus, I am still unsurprised when dict.get returns the value of an >>>> existing key. >>> >>> As am I. >>> >>>> What am I missing? >>> >>> You'll need to tell me at this point. >> >> I was just slow and confused, but you helped me get there in the end. I >> now realise that issue is not about the result of the dict.get(), but >> rather about the fact that the method which generates the default value >> is called, whether or not it is needed. >> >> I shall remember that next time I think it might be a good idea to >> define a computationally massively expensive value as a rarely needed >> default :-) >> > > Yep! That's what defaultdict can do - or if you need more flexibility, > subclass dict and add a __missing__ method. Or, if the computationally massively expensive call uses potentially different arguments for each invocation: some_var = d.get('a') or cme(arg1, arg2, ...) -- ~Ethan~ From ethan at stoneleaf.us Wed Dec 16 12:06:48 2020 From: ethan at stoneleaf.us (Ethan Furman) Date: Wed, 16 Dec 2020 09:06:48 -0800 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: <20201216110823.GA27513@hjp.at> References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <3f9bf105-1909-3b3a-4823-eaa450a1a2ec@stoneleaf.us> <20201216110823.GA27513@hjp.at> Message-ID: <23916595-bcbe-0db1-9f75-6f85cb95bb9a@stoneleaf.us> On 12/16/20 3:08 AM, Peter J. Holzer wrote: > On 2020-12-15 13:07:25 -0800, Ethan Furman wrote: >> On 12/15/20 9:07 AM, Mark Polesky via Python-list wrote: >> >>> D = {'a':1} >>> >>> def get_default(): >>> print('Nobody expects this') >>> return 0 >>> >>> print(D.get('a', get_default())) >> >> Python has short-circuiting logical operations, so one way to get the behavior you're looking for is: >> >> D.get('a') or get_default() > > That will call get_default for any falsey value (0, "", an empty list ...), > not just for missing values. > > Which may or may not be what the OP wants. Good point, thanks for clarifying. -- ~Ethan~ From ijbrewster at alaska.edu Wed Dec 16 12:22:12 2020 From: ijbrewster at alaska.edu (Israel Brewster) Date: Wed, 16 Dec 2020 08:22:12 -0900 Subject: Python concurrent.futures.ProcessPoolExecutor In-Reply-To: References: Message-ID: <5550C8CA-A679-40FF-8389-FC4A2C3FD2B4@alaska.edu> > On Dec 16, 2020, at 7:04 AM, Rob Rosengard wrote: > > Warning: I am new to this group > Warning: I am not an expert at Python, I've written a few small programs, and spend 20 hours of online classes, and maybe a book or two. > Warning: I am new to trying to use concurrent.futures.ProcessPoolExecutor > - Prior to writing this question I updated to Python 3.9 and PyCharm 2020.3. And confirmed the problem still exists. > - Running on Windows 10 Professional > - I've been trying to run a simple piece of code to exactly match what I have seen done in various training videos. By I am getting a different and > unexpected set of results. I.e. the instructor got different results than I did on my computer. My code is very simple: > > import concurrent.futures > import time > > > start = time.perf_counter() > > > def task(myarg): > print(f'Sleeping one second...{myarg}') > time.sleep(1) > return 'Done sleeping...' > > > if __name__ == '__main__': > with concurrent.futures.ProcessPoolExecutor() as executor: > future1 = executor.submit(task, 1) > future2 = executor.submit(task, 2) > finish = time.perf_counter() > print(f'Finished in {round(finish-start,2)} seconds') > > And the output is: > Finished in 0.0 seconds > Finished in 0.0 seconds > Sleeping one second...1 > Sleeping one second...2 > Finished in 1.14 seconds > > Process finished with exit code 0 > > --- > QUESTIONS and CONCERNS that I have... > It seems that both calls to task not only runs that function, but then keeps executing the rest of the main line code. I only expected it to run the function and then immediately quit/disappear. That is, I expect the output to look like (i.e. not having the three lines of "Finished in x.x seconds", rather, just one line like that): > Sleeping one second...1 > Sleeping one second...2 > Finished in 1.14 seconds > > Goal: I need the executor tasks to only run that one function, and then completely go away and stop. Not keep executing more code that doesn't belong to the task function. > > I've tried many iterations of this issue, and placed PRINT statements all over to try to track what is going on. And I used if/else statements in the main code, which caused even more problems. I.e. both the IF and the ELSE was executed each time through the code. Which completely blows my mind. > > Any thoughts on this? Thanks for your time and help! Assuming the code above is indented exactly as you run it, you have an indentation error. That is, the finish and print() are not indented to be part of the if __name__? call. As such, they run on import. When you launch a new process, it imports the module, which then runs those lines, since they are not guarded by the if statement. Indent those last two lines to be under the if (they don?t need to be indented to be under the with, just the if), and it should work as intended. --- Israel Brewster Software Engineer Alaska Volcano Observatory Geophysical Institute - UAF 2156 Koyukuk Drive Fairbanks AK 99775-7320 Work: 907-474-5172 cell: 907-328-9145 > > R > -- > https://mail.python.org/mailman/listinfo/python-list From drsalists at gmail.com Wed Dec 16 12:49:52 2020 From: drsalists at gmail.com (Dan Stromberg) Date: Wed, 16 Dec 2020 09:49:52 -0800 Subject: Python concurrent.futures.ProcessPoolExecutor In-Reply-To: <5550C8CA-A679-40FF-8389-FC4A2C3FD2B4@alaska.edu> References: <5550C8CA-A679-40FF-8389-FC4A2C3FD2B4@alaska.edu> Message-ID: On Wed, Dec 16, 2020 at 9:23 AM Israel Brewster wrote: > > On Dec 16, 2020, at 7:04 AM, Rob Rosengard > wrote: > > > > Warning: I am new to this group > > Warning: I am not an expert at Python, I've written a few small > programs, and spend 20 hours of online classes, and maybe a book or two. > > Warning: I am new to trying to use > concurrent.futures.ProcessPoolExecutor > > - Prior to writing this question I updated to Python 3.9 and PyCharm > 2020.3. And confirmed the problem still exists. > > - Running on Windows 10 Professional > > - I've been trying to run a simple piece of code to exactly match what I > have seen done in various training videos. By I am getting a different and > > unexpected set of results. I.e. the instructor got different results > than I did on my computer. My code is very simple: > > > > import concurrent.futures > > import time > > > > > > start = time.perf_counter() > > > > > > def task(myarg): > > print(f'Sleeping one second...{myarg}') > > time.sleep(1) > > return 'Done sleeping...' > > > > > > if __name__ == '__main__': > > with concurrent.futures.ProcessPoolExecutor() as executor: > > future1 = executor.submit(task, 1) > > future2 = executor.submit(task, 2) > > finish = time.perf_counter() > > print(f'Finished in {round(finish-start,2)} seconds') > > > > And the output is: > > Finished in 0.0 seconds > > Finished in 0.0 seconds > > Sleeping one second...1 > > Sleeping one second...2 > > Finished in 1.14 seconds > > > > Process finished with exit code 0 > > Assuming the code above is indented exactly as you run it, you have an > indentation error. That is, the finish and print() are not indented to be > part of the if __name__? call. As such, they run on import. When you launch > a new process, it imports the module, which then runs those lines, since > they are not guarded by the if statement. > > Indent those last two lines to be under the if (they don?t need to be > indented to be under the with, just the if), and it should work as intended. > Windows has a problem forking, so the indentation is more persnickety there. On Linux and I believe on Mac, you don't have to be so careful with multiprocessing and concurrent.futures. From python at mrabarnett.plus.com Wed Dec 16 12:51:53 2020 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 16 Dec 2020 17:51:53 +0000 Subject: Python concurrent.futures.ProcessPoolExecutor In-Reply-To: References: Message-ID: <391d74a8-9371-59be-42a1-f7c36dfbf145@mrabarnett.plus.com> On 2020-12-16 16:04, Rob Rosengard wrote: > Warning: I am new to this group > Warning: I am not an expert at Python, I've written a few small programs, and spend 20 hours of online classes, and maybe a book or two. > Warning: I am new to trying to use concurrent.futures.ProcessPoolExecutor > - Prior to writing this question I updated to Python 3.9 and PyCharm 2020.3. And confirmed the problem still exists. > - Running on Windows 10 Professional > - I've been trying to run a simple piece of code to exactly match what I have seen done in various training videos. By I am getting a different and > unexpected set of results. I.e. the instructor got different results than I did on my computer. My code is very simple: > > import concurrent.futures > import time > > > start = time.perf_counter() > > > def task(myarg): > print(f'Sleeping one second...{myarg}') > time.sleep(1) > return 'Done sleeping...' > > > if __name__ == '__main__': > with concurrent.futures.ProcessPoolExecutor() as executor: > future1 = executor.submit(task, 1) > future2 = executor.submit(task, 2) > finish = time.perf_counter() > print(f'Finished in {round(finish-start,2)} seconds') > > And the output is: > Finished in 0.0 seconds > Finished in 0.0 seconds > Sleeping one second...1 > Sleeping one second...2 > Finished in 1.14 seconds > > Process finished with exit code 0 > > --- > QUESTIONS and CONCERNS that I have... > It seems that both calls to task not only runs that function, but then keeps executing the rest of the main line code. I only expected it to run the function and then immediately quit/disappear. That is, I expect the output to look like (i.e. not having the three lines of "Finished in x.x seconds", rather, just one line like that): > Sleeping one second...1 > Sleeping one second...2 > Finished in 1.14 seconds > > Goal: I need the executor tasks to only run that one function, and then completely go away and stop. Not keep executing more code that doesn't belong to the task function. > > I've tried many iterations of this issue, and placed PRINT statements all over to try to track what is going on. And I used if/else statements in the main code, which caused even more problems. I.e. both the IF and the ELSE was executed each time through the code. Which completely blows my mind. > > Any thoughts on this? Thanks for your time and help! > It imports the module to run the function, so any top-level code _will_ be run. Here's a modified version: --8<----------------------------8<-- import concurrent.futures import time print('Main code, __name__ is {!a}'.format(__name__)) start = time.perf_counter() def task(myarg): print('In task, __name__ is {!a}'.format(__name__)) print(f'Sleeping one second...{myarg}') time.sleep(1) return 'Done sleeping...' if __name__ == '__main__': with concurrent.futures.ProcessPoolExecutor() as executor: future1 = executor.submit(task, 1) future2 = executor.submit(task, 2) finish = time.perf_counter() print(f'Finished in {round(finish-start,2)} seconds') --8<----------------------------8<-- It prints: --8<----------------------------8<-- Main code, __name__ is '__main__' Main code, __name__ is '__mp_main__' Finished in 0.0 seconds Main code, __name__ is '__mp_main__' Finished in 0.0 seconds In task, __name__ is '__mp_main__' Sleeping one second...1 In task, __name__ is '__mp_main__' Sleeping one second...2 Finished in 1.8 seconds --8<----------------------------8<-- Any top-level code that you don't want it to run when it re-imports the module should be protected by the __name__ test. From willum97 at gmail.com Wed Dec 16 12:15:57 2020 From: willum97 at gmail.com (Erick Willum) Date: Wed, 16 Dec 2020 17:15:57 +0000 Subject: Fwd: bug in download References: Message-ID: <02A2815D-8377-4A65-AB47-B67FE33B6D07@gmail.com> Begin forwarded message: > From: Erick Willum > Date: 16 December 2020 at 15:53:40 GMT > To: python-list at python.org > Subject: bug in download > > Hallo and good afternoon, > > Having installed python (big thank you) and sublime text, i get the next message when trying to download numpy or matplotlib in sublime text: > > fails to pass a sanity check due to a bug in the windows runtime. See this issue for more information: > https://tinyurl.com/y3dm3h86I > > I got the next message from tiny.url, the long url is: > > https://developercommunity.visualstudio.com/content/problem/ > 1207405/fmod-after-an-update-to-windows-2004-is-causing-a.html > > These next lines appear in the sublime window as well: > > File "C:\Users\Bill\AppData\Local\Programs\Python\Python39\lib\site-packages\numpy\__init__.py", line 305, in > _win_os_check() > File "C:\Users\Bill\AppData\Local\Programs\Python\Python39\lib\site-packages\numpy\__init__.py", line 302, in _win_os_check > raise RuntimeError(msg.format(__file__)) from None > > I would appreciate your help. > Thanks again. > Bill. > > From cl at isbd.net Wed Dec 16 13:51:54 2020 From: cl at isbd.net (Chris Green) Date: Wed, 16 Dec 2020 18:51:54 +0000 Subject: Python 2 to Python 3 .so library incompatibility - need help Message-ID: Some time ago (in July) I asked some questions here about problems migrating some code from Python 2 to Python 3. The specific problem that finally prevented me from managing to get it to work was a (Linux) .so file that had been built for Python 2 and, as I don't have the source, I can't build for Python 3. I need to have another go at fixing this as otherwise the code that I need to manage my printer will stop working as I update my Ubuntu systems. The specific error I'm getting is as follows:- File "/usr/libexec/okimfputl.new/guicom.py", line 66, in import pyscand ImportError: /usr/libexec/okimfpdrv/pyscand.so: undefined symbol: _Py_ZeroStruct I know this is because the extension module is compiled for Python 2 and _Py_ZeroStruct is only available in Python 2. I don't have the C code for the module. Is there *any* other way around this, like a 'compatibility module' to use Python 2 .so files in Python 3 or anything like it? I have all the Python code and have (up to hitting this problem) converted it to Python 3. -- Chris Green ? From rosuav at gmail.com Wed Dec 16 14:16:23 2020 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 17 Dec 2020 06:16:23 +1100 Subject: Python 2 to Python 3 .so library incompatibility - need help In-Reply-To: References: Message-ID: On Thu, Dec 17, 2020 at 6:06 AM Chris Green wrote: > > Some time ago (in July) I asked some questions here > about problems migrating some code from Python 2 to Python 3. > > The specific problem that finally prevented me from managing to get it > to work was a (Linux) .so file that had been built for Python 2 and, > as I don't have the source, I can't build for Python 3. > > I need to have another go at fixing this as otherwise the code that I > need to manage my printer will stop working as I update my Ubuntu > systems. > > The specific error I'm getting is as follows:- > > File "/usr/libexec/okimfputl.new/guicom.py", line 66, in import pyscand > ImportError: /usr/libexec/okimfpdrv/pyscand.so: undefined symbol: _Py_ZeroStruct > > I know this is because the extension module is compiled for Python 2 > and _Py_ZeroStruct is only available in Python 2. I don't have the C > code for the module. > > Is there *any* other way around this, like a 'compatibility module' to > use Python 2 .so files in Python 3 or anything like it? I have all > the Python code and have (up to hitting this problem) converted it to > Python 3. > Basically no. The error you're seeing is a nice noisy one, but even if you got past that, there'll be a LOT of incompatibilities. Unfortunately, a quick google search for 'pyscand' showed up.... places where you've asked this question, suggesting that nobody else uses this library. It looks like you're going to have to take a big step back and figure out what the library is doing for you, and reimplement that somehow. :( Good luck. ChrisA From grant.b.edwards at gmail.com Wed Dec 16 14:31:23 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Wed, 16 Dec 2020 19:31:23 -0000 (UTC) Subject: dict.get(key, default) evaluates default even if key exists References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <1823740026.830499.1608062933098@mail.yahoo.com> Message-ID: On 2020-12-16, Dennis Lee Bieber wrote: > On Tue, 15 Dec 2020 20:08:53 +0000 (UTC), Mark Polesky via Python-list > declaimed the following: > >>behavior, and I can't remember any programming language in which it's >>different. > > https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_name Most of us only run across call-by-name when using macro processors (cpp, m4, TeX, various assemblers). I vaguely recall some other old language I ran across in a survey course when in college that used it. IIRC it was Algol. Somebody else already mentioned Haskel. -- Grant From tjreedy at udel.edu Wed Dec 16 14:46:14 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Wed, 16 Dec 2020 14:46:14 -0500 Subject: Fwd: bug in download In-Reply-To: <02A2815D-8377-4A65-AB47-B67FE33B6D07@gmail.com> References: <02A2815D-8377-4A65-AB47-B67FE33B6D07@gmail.com> Message-ID: On 12/16/2020 12:15 PM, Erick Willum wrote: > > > > Begin forwarded message: > >> From: Erick Willum >> Date: 16 December 2020 at 15:53:40 GMT >> To: python-list at python.org >> Subject: bug in download >> >> Hallo and good afternoon, >> >> Having installed python (big thank you) and sublime text, i get the next message when trying to download numpy or matplotlib in sublime text: >> >> fails to pass a sanity check due to a bug in the windows runtime. See this issue for more information: >> https://tinyurl.com/y3dm3h86I The answer on stackoverflow.com, easily accessed by their local search or Google web search: use 1.9.3 on Windows 2004, 1.9.4 on *nix. 1.9.3 did not work on *nix, and the 1.9.4 hotfix does not work on on some Windows. I have not seen anything either way about the 2009 Windows update -- Terry Jan Reedy From python at mrabarnett.plus.com Wed Dec 16 15:22:40 2020 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 16 Dec 2020 20:22:40 +0000 Subject: Python 2 to Python 3 .so library incompatibility - need help In-Reply-To: References: Message-ID: <1da544bc-3e69-cc16-5f78-8a3dad402064@mrabarnett.plus.com> On 2020-12-16 19:16, Chris Angelico wrote: > On Thu, Dec 17, 2020 at 6:06 AM Chris Green wrote: >> >> Some time ago (in July) I asked some questions here >> about problems migrating some code from Python 2 to Python 3. >> >> The specific problem that finally prevented me from managing to get it >> to work was a (Linux) .so file that had been built for Python 2 and, >> as I don't have the source, I can't build for Python 3. >> >> I need to have another go at fixing this as otherwise the code that I >> need to manage my printer will stop working as I update my Ubuntu >> systems. >> >> The specific error I'm getting is as follows:- >> >> File "/usr/libexec/okimfputl.new/guicom.py", line 66, in import pyscand >> ImportError: /usr/libexec/okimfpdrv/pyscand.so: undefined symbol: _Py_ZeroStruct >> >> I know this is because the extension module is compiled for Python 2 >> and _Py_ZeroStruct is only available in Python 2. I don't have the C >> code for the module. >> >> Is there *any* other way around this, like a 'compatibility module' to >> use Python 2 .so files in Python 3 or anything like it? I have all >> the Python code and have (up to hitting this problem) converted it to >> Python 3. >> > > Basically no. The error you're seeing is a nice noisy one, but even if > you got past that, there'll be a LOT of incompatibilities. > Unfortunately, a quick google search for 'pyscand' showed up.... > places where you've asked this question, suggesting that nobody else > uses this library. It looks like you're going to have to take a big > step back and figure out what the library is doing for you, and > reimplement that somehow. :( > > Good luck. > Alternatively, run something in Python 2.7 that can import it and talk to the main Python 3 code, at least until you have a long-term solution. From rosuav at gmail.com Wed Dec 16 15:32:20 2020 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 17 Dec 2020 07:32:20 +1100 Subject: Python 2 to Python 3 .so library incompatibility - need help In-Reply-To: <1da544bc-3e69-cc16-5f78-8a3dad402064@mrabarnett.plus.com> References: <1da544bc-3e69-cc16-5f78-8a3dad402064@mrabarnett.plus.com> Message-ID: On Thu, Dec 17, 2020 at 7:27 AM MRAB wrote: > > On 2020-12-16 19:16, Chris Angelico wrote: > > On Thu, Dec 17, 2020 at 6:06 AM Chris Green wrote: > >> > >> Some time ago (in July) I asked some questions here > >> about problems migrating some code from Python 2 to Python 3. > >> > >> The specific problem that finally prevented me from managing to get it > >> to work was a (Linux) .so file that had been built for Python 2 and, > >> as I don't have the source, I can't build for Python 3. > >> > >> I need to have another go at fixing this as otherwise the code that I > >> need to manage my printer will stop working as I update my Ubuntu > >> systems. > >> > >> The specific error I'm getting is as follows:- > >> > >> File "/usr/libexec/okimfputl.new/guicom.py", line 66, in import pyscand > >> ImportError: /usr/libexec/okimfpdrv/pyscand.so: undefined symbol: _Py_ZeroStruct > >> > >> I know this is because the extension module is compiled for Python 2 > >> and _Py_ZeroStruct is only available in Python 2. I don't have the C > >> code for the module. > >> > >> Is there *any* other way around this, like a 'compatibility module' to > >> use Python 2 .so files in Python 3 or anything like it? I have all > >> the Python code and have (up to hitting this problem) converted it to > >> Python 3. > >> > > > > Basically no. The error you're seeing is a nice noisy one, but even if > > you got past that, there'll be a LOT of incompatibilities. > > Unfortunately, a quick google search for 'pyscand' showed up.... > > places where you've asked this question, suggesting that nobody else > > uses this library. It looks like you're going to have to take a big > > step back and figure out what the library is doing for you, and > > reimplement that somehow. :( > > > > Good luck. > > > Alternatively, run something in Python 2.7 that can import it and talk > to the main Python 3 code, at least until you have a long-term solution. Yes, that's a possibility. A hack, but a definite hack. But this is one of the places where the universality of stdin/stdout is extremely handy. ChrisA From cs at cskk.id.au Wed Dec 16 16:24:47 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 17 Dec 2020 08:24:47 +1100 Subject: Python 2 to Python 3 .so library incompatibility - need help In-Reply-To: References: Message-ID: <20201216212447.GA22531@cskk.homeip.net> On 16Dec2020 18:51, Chris Green wrote: >The specific problem that finally prevented me from managing to get it >to work was a (Linux) .so file that had been built for Python 2 and, >as I don't have the source, I can't build for Python 3. ChrisA I think suggested keeping a Python 2.7 install around for this. >I need to have another go at fixing this as otherwise the code that I >need to manage my printer will stop working as I update my Ubuntu >systems. Have you considered keeping a legacy VM around as well? I have a few VMs sitting here I use for some legacy software. Have you checked an upgraded Ubuntu to failure to run your software using Python 2? Python 2 won't be installed by default, but I'm pretty sure you can add it in. It is just the "system Python" which is moving to Python 3. Also, make note of the specific Python 2 version where your software works - the CPython API does change somewhat sometimes. >The specific error I'm getting is as follows:- > File "/usr/libexec/okimfputl.new/guicom.py", line 66, in import pyscand > ImportError: /usr/libexec/okimfpdrv/pyscand.so: undefined symbol: _Py_ZeroStruct Guessing from the library name, have you looked on the OKI.com site for current software? Maybe here? What's your printer model? https://www.oki.com/au/printing/support/drivers-and-utilities/index.html Not that I've found anything helpful... What Ubuntu package supplies that .so file? >Is there *any* other way around this, like a 'compatibility module' to >use Python 2 .so files in Python 3 or anything like it? I have all >the Python code and have (up to hitting this problem) converted it to >Python 3. Almost certainly not. I think ChrisA's Python 2 suggestion is the go here. You may need to manually copy the requisite .so files if the package is about to vanish. Cheers, Cameron Simpson From rosuav at gmail.com Wed Dec 16 16:32:11 2020 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 17 Dec 2020 08:32:11 +1100 Subject: Python 2 to Python 3 .so library incompatibility - need help In-Reply-To: <20201216212447.GA22531@cskk.homeip.net> References: <20201216212447.GA22531@cskk.homeip.net> Message-ID: On Thu, Dec 17, 2020 at 8:26 AM Cameron Simpson wrote: > > On 16Dec2020 18:51, Chris Green wrote: > >The specific problem that finally prevented me from managing to get it > >to work was a (Linux) .so file that had been built for Python 2 and, > >as I don't have the source, I can't build for Python 3. > > ChrisA I think suggested keeping a Python 2.7 install around for this. (MRAB did, but I agree with it.) ChrisA From cl at isbd.net Wed Dec 16 16:59:17 2020 From: cl at isbd.net (Chris Green) Date: Wed, 16 Dec 2020 21:59:17 +0000 Subject: Python 2 to Python 3 .so library incompatibility - need help References: <20201216212447.GA22531@cskk.homeip.net> Message-ID: Cameron Simpson wrote: > On 16Dec2020 18:51, Chris Green wrote: > >The specific problem that finally prevented me from managing to get it > >to work was a (Linux) .so file that had been built for Python 2 and, > >as I don't have the source, I can't build for Python 3. > > ChrisA I think suggested keeping a Python 2.7 install around for this. > Not possible really as there are other python conflicts that start appearing if one tries to retain the libraries needed. > >I need to have another go at fixing this as otherwise the code that I > >need to manage my printer will stop working as I update my Ubuntu > >systems. > > Have you considered keeping a legacy VM around as well? I have a few VMs > sitting here I use for some legacy software. > That's not a lot of use. The programs that I want to run (by converting to Python 3) are utility programs for my printer, they install with a handy 'app' in my toolbar. Having them in a VM wouldn't really do much good! :-) > Have you checked an upgraded Ubuntu to failure to run your software > using Python 2? Python 2 won't be installed by default, but I'm pretty > sure you can add it in. It is just the "system Python" which is moving > to Python 3. > > Also, make note of the specific Python 2 version where your software > works - the CPython API does change somewhat sometimes. > I still have python 2. The issue is that the programs need modules which come from a PPA to support Python GTK, these conflict with ongoing updates to Python. The PPA works OK in Ubuntu 20.04 but prevents some updates in 20.10. I expect it will get worse as time goes on. > >The specific error I'm getting is as follows:- > > File "/usr/libexec/okimfputl.new/guicom.py", line 66, in import pyscand > > ImportError: /usr/libexec/okimfpdrv/pyscand.so: undefined symbol: _Py_ZeroStruct > > > Guessing from the library name, have you looked on the OKI.com site for > current software? Maybe here? What's your printer model? > > https://www.oki.com/au/printing/support/drivers-and-utilities/index.html > > Not that I've found anything helpful... > > What Ubuntu package supplies that .so file? > It comes from OKI with the Linux utilities for the printer, it's an MC342N. I have tried asking them for a Python 3 version, maybe I should try again. -- Chris Green ? From rosuav at gmail.com Wed Dec 16 17:18:51 2020 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 17 Dec 2020 09:18:51 +1100 Subject: Python 2 to Python 3 .so library incompatibility - need help In-Reply-To: References: <20201216212447.GA22531@cskk.homeip.net> Message-ID: On Thu, Dec 17, 2020 at 9:06 AM Chris Green wrote: > > Also, make note of the specific Python 2 version where your software > > works - the CPython API does change somewhat sometimes. > > > I still have python 2. The issue is that the programs need modules > which come from a PPA to support Python GTK, these conflict with > ongoing updates to Python. The PPA works OK in Ubuntu 20.04 but > prevents some updates in 20.10. I expect it will get worse as time > goes on. > Try getting JUST the printer info in Python 2, and then outputting that to stdout in JSON format. Then your Python 3 script can run your Python 2 script, read what it sends on stdout, and do whatever it needs to. ChrisA From cs at cskk.id.au Wed Dec 16 17:48:11 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 17 Dec 2020 09:48:11 +1100 Subject: Python 2 to Python 3 .so library incompatibility - need help In-Reply-To: References: Message-ID: <20201216224811.GA63294@cskk.homeip.net> On 16Dec2020 21:59, Chris Green wrote: >Cameron Simpson wrote: >> On 16Dec2020 18:51, Chris Green wrote: >> >The specific problem that finally prevented me from managing to get it >> >to work was a (Linux) .so file that had been built for Python 2 and, >> >as I don't have the source, I can't build for Python 3. >> >> ChrisA I think suggested keeping a Python 2.7 install around for this. >> >Not possible really as there are other python conflicts that start >appearing if one tries to retain the libraries needed. Runtime python issues like you missing symbol error, or package conflict issues? i.e. can you keep the OKI stuff sitting around along with Python 2 install without having trouble with the PPA? >> >I need to have another go at fixing this as otherwise the code that >> >I need to manage my printer will stop working as I update my Ubuntu >> >systems. I'm leaning towards ChrisA's JSON suggestion at this point (absent newer driver software). Keep a small Python 2 programme around which uses the printer driver in whatever _basic_ ways you need, and _invoke that_ from your modern Python 3 code as an external command, passing/receiving the necessary information in JSON form as input.output, or on its command line if that is more convenient. >> Have you considered keeping a legacy VM around as well? I have a few VMs >> sitting here I use for some legacy software. >> >That's not a lot of use. The programs that I want to run (by >converting to Python 3) are utility programs for my printer, they >install with a handy 'app' in my toolbar. Having them in a VM >wouldn't really do much good! :-) Fair enough. It seemed cumbersome to me too, but it is a viable way to keep something legacy around, particularly if that legacy thing requires a legacy OS. >I still have python 2. The issue is that the programs need modules >which come from a PPA to support Python GTK, these conflict with >ongoing updates to Python. The PPA works OK in Ubuntu 20.04 but >prevents some updates in 20.10. I expect it will get worse as time >goes on. [...] >> Guessing from the library name, have you looked on the OKI.com site >> for current software? Maybe here? What's your printer model? >> https://www.oki.com/au/printing/support/drivers-and-utilities/index.html >> >> >It comes from OKI with the Linux utilities for the printer, it's an >MC342N. From here? https://www.oki.com/uk/printing/support/drivers-and-utilities/colour-multifunction/01331401/?os=ab33&lang=ac2 This driver? https://www.oki.com/uk/printing/support/drivers-and-utilities/?id=46252701FZ01&tab=drivers-and-utilities&productCategory=colour-multifunction&sku=01331401&os=ab33&lang=ac2 I've just installed the .deb above on my Ubuntu 20.04.1 LTS system. Aside from whinging about systemd it installed ok. How do I reproduce your problems? (I've got no printer of course, but...) >I have tried asking them for a Python 3 version, maybe I should try >again. Can't hurt, but may not be necessary if you are prepared to split your Python 3 code form the Python 2 stuff that ships with the .deb. Cheers, Cameron Simpson From Bischoop at vimart.net Wed Dec 16 21:33:56 2020 From: Bischoop at vimart.net (Bischoop) Date: Thu, 17 Dec 2020 02:33:56 -0000 (UTC) Subject: Review, suggestion etc? Message-ID: I've done my biggest project that allowed me to learn a lot. It's basically simply Database with basic options >> https://bpa.st/FU4A . What sucks here is basically the find_people() I'll have to work on it yet to make it more useful. . If anyone was bored and wished to point me some wrong way or suggest a better one I'd appreciate. -- Thanks From Bischoop at vimart.net Wed Dec 16 21:40:51 2020 From: Bischoop at vimart.net (Bischoop) Date: Thu, 17 Dec 2020 02:40:51 -0000 (UTC) Subject: Function returns old value References: Message-ID: On 2020-12-12, Terry Reedy wrote: > > Don't post links to unknown sites. Reduce it to the minimum needed to > exhibit the questionable behavior and include inline with the question. > >> How this functions should look properly? > > I've solved the problem. BTW bpa.st/+python is well known for code sharing among Python communities it's alternative to pastebin.com. From PythonList at DancesWithMice.info Wed Dec 16 21:56:16 2020 From: PythonList at DancesWithMice.info (dn) Date: Thu, 17 Dec 2020 15:56:16 +1300 Subject: Function returns old value In-Reply-To: References: Message-ID: <5b8a1f0b-07a1-6bc7-39d3-b441adbb2010@DancesWithMice.info> On 17/12/2020 15:40, Bischoop wrote: > On 2020-12-12, Terry Reedy wrote: >> >> Don't post links to unknown sites. Reduce it to the minimum needed to >> exhibit the questionable behavior and include inline with the question. > BTW bpa.st/+python is well known for code sharing among Python > communities it's alternative to pastebin.com. Remember that posts to the list are archived, and thus may be searched. People experiencing similar problems in-future will be able to 'mine' the archives for help and advice. Using a/any pastebin is great for immediate sharing. Remember that in this case their links expire/the bin 'disappears'. After expiry, any posts 'here' with links to 'there', will be useless. -- Regards =dn From Bischoop at vimart.net Wed Dec 16 22:06:32 2020 From: Bischoop at vimart.net (Bischoop) Date: Thu, 17 Dec 2020 03:06:32 -0000 (UTC) Subject: Function returns old value References: <5b8a1f0b-07a1-6bc7-39d3-b441adbb2010@DancesWithMice.info> Message-ID: On 2020-12-17, dn wrote: > Remember that posts to the list are archived, and thus may be searched. > People experiencing similar problems in-future will be able to 'mine' > the archives for help and advice. > > Using a/any pastebin is great for immediate sharing. Remember that in > this case their links expire/the bin 'disappears'. > > After expiry, any posts 'here' with links to 'there', will be useless. I do mind that however I thoght it better if paste a whole code to see and pasting from my IDE to vim/slrn was messing syntax, I'll do better next time. From Bischoop at vimart.net Wed Dec 16 21:48:39 2020 From: Bischoop at vimart.net (Bischoop) Date: Thu, 17 Dec 2020 02:48:39 -0000 (UTC) Subject: Review, suggestion etc? References: Message-ID: On 2020-12-17, Bischoop wrote: Accidently removed the paste, https://bpa.st/E3FQ From PythonList at DancesWithMice.info Wed Dec 16 22:22:53 2020 From: PythonList at DancesWithMice.info (dn) Date: Thu, 17 Dec 2020 16:22:53 +1300 Subject: Function returns old value In-Reply-To: References: <5b8a1f0b-07a1-6bc7-39d3-b441adbb2010@DancesWithMice.info> Message-ID: <6c4028ef-0359-098e-6066-87765d51fb6a@DancesWithMice.info> On 17/12/2020 16:06, Bischoop wrote: > On 2020-12-17, dn wrote: > >> Remember that posts to the list are archived, and thus may be searched. >> People experiencing similar problems in-future will be able to 'mine' >> the archives for help and advice. >> >> Using a/any pastebin is great for immediate sharing. Remember that in >> this case their links expire/the bin 'disappears'. >> >> After expiry, any posts 'here' with links to 'there', will be useless. > > I do mind that however I thoght it better if paste a whole code to see > and pasting from my IDE to vim/slrn was messing syntax, I'll do better > next time. Yes, it can be difficult to know how much code to include and how much can be left-out. Don't worry about that - replies can always trim any excess. Also, don't be concerned about such comments. Rather than complaints, please regard them as advice from folk who have been 'here' and/or using Python for some time. -- Regards =dn From greg.ewing at canterbury.ac.nz Thu Dec 17 04:44:27 2020 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Thu, 17 Dec 2020 22:44:27 +1300 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <1823740026.830499.1608062933098@mail.yahoo.com> Message-ID: On 17/12/20 8:31 am, Grant Edwards wrote: > On 2020-12-16, Dennis Lee Bieber wrote: >> https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_name > > I vaguely recall some other old > language I ran across in a survey course when in college that used it. > IIRC it was Algol. Algol 60. Also, Lisp macros effectively let you do something similar. -- Greg From hjp-python at hjp.at Thu Dec 17 04:57:51 2020 From: hjp-python at hjp.at (Peter J. Holzer) Date: Thu, 17 Dec 2020 10:57:51 +0100 Subject: Function returns old value In-Reply-To: References: <5b8a1f0b-07a1-6bc7-39d3-b441adbb2010@DancesWithMice.info> Message-ID: <20201217095751.GA8064@hjp.at> On 2020-12-17 03:06:32 -0000, Bischoop wrote: > pasting from my IDE to vim/slrn was messing syntax, You can :set paste in vim to prevent it from messing with pasted content (don't forget to set nopaste afterwards). With newer vims that's rarely necessary though since they can distinguish between input that was pasted and input that was typed. 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 cl at isbd.net Thu Dec 17 04:58:24 2020 From: cl at isbd.net (Chris Green) Date: Thu, 17 Dec 2020 09:58:24 +0000 Subject: Python 2 to Python 3 .so library incompatibility - need help References: <20201216224811.GA63294@cskk.homeip.net> Message-ID: <0nmrah-odo3.ln1@esprimo.zbmc.eu> Cameron Simpson wrote: > >> Guessing from the library name, have you looked on the OKI.com site > >> for current software? Maybe here? What's your printer model? > >> https://www.oki.com/au/printing/support/drivers-and-utilities/index.html > >> > >> > >It comes from OKI with the Linux utilities for the printer, it's an > >MC342N. > > From here? > > https://www.oki.com/uk/printing/support/drivers-and-utilities/colour-multifunction/01331401/?os=ab33&lang=ac2 > > > This driver? > > https://www.oki.com/uk/printing/support/drivers-and-utilities/?id=46252701FZ01&tab=drivers-and-utilities&productCategory=colour-multifunction&sku=01331401&os=ab33&lang=ac2 > > > I've just installed the .deb above on my Ubuntu 20.04.1 LTS system. > Aside from whinging about systemd it installed ok. How do I reproduce > your problems? (I've got no printer of course, but...) > Try running scantool.py, that should pop up a little GUI. It uses GTK which of course in itself makes migration tricky because one has to move from the native Python 2 code to the 'introspection' code on Python 3. However I can do those code changes, the killer is that several of the scripts import pyscand and that's the Python 2 library. The issue basically is that you can't run Python 2 GTK in a modern system that's mostly Python 3 because the GTK libraries conflict. Thus I need to convert the code to Python 3 but I can't because of the library. I've extracted all the calls/uses of pyscand from the Python code:- pyscand.ADF: pyscand.BEGIN: pyscand.EVENT_PUSHSCAN: pyscand.EVENT_PUSHSCANCCL: pyscand.E_BUSY pyscand.E_BUSY: pyscand.E_CANCELED: pyscand.E_CONNECTION_REFUSED: pyscand.E_ERROR pyscand.E_IOERROR: pyscand.E_NODATA: pyscand.E_SUCCESS pyscand.E_SUCCESS: pyscand.FINISHED: pyscand.O_HEIGHT pyscand.O_PAPER_HEIGHT pyscand.O_PAPER_WIDTH pyscand.O_WIDTH pyscand.PRM_ACTION pyscand.PRM_DEVICE pyscand.PRM_DEVICE pyscand.PRM_PAGE pyscand.PRM_PATH pyscand.PRM_PROGRESS pyscand.PRM_PUSHSCAN_ID pyscand.PRM_SOURCE pyscand.PRM_STATUS pyscand.PROGRESS: pyscand.TO_APPLICATION: pyscand.TO_FOLDER: pyscand.cancel_register_client() pyscand.cancel_scan(device) pyscand.exit_client() pyscand.get_device_list(devicelist) pyscand.is_registered() pyscand.recv_client_event() pyscand.register_client() pyscand.scan(self._device, self._cfg, outpath, self._scan_callback, self._pushscanid) pyscand.strstatus(rc))) pyscand.strstatus(status) pyscandsupp.to_device_name_list(devicelist) As you can see it's mostly constants but there's that pyscand.scan() at the bottom which I suspect is the fundamental scanning software. -- Chris Green ? From swistakm at gmail.com Thu Dec 17 04:51:50 2020 From: swistakm at gmail.com (=?UTF-8?Q?Micha=C5=82_Jaworski?=) Date: Thu, 17 Dec 2020 10:51:50 +0100 Subject: Python 2 to Python 3 .so library incompatibility - need help In-Reply-To: <20201216224811.GA63294@cskk.homeip.net> References: <20201216224811.GA63294@cskk.homeip.net> Message-ID: I've looked into the details of the deb package that Cameron mentioned. It may be the one that you Chris uss because it does indeed include a pyscand.so file. Quick question to you Chris: the utilities you've mentioned are the code that you've written yourself or utilities from /usr/libexec/okimfputl that are shipped with the "driver package". In the deb package I've found following files: /usr/libexec/okimfputl/imgfilecv.py /usr/libexec/okimfputl/pushconfig.py /usr/libexec/okimfputl/pushass.py /usr/libexec/okimfputl/mfpcfgfile.py ... If that's the latter, I wouldn't even try to port that to Python 3. First, it would be clearly against the licence agreement. Second, that would probably result in total mess and take more time that it takes to earn for a new printer. If you really want to keep the printer (I wouldn't) I would do the following: upgrade your system, install Python 2.7 straight from sources in a separate location (e.g. /opt/oki-python?) and modify all shebang lines of the OKI python utilities from utilities to use that python location instead of "/usr/bin/env python" or "/usr/bin/python". That would make it totally independent of your system installation. The last thing would be probably installing pygtk in that "isolated" python installation as OKI utilities clearly rely on this. You could use venv for that or just simply make sure that gtk for python2 is in that python's library path. Whatever more convenient: you won't be using that python installation for anything else than supporting the driver. To be honest, what I would really do is to buy a new printer from a vendor that is known to be supporting their hardware for long term on the system you use. Printer vendors sucks. In the end, they always stop producing printing supplies you need and render your hardware useless. I have a combo that I can't refill with toner anymore which has used photoconductor drum that I can't replace anymore. I keep it around because it has a working scanner and haven't buyed a new printer because this one "almost works". Cheers, Micha? ?r., 16 gru 2020 o 23:48 Cameron Simpson napisa?(a): > On 16Dec2020 21:59, Chris Green wrote: > >Cameron Simpson wrote: > >> On 16Dec2020 18:51, Chris Green wrote: > >> >The specific problem that finally prevented me from managing to get it > >> >to work was a (Linux) .so file that had been built for Python 2 and, > >> >as I don't have the source, I can't build for Python 3. > >> > >> ChrisA I think suggested keeping a Python 2.7 install around for this. > >> > >Not possible really as there are other python conflicts that start > >appearing if one tries to retain the libraries needed. > > Runtime python issues like you missing symbol error, or package conflict > issues? > > i.e. can you keep the OKI stuff sitting around along with Python 2 > install without having trouble with the PPA? > > >> >I need to have another go at fixing this as otherwise the code that > >> >I need to manage my printer will stop working as I update my Ubuntu > >> >systems. > > I'm leaning towards ChrisA's JSON suggestion at this point (absent newer > driver software). Keep a small Python 2 programme around which uses the > printer driver in whatever _basic_ ways you need, and _invoke that_ from > your modern Python 3 code as an external command, passing/receiving the > necessary information in JSON form as input.output, or on its command > line if that is more convenient. > > >> Have you considered keeping a legacy VM around as well? I have a few VMs > >> sitting here I use for some legacy software. > >> > >That's not a lot of use. The programs that I want to run (by > >converting to Python 3) are utility programs for my printer, they > >install with a handy 'app' in my toolbar. Having them in a VM > >wouldn't really do much good! :-) > > Fair enough. It seemed cumbersome to me too, but it is a viable way to > keep something legacy around, particularly if that legacy thing requires > a legacy OS. > > >I still have python 2. The issue is that the programs need modules > >which come from a PPA to support Python GTK, these conflict with > >ongoing updates to Python. The PPA works OK in Ubuntu 20.04 but > >prevents some updates in 20.10. I expect it will get worse as time > >goes on. > [...] > >> Guessing from the library name, have you looked on the OKI.com site > >> for current software? Maybe here? What's your printer model? > >> > https://www.oki.com/au/printing/support/drivers-and-utilities/index.html > >> > >> > >It comes from OKI with the Linux utilities for the printer, it's an > >MC342N. > > From here? > > > https://www.oki.com/uk/printing/support/drivers-and-utilities/colour-multifunction/01331401/?os=ab33&lang=ac2 > > This driver? > > > https://www.oki.com/uk/printing/support/drivers-and-utilities/?id=46252701FZ01&tab=drivers-and-utilities&productCategory=colour-multifunction&sku=01331401&os=ab33&lang=ac2 > > I've just installed the .deb above on my Ubuntu 20.04.1 LTS system. > Aside from whinging about systemd it installed ok. How do I reproduce > your problems? (I've got no printer of course, but...) > > >I have tried asking them for a Python 3 version, maybe I should try > >again. > > Can't hurt, but may not be necessary if you are prepared to split your > Python 3 code form the Python 2 stuff that ships with the .deb. > > Cheers, > Cameron Simpson > -- > https://mail.python.org/mailman/listinfo/python-list > From patatetom at gmail.com Thu Dec 17 05:17:37 2020 From: patatetom at gmail.com (Pascal) Date: Thu, 17 Dec 2020 11:17:37 +0100 Subject: sudo python PermissionError [Errno 13] Permission denied Message-ID: hi, here, I have this simple script that tests if the /tmp/test file can be opened in write mode : $ cat /tmp/append #!/usr/bin/python with open('/tmp/test', 'a'): pass the file does not exist yet : $ chmod +x /tmp/append $ ls -l /tmp/test ls: cannot access '/tmp/test': No such file or directory the script is launched as a simple user : $ /tmp/append $ ls -l /tmp/test -rw-r--r-- 1 user user 0 Dec 17 10:30 /tmp/test everything is ok. now, the script fails if it is replayed as root user with the sudo command : $ sudo /tmp/append [sudo] password for user: Traceback (most recent call last): File "/tmp/append", line 2, in with open('/tmp/test', 'a'): PermissionError: [Errno 13] Permission denied: '/tmp/test' the problem is the same if the opening mode is 'w' or if "sudo -i" or "su -" are used. why can't root user under python manipulate the simple user file ? regards, lacsaP. From nospam at please.ty Thu Dec 17 06:16:29 2020 From: nospam at please.ty (jak) Date: Thu, 17 Dec 2020 12:16:29 +0100 Subject: dict.get(key, default) evaluates default even if key exists References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> Message-ID: Il 15/12/2020 18:07, Mark Polesky ha scritto: > Hi. > > # Running this script.... > > D = {'a':1} > def get_default(): > ??? print('Nobody expects this') > ??? return 0 > print(D.get('a', get_default())) > > # ...generates this output: > > Nobody expects this > 1 > > ### > > Since I'm brand new to this community, I thought I'd ask here first... Is this worthy of a bug report?? This behavior is definitely unexpected to me, and I accidentally coded an endless loop in a mutual recursion situation because of it.? Calling dict.get.__doc__ only gives this short sentence: Return the value for key if key is in the dictionary, else default.? Nothing in that docstring suggests that the default value is evaluated even if the key exists, and I can't think of any good reason to do so. > > Am I missing something? > > Thanks, > Mark > print(_ if d.get('a', None) is not None else get_default()) From nospam at please.ty Thu Dec 17 06:32:39 2020 From: nospam at please.ty (jak) Date: Thu, 17 Dec 2020 12:32:39 +0100 Subject: dict.get(key, default) evaluates default even if key exists References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> Message-ID: Il 17/12/2020 12:16, jak ha scritto: > Il 15/12/2020 18:07, Mark Polesky ha scritto: >> Hi. >> >> # Running this script.... >> >> D = {'a':1} >> def get_default(): >> ???? print('Nobody expects this') >> ???? return 0 >> print(D.get('a', get_default())) >> >> # ...generates this output: >> >> Nobody expects this >> 1 >> >> ### >> >> Since I'm brand new to this community, I thought I'd ask here first... >> Is this worthy of a bug report?? This behavior is definitely >> unexpected to me, and I accidentally coded an endless loop in a mutual >> recursion situation because of it.? Calling dict.get.__doc__ only >> gives this short sentence: Return the value for key if key is in the >> dictionary, else default.? Nothing in that docstring suggests that the >> default value is evaluated even if the key exists, and I can't think >> of any good reason to do so. >> >> Am I missing something? >> >> Thanks, >> Mark >> > > print(_ if d.get('a', None) is not None else get_default()) > > > ops... print((_ if d.get('a', None) is not None else get_default())) From hjp-python at hjp.at Thu Dec 17 06:40:49 2020 From: hjp-python at hjp.at (Peter J. Holzer) Date: Thu, 17 Dec 2020 12:40:49 +0100 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> Message-ID: <20201217114049.GB8064@hjp.at> On 2020-12-17 12:16:29 +0100, jak wrote: > print(_ if d.get('a', None) is not None else get_default()) That doesn't work: >>> print(_ if d.get('a', None) is not None else get_default()) Traceback (most recent call last): File "", line 1, in NameError: name '_' is not defined But this works: >>> print(_ if (_ := d.get('a', None)) is not None else get_default()) 1 (I would prefer ChrisA's solution, though.) 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 swistakm at gmail.com Thu Dec 17 06:55:31 2020 From: swistakm at gmail.com (=?UTF-8?Q?Micha=C5=82_Jaworski?=) Date: Thu, 17 Dec 2020 12:55:31 +0100 Subject: Review, suggestion etc? In-Reply-To: References: Message-ID: I've made a quick look at the code and even executed it. It looks pretty clear and is easy to understand, although it has some structural problems. I won't do a thorough review but highlight the most important problems. First, the recursive user input pattern you use: def marriage(): maritals = input('Married: Yes/No ?: ').title() while maritals != 'Yes' and maritals != 'No': return marriage() return maritals It may look really convenient but you should really avoid that. In small amounts it can be harmless, but it is kind of a resource leak. Aslo this pattern is omnipresent so can quickly get out of hand and exceed maximum recursion depth: ... You can choose only numbers. What you wanna do?: You can choose only numbers. What you wanna do?: You can choose only numbers. What you wanna do?: You can choose only numbers. What you wanna do?: You can choose only numbers. What you wanna do?: You can choose only numbers. Fatal Python error: Cannot recover from stack overflow. Current thread 0x0000000112836dc0 (most recent call first): ... File "vimart.py", line 52 in menu_choice File "vimart.py", line 52 in menu_choice ... Abort trap: 6 Also, this choice-prompt pattern could be moved to a separate general function so you don't have to repeat it all over the code. Take a look at the prompt() function from click.termui module to get a better understanding on how to build such things ( https://github.com/pallets/click/blob/master/src/click/termui.py). I would also recommend creating helper functions for common things like displaying results because right now it's hard to figure out which parts of application constitute its presentation layer and which are part of "core logic". Try to keep these two concepts separate and you will get better results. Second major structural "problem" are inline function definitions: def add_people(): def how_old(): ... def p_sex(): ... def marriage(): ... You shouldn't be doing that unless you need a closure with nonlocal variables to read from. Otherwise it really harms the readability. I understand the urge to keep relevant code close to the usage but you would have better results with modules. If you really want to keep everything in a single module, keep functions close together in the file but don't nest them. Use relevant naming conventions instead. Simply think of how you would write that in C. You could use some object-oriented approach too, but I would recommend polishing structural programming first. There are also other issues like not always closing files, and not validating the user input in specific places. Still, these will be more evident as you improve the structure of application and do thorough testing. Anyway, the code doesn't look bad. It of course needs improvement but I've also seen worse specimens from people being actually paid for writing the code. Remember that "how to make things better" is a function of few parameters: - what you want to achieve - what are you able to do - how much time do you have If your sole goal is to learn and improve skills, I would recommend polishing this in current procedural fashion to some extent, but not trying to make it perfect. Then I would start from scratch and experiment with different paradigms (OOP for instance). Then I would try to make a smaller project that has some actual utility. czw., 17 gru 2020 o 04:17 Bischoop napisa?(a): > On 2020-12-17, Bischoop wrote: > > > Accidently removed the paste, https://bpa.st/E3FQ > -- > https://mail.python.org/mailman/listinfo/python-list > From 2QdxY4RzWzUUiLuE at potatochowder.com Thu Dec 17 07:06:22 2020 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Thu, 17 Dec 2020 06:06:22 -0600 Subject: sudo python PermissionError [Errno 13] Permission denied In-Reply-To: References: Message-ID: On 2020-12-17 at 11:17:37 +0100, Pascal wrote: > hi, > > here, I have this simple script that tests if the /tmp/test file can be > opened in write mode : > > $ cat /tmp/append > #!/usr/bin/python > with open('/tmp/test', 'a'): pass > > the file does not exist yet : > > $ chmod +x /tmp/append > $ ls -l /tmp/test > ls: cannot access '/tmp/test': No such file or directory > > the script is launched as a simple user : > > $ /tmp/append > $ ls -l /tmp/test > -rw-r--r-- 1 user user 0 Dec 17 10:30 /tmp/test > > everything is ok. > now, the script fails if it is replayed as root user with the sudo command : > > $ sudo /tmp/append > [sudo] password for user: > Traceback (most recent call last): > File "/tmp/append", line 2, in > with open('/tmp/test', 'a'): > PermissionError: [Errno 13] Permission denied: '/tmp/test' > > the problem is the same if the opening mode is 'w' or if "sudo -i" or "su -" > are used. > > why can't root user under python manipulate the simple user file ? This has to do with the idiosyncratic permissions of the /tmp directory and not your code. In my shell on my Linux box: $ rm -f /tmp/x $ echo x >/tmp/x $ echo x | sudo tee /tmp/x tee: /tmp/x: Permission denied x $ ls -ld /tmp drwxrwxrwt 13 root root 380 Dec 17 06:03 /tmp Try your experiment in a different directory, one without the sticky bit set. From nospam at please.ty Thu Dec 17 07:10:17 2020 From: nospam at please.ty (jak) Date: Thu, 17 Dec 2020 13:10:17 +0100 Subject: dict.get(key, default) evaluates default even if key exists References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <20201217114049.GB8064@hjp.at> Message-ID: Il 17/12/2020 12:40, Peter J. Holzer ha scritto: > On 2020-12-17 12:16:29 +0100, jak wrote: >> print(_ if d.get('a', None) is not None else get_default()) > > That doesn't work: > >>>> print(_ if d.get('a', None) is not None else get_default()) > Traceback (most recent call last): > File "", line 1, in > NameError: name '_' is not defined > > But this works: > >>>> print(_ if (_ := d.get('a', None)) is not None else get_default()) > 1 > > (I would prefer ChrisA's solution, though.) > > hp > this one? """" D['a'] if 'a' in D else get_default() ChrisA """" This solution search two times same key. From rosuav at gmail.com Thu Dec 17 07:33:55 2020 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 17 Dec 2020 23:33:55 +1100 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <20201217114049.GB8064@hjp.at> Message-ID: On Thu, Dec 17, 2020 at 11:16 PM jak wrote: > > Il 17/12/2020 12:40, Peter J. Holzer ha scritto: > > On 2020-12-17 12:16:29 +0100, jak wrote: > >> print(_ if d.get('a', None) is not None else get_default()) > > > > That doesn't work: > > > >>>> print(_ if d.get('a', None) is not None else get_default()) > > Traceback (most recent call last): > > File "", line 1, in > > NameError: name '_' is not defined > > > > But this works: > > > >>>> print(_ if (_ := d.get('a', None)) is not None else get_default()) > > 1 > > > > (I would prefer ChrisA's solution, though.) > > > > hp > > > this one? > > """" > > D['a'] if 'a' in D else get_default() > > ChrisA > > """" > > This solution search two times same key. Yes, it does, but hash lookups are pretty fast. Unless your key is some sort of custom object with a very expensive __hash__ function, the double lookup isn't going to be too costly. But if that does bother you, you can write it as a try/except instead. ChrisA From nospam at please.ty Thu Dec 17 07:36:03 2020 From: nospam at please.ty (jak) Date: Thu, 17 Dec 2020 13:36:03 +0100 Subject: dict.get(key, default) evaluates default even if key exists References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <20201217114049.GB8064@hjp.at> Message-ID: Il 17/12/2020 12:40, Peter J. Holzer ha scritto: > On 2020-12-17 12:16:29 +0100, jak wrote: >> print(_ if d.get('a', None) is not None else get_default()) > > That doesn't work: > >>>> print(_ if d.get('a', None) is not None else get_default()) > Traceback (most recent call last): > File "", line 1, in > NameError: name '_' is not defined > > But this works: > >>>> print(_ if (_ := d.get('a', None)) is not None else get_default()) > 1 > > (I would prefer ChrisA's solution, though.) > > hp > I had already corrected my oversight (jak 12:32): > print((_ if d.get('a', None) is not None else get_default())) while your fix works but not correctly because in that way does not collect the return code of the function get_default(). From patatetom at gmail.com Thu Dec 17 07:43:42 2020 From: patatetom at gmail.com (Pascal) Date: Thu, 17 Dec 2020 13:43:42 +0100 Subject: sudo python PermissionError [Errno 13] Permission denied In-Reply-To: References: Message-ID: you are right ! the "sticky bit" set to /tmp/ prevents the root user from altering the file belonging to the simple user ! $ ls -ld /tmp/ drwxrwxrwt 13 root root 320 Dec 17 13:22 /tmp/ $ ls -l /tmp/test -rw-r--r-- 1 user 0 Dec 17 13:24 /tmp/test $ echo test | sudo tee -a /tmp/test tee: /tmp/test: Permission denied test but it does not prevent its deletion ! $ sudo rm -v /tmp/test removed '/tmp/test'. which misled me : sorry for the waste of time. happy end of year 2020, lacsaP. Le jeu. 17 d?c. 2020 ? 13:09, <2QdxY4RzWzUUiLuE at potatochowder.com> a ?crit : > On 2020-12-17 at 11:17:37 +0100, > Pascal wrote: > > > hi, > > > > here, I have this simple script that tests if the /tmp/test file can be > > opened in write mode : > > > > $ cat /tmp/append > > #!/usr/bin/python > > with open('/tmp/test', 'a'): pass > > > > the file does not exist yet : > > > > $ chmod +x /tmp/append > > $ ls -l /tmp/test > > ls: cannot access '/tmp/test': No such file or directory > > > > the script is launched as a simple user : > > > > $ /tmp/append > > $ ls -l /tmp/test > > -rw-r--r-- 1 user user 0 Dec 17 10:30 /tmp/test > > > > everything is ok. > > now, the script fails if it is replayed as root user with the sudo > command : > > > > $ sudo /tmp/append > > [sudo] password for user: > > Traceback (most recent call last): > > File "/tmp/append", line 2, in > > with open('/tmp/test', 'a'): > > PermissionError: [Errno 13] Permission denied: '/tmp/test' > > > > the problem is the same if the opening mode is 'w' or if "sudo -i" or > "su -" > > are used. > > > > why can't root user under python manipulate the simple user file ? > > This has to do with the idiosyncratic permissions of the /tmp directory > and not your code. In my shell on my Linux box: > > $ rm -f /tmp/x > $ echo x >/tmp/x > $ echo x | sudo tee /tmp/x > tee: /tmp/x: Permission denied > x > > $ ls -ld /tmp > drwxrwxrwt 13 root root 380 Dec 17 06:03 /tmp > > Try your experiment in a different directory, one without the sticky bit > set. > -- > https://mail.python.org/mailman/listinfo/python-list > From nospam at please.ty Thu Dec 17 07:49:22 2020 From: nospam at please.ty (jak) Date: Thu, 17 Dec 2020 13:49:22 +0100 Subject: dict.get(key, default) evaluates default even if key exists References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <20201217114049.GB8064@hjp.at> Message-ID: Il 17/12/2020 13:33, Chris Angelico ha scritto: > On Thu, Dec 17, 2020 at 11:16 PM jak wrote: >> >> Il 17/12/2020 12:40, Peter J. Holzer ha scritto: >>> On 2020-12-17 12:16:29 +0100, jak wrote: >>>> print(_ if d.get('a', None) is not None else get_default()) >>> >>> That doesn't work: >>> >>>>>> print(_ if d.get('a', None) is not None else get_default()) >>> Traceback (most recent call last): >>> File "", line 1, in >>> NameError: name '_' is not defined >>> >>> But this works: >>> >>>>>> print(_ if (_ := d.get('a', None)) is not None else get_default()) >>> 1 >>> >>> (I would prefer ChrisA's solution, though.) >>> >>> hp >>> >> this one? >> >> """" >> >> D['a'] if 'a' in D else get_default() >> >> ChrisA >> >> """" >> >> This solution search two times same key. > > Yes, it does, but hash lookups are pretty fast. Unless your key is > some sort of custom object with a very expensive __hash__ function, > the double lookup isn't going to be too costly. But if that does > bother you, you can write it as a try/except instead. > > ChrisA > try/except is a very expensive time. if we have a small dictionary in which you do little research, you definitely have reason. I would be curious to see the differences by taking times with 50 / 60K records by repeating the search 1 or 2 million times with and without try/except and also searching 1 or 2 times too. Cheers From Bischoop at vimart.net Thu Dec 17 11:10:44 2020 From: Bischoop at vimart.net (Bischoop) Date: Thu, 17 Dec 2020 16:10:44 -0000 (UTC) Subject: Review, suggestion etc? References: Message-ID: On 2020-12-17, Micha? Jaworski wrote: Thanks for feedback and useful tips. I couldn't use any OOP here because have not a clue about it, just going to go toward it. > I've made a quick look at the code and even executed it. It looks pretty > clear and is easy to understand, although it has some structural problems. > I won't do a thorough review but highlight the most important problems. > > First, the recursive user input pattern you use: > def marriage(): > maritals = input('Married: Yes/No ?: ').title() > while maritals != 'Yes' and maritals != 'No': > return marriage() > return maritals > > > def marriage(): > ... > Could you expand here, I rather don't know how I could do it different way apart from if maritals == 'Yes' or maritals == 'No' or is it what you meant? > You shouldn't be doing that unless you need a closure with nonlocal > variables to read from. Otherwise it really harms the readability. I > understand the urge to keep relevant code close to the usage but you would > have better results with modules. If you really want to keep everything in > a single module, keep functions close together in the file but don't nest > them. Use relevant naming conventions instead. Simply think of how you > would write that in C. You could use some object-oriented approach too, but > I would recommend polishing structural programming first. > Well I don't know C, the only other language I was learning it was basic for Atari :-) So in other words I shoudn't nest functions like in changes(), add_people() etc but keep everything in one functions. > There are also other issues like not always closing files, and not > validating the user input in specific places. Still, these will be more > evident as you improve the structure of application and do thorough > testing. Anyway, the code doesn't look bad. It of course needs improvement > but I've also seen worse specimens from people being actually paid for > writing the code. > > Remember that "how to make things better" is a function of few parameters: > - what you want to achieve > - what are you able to do > - how much time do you have > > If your sole goal is to learn and improve skills, I would recommend > polishing this in current procedural fashion to some extent, but not trying > to make it perfect. Then I would start from scratch and experiment with > different paradigms (OOP for instance). Then I would try to make a smaller > project that has some actual utility. > Yes, I was pretty much interested in Python at the end 90s however life made me putting this hobby away and now life changed again so I've more free time and I'm happy be back with Python so after couple months learning it again and writing few liners this is first thing that got me to use what I've learnt so far and gave opportunity to solve moany problems I had to deal with (had few nights without sleep ) :-) Now I'll learn OOP as you said and then try to made this program again with OOP from scratch. -- Thanks From Bischoop at vimart.net Thu Dec 17 11:20:16 2020 From: Bischoop at vimart.net (Bischoop) Date: Thu, 17 Dec 2020 16:20:16 -0000 (UTC) Subject: Messed up syntax in Vim when pasting python code to post to the groups. Message-ID: I've being asked not to use external links for code sharing to the groups but when I paste the code in to my vim editor I do use with slrn client the code is just messed up. How dear people people using vim solved this? From 2QdxY4RzWzUUiLuE at potatochowder.com Thu Dec 17 11:31:45 2020 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Thu, 17 Dec 2020 10:31:45 -0600 Subject: Messed up syntax in Vim when pasting python code to post to the groups. In-Reply-To: References: Message-ID: On 2020-12-17 at 16:20:16 -0000, Bischoop wrote: > I've being asked not to use external links for code sharing to the > groups but when I paste the code in to my vim editor I do use with > slrn client the code is just messed up. > How dear people people using vim solved this? I'm not a vim user, but it just came up to look into the paste and nopaste commands. From torriem at gmail.com Thu Dec 17 11:37:56 2020 From: torriem at gmail.com (Michael Torrie) Date: Thu, 17 Dec 2020 09:37:56 -0700 Subject: Review, suggestion etc? In-Reply-To: References: Message-ID: <1aabf08d-63e6-9a36-8130-f1aa26cccdff@gmail.com> On 12/17/20 9:10 AM, Bischoop wrote: > Could you expand here, I rather don't know how I could do it different > way apart from if maritals == 'Yes' or maritals == 'No' or is it what > you meant? I think he's hinting at using a loop instead. while maritals != 'Yes' and maritals != 'No': maritals = input('Married: Yes/No ?: ').title() I think I got the logical condition right. Sometimes those are tricky! From Bischoop at vimart.net Thu Dec 17 11:42:46 2020 From: Bischoop at vimart.net (Bischoop) Date: Thu, 17 Dec 2020 16:42:46 -0000 (UTC) Subject: Messed up syntax in Vim when pasting python code to post to the groups. References: Message-ID: On 2020-12-17, Bischoop wrote: > > I've being asked not to use external links for code sharing to the > groups but when I paste the code in to my vim editor I do use with slrn > client the code is just messed up. > How dear people people using vim solved this? Solved, partialy. Paste mode F2, however after pasting clicking F2 again supposed to go to paste option OFF but in my case it's still pasting without messing syntax, but yes I can paste with correct syntax. -- Thanks From Bischoop at vimart.net Thu Dec 17 11:52:14 2020 From: Bischoop at vimart.net (Bischoop) Date: Thu, 17 Dec 2020 16:52:14 -0000 (UTC) Subject: Messed up syntax in Vim when pasting python code to post to the groups. References: Message-ID: On 2020-12-17, 2QdxY4RzWzUUiLuE at potatochowder.com <2QdxY4RzWzUUiLuE at potatochowder.com> wrote: > > I'm not a vim user, but it just came up to look into the paste and > nopaste commands. I've googled the matter and found pressing F2 toogles 'paste' mode and then after pasting F2 again to switch off paste mode or manually :set paste :set nopaste https://vim.fandom.com/wiki/Toggle_auto-indenting_for_code_paste -- Thanks From Bischoop at vimart.net Thu Dec 17 12:00:45 2020 From: Bischoop at vimart.net (Bischoop) Date: Thu, 17 Dec 2020 17:00:45 -0000 (UTC) Subject: Review, suggestion etc? References: <1aabf08d-63e6-9a36-8130-f1aa26cccdff@gmail.com> Message-ID: On 2020-12-17, Michael Torrie wrote: > On 12/17/20 9:10 AM, Bischoop wrote: >> Could you expand here, I rather don't know how I could do it different >> way apart from if maritals == 'Yes' or maritals == 'No' or is it what >> you meant? > > I think he's hinting at using a loop instead. > > while maritals != 'Yes' and maritals != 'No': > maritals = input('Married: Yes/No ?: ').title() > > I think I got the logical condition right. Sometimes those are tricky! I think you're right. Yes those are tricky sometimes :-) Look how I had it previously: def marriage(): maritals = input('Married: Yes/No ?: ').title() while maritals != 'Yes' and maritals != 'No': return marriage() return maritals marital = marriage() When looking at it now I couldn't find the dumbest way for it. From swistakm at gmail.com Thu Dec 17 12:16:05 2020 From: swistakm at gmail.com (=?UTF-8?Q?Micha=C5=82_Jaworski?=) Date: Thu, 17 Dec 2020 18:16:05 +0100 Subject: Review, suggestion etc? In-Reply-To: <1aabf08d-63e6-9a36-8130-f1aa26cccdff@gmail.com> References: <1aabf08d-63e6-9a36-8130-f1aa26cccdff@gmail.com> Message-ID: > I think he's hinting at using a loop instead. > > while maritals != 'Yes' and maritals != 'No': > maritals = input('Married: Yes/No ?: ').title() Exactly. I would go even further and make it a reusable function. Eg. def prompt_choices(prompt, choices): choices = set(c.lower() for c in choices) while value := input(f"{prompt} {choices}:").lower() not in choices: pass return value Or without := operator: def prompt_choices(prompt, choices): value = None choices = set(c.lower() for c in choices) while value not in choices: input(f"{prompt} {choices}:").lower() return value That way you can use it as follows: marital = prompt_choices("Married", ["yes", "no"]) > So in other words I shoudn't nest functions like in > changes(), add_people() etc but keep > everything in one functions. Simply move those functions outside of their "hosting" functions and call them as they are. Also, many of them won't be needed anymore as you introduce some generic helper functions (e.g. prompt_choices). > Now I'll learn OOP as you said and then try to made this program again > with OOP from scratch. Recommend polishing the procedural approach a bit more too, though. Like reducing code repetition. Looking into how data is stored, eg. can fields be stored in CSV columns instead of JSON? OOP can be overwhelming at the very beginning. For instance it can take some time learning what should be an object and what shouldn't. You definitely can start adding e.g. dataclasses because they are more like structures (e.g. struct in C mentioned earlier). czw., 17 gru 2020 o 17:38 Michael Torrie napisa?(a): > On 12/17/20 9:10 AM, Bischoop wrote: > > Could you expand here, I rather don't know how I could do it different > > way apart from if maritals == 'Yes' or maritals == 'No' or is it what > > you meant? > > I think he's hinting at using a loop instead. > > while maritals != 'Yes' and maritals != 'No': > maritals = input('Married: Yes/No ?: ').title() > > I think I got the logical condition right. Sometimes those are tricky! > -- > https://mail.python.org/mailman/listinfo/python-list > From Bischoop at vimart.net Thu Dec 17 12:47:54 2020 From: Bischoop at vimart.net (Bischoop) Date: Thu, 17 Dec 2020 17:47:54 -0000 (UTC) Subject: Review, suggestion etc? References: <1aabf08d-63e6-9a36-8130-f1aa26cccdff@gmail.com> Message-ID: On 2020-12-17, Micha? Jaworski wrote: > > Exactly. I would go even further and make it a reusable function. Eg. > > def prompt_choices(prompt, choices): > choices = set(c.lower() for c in choices) > while value := input(f"{prompt} {choices}:").lower() not in choices: > pass > return value > > Or without := operator: > > def prompt_choices(prompt, choices): > value = None > choices = set(c.lower() for c in choices) > while value not in choices: > input(f"{prompt} {choices}:").lower() > return value > > That way you can use it as follows: > > marital = prompt_choices("Married", ["yes", "no"]) > Oh man that really not like they teach in tutorials. These are the examples at which you look and think: moment, I need a few sec to follow :-) >> So in other words I shoudn't nest functions like in >> changes(), add_people() etc but keep >> everything in one functions. > > Simply move those functions outside of their "hosting" functions and > call them as they are. Also, many of them won't be needed anymore as you > introduce some generic helper functions (e.g. prompt_choices). > Honestly I've done it like that because I thought that would be more elegant way to have how_old(), marriage() etc hosted in add_people() but I'm glad I've done this time because learn a bit, I had quite a problem to keep people argument storing and returning in every function, I see it was unecessary as I know now but another experience. >> Now I'll learn OOP as you said and then try to made this program again >> with OOP from scratch. > > Recommend polishing the procedural approach a bit more too, though. Like > reducing code repetition. Looking into how data is stored, eg. can fields > be stored in CSV columns instead of JSON? OOP can be overwhelming at the > very beginning. For instance it can take some time learning what should be > an object and what shouldn't. You definitely can start adding e.g. > dataclasses because they are more like structures (e.g. struct in C > mentioned earlier). > Right I keep it in mind. Yes, the storing you mention I'll have to improve, even the json I've done sucks because I've noticed it storing everything in one column lol I thought that json library handles it itself but apparently I have to tell him about it to insert key,values into different columns. -- Dzieki From Bischoop at vimart.net Thu Dec 17 12:55:28 2020 From: Bischoop at vimart.net (Bischoop) Date: Thu, 17 Dec 2020 17:55:28 -0000 (UTC) Subject: Function returns old value References: <5b8a1f0b-07a1-6bc7-39d3-b441adbb2010@DancesWithMice.info> <6c4028ef-0359-098e-6066-87765d51fb6a@DancesWithMice.info> Message-ID: On 2020-12-17, dn wrote: >> After expiry, any posts 'here' with links to 'there', will be useless. >> >> I do mind that however I thoght it better if paste a whole code to see >> and pasting from my IDE to vim/slrn was messing syntax, I'll do better >> next time. > > > Yes, it can be difficult to know how much code to include and how much > can be left-out. Don't worry about that - replies can always trim any > excess. > I solved the pasting problem but about triming the excess, well some people don't give a fuck and don't cut unecessary lines. I'm pretty sure that if I post a 100 line code, some will reply without cutting it just to point what's wrong in line 50 lol. > Also, don't be concerned about such comments. Rather than complaints, > please regard them as advice from folk who have been 'here' and/or using > Python for some time. I'm not concerned at all :-) I'm using newsgroups,irc for good over 20 years so I don't bother. -- Thanks From Bischoop at vimart.net Thu Dec 17 13:05:09 2020 From: Bischoop at vimart.net (Bischoop) Date: Thu, 17 Dec 2020 18:05:09 -0000 (UTC) Subject: Function returns old value References: <5b8a1f0b-07a1-6bc7-39d3-b441adbb2010@DancesWithMice.info> <20201217095751.GA8064@hjp.at> Message-ID: On 2020-12-17, Peter J. Holzer wrote: > > --EVF5PPMfhYS0aIcm > Content-Type: text/plain; charset=us-ascii > Content-Disposition: inline > Content-Transfer-Encoding: quoted-printable > > On 2020-12-17 03:06:32 -0000, Bischoop wrote: >> pasting from my IDE to vim/slrn was messing syntax, > > You can=20 > >:set paste Indeed, thanks I just didn't come to conclusion that it has to be special paste mode to paste without breaking the lines. Also adding in * set pastetoggle= * in vimrc activates paste mode when pressing F2, I find it more convenient. > From arj.python at gmail.com Thu Dec 17 14:52:07 2020 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Thu, 17 Dec 2020 23:52:07 +0400 Subject: Lambda in parameters Message-ID: Greetings list, Here is a famous question's solution def cons(a, b): def pair(f): return f(a, b) return pair def car(c): return c(lambda a, b: a) print(cons(1, 2)(lambda a, b: a)) print(car(cons(1, 2))) The aim of car is to return 1 but i don't understand how lambda achieves this Kind Regards, Abdur-Rahmaan Janhangeer https://www.github.com/Abdur-RahmaanJ Mauritius sent from gmail client on Android, that's why the signature is so ugly. From mstemper at gmail.com Thu Dec 17 15:22:41 2020 From: mstemper at gmail.com (Michael F. Stemper) Date: Thu, 17 Dec 2020 14:22:41 -0600 Subject: Function returns old value In-Reply-To: References: <5b8a1f0b-07a1-6bc7-39d3-b441adbb2010@DancesWithMice.info> <20201217095751.GA8064@hjp.at> Message-ID: On 17/12/2020 03.57, Peter J. Holzer wrote: > On 2020-12-17 03:06:32 -0000, Bischoop wrote: >> pasting from my IDE to vim/slrn was messing syntax, > > You can > > :set paste > > in vim to prevent it from messing with pasted content (don't forget to > set nopaste afterwards). What's the difference between that and :set ai and :set noai > With newer vims that's rarely necessary though since they can distinguish > between input that was pasted and input that was typed. I thought that I was going nuts when I encountered that. Any idea how to defeat such a so-called 'feature"? -- Michael F. Stemper The name of the story is "A Sound of Thunder". It was written by Ray Bradbury. You're welcome. From rshepard at appl-ecosys.com Thu Dec 17 17:29:30 2020 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Thu, 17 Dec 2020 14:29:30 -0800 (PST) Subject: setuptools issue Message-ID: I want to use tkcalendar and dateentry in my application but have problems with tkcalendar's dependency on babel and setuptools. When I try to build babel it fails: Traceback (most recent call last): File "/tmp/SBo/babel-2.8.1/setup.py", line 7, in from setuptools import setup ModuleNotFoundError: No module named 'setuptools' Installed on this Slackware-14.2/x86_64 workstation with python-3.9.1 are: python-setuptools-22.0.5-x86_64-1 setuptools-git-1.1-x86_64-1_SBo setuptools-scm-3.3.3-x86_64-1_SBo Please advise me how I diagnose the reason babel's setup.py cannot find a suitable setuptools. TIA, Rich From Bischoop at vimart.net Thu Dec 17 18:04:26 2020 From: Bischoop at vimart.net (Bischoop) Date: Thu, 17 Dec 2020 23:04:26 -0000 (UTC) Subject: Review, suggestion etc? References: Message-ID: On 2020-12-17, Dennis Lee Bieber wrote: >> > > The main concern is that you are using a RECURSIVE call. It is much > better for such input checking to use an ITERATIVE (loop) scheme. > > def marriage(): > #loop forever > while True: > #get response from user > maritals = input("Married: Yes/No ?").title() > #if response is good, exit (break) the loop > if maritals in ["Yes", "No"]: break > #otherwise display error message and repeat loop > print("Try again. Please respond with Yes or No") > #return valid response > return maritals > > It makes sense for me now, better logic used here than mine. I've never met that way used in * if maritals in ['Yes', No']: * , it makes code elegant. So it's not good to use calling function itself (recursive call), I get it now. From Bischoop at vimart.net Thu Dec 17 18:05:46 2020 From: Bischoop at vimart.net (Bischoop) Date: Thu, 17 Dec 2020 23:05:46 -0000 (UTC) Subject: Review, suggestion etc? References: Message-ID: On 2020-12-17, Bischoop wrote: > On 2020-12-17, Dennis Lee Bieber wrote: >>> >> >> The main concern is that you are using a RECURSIVE call. It is much >> better for such input checking to use an ITERATIVE (loop) scheme. >> >> def marriage(): >> #loop forever >> while True: >> #get response from user >> maritals = input("Married: Yes/No ?").title() >> #if response is good, exit (break) the loop >> if maritals in ["Yes", "No"]: break >> #otherwise display error message and repeat loop >> print("Try again. Please respond with Yes or No") >> #return valid response >> return maritals >> >> > It makes sense for me now, better logic used here than mine. > I've never met that way used in * if maritals in ['Yes', No']: * , > it makes code elegant. > So it's not good to use calling function itself (recursive call), I get it now. -- Thanks From jcasale at activenetwerx.com Thu Dec 17 19:05:12 2020 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Fri, 18 Dec 2020 00:05:12 +0000 Subject: setuptools issue In-Reply-To: References: Message-ID: <118586e610d849dca2b10325dd0cd1bf@activenetwerx.com> > Installed on this Slackware-14.2/x86_64 workstation with python-3.9.1 are: > python-setuptools-22.0.5-x86_64-1 I just ran into this recently, I don't recall the actual source but it was the version of setuptools having been so old. Your version is from Jun 3, 2016... Update it, that was what worked for me. jlc From pfeiffer at cs.nmsu.edu Thu Dec 17 20:17:32 2020 From: pfeiffer at cs.nmsu.edu (Joe Pfeiffer) Date: Thu, 17 Dec 2020 18:17:32 -0700 Subject: Review, suggestion etc? References: Message-ID: <1btusjap5f.fsf@pfeifferfamily.net> Bischoop writes: > On 2020-12-17, Dennis Lee Bieber wrote: >>> >> >> The main concern is that you are using a RECURSIVE call. It is much >> better for such input checking to use an ITERATIVE (loop) scheme. >> >> def marriage(): >> #loop forever >> while True: >> #get response from user >> maritals = input("Married: Yes/No ?").title() >> #if response is good, exit (break) the loop >> if maritals in ["Yes", "No"]: break >> #otherwise display error message and repeat loop >> print("Try again. Please respond with Yes or No") >> #return valid response >> return maritals >> >> > It makes sense for me now, better logic used here than mine. > I've never met that way used in * if maritals in ['Yes', No']: * , > it makes code elegant. > So it's not good to use calling function itself (recursive call), I get it now. Recursion has very limited application, but where it's the right tool it's invaluable (top-down parsers, some graph algorithms...). We teach it primarily because by the time a student has a good handle on how to write a recursive function they understand functions in general really well. From grant.b.edwards at gmail.com Thu Dec 17 23:02:18 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Fri, 18 Dec 2020 04:02:18 -0000 (UTC) Subject: Review, suggestion etc? References: <1btusjap5f.fsf@pfeifferfamily.net> Message-ID: On 2020-12-18, Joe Pfeiffer wrote: > Recursion has very limited application, but where it's the right > tool it's invaluable (top-down parsers, some graph algorithms...). > We teach it primarily because by the time a student has a good > handle on how to write a recursive function they understand > functions in general really well. Yep, there are definitly cases where it's pretty much the only right answer. If you try to avoid it, you end up writing what turns into a simulation of recursion -- and doing that correctly isn't easy. -- Grant From cs at cskk.id.au Fri Dec 18 01:02:42 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Fri, 18 Dec 2020 17:02:42 +1100 Subject: Lambda in parameters In-Reply-To: References: Message-ID: <20201218060242.GA45279@cskk.homeip.net> On 17Dec2020 23:52, Abdur-Rahmaan Janhangeer wrote: >Here is a famous question's solution These look like implementations of Lisp operators, which I've never found easy to remember. So I'll do this from first principles, but looking at the (uncommented) code. This is some gratuitiously tricky code. Maybe that's needed for these operators. But there's a lot here, so let's unpick it: >def cons(a, b): > def pair(f): > return f(a, b) > return pair Cons returns "pair", a function which itself accepts a function "f", calls it with 2 values "a, b" and returns the result. For ultra trickiness, those 2 values "a, b" are the ones you passed to the initial call to cons(). This last bit is a closure: when you define a function, any nonlocal variables (those you use but never assign to) have the defining scope available for finding them. So the "pair" function gets "a" and "b" from those you passed to "cons". Anyway, cons() returns a "pair" function hooked to the "a" and "b" you called it with. >def car(c): > return c(lambda a, b: a) The function accepts a function, and calls that function with "lambda a, b: a", which is itself a function which returns its first argument. You could write car like this: def car(c): def first(a, b): return a return c(first) The lambda is just a way to write a simple single expression function. >print(cons(1, 2)(lambda a, b: a)) What is "cons(1,2)". That returns a "pair" function hooked up to the a=1 and b=2 values you supplied. And the pair function accepts a function of 2 variables. What does this do? cons(1, 2)(lambda a, b: a) This takes the function returns by cons(1,2) and _calls_ that with a simple function which accepts 2 values and returns the first of them. So: cons(1,2) => "pair function hooked to a=1 and b=2" Then call: pair(lambda a, b: a) which sets "f" to the lambda function, can calls that with (a,b). So it calls the lambda function with (1,2). Which returns 1. >print(car(cons(1, 2))) The "car" function pretty much just embodies the call-with-the-lambda. >but i don't understand how lambda achieves this If you rewite the lambda like this: def a_from_ab(a,b): return a and then rewrite the first call to cons() like this: cons(1,2)(a_from_ab) does it make any more sense? Frankly, I think this is a terrible way to solve this problem, whatever the problem was supposed to be - that is not clear. On the other hand, I presume it does implement the Lisp cons and car functions. I truly have no idea, I just remember these names from my brief brush with Lisp in the past. Cheers, Cameron Simpson From cs at cskk.id.au Fri Dec 18 01:09:43 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Fri, 18 Dec 2020 17:09:43 +1100 Subject: Function returns old value In-Reply-To: References: Message-ID: <20201218060943.GA42805@cskk.homeip.net> On 17Dec2020 14:22, Michael F. Stemper wrote: >On 17/12/2020 03.57, Peter J. Holzer wrote: >>On 2020-12-17 03:06:32 -0000, Bischoop wrote: >>>pasting from my IDE to vim/slrn was messing syntax, >> >>You can >> >>:set paste >> >>in vim to prevent it from messing with pasted content (don't forget to >>set nopaste afterwards). > >What's the difference between that and >:set ai >and >:set noai Well, based on my experience (since the above is what I always do) that leave my automatic line folding and related "line wrapping" stuff still in play. Which I routinely have to repair if the pasted code is at all wide. [ Experiments with ":set paste". ] Yeah, the paste mode turns all that wrapping stuff off, and ":set nopaste" restores it intact. Ok, I guess I'm going to have to retrain my fingers now. >>With newer vims that's rarely necessary though since they can >>distinguish >>between input that was pasted and input that was typed. Mine doesn't seem to (vim inside a MacOS iTerm). >I thought that I was going nuts when I encountered that. Any idea how to >defeat such a so-called 'feature"? You mean having vim figure that out? I dunno. I came here from vi and haven't fully embraced al the stuff vim has. I _did_ discover recently that somehow iTerm and/or vim knows about my vim split buffers and doesn't cross the entirely in-vim-curses window boundary, very very handy. I guess iTerm may know about terminal scrolling regions, if that's how vim implements the windowing stuff. Cheers, Cameron Simpson From auriocus at gmx.de Fri Dec 18 07:05:26 2020 From: auriocus at gmx.de (Christian Gollwitzer) Date: Fri, 18 Dec 2020 13:05:26 +0100 Subject: Function returns old value In-Reply-To: References: <5b8a1f0b-07a1-6bc7-39d3-b441adbb2010@DancesWithMice.info> <20201217095751.GA8064@hjp.at> Message-ID: Am 17.12.20 um 21:22 schrieb Michael F. Stemper: > On 17/12/2020 03.57, Peter J. Holzer wrote: >> On 2020-12-17 03:06:32 -0000, Bischoop wrote: >>> pasting from my IDE to vim/slrn was messing syntax, >> >> You can >> >> :set paste >> >> in vim to prevent it from messing with pasted content (don't forget to >> set nopaste afterwards). > > What's the difference between that and > :set ai > and > :set noai > >> With newer vims that's rarely necessary though since they can distinguish >> between input that was pasted and input that was typed. > > I thought that I was going nuts when I encountered that. Any idea how to > defeat such a so-called 'feature"? Use "gvim" instead of "vim" in a Terminal. The problems arises because vim in the terminal simply gets the input and "thinks" that you typed that stuff in, for which it does auto-indenting. gvim, OTOH, doe sthe pasting by itself. It also has other useful features like menus and popup-dialogs for searching etc. Christian From arj.python at gmail.com Fri Dec 18 09:20:13 2020 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Fri, 18 Dec 2020 18:20:13 +0400 Subject: Lambda in parameters In-Reply-To: <20201218060242.GA45279@cskk.homeip.net> References: <20201218060242.GA45279@cskk.homeip.net> Message-ID: The Question: # --- This problem was asked by Jane Street. cons(a, b) constructs a pair, and car(pair) and cdr(pair) returns the first and last element of that pair. For example, car(cons(3, 4)) returns 3, and cdr(cons(3, 4)) returns 4. Given this implementation of cons: def cons(a, b): def pair(f): return f(a, b) return pair Implement car and cdr. # --- Kind Regards, Abdur-Rahmaan Janhangeer https://www.github.com/Abdur-RahmaanJ Mauritius sent from gmail client on Android, that's why the signature is so ugly. On Fri, 18 Dec 2020, 10:02 Cameron Simpson, wrote: > On 17Dec2020 23:52, Abdur-Rahmaan Janhangeer wrote: > >Here is a famous question's solution > > These look like implementations of Lisp operators, which I've never > found easy to remember. So I'll do this from first principles, but > looking at the (uncommented) code. > > This is some gratuitiously tricky code. Maybe that's needed for these > operators. But there's a lot here, so let's unpick it: > > >def cons(a, b): > > def pair(f): > > return f(a, b) > > return pair > > Cons returns "pair", a function which itself accepts a function "f", > calls it with 2 values "a, b" and returns the result. For ultra > trickiness, those 2 values "a, b" are the ones you passed to the initial > call to cons(). > > This last bit is a closure: when you define a function, any nonlocal > variables (those you use but never assign to) have the defining scope > available for finding them. So the "pair" function gets "a" and "b" from > those you passed to "cons". > > Anyway, cons() returns a "pair" function hooked to the "a" and "b" you > called it with. > > >def car(c): > > return c(lambda a, b: a) > > The function accepts a function, and calls that function with "lambda a, > b: a", which is itself a function which returns its first argument. You > could write car like this: > > def car(c): > def first(a, b): > return a > return c(first) > > The lambda is just a way to write a simple single expression function. > > >print(cons(1, 2)(lambda a, b: a)) > > What is "cons(1,2)". That returns a "pair" function hooked up to the a=1 > and b=2 values you supplied. And the pair function accepts a function of > 2 variables. > > What does this do? > > cons(1, 2)(lambda a, b: a) > > This takes the function returns by cons(1,2) and _calls_ that with a > simple function which accepts 2 values and returns the first of them. > > So: > > cons(1,2) => "pair function hooked to a=1 and b=2" > > Then call: > > pair(lambda a, b: a) > > which sets "f" to the lambda function, can calls that with (a,b). So it > calls the lambda function with (1,2). Which returns 1. > > >print(car(cons(1, 2))) > > The "car" function pretty much just embodies the call-with-the-lambda. > > >but i don't understand how lambda achieves this > > If you rewite the lambda like this: > > def a_from_ab(a,b): > return a > > and then rewrite the first call to cons() like this: > > cons(1,2)(a_from_ab) > > does it make any more sense? > > Frankly, I think this is a terrible way to solve this problem, whatever > the problem was supposed to be - that is not clear. > > On the other hand, I presume it does implement the Lisp cons and car > functions. I truly have no idea, I just remember these names from my > brief brush with Lisp in the past. > > Cheers, > Cameron Simpson > -- > https://mail.python.org/mailman/listinfo/python-list > From pfeiffer at cs.nmsu.edu Fri Dec 18 11:12:11 2020 From: pfeiffer at cs.nmsu.edu (Joe Pfeiffer) Date: Fri, 18 Dec 2020 09:12:11 -0700 Subject: Review, suggestion etc? References: <1btusjap5f.fsf@pfeifferfamily.net> Message-ID: <1bpn379jqc.fsf@pfeifferfamily.net> Grant Edwards writes: > On 2020-12-18, Joe Pfeiffer wrote: > >> Recursion has very limited application, but where it's the right >> tool it's invaluable (top-down parsers, some graph algorithms...). >> We teach it primarily because by the time a student has a good >> handle on how to write a recursive function they understand >> functions in general really well. > > Yep, there are definitly cases where it's pretty much the only right > answer. If you try to avoid it, you end up writing what turns into a > simulation of recursion -- and doing that correctly isn't easy. Decades ago I had to write a binary tree search in FORTRAN IV. It wasn't pretty. From barry at barrys-emacs.org Fri Dec 18 11:19:08 2020 From: barry at barrys-emacs.org (Barry) Date: Fri, 18 Dec 2020 16:19:08 +0000 Subject: Lambda in parameters In-Reply-To: References: Message-ID: <4801D5FB-BA12-494B-B971-508F99F6B0C6@barrys-emacs.org> > On 18 Dec 2020, at 14:23, Abdur-Rahmaan Janhangeer wrote: > > ?The Question: > > # --- > This problem was asked by Jane Street. > > cons(a, b) constructs a pair, and car(pair) and cdr(pair) returns the first > and last element of that pair. For example, car(cons(3, 4)) returns 3, and > cdr(cons(3, 4)) returns 4. > > Given this implementation of cons: > > def cons(a, b): > def pair(f): > return f(a, b) > return pair > > Implement car and cdr. Why car and cdr? Well obviously car is content of the address register and cdr is content of data register. Apparently an artefact of a early implementation of lisp. Barry > # --- > > Kind Regards, > > > Abdur-Rahmaan Janhangeer > > https://www.github.com/Abdur-RahmaanJ > > Mauritius > > sent from gmail client on Android, that's why the signature is so ugly. > >> On Fri, 18 Dec 2020, 10:02 Cameron Simpson, wrote: >> >>> On 17Dec2020 23:52, Abdur-Rahmaan Janhangeer wrote: >>> Here is a famous question's solution >> >> These look like implementations of Lisp operators, which I've never >> found easy to remember. So I'll do this from first principles, but >> looking at the (uncommented) code. >> >> This is some gratuitiously tricky code. Maybe that's needed for these >> operators. But there's a lot here, so let's unpick it: >> >>> def cons(a, b): >>> def pair(f): >>> return f(a, b) >>> return pair >> >> Cons returns "pair", a function which itself accepts a function "f", >> calls it with 2 values "a, b" and returns the result. For ultra >> trickiness, those 2 values "a, b" are the ones you passed to the initial >> call to cons(). >> >> This last bit is a closure: when you define a function, any nonlocal >> variables (those you use but never assign to) have the defining scope >> available for finding them. So the "pair" function gets "a" and "b" from >> those you passed to "cons". >> >> Anyway, cons() returns a "pair" function hooked to the "a" and "b" you >> called it with. >> >>> def car(c): >>> return c(lambda a, b: a) >> >> The function accepts a function, and calls that function with "lambda a, >> b: a", which is itself a function which returns its first argument. You >> could write car like this: >> >> def car(c): >> def first(a, b): >> return a >> return c(first) >> >> The lambda is just a way to write a simple single expression function. >> >>> print(cons(1, 2)(lambda a, b: a)) >> >> What is "cons(1,2)". That returns a "pair" function hooked up to the a=1 >> and b=2 values you supplied. And the pair function accepts a function of >> 2 variables. >> >> What does this do? >> >> cons(1, 2)(lambda a, b: a) >> >> This takes the function returns by cons(1,2) and _calls_ that with a >> simple function which accepts 2 values and returns the first of them. >> >> So: >> >> cons(1,2) => "pair function hooked to a=1 and b=2" >> >> Then call: >> >> pair(lambda a, b: a) >> >> which sets "f" to the lambda function, can calls that with (a,b). So it >> calls the lambda function with (1,2). Which returns 1. >> >>> print(car(cons(1, 2))) >> >> The "car" function pretty much just embodies the call-with-the-lambda. >> >>> but i don't understand how lambda achieves this >> >> If you rewite the lambda like this: >> >> def a_from_ab(a,b): >> return a >> >> and then rewrite the first call to cons() like this: >> >> cons(1,2)(a_from_ab) >> >> does it make any more sense? >> >> Frankly, I think this is a terrible way to solve this problem, whatever >> the problem was supposed to be - that is not clear. >> >> On the other hand, I presume it does implement the Lisp cons and car >> functions. I truly have no idea, I just remember these names from my >> brief brush with Lisp in the past. >> >> Cheers, >> Cameron Simpson >> -- >> https://mail.python.org/mailman/listinfo/python-list >> > -- > https://mail.python.org/mailman/listinfo/python-list > From rshepard at appl-ecosys.com Fri Dec 18 11:25:05 2020 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Fri, 18 Dec 2020 08:25:05 -0800 (PST) Subject: setuptools issue In-Reply-To: <118586e610d849dca2b10325dd0cd1bf@activenetwerx.com> References: <118586e610d849dca2b10325dd0cd1bf@activenetwerx.com> Message-ID: On Fri, 18 Dec 2020, Joseph L. Casale wrote: > I just ran into this recently, I don't recall the actual source but it was > the version of setuptools having been so old. Your version is from Jun 3, > 2016... > Update it, that was what worked for me. jlc, Upgraded to python-setuptools-51.0.0-x86_64. Now when I try building python3-babel it fails at this point: running import_cldr Extracting CLDR to '/tmp/SBo/babel-2.8.1/cldr/cldr-core-36' Traceback (most recent call last): File "/tmp/SBo/babel-2.8.1/scripts/import_cldr.py", line 34, in from babel import dates, numbers File "/tmp/SBo/babel-2.8.1/babel/dates.py", line 23, in import pytz as _pytz ModuleNotFoundError: No module named 'pytz' ## N.B.: pytz is installed here: pytz-2018.3-x86_64-1_SBo ## Could this also be too old? There's a pytz-2020.4 on PyPI Traceback (most recent call last): File "/tmp/SBo/babel-2.8.1/scripts/download_import_cldr.py", line 104, in main() File "/tmp/SBo/babel-2.8.1/scripts/download_import_cldr.py", line 97, in main subprocess.check_call([ File "/usr/lib64/python3.9/subprocess.py", line 373, in check_call raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command '['/usr/bin/python3', '/tmp/SBo/babel-2.8.1/scripts/import_cldr.py', '/tmp/SBo/babel-2.8.1/cldr/cldr-core-36/common']' returned non-zero exit status 1. Traceback (most recent call last): File "/tmp/SBo/babel-2.8.1/setup.py", line 30, in setup( File "/usr/lib/python3.9/site-packages/setuptools/__init__.py", line 153, in setup return distutils.core.setup(**attrs) File "/usr/lib64/python3.9/distutils/core.py", line 148, in setup dist.run_commands() File "/usr/lib64/python3.9/distutils/dist.py", line 966, in run_commands self.run_command(cmd) File "/usr/lib64/python3.9/distutils/dist.py", line 985, in run_command cmd_obj.run() File "/tmp/SBo/babel-2.8.1/setup.py", line 27, in run subprocess.check_call([sys.executable, 'scripts/download_import_cldr.py']) File "/usr/lib64/python3.9/subprocess.py", line 373, in check_call raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command '['/usr/bin/python3', 'scripts/download_import_cldr.py']' returned non-zero exit status 1. Regards, Rich From julio at diegidio.name Fri Dec 18 11:26:42 2020 From: julio at diegidio.name (Julio Di Egidio) Date: Fri, 18 Dec 2020 08:26:42 -0800 (PST) Subject: Lambda in parameters In-Reply-To: References: <20201218060242.GA45279@cskk.homeip.net> Message-ID: On Friday, 18 December 2020 at 15:20:59 UTC+1, Abdur-Rahmaan Janhangeer wrote: > The Question: > > # --- > This problem was asked by Jane Street. > > cons(a, b) constructs a pair, and car(pair) and cdr(pair) returns the first > and last element of that pair. For example, car(cons(3, 4)) returns 3, and > cdr(cons(3, 4)) returns 4. > > Given this implementation of cons: > def cons(a, b): > def pair(f): > return f(a, b) > return pair > Implement car and cdr. > # --- Notice that you don't need (Python) lambdas to code it, plain function definitions are fine: # --- def cons(a, b): def pair(f): return f(a, b) return pair def car(pair): def left(a, b): return a return pair(left) pair = cons(1, 2) assert car(pair) == 1 # --- That said, few basic comments: In Python, that 'cons' does not construct a pair, it rather returns a function with values a and b in its closure that, given some function, applies it to those values. In fact, Python has tuples built-in, how to build them as well as how to access their members. I take it the point of the exercise is how to use a purely functional language, such as here a fragment of Python, to encode (i.e. formalize) pairs and their operations. Julio From grant.b.edwards at gmail.com Fri Dec 18 11:31:24 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Fri, 18 Dec 2020 16:31:24 -0000 (UTC) Subject: Review, suggestion etc? References: <1btusjap5f.fsf@pfeifferfamily.net> <1bpn379jqc.fsf@pfeifferfamily.net> Message-ID: On 2020-12-18, Joe Pfeiffer wrote: > Grant Edwards writes: > >> Yep, there are definitly cases where it's pretty much the only right >> answer. If you try to avoid it, you end up writing what turns into a >> simulation of recursion -- and doing that correctly isn't easy. > > Decades ago I had to write a binary tree search in FORTRAN IV. It > wasn't pretty. I saw somebody try to write a graph search in GW-BASIC once. It was a huge mess, and wasn't anywhere close to working. Doing the same thing recursively was trivial -- even in C. In Python it wuld have been even trivialler. -- Grant From grant.b.edwards at gmail.com Fri Dec 18 11:35:31 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Fri, 18 Dec 2020 16:35:31 -0000 (UTC) Subject: Lambda in parameters References: <4801D5FB-BA12-494B-B971-508F99F6B0C6@barrys-emacs.org> Message-ID: On 2020-12-18, Barry wrote: >> Implement car and cdr. > Why car and cdr? > > Well obviously car is content of the address register and cdr is content of data register. > Apparently an artefact of a early implementation of lisp. While car and cdr are lisp operators, the "content of address register" and "content of data register" etymology is apparently apocryphal: https://en.wikipedia.org/wiki/CAR_and_CDR#Etymology -- Grant From PythonList at DancesWithMice.info Fri Dec 18 16:35:23 2020 From: PythonList at DancesWithMice.info (dn) Date: Sat, 19 Dec 2020 10:35:23 +1300 Subject: "Worst bugs" and Python? Message-ID: TechRepublic have published a lovely piece of 'click-bait' featuring alarmist claims such as "open-source libraries are increasingly untrustworthy" whilst trotting-out tired, old, memes and bias. Don't panic - hold-on to your PyPi! <<< The worst bugs in the top programming languages by Brandon Vigliarolo in Security on December 17, 2020, 9:32 AM PST A heatmap shows PHP has the most flaws followed by C++, then Java, .Net, JavaScript, and Python in Veracode's annual security report. >>> https://www.techrepublic.com/article/the-worst-bugs-in-the-top-programming-languages/ Does anyone think that code is 'bug free'? That's a 'filler topic' for any columnist lacking fresh ideas and desperate to fill a publishing deadline. The basis is "State of Software Security v11" 'report' produced by Veracode (https://www.veracode.com/state-of-software-security-report). You will not be surprised to note that Veracode is in the business of marketing test and analysis software. Any such report is inherently useful. They serve to ensure that we do not become complacent in our attitude to security. However, there are more "bugs" in software than fit under the heading of 'security'. Similarly, at times the report appears to lump-together C, C++, and C#; whereas at others they may not; which makes it difficult to generalise or analyse. In the same vein, infographics look nice, but what does "Code Quality" really mean? Another observation is that many of their 'categories' apply mainly to the on-line world. Corporation-only applications are protected by network defences rather than by their own devices. A more interesting figure, which is under-reported both in the article and within Veracode's summaries, is the period of vulnerability - how long it takes to fix a bug after it has been reported - and preferably with the 'danger' of the bug factored-in. Thus a bug which doesn't allow the addition of new user-credentials is quite a different matter from one which allows existing users to upgrade themselves to 'super-user'. Such analysis is possibly available, but not in the summaries (above). A quick dip into Veracode's 'vulnerability database' yielded the following intelligence: Top three "library artefacts" with Python as [the only] keyword: - firefox - thunderbird - linux-rt Is Python 'counted' in these cases because it is involved somewhere within the package, because it is the majority-language used, because it is the only language employed, or because its use contributes to most of the faults-found? Finally, such reports are primarily marketing tools, and thus notorious for bias or superficial content. Veracode do not declare the range, or limits on the range, of software they've analysed. Companies such as Microsoft and Oracle (plus, plus, ...) do not allow just-anyone to analyse their source-code - whereas 'open source' is available for analysis, by definition! An easy 'target' for shallow analysis? At this point I gave up, lacking the interest to fill-out the contact-form, or to read the entire report. The good news is, that of the six languages headlined in the summaries, Python comes-off 'best' (cf .Net, C++, Java, JavaScript, and PHP). -- Regards, =dn From Joseph.Schachner at Teledyne.com Fri Dec 18 17:41:42 2020 From: Joseph.Schachner at Teledyne.com (Schachner, Joseph) Date: Fri, 18 Dec 2020 22:41:42 +0000 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: <263519400.745131.1608052036522@mail.yahoo.com> References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> Message-ID: Yes. In order to call D.get( ) it needs to pass two arguments. The first is 'a', simple. The second is the result of a call to get_default(). So, that is called. From INSIDE get_default() it prints 'Nobody expects this' but you should expect it, get_default() gets executed. Following that it prints '1', because the default value was NOT USED. If it was used, you would see 'Nobody expects this' followed by 0. --- Joseph S. -----Original Message----- From: Mark Polesky Sent: Tuesday, December 15, 2020 12:07 PM To: python-list at python.org Subject: dict.get(key, default) evaluates default even if key exists Hi. # Running this script.... D = {'a':1} def get_default(): ??? print('Nobody expects this') ??? return 0 print(D.get('a', get_default())) # ...generates this output: Nobody expects this 1 ### Since I'm brand new to this community, I thought I'd ask here first... Is this worthy of a bug report?? This behavior is definitely unexpected to me, and I accidentally coded an endless loop in a mutual recursion situation because of it.? Calling dict.get.__doc__ only gives this short sentence: Return the value for key if key is in the dictionary, else default.? Nothing in that docstring suggests that the default value is evaluated even if the key exists, and I can't think of any good reason to do so. Am I missing something? Thanks, Mark From rshepard at appl-ecosys.com Fri Dec 18 17:30:57 2020 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Fri, 18 Dec 2020 14:30:57 -0800 (PST) Subject: "Worst bugs" and Python? In-Reply-To: References: Message-ID: On Sat, 19 Dec 2020, dn via Python-list wrote: > Companies such as Microsoft and Oracle (plus, plus, ...) do not allow > just-anyone to analyse their source-code - whereas 'open source' is > available for analysis, by definition! An easy 'target' for shallow > analysis? Looks bass-ackwards to me. That's the same argument made by proprietary companies (especially Micro$oft) in the early 1990s. What falsifies the writer's argument is all the malware that's affected Windoze over the past couple of decades compared to F/OSS OSes and applications. Sigh. Fake news hits the software industry. Carpe weekend, Rich From mstemper at gmail.com Sat Dec 19 09:46:05 2020 From: mstemper at gmail.com (Michael F. Stemper) Date: Sat, 19 Dec 2020 08:46:05 -0600 Subject: Function returns old value In-Reply-To: References: <20201218060943.GA42805@cskk.homeip.net> Message-ID: On 18/12/2020 00.09, Cameron Simpson wrote: > On 17Dec2020 14:22, Michael F. Stemper wrote: >> On 17/12/2020 03.57, Peter J. Holzer wrote: >>> On 2020-12-17 03:06:32 -0000, Bischoop wrote: >>> With newer vims that's rarely necessary though since they can >>> distinguish >>> between input that was pasted and input that was typed. > > Mine doesn't seem to (vim inside a MacOS iTerm). > >> I thought that I was going nuts when I encountered that. Any idea how to >> defeat such a so-called 'feature"? > > You mean having vim figure that out? I dunno. I came here from vi and > haven't fully embraced al the stuff vim has. What I want is for vi to treat all input the same, whether it comes directly from the keyboard, or from a copy/paste buffer. It did everything fine from '92 when I started using it on AIX until a year or two back when I briefly went to Ubuntu 18.04 LTS. Then, I could paste a command into it, and it would insert it into the text, rather than executing it. Or, I'd paste (in input mode; repeatedly verified) some TeX and it would decide that it was really a command and execute it. And I've just realized which group this is, so my complaint is completely off-topic. Sorry. -- Michael F. Stemper Deuteronomy 24:17 From meunier at ccs.neu.edu Sat Dec 19 07:39:13 2020 From: meunier at ccs.neu.edu (Philippe Meunier) Date: Sat, 19 Dec 2020 07:39:13 -0500 Subject: Lambda in parameters In-Reply-To: Message-ID: Abdur-Rahmaan Janhangeer wrote: >The aim of car is to return 1 >but i don't understand how lambda achieves this Cameron Simpson's explanation is very good. See also the example reduction here: https://en.wikipedia.org/wiki/Church_encoding#Church_pairs >This problem was asked by Jane Street. Jane Street is well known for its love of functional programming in general and of OCaml in particular. If you don't know OCaml yet, I highly recommend it. You can think of it as Python with (static) types. Best, Philippe From lammenspaolo at gmail.com Sat Dec 19 09:38:21 2020 From: lammenspaolo at gmail.com (Paolo Lammens) Date: Sat, 19 Dec 2020 15:38:21 +0100 Subject: Delegating to part of a subgenerator Message-ID: Dear all, I've been struggling with the following problem, and I thought maybe there is someone here in python-list who could shine some light on this. Suppose we have a generator function `subgen`, and we want to wrap this in another generator function, `gen`. For clarity, these are "full" generators, i.e. they make use of .send, .throw, .close, etc. The purpose of `gen` is to intercept the first value yielded by `subgen`, transforming it in some form, and forwarding it on to the caller; after that, it should just delegate to the rest of the generator iterator with `yield from`. The problem is, the semantics of `yield from` expect a "fresh" generator iterator, not a partially consumed generator. Indeed, the first value that `yield from` will send to the iterator will be `None`, to start the execution of the generator. But in this case we have already started the generator, and to continue its execution we should really send whatever we received after yielding the first value. However there's no way to specify this with the `yield from` syntax. A solution would be to re-implement the semantics of `yield from`, but with an optional starting value (other than None) that will be sent to the iterator as the initial value. However this means, as I said, re-implementing the whole of `yield from`, i.e. handling .send(), .throw(), .close(), etc., which is not ideal. So that would not be a good solution. Am I asking for the impossible? More details and an example in my original stackoverflow question: https://stackoverflow.com/q/65369447/6117426 Best, From cs at cskk.id.au Sat Dec 19 16:24:59 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Sun, 20 Dec 2020 08:24:59 +1100 Subject: Lambda in parameters In-Reply-To: References: Message-ID: <20201219212459.GA28218@cskk.homeip.net> On 19Dec2020 07:39, Philippe Meunier wrote: >See also the example reduction >here: https://en.wikipedia.org/wiki/Church_encoding#Church_pairs Thank you for this reference. I've stuck it on my reading list. Cheers, Cameron Simpson From greg.ewing at canterbury.ac.nz Sat Dec 19 17:52:59 2020 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Sun, 20 Dec 2020 11:52:59 +1300 Subject: Lambda in parameters In-Reply-To: References: <20201218060242.GA45279@cskk.homeip.net> Message-ID: On 18/12/20 7:02 pm, Cameron Simpson wrote: > Frankly, I think this is a terrible way to solve this problem, whatever > the problem was supposed to be - that is not clear. It demonstrates that a programming language doesn't strictly need data structes -- you can do everything with nothing but functions. This is mainly of theoretical interest; it's not usually a practical way to go about things. But it's a good exercise in thinking about functions as objects to be manipulated. -- Greg From arj.python at gmail.com Sat Dec 19 22:47:36 2020 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Sun, 20 Dec 2020 07:47:36 +0400 Subject: Lambda in parameters In-Reply-To: <20201218060242.GA45279@cskk.homeip.net> References: <20201218060242.GA45279@cskk.homeip.net> Message-ID: Greetings, Very clear explanations, rewriting lambdas as a function was the key to understand it. Did not know was a lisp inspiration. My mind still spiralling XD Kind Regards, Abdur-Rahmaan Janhangeer about | blog github Mauritius From arj.python at gmail.com Sat Dec 19 22:49:07 2020 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Sun, 20 Dec 2020 07:49:07 +0400 Subject: Lambda in parameters In-Reply-To: <4801D5FB-BA12-494B-B971-508F99F6B0C6@barrys-emacs.org> References: <4801D5FB-BA12-494B-B971-508F99F6B0C6@barrys-emacs.org> Message-ID: Greetings list, Why car and cdr? Well obviously car is content of the address register and cdr is content of data register. Apparently an artefact of a early implementation of lisp. Oh did not know that detail. More twists for sure. Thought lisp did not go lowlevel. Kind Regards, Abdur-Rahmaan Janhangeer about | blog github Mauritius From arj.python at gmail.com Sat Dec 19 22:52:32 2020 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Sun, 20 Dec 2020 07:52:32 +0400 Subject: Lambda in parameters In-Reply-To: References: Message-ID: Greetings list, Jane Street is well known for its love of functional programming in general and of OCaml in particular. If you don't know OCaml yet, I highly recommend it. You can think of it as Python with (static) types. Yes i know OCaml when i was exploring haskell and the like. At that time i was looking for companies who use OCaml etc Did not come across Jane Street (If you know someone from there tell them the question writer has a really twisted mind ^^)/. I don't understand why though you would prefer OCaml over Python, Go, Java etc for a company ^^ Kind Regards, Abdur-Rahmaan Janhangeer about | blog github Mauritius From cl at isbd.net Sun Dec 20 04:39:17 2020 From: cl at isbd.net (Chris Green) Date: Sun, 20 Dec 2020 09:39:17 +0000 Subject: How do you find what exceptions a class can throw? Message-ID: <5ni3bh-r5rj.ln1@esprimo.zbmc.eu> I am using poplib.POP3_SSL() and I want to know what exceptions can be thrown when I instantiate it. Presumably it inherits them because there's nothing much in the documentation page for poplib.POP3_SSL(). I specifically want to trap timeout exceptions. (... and, yes, I know I should maybe move to IMAP but that's too much work at the moment!) -- Chris Green ? From PythonList at DancesWithMice.info Sun Dec 20 05:39:28 2020 From: PythonList at DancesWithMice.info (dn) Date: Sun, 20 Dec 2020 23:39:28 +1300 Subject: How do you find what exceptions a class can throw? In-Reply-To: <5ni3bh-r5rj.ln1@esprimo.zbmc.eu> References: <5ni3bh-r5rj.ln1@esprimo.zbmc.eu> Message-ID: On 20/12/2020 22:39, Chris Green wrote: > I am using poplib.POP3_SSL() and I want to know what exceptions can be > thrown when I instantiate it. Presumably it inherits them because > there's nothing much in the documentation page for poplib.POP3_SSL(). > > I specifically want to trap timeout exceptions. > > (... and, yes, I know I should maybe move to IMAP but that's too much > work at the moment!) This morning, reading the results of the Virtual Python Core Developer Sprint 2020 (https://pyfound.blogspot.com/2020/12/virtual-python-core-developer-sprint.html) and from there, PEP 594 -- Removing dead batteries from the standard library (https://www.python.org/dev/peps/pep-0594/), the impression gained is that the old/existing PSL offerings, eg poplib, are soon to be deprecated, in favor of asyncio and presumably something like aioimap (https://pypi.org/project/aioimaplib/). Async handles with timeouts implicitly. Apologies for the lack of direct-answer. That's as far as my reading has taken me. Hopefully someone, more in-the-know, will be able to advise... -- Regards =dn From roel at roelschroeven.net Sat Dec 19 16:29:34 2020 From: roel at roelschroeven.net (Roel Schroeven) Date: Sat, 19 Dec 2020 22:29:34 +0100 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: <09aee7aa-146c-1c7f-1d0e-b800d7f4eac5@stoneleaf.us> References: <263519400.745131.1608052036522.ref@mail.yahoo.com> <263519400.745131.1608052036522@mail.yahoo.com> <87bleu18s9.fsf@hornfels.zedat.fu-berlin.de> <92ed36a3e1fe6a3d3aaf5c935da1dc75402b172b.camel@anode.ca> <87pn3ayvj2.fsf@hornfels.zedat.fu-berlin.de> <05df3a5f53b4d92a34f8399265a84b27f630da96.camel@anode.ca> <87lfdyytwd.fsf@hornfels.zedat.fu-berlin.de> <09aee7aa-146c-1c7f-1d0e-b800d7f4eac5@stoneleaf.us> Message-ID: Ethan Furman schreef op 16/12/2020 om 17:59: > Or, if the computationally massively expensive call uses potentially > different arguments for each invocation: > > some_var = d.get('a') or cme(arg1, arg2, ...) I don't like that because it is very fragile: the expression will evaluate to the second part not only when 'a' is not in the dictionary but also whenever the value corresponding to key 'a' is false-y. Example: def slow_function(a, b): # Pretend this is slow, or there is any other reason for this # function to be called only when strictly necessary. print('slow_function called') return a + b d = { 'spam': 0, 'ham': 1, 'parrot': 2, } some_var = d.get('spam') or slow_function(31, 11) print(some_var) Result: slow_function is called, and some_var equals 42 instead of 0. You could make it work reliable by using a unique sentinel value and the walrus operator: SENTINEL = object() some_var = ( r if (r := d.get('spam', SENTINEL)) is not SENTINEL else slow_function(31, 11) ) But I don't like that either because it's way too complicated. What could be useful in some use cases, I think, is a wrapper function that evaluates the function lazily: def dict_get_lazily(d, key, fnc, *args, **kwargs): try: return d[key] except KeyError: return fnc(*args, **kwargs) some_var = dict_get_lazily(d, 'spam', some_function, 31, 11) -- "Honest criticism is hard to take, particularly from a relative, a friend, an acquaintance, or a stranger." -- Franklin P. Jones Roel Schroeven From 2QdxY4RzWzUUiLuE at potatochowder.com Sun Dec 20 08:45:50 2020 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Sun, 20 Dec 2020 07:45:50 -0600 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: References: <87bleu18s9.fsf@hornfels.zedat.fu-berlin.de> <92ed36a3e1fe6a3d3aaf5c935da1dc75402b172b.camel@anode.ca> <87pn3ayvj2.fsf@hornfels.zedat.fu-berlin.de> <05df3a5f53b4d92a34f8399265a84b27f630da96.camel@anode.ca> <87lfdyytwd.fsf@hornfels.zedat.fu-berlin.de> <09aee7aa-146c-1c7f-1d0e-b800d7f4eac5@stoneleaf.us> Message-ID: On 2020-12-19 at 22:29:34 +0100, Roel Schroeven wrote: > What could be useful in some use cases, I think, is a wrapper function > that evaluates the function lazily: > > def dict_get_lazily(d, key, fnc, *args, **kwargs): > try: > return d[key] > except KeyError: > return fnc(*args, **kwargs) > > some_var = dict_get_lazily(d, 'spam', some_function, 31, 11) There's no need to pass all those arguments through dict_get_lazily, and the language already has a way to evaluate an expression lazily: def dict_get_lazily(d, key, f): try: return d[key] except KeyError: return f() some_var = dict_get_lazily(d, 'spam', lambda: some_function(31, 11)) So, beyond a cache (of which there are many variations and many implementations for many use cases), what are the use cases for an entire dictionary of lazily computed values? And if my application has to know when to access d['key'] directly and when to call dict_get_lazily(d, 'key', f), then whom am I fooling by "hiding" the lazy evaluation? But if I always call dict_get_lazily when I access d, then why do those two or three lines belong in the standard library instead of my application or my private toolbox? From rosuav at gmail.com Sun Dec 20 09:10:30 2020 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 21 Dec 2020 01:10:30 +1100 Subject: dict.get(key, default) evaluates default even if key exists In-Reply-To: References: <87bleu18s9.fsf@hornfels.zedat.fu-berlin.de> <92ed36a3e1fe6a3d3aaf5c935da1dc75402b172b.camel@anode.ca> <87pn3ayvj2.fsf@hornfels.zedat.fu-berlin.de> <05df3a5f53b4d92a34f8399265a84b27f630da96.camel@anode.ca> <87lfdyytwd.fsf@hornfels.zedat.fu-berlin.de> <09aee7aa-146c-1c7f-1d0e-b800d7f4eac5@stoneleaf.us> Message-ID: On Mon, Dec 21, 2020 at 12:47 AM <2QdxY4RzWzUUiLuE at potatochowder.com> wrote: > > On 2020-12-19 at 22:29:34 +0100, > Roel Schroeven wrote: > > > What could be useful in some use cases, I think, is a wrapper function > > that evaluates the function lazily: > > > > def dict_get_lazily(d, key, fnc, *args, **kwargs): > > try: > > return d[key] > > except KeyError: > > return fnc(*args, **kwargs) > > > > some_var = dict_get_lazily(d, 'spam', some_function, 31, 11) > > There's no need to pass all those arguments through dict_get_lazily, and > the language already has a way to evaluate an expression lazily: > > def dict_get_lazily(d, key, f): > try: > return d[key] > except KeyError: > return f() > > some_var = dict_get_lazily(d, 'spam', lambda: some_function(31, 11)) > class LazyDict(dict): def __missing__(self, key): # Pretend this is slow print("slow function called") return 31 + 11 d = LazyDict({ 'spam': 0, 'ham': 1, 'parrot': 2, }) print(d['spam']) print(d['eggs']) Guaranteed to be called when and only when the key is missing. This does imply a variant architecture in which the data structure itself is aware of the calculations necessary to generate the data, so it may not be appropriate to all situations, but it's clean, easy, and efficient. If you can't do this, I'd recommend using the try/except method, maybe wrapped up in a function if you want to. In the case where the key is found, the cost is one try block and one lookup - barely more than any other option (for the record, a try block is pretty cheap in CPython, and it's only costly when you hit an exception); and where it isn't found, it's two lookups plus the cost of generating the default (and we've already established that generating the default is expensive, otherwise setdefault would be appropriate). ChrisA From cl at isbd.net Sun Dec 20 11:02:53 2020 From: cl at isbd.net (Chris Green) Date: Sun, 20 Dec 2020 16:02:53 +0000 Subject: How do you find what exceptions a class can throw? References: <5ni3bh-r5rj.ln1@esprimo.zbmc.eu> Message-ID: Stefan Ram wrote: > Chris Green writes: > >I am using poplib.POP3_SSL() and I want to know what exceptions can be > >thrown when I instantiate it. Presumably it inherits them because > >there's nothing much in the documentation page for poplib.POP3_SSL(). > > Both Java and C++ have tried to introduce a static > declaration of exceptions IIRC, but IIRC this was less > popular as it led to problems. > > Ultimately, it is not possible to tell what exceptions > a call might throw. In such a case, it may help to explain > to the newsgroup why this information is needed. > So that, as is always advised, I can catch the specific exception being thrown! -- Chris Green ? From 2QdxY4RzWzUUiLuE at potatochowder.com Sun Dec 20 12:05:26 2020 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Sun, 20 Dec 2020 11:05:26 -0600 Subject: How do you find what exceptions a class can throw? In-Reply-To: References: <5ni3bh-r5rj.ln1@esprimo.zbmc.eu> Message-ID: On 2020-12-20 at 16:02:53 +0000, Regarding "Re: How do you find what exceptions a class can throw?," Chris Green wrote: > Stefan Ram wrote: > > Chris Green writes: > > >I am using poplib.POP3_SSL() and I want to know what exceptions can be > > >thrown when I instantiate it. Presumably it inherits them because > > >there's nothing much in the documentation page for poplib.POP3_SSL(). > > > > Both Java and C++ have tried to introduce a static > > declaration of exceptions IIRC, but IIRC this was less > > popular as it led to problems. > > > > Ultimately, it is not possible to tell what exceptions > > a call might throw. In such a case, it may help to explain > > to the newsgroup why this information is needed. > > > So that, as is always advised, I can catch the specific exception > being thrown! To the point: what are you going to do with it once you catch it? Are you prepared to handle every exception individually, or are you fishing for exceptions that you think might be worth catching? Remember, you get reporting (a traceback) and program cleanup and exit for free. What will catching an exception *add* to the user experience? From julio at diegidio.name Sun Dec 20 13:12:49 2020 From: julio at diegidio.name (Julio Di Egidio) Date: Sun, 20 Dec 2020 10:12:49 -0800 (PST) Subject: How do you find what exceptions a class can throw? In-Reply-To: <7uc4bh-q3gl.ln1@esprimo.zbmc.eu> References: <5ni3bh-r5rj.ln1@esprimo.zbmc.eu> <7uc4bh-q3gl.ln1@esprimo.zbmc.eu> Message-ID: <30539a00-eb92-4a39-b113-8a2ba03b9437n@googlegroups.com> On Sunday, 20 December 2020 at 18:18:26 UTC+1, Chris Green wrote: > If I ignore the exception then the > program just exits, if I want the program to do something useful about > it (like try again) then I have to catch the specific exception as I > don't want to try again with other exceptions. As other have hinted at, it's about handling, not so much about catching. That said, the docs are your friend: "exception poplib.error_proto -- Exception raised on any errors from this module (errors from socket module are not caught) [where "error_proto" I suppose stands for "protocol error"]. The reason for the exception is passed to the constructor as a string." (It's also documented in the code docs...) So that's one exception and the only explicit one (see below) specific to that module. Then you should check the exceptions in the socket module: Incidentally, I have peeked at the source code for poplib, and the initializer of poplib.POP3_SSL also raises ValueError on invalid arguments. I suppose similar should be expected from the socket module. But these are the exceptions that typically are not handled: one has to validate input, so that, at that point, a ValueError, or a TypeError (or a KeyError, etc.) is rather a bug. Anyway, this is another story... Julio From cl at isbd.net Sun Dec 20 13:13:27 2020 From: cl at isbd.net (Chris Green) Date: Sun, 20 Dec 2020 18:13:27 +0000 Subject: How do you find what exceptions a class can throw? References: <5ni3bh-r5rj.ln1@esprimo.zbmc.eu> Message-ID: <7rg4bh-bvnl.ln1@esprimo.zbmc.eu> 2QdxY4RzWzUUiLuE at potatochowder.com wrote: > On 2020-12-20 at 16:02:53 +0000, > Regarding "Re: How do you find what exceptions a class can throw?," > Chris Green wrote: > > > Stefan Ram wrote: > > > Chris Green writes: > > > >I am using poplib.POP3_SSL() and I want to know what exceptions can be > > > >thrown when I instantiate it. Presumably it inherits them because > > > >there's nothing much in the documentation page for poplib.POP3_SSL(). > > > > > > Both Java and C++ have tried to introduce a static > > > declaration of exceptions IIRC, but IIRC this was less > > > popular as it led to problems. > > > > > > Ultimately, it is not possible to tell what exceptions > > > a call might throw. In such a case, it may help to explain > > > to the newsgroup why this information is needed. > > > > > So that, as is always advised, I can catch the specific exception > > being thrown! > > To the point: what are you going to do with it once you catch it? > > Are you prepared to handle every exception individually, or are you > fishing for exceptions that you think might be worth catching? > > Remember, you get reporting (a traceback) and program cleanup and exit > for free. What will catching an exception *add* to the user experience? If it's a timeout exception I'm going to delay a little while and then try again. The timeout is probably because the server is busy. If it's not a timeout then I'll (as you suggest) leave it to terminate the program and report the error. -- Chris Green ? From Karsten.Hilbert at gmx.net Sun Dec 20 13:34:51 2020 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Sun, 20 Dec 2020 19:34:51 +0100 Subject: Aw: Re: How do you find what exceptions a class can throw? In-Reply-To: <7rg4bh-bvnl.ln1@esprimo.zbmc.eu> References: <5ni3bh-r5rj.ln1@esprimo.zbmc.eu> <7rg4bh-bvnl.ln1@esprimo.zbmc.eu> Message-ID: > > Remember, you get reporting (a traceback) and program cleanup and exit > > for free. What will catching an exception *add* to the user experience? > > If it's a timeout exception I'm going to delay a little while and then > try again. The timeout is probably because the server is busy. So what you are looking for is the form of a potential "timeout exception" (say, exception name) ? Provoke one and have a look. Then catch what you saw. Karsten From julio at diegidio.name Sun Dec 20 13:46:25 2020 From: julio at diegidio.name (Julio Di Egidio) Date: Sun, 20 Dec 2020 10:46:25 -0800 (PST) Subject: How do you find what exceptions a class can throw? In-Reply-To: References: <5ni3bh-r5rj.ln1@esprimo.zbmc.eu> <7rg4bh-bvnl.ln1@esprimo.zbmc.eu> Message-ID: <9a654681-64c8-4856-bafd-5984bd860f4an@googlegroups.com> On Sunday, 20 December 2020 at 19:35:21 UTC+1, Karsten Hilbert wrote: > > If it's a timeout exception I'm going to delay a little while and then > > try again. The timeout is probably because the server is busy. > > So what you are looking for is the form of a potential > "timeout exception" (say, exception name) ? > > Provoke one and have a look. > > Then catch what you saw. Programmers don't guess... HTH, Julio From grant.b.edwards at gmail.com Sun Dec 20 13:25:40 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Sun, 20 Dec 2020 18:25:40 -0000 (UTC) Subject: How do you find what exceptions a class can throw? References: <5ni3bh-r5rj.ln1@esprimo.zbmc.eu> Message-ID: On 2020-12-20, 2QdxY4RzWzUUiLuE at potatochowder.com <2QdxY4RzWzUUiLuE at potatochowder.com> wrote: > Chris Green wrote: > >>> Ultimately, it is not possible to tell what exceptions >>> a call might throw. While it may not be "ultimately possible", in practice it usually is. Most libarary documentation lists exceptions thrown by fuctions and explains what causes them. >>> In such a case, it may help to explain >>> to the newsgroup why this information is needed. >> >> So that, as is always advised, I can catch the specific exception >> being thrown! > > To the point: what are you going to do with it once you catch it? Seriously? You've never written code that handled an exception? > Are you prepared to handle every exception individually, Of course he isn't. > or are you fishing for exceptions that you think might be worth > catching? You handle whatever exception(s) you expect, and let the others pass up to higher levels. There are lots of cases where there may be one or two exceptions that you want to handle. > Remember, you get reporting (a traceback) and program cleanup and > exit for free. What will catching an exception *add* to the user > experience? Yes, if you can deal with it in such a way that normal execution of the program (from the user's POV) continues. Exceptions aren't always bugs and errors. Sometimes it's just an uncommon use-case that is foreseen and dealt with. From cl at isbd.net Sun Dec 20 12:06:47 2020 From: cl at isbd.net (Chris Green) Date: Sun, 20 Dec 2020 17:06:47 +0000 Subject: How do you find what exceptions a class can throw? References: <5ni3bh-r5rj.ln1@esprimo.zbmc.eu> Message-ID: <7uc4bh-q3gl.ln1@esprimo.zbmc.eu> Stefan Ram wrote: > Chris Green writes: > >So that, as is always advised, I can catch the specific exception > >being thrown! > > It usually is advisable to be more specific when catching > exceptions. The worst thing to do is surely a bare "except:" > which then ignores the exception. > > A general "except Exception:" is slightly better, since it > will not catch SystemExit and KeyboardInterrupt exceptions. > > According to me, you should only catch a specific exception > if you know better than your caller what to do in this case. > Otherwise just let it pass through to your caller. > > "better than your caller"??? If I ignore the exception then the program just exits, if I want the program to do something useful about it (like try again) then I have to catch the specific exception as I don't want to try again with other exceptions. -- Chris Green ? From Karsten.Hilbert at gmx.net Sun Dec 20 13:53:42 2020 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Sun, 20 Dec 2020 19:53:42 +0100 Subject: Aw: Re: Re: How do you find what exceptions a class can throw? In-Reply-To: <9a654681-64c8-4856-bafd-5984bd860f4an@googlegroups.com> References: <5ni3bh-r5rj.ln1@esprimo.zbmc.eu> <7rg4bh-bvnl.ln1@esprimo.zbmc.eu> <9a654681-64c8-4856-bafd-5984bd860f4an@googlegroups.com> Message-ID: > > So what you are looking for is the form of a potential > > "timeout exception" (say, exception name) ? > > > > Provoke one and have a look. > > > > Then catch what you saw. > > > > Programmers don't guess... I did not suggest guessing. I suggested gathering scientific evidence by running a controlled experiment. Or should I say "Programmers don't trust..." ? Karsten From julio at diegidio.name Sun Dec 20 14:14:24 2020 From: julio at diegidio.name (Julio Di Egidio) Date: Sun, 20 Dec 2020 11:14:24 -0800 (PST) Subject: How do you find what exceptions a class can throw? In-Reply-To: References: <5ni3bh-r5rj.ln1@esprimo.zbmc.eu> <7rg4bh-bvnl.ln1@esprimo.zbmc.eu> <9a654681-64c8-4856-bafd-5984bd860f4an@googlegroups.com> Message-ID: <1ba0402d-e82a-460e-a7b0-fd24c35f29c8n@googlegroups.com> On Sunday, 20 December 2020 at 19:54:08 UTC+1, Karsten Hilbert wrote: > > > So what you are looking for is the form of a potential > > > "timeout exception" (say, exception name) ? > > > > > > Provoke one and have a look. > > > > > > Then catch what you saw. > > > > > > > > Programmers don't guess... > > I did not suggest guessing. Yes, you did. :) > I suggested gathering scientific evidence by > running a controlled experiment. Programming is not a science: in fact, computer science is a mathematics, and engineering is engineering. Rather (speaking generally), the "trial and error" together with "not reading the docs" is a typical beginner's mistake. > Or should I say "Programmers don't trust..." ? Trust me: it takes 100x getting anything done plus keep up with your prayers, and it takes 100^100x learning anything solid, as in just forget about it. Indeed, consider that we are rather going to the formal verification of programs, software, and even hardware... Julio From Karsten.Hilbert at gmx.net Sun Dec 20 14:34:03 2020 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Sun, 20 Dec 2020 20:34:03 +0100 Subject: Aw: Re: Re: Re: How do you find what exceptions a class can throw? In-Reply-To: <1ba0402d-e82a-460e-a7b0-fd24c35f29c8n@googlegroups.com> References: <5ni3bh-r5rj.ln1@esprimo.zbmc.eu> <7rg4bh-bvnl.ln1@esprimo.zbmc.eu> <9a654681-64c8-4856-bafd-5984bd860f4an@googlegroups.com> <1ba0402d-e82a-460e-a7b0-fd24c35f29c8n@googlegroups.com> Message-ID: > Trust me: it takes 100x getting anything done plus keep up with your prayers, and it takes 100^100x learning anything solid, as in just forget about it. Indeed, consider that we are rather going to the formal verification of programs, software, and even hardware... I sincerly wish you that your hope becomes reality within your lifetime. Karsten From tanto at non.va.invalid Sun Dec 20 15:00:19 2020 From: tanto at non.va.invalid (danilob) Date: Sun, 20 Dec 2020 21:00:19 +0100 Subject: list() strange behaviour Message-ID: Hi, I'm an absolute beginner in Python (and in English too ;-) Running this code: -------------- # Python 3.9.0 a = [[1, 2, 0, 3, 0], [0, 4, 5, 0, 6], [7, 0, 8, 0, 9], [2, 3, 0, 0, 1], [0, 0, 1, 8, 0]] b = ((x[0] for x in a)) print(list(b)) print(list(b)) --------------- I get this output: [1, 0, 7, 2, 0] [] I don't know why the second print() output shows an empty list. Is it possible that the first print() call might have changed the value of "b"? Thank you in advance. From 2QdxY4RzWzUUiLuE at potatochowder.com Sun Dec 20 15:49:08 2020 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Sun, 20 Dec 2020 14:49:08 -0600 Subject: How do you find what exceptions a class can throw? In-Reply-To: References: <5ni3bh-r5rj.ln1@esprimo.zbmc.eu> Message-ID: On 2020-12-20 at 18:25:40 -0000, Grant Edwards wrote: > On 2020-12-20, 2QdxY4RzWzUUiLuE at potatochowder.com <2QdxY4RzWzUUiLuE at potatochowder.com> wrote: > > Chris Green wrote: > > > >>> Ultimately, it is not possible to tell what exceptions > >>> a call might throw. > > While it may not be "ultimately possible", in practice it usually > is. Most libarary documentation lists exceptions thrown by fuctions > and explains what causes them. > > >>> In such a case, it may help to explain > >>> to the newsgroup why this information is needed. > >> > >> So that, as is always advised, I can catch the specific exception > >> being thrown! > > > > To the point: what are you going to do with it once you catch it? > > Seriously? You've never written code that handled an exception? No. Of course I've written code that catches exceptions. Have you ever written code that ignored an exception, explicitly or implicitly? Of course you have. My point was to get the OP to think about *handling* exceptions, not just catching them because a library function throws them, or trying to deal with everything that might happen in the future. > > Are you prepared to handle every exception individually, > > Of course he isn't. How do we know that? > > or are you fishing for exceptions that you think might be worth > > catching? > > You handle whatever exception(s) you expect, and let the others pass > up to higher levels. There are lots of cases where there may be one or > two exceptions that you want to handle. Subsequent emails indicate that Chris Green does as well, but it took a while to get there (or perhaps I just misunderstood all those vague references to catching exceptions). > > Remember, you get reporting (a traceback) and program cleanup and > > exit for free. What will catching an exception *add* to the user > > experience? > > Yes, if you can deal with it in such a way that normal execution of > the program (from the user's POV) continues. Exceptions aren't always > bugs and errors. Sometimes it's just an uncommon use-case that is > foreseen and dealt with. Agreed. Some programs recover from and continue under (for their own definitions of "recover" and "continue") horrendous conditions, other programs dump a traceback and let a user/operator/customer deal with it. Chris Green gave little or no indication of expectations or desires. From python.list at tim.thechases.com Sun Dec 20 15:38:47 2020 From: python.list at tim.thechases.com (Tim Chase) Date: Sun, 20 Dec 2020 14:38:47 -0600 Subject: list() strange behaviour In-Reply-To: References: Message-ID: <20201220143847.1ff747ea@bigbox.attlocal.net> On 2020-12-20 21:00, danilob wrote: > b = ((x[0] for x in a)) here you create a generator > print(list(b)) > [1, 0, 7, 2, 0] and then you consume all the things it generates here which means that when you go to do this a second time > print(list(b)) the generator is already empty/exhausted so there's nothing more to yield, giving you the empty result that you got: > [] If you want to do this, convert it to a list once: >>> c = list(b) or use a list-comprehension instead creating a generator >>> c = [x[0] for x in a] and then print that resulting list: >>> print(c) >>> print(c) -tkc From cs at cskk.id.au Sun Dec 20 16:09:47 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Mon, 21 Dec 2020 08:09:47 +1100 Subject: list() strange behaviour In-Reply-To: References: Message-ID: <20201220210947.GA66939@cskk.homeip.net> On 20Dec2020 21:00, danilob wrote: >I'm an absolute beginner in Python (and in English too ;-) Well your English is far better than my very poor second language. >Running this code: >-------------- ># Python 3.9.0 > >a = [[1, 2, 0, 3, 0], > [0, 4, 5, 0, 6], > [7, 0, 8, 0, 9], > [2, 3, 0, 0, 1], > [0, 0, 1, 8, 0]] This is a list of lists. >b = ((x[0] for x in a)) This is a generator comprehension, and _not_ a list. Explainations below. >print(list(b)) >print(list(b)) >--------------- >I get this output: > >[1, 0, 7, 2, 0] As you expect. >[] As a surprise. >I don't know why the second print() output shows an empty list. >Is it possible that the first print() call might have changed the value >of "b"? It hasn't but, it has changed its state. Let me explain. In Python there are 2 visually similar list-like comprehensions: This is a _list_ comprehension (note the surrounding square brackets): [ x for x in range(5) ] It genuinely constructs a list containing: [ 0, 1, 2, 3, 4 ] and would behave as you expect in print(). By contrast, this is a generator comprehension (note the round brackets): ( x for x in range(5) ) This is a "lazy" construct, and is like writing a generator function: def g(): for x in range(5): yield x It is a little iterable which _counts_ from 0 through 4 inclusive and yields each value as requested. Try putting a: print(b) before your other print calls. It will not show a list. So, what is happening? b = ((x[0] for x in a)) This makes a generator comprehension. The outermost brackets are redundant, by the way, and can be discarded: b = (x[0] for x in a) And does this (using my simpler example range(5)): >>> b=(x for x in range(5)) >>> b at 0x10539e120> When you make a list from that: >>> L = list(b) >>> L [0, 1, 2, 3, 4] the generator _runs_ and emits the values to be used in the list. If you make another list: >>> L = list(b) >>> L [] The generator has finished. Using it again produces no values, and so list() constructs an empty list. That is what is happening in your print statements. If, instead, you had gone: b = [x[0] for x in a] Then "b" would be an actual list (a sequence of values stored in memory) and your prints would have done what you expect. Python has several "lazy" operations available, which do not do the entire computation when they are defined; instead they give you a "generator" which performs the computation incrementally, running until the next value is found - when the user asks for the next value, _then_ the generator runs until that value is obtained and "yield"ed. Supposing your array "a" were extremely large, or perhaps in some way stored in a database instead of in memory. It might be expensive or very slow to get _all_ the values. A generator lets you get values as they are required. A generator expression like this: b = ( x for x in range(5) ) counts from 0 through 4 inclusively (or 0 through 5, excluding 5, which is how ranges egenrally work in Python) when asks. As a function it might look like this: def b(): for x in range(5) yield x When you call "list(b)" the list constructor collects values from "iter(b)", which iterates over "b". Like this, written longhand: L = [] for value in b: L.append(b) Written even longer: L = [] b_values = iter(b) while True: try: value = next(b_values) except Stopiteration: break L.append(value) which more clearly shows a call to "next()" to run the iterator b_values once, until it yields a value. The Python for-statement is a builtin convenient way to write the while-loop above - it iterates over any iterable like "b". Cheers, Cameron Simpson From cs at cskk.id.au Sun Dec 20 17:15:32 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Mon, 21 Dec 2020 09:15:32 +1100 Subject: How do you find what exceptions a class can throw? In-Reply-To: References: Message-ID: <20201220221532.GA14120@cskk.homeip.net> On 20Dec2020 20:34, Karsten Hilbert wrote: >> Trust me: it takes 100x getting anything done plus keep up with your prayers, and it takes 100^100x learning anything solid, as in just forget about it. Indeed, consider that we are rather going to the formal verification of programs, software, and even hardware... > >I sincerly wish you that your hope becomes reality within your >lifetime. Aye, since "we are rather going to the formal verification of programs, software, and even hardware" was true when I was at university. In the 1980s and 1990s. Gathering evidence is indeed part of science, and computer science is indeed mathematics, but alas programmering is just a craft and software engineering often ... isn't. Anyway, I would hope we're all for more rigour rather than less. Cheers, Cameron Simpson From julio at diegidio.name Sun Dec 20 21:06:02 2020 From: julio at diegidio.name (Julio Di Egidio) Date: Sun, 20 Dec 2020 18:06:02 -0800 (PST) Subject: How do you find what exceptions a class can throw? In-Reply-To: References: <20201220221532.GA14120@cskk.homeip.net> Message-ID: <12ee97ce-2c08-4e71-a554-57e5465517cfn@googlegroups.com> On Sunday, 20 December 2020 at 23:16:10 UTC+1, cameron... at gmail.com wrote: > On 20Dec2020 20:34, Karsten Hilbert wrote: > >> Trust me: it takes 100x getting anything done plus keep up with your prayers, and it takes 100^100x learning anything solid, as in just forget about it. Indeed, consider that we are rather going to the formal verification of programs, software, and even hardware... > > > >I sincerly wish you that your hope becomes reality within your > >lifetime. > > Aye, since "we are rather going to the formal verification of programs, > software, and even hardware" was true when I was at university. In the > 1980s and 1990s. You could have taken the chance to pay attention, as after 30 years of fake agility, lies over the very state of the art, and of course the chronic spectacular failures, the defamation game and the misery of an entire industry, we are eventually getting back to where we were. And, while we are still quite far from an end-to-end integrated experience, by now, Dec 2020, it is already the case that there are enough systems, libraries/components and of course the underlying theory that for the practitioner (i.e. the professional in the field) the problem at the moment is rather which ones to commit to (i.e. invest money and time into). > Gathering evidence is indeed part of science, and computer science is > indeed mathematics, but alas programmering is just a craft and software > engineering often ... isn't. Programming is a *discipline*, while you keep echoing cheap and vile marketing nonsense. > Anyway, I would hope we're all for more rigour rather than less. I am sure you do, rigour mortis eventually... EOD. Julio From ethan at stoneleaf.us Sun Dec 20 21:26:35 2020 From: ethan at stoneleaf.us (Ethan Furman) Date: Sun, 20 Dec 2020 18:26:35 -0800 Subject: How do you find what exceptions a class can throw? In-Reply-To: <12ee97ce-2c08-4e71-a554-57e5465517cfn@googlegroups.com> References: <20201220221532.GA14120@cskk.homeip.net> <12ee97ce-2c08-4e71-a554-57e5465517cfn@googlegroups.com> Message-ID: <8796dfbb-309f-36d4-6e31-530f119b6aff@stoneleaf.us> On 12/20/20 6:06 PM, Julio Di Egidio wrote: > You could have taken the chance to pay attention > Programming is a *discipline*, while you keep echoing cheap and vile marketing nonsense. > I am sure you do, rigour mortis eventually... Mean-spirited and hostile messages are not welcome on this list. -- ~Ethan~ From rosuav at gmail.com Sun Dec 20 21:35:05 2020 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 21 Dec 2020 13:35:05 +1100 Subject: How do you find what exceptions a class can throw? In-Reply-To: <12ee97ce-2c08-4e71-a554-57e5465517cfn@googlegroups.com> References: <20201220221532.GA14120@cskk.homeip.net> <12ee97ce-2c08-4e71-a554-57e5465517cfn@googlegroups.com> Message-ID: On Mon, Dec 21, 2020 at 1:11 PM Julio Di Egidio wrote: > > Gathering evidence is indeed part of science, and computer science is > > indeed mathematics, but alas programmering is just a craft and software > > engineering often ... isn't. > > Programming is a *discipline* It's a discipline, a science, AND an art. I love programming :) ChrisA From avigross at verizon.net Sun Dec 20 21:46:48 2020 From: avigross at verizon.net (Avi Gross) Date: Sun, 20 Dec 2020 21:46:48 -0500 Subject: How do you find what exceptions a class can throw? In-Reply-To: <12ee97ce-2c08-4e71-a554-57e5465517cfn@googlegroups.com> References: <20201220221532.GA14120@cskk.homeip.net> <12ee97ce-2c08-4e71-a554-57e5465517cfn@googlegroups.com> Message-ID: <0ad701d6d743$87c42e10$974c8a30$@verizon.net> The original question sounded like someone was asking what errors might be thrown for a routine they wrote that used other components that might directly throw exceptions or called yet others, ad nauseum. Some have questioned the purpose. I can well imagine that if such info was available, you could construct a data structure such as a graph and trace every possible error that could propagate back. But I am not so sure it is that simple. Some of the intervening functions will quite possibly deal with those errors. If a routine downstream already knows a further function might divide by zero, it may arrange to capture that exception and deal with it. So it will not likely propagate up from that source, albeit a second path may also possibly let it propagate through on another such bad calculation that does not deal with it.. Further, some programs have code that checks the environment and may use different functions/methods if on one kind of machine or OS or version of python than another. Ideally you would need to know the profile for the build you are on. And with interpreted languages, some are not so much built ahead of time as assembled as they go. Loading an alternate module or library with functions having the same names, may bring in a very different profile of possible exceptions. And what if your function is later used by others and they do not know you added code to intercept all possible interruptions and chose how to deal with them and they write code hoping to intercept something that then never arrives. Things may fail differently than expected. Some nice programming tricks that depend on it failing sometimes, may no longer work as expected. What exactly is the right way to deal with each interrupt? Choices range from ignoring them while squelching them, to passing them along relatively unchanged, perhaps logging what came by, raising a different exception, perhaps your own new variety, or just halting everything. Any time some deeper software is changed, as for a bug fix, they may change the profile of propagated errors. A routine that once worried about running out of memory may instead change to only working on memory pre-allocated in large blocks yet leave in the code that would throw an exception if it is ever reached. It may be it can now never happen but yet you might still be on the lookout for it, especially if the documentation does not change or you do not read it each and every time. I also wonder at the complexity of the code needed. If a given error in a dozen places can generate the same exception, can you tell them apart so each has an appropriate solution or do you lump them together? Can you replace a function with a few lines of code with thousands of lines of just-in-case code and remain viable if every function does this and you have giant programs that use lots of CPU and memory? I would say it is a more laudable goal for each function to publish what interrupts they do NOT handle that might come through and perhaps why. Any they claim to handle make it moot what happens further along the stream if done right. Bulletproofing even then may seem harmless, of course. I have had cases where I intercepted ALL errors when a rare case broke code I used that I did not write. I got an odd error maybe once every million times running on random simulated data and I just wanted to throw that result away and keep a subset of those that worked and converged and passed some post.tests. It did not matter to me why it failed, just that it not be allowed to crash the program entirely. Trying to deal with every possible exception would have been overkill. So, I do sympathize with a wish to be able to decide what errors might arise and be able to decide if having your code deal with it makes sense. I just suggest whatever you do in the general case may not be optimal. It may do too much and yet allow problems to seep through. From 2QdxY4RzWzUUiLuE at potatochowder.com Sun Dec 20 22:24:00 2020 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Sun, 20 Dec 2020 21:24:00 -0600 Subject: How do you find what exceptions a class can throw? In-Reply-To: <0ad701d6d743$87c42e10$974c8a30$@verizon.net> References: <20201220221532.GA14120@cskk.homeip.net> <12ee97ce-2c08-4e71-a554-57e5465517cfn@googlegroups.com> <0ad701d6d743$87c42e10$974c8a30$@verizon.net> Message-ID: On 2020-12-20 at 21:46:48 -0500, Avi Gross via Python-list wrote: [...] > I would say it is a more laudable goal for each function to publish > what interrupts they do NOT handle that might come through and perhaps > why ... I'm not disagreeing. Documenting important decisions and the reasons behind them is amongst the best of Best Practices. That said, either way, it's the same thing. If A calls B, and B calls C, and B claims *not* to handle exceptions X and Y, then A has to track down everything else that might come from C, and we're right back to square one (or square zero, but I digress). > So, I do sympathize with a wish to be able to decide what errors might > arise and be able to decide if having your code deal with it makes > sense. I just suggest whatever you do in the general case may not be > optimal. It may do too much and yet allow problems to seep through. Excellent point, and well said. So how do we eliminate the general case? ;-) From cs at cskk.id.au Sun Dec 20 22:42:58 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Mon, 21 Dec 2020 14:42:58 +1100 Subject: list() strange behaviour In-Reply-To: <20201220210947.GA66939@cskk.homeip.net> References: <20201220210947.GA66939@cskk.homeip.net> Message-ID: <20201221034258.GA64908@cskk.homeip.net> On 21Dec2020 08:09, Cameron Simpson wrote: >>b = ((x[0] for x in a)) > >This is a generator comprehension, and _not_ a list. I should amend this: a "generator _expression_", not comprehension. A "generator comprehension" is not a thing. Apologies, Cameron Simpson From cl at isbd.net Mon Dec 21 04:06:02 2020 From: cl at isbd.net (Chris Green) Date: Mon, 21 Dec 2020 09:06:02 +0000 Subject: How do you find what exceptions a class can throw? References: <20201220221532.GA14120@cskk.homeip.net> <12ee97ce-2c08-4e71-a554-57e5465517cfn@googlegroups.com> <0ad701d6d743$87c42e10$974c8a30$@verizon.net> Message-ID: Avi Gross wrote: > The original question sounded like someone was asking what errors might be > thrown for a routine they wrote that used other components that might > directly throw exceptions or called yet others, ad nauseum. > OP here. The original question was because I wanted to trap timout errors when connectiing to a POP3 server in a very simple little program that collects mail and runs it through a filter before delivering it. Thus I simply needed to know what the 'name' of the exception was so I could trap only timeouts. Timeout errors are (probably) 'soft' errors which merit a retry, most other errors when trying to connect to a POP server would be unrecoverable (POP syntax, wrong name, wrong password, etc.). It didn't seem such a difficult question when I asked it! :-) -- Chris Green ? From larry.martell at gmail.com Mon Dec 21 08:30:03 2020 From: larry.martell at gmail.com (Larry Martell) Date: Mon, 21 Dec 2020 08:30:03 -0500 Subject: How do you find what exceptions a class can throw? In-Reply-To: References: <20201220221532.GA14120@cskk.homeip.net> <12ee97ce-2c08-4e71-a554-57e5465517cfn@googlegroups.com> Message-ID: On Sun, Dec 20, 2020 at 9:36 PM Chris Angelico wrote: > > On Mon, Dec 21, 2020 at 1:11 PM Julio Di Egidio wrote: > > > Gathering evidence is indeed part of science, and computer science is > > > indeed mathematics, but alas programmering is just a craft and software > > > engineering often ... isn't. > > > > Programming is a *discipline* > > It's a discipline, a science, AND an art. I love programming :) I love it too. But I think it?s a craft not an art. I think of art as totally unconstrained, and a craft as having to functionally work. I really like this quote: "Debugging is like being the detective in a crime movie where you are also the murderer." - Filipe Fortes From rosuav at gmail.com Mon Dec 21 08:58:30 2020 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 22 Dec 2020 00:58:30 +1100 Subject: How do you find what exceptions a class can throw? In-Reply-To: References: <20201220221532.GA14120@cskk.homeip.net> <12ee97ce-2c08-4e71-a554-57e5465517cfn@googlegroups.com> Message-ID: On Tue, Dec 22, 2020 at 12:32 AM Larry Martell wrote: > > On Sun, Dec 20, 2020 at 9:36 PM Chris Angelico wrote: > > > > On Mon, Dec 21, 2020 at 1:11 PM Julio Di Egidio wrote: > > > > Gathering evidence is indeed part of science, and computer science is > > > > indeed mathematics, but alas programmering is just a craft and software > > > > engineering often ... isn't. > > > > > > Programming is a *discipline* > > > > It's a discipline, a science, AND an art. I love programming :) > > > I love it too. But I think it?s a craft not an art. I think of art as > totally unconstrained, and a craft as having to functionally work. Hmmmmmmmmmmm... *looks at some of his recent code* This stuff has to work?!? I've been doing it all wrong... > I really like this quote: "Debugging is like being the detective in a > crime movie where you are also the murderer." - Filipe Fortes Oh yes, absolutely. Only, you don't even know if a murder's been committed yet... ChrisA From sersadaka1 at outlook.com Mon Dec 21 11:01:55 2020 From: sersadaka1 at outlook.com (Sadaka Technology) Date: Mon, 21 Dec 2020 08:01:55 -0800 (PST) Subject: Python pyrebase user auth Message-ID: <89009d57-1c2f-4eb6-b8f0-7e95167ea87dn@googlegroups.com> Hello guys, how can I get user auth refresh token and local id ? From lukasz at langa.pl Mon Dec 21 14:42:03 2020 From: lukasz at langa.pl (=?utf-8?Q?=C5=81ukasz_Langa?=) Date: Mon, 21 Dec 2020 20:42:03 +0100 Subject: [RELEASE] Python 3.8.7 is now available Message-ID: <9E5D7EDC-1A52-4962-ABD8-F01AF62C4CF0@langa.pl> Python 3.8.7 is the seventh maintenance release of Python 3.8. Go get it here: https://www.python.org/downloads/release/python-387/ Note: this is a bugfix release for the 3.8 series which was superseded by Python 3.9, currently the latest feature release series of Python 3. You can find the latest release of 3.9.x here . Maintenance releases for the 3.8 series will continue at regular bi-monthly intervals, with 3.8.8 planned for February 2021. macOS 11 Big Sur not fully supported Python 3.8.7 is not yet fully supported on macOS 11 Big Sur. It will install on macOS 11 Big Sur and will run on Apple Silicon Macs using Rosetta 2 translation. However, a few features do not work correctly, most noticeably those involving searching for system libraries (vs user libraries) such as ctypes.util.find_library() and in Distutils. This limitation affects both Apple Silicon and Intel processors. We are looking into improving the situation for Python 3.8.8. Python 3.9.1 provides full support for Big Sur and Apple Silicon Macs, including building natively on Apple Silicon Macs and support for universal2 binaries. What?s new? The Python 3.8 series contains many new features and optimizations over 3.7. See the ?What?s New in Python 3.8 ? document for more information about features included in the 3.8 series. Detailed information about all changes made in version 3.8.7 specifically can be found in its change log . Note that compared to 3.8.6 this release also contains all changes present in 3.8.7rc1. We hope you enjoy Python 3.8! 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. Your friendly release team, Ned Deily @nad Steve Dower @steve.dower ?ukasz Langa @ambv From grant.b.edwards at gmail.com Sun Dec 20 22:50:32 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 21 Dec 2020 03:50:32 -0000 (UTC) Subject: How do you find what exceptions a class can throw? References: <20201220221532.GA14120@cskk.homeip.net> <12ee97ce-2c08-4e71-a554-57e5465517cfn@googlegroups.com> Message-ID: On 2020-12-21, Chris Angelico wrote: > On Mon, Dec 21, 2020 at 1:11 PM Julio Di Egidio wrote: >> > Gathering evidence is indeed part of science, and computer science is >> > indeed mathematics, but alas programmering is just a craft and software >> > engineering often ... isn't. >> >> Programming is a *discipline* > > It's a discipline, a science, AND an art. And a craft. And a dessert topping! From peter at p-walker.co.uk Mon Dec 21 06:23:39 2020 From: peter at p-walker.co.uk (peter walker) Date: Mon, 21 Dec 2020 11:23:39 -0000 Subject: Problem running Pygame Zero Message-ID: <011501d6d78b$bbcf2870$336d7950$@p-walker.co.uk> Hi I hope you can help. I am trying to use pygame zero (working with my 10 year old grandson) but it won't run anything ( I did have it running for a little while now nothing). Below are the results of: 1. Installing pygame zero 2. Running a listing (whatever I run I get the same result). 3. Listing of the file I am running I have tried more than one version of Python and get the same results except on Python 3.9.0 and .1 when pygame won't even install. Please give me some help, I don't know how to proceed. Thanking you in advance. Peter Walker PS C:\Users\Peter\Dropbox\My PC (Peter-Desktop)\Documents\escape> pip install pgzero Collecting pgzero Using cached pgzero-1.2-py3-none-any.whl (69 kB) Requirement already satisfied: pygame<2.0,>=1.9.2 in c:\users\peter\appdata\local\programs\python\python38\lib\site-packages (from pgzero) (1.9.6) Requirement already satisfied: numpy in c:\users\peter\appdata\local\programs\python\python38\lib\site-packages (from pgzero) (1.19.4) Installing collected packages: pgzero Successfully installed pgzero-1.2 PS C:\Users\Peter\Dropbox\My PC (Peter-Desktop)\Documents\escape> PS C:\Users\Peter\Dropbox\My PC (Peter-Desktop)\Documents\escape> pgzrun test.py ** On entry to DGEBAL parameter number 3 had an illegal value ** On entry to DGEHRD parameter number 2 had an illegal value ** On entry to DORGHR DORGQR parameter number 2 had an illegal value ** On entry to DHSEQR parameter number 4 had an illegal value Traceback (most recent call last): File "c:\users\peter\appdata\local\programs\python\python38\lib\runpy.py", line 194, in _run_module_as_main return _run_code(code, main_globals, None, File "c:\users\peter\appdata\local\programs\python\python38\lib\runpy.py", line 87, in _run_code exec(code, run_globals) File "C:\Users\Peter\AppData\Local\Programs\Python\Python38\Scripts\pgzrun.exe\__ main__.py", line 4, in File "c:\users\peter\appdata\local\programs\python\python38\lib\site-packages\pgz ero\runner.py", line 1, in import pygame File "c:\users\peter\appdata\local\programs\python\python38\lib\site-packages\pyg ame\__init__.py", line 343, in import pygame.surfarray File "c:\users\peter\appdata\local\programs\python\python38\lib\site-packages\pyg ame\surfarray.py", line 64, in import pygame._numpysurfarray as numpysf File "c:\users\peter\appdata\local\programs\python\python38\lib\site-packages\pyg ame\_numpysurfarray.py", line 51, in import numpy File "c:\users\peter\appdata\local\programs\python\python38\lib\site-packages\num py\__init__.py", line 305, in _win_os_check() File "c:\users\peter\appdata\local\programs\python\python38\lib\site-packages\num py\__init__.py", line 302, in _win_os_check raise RuntimeError(msg.format(__file__)) from None RuntimeError: The current Numpy installation ('c:\\users\\peter\\appdata\\local\\programs\\python\\python38\\lib\\site-pa ckages\\numpy\\__init__.py') fails to pass a sanity check due to a bug in the windows runtime. See this issue for more information: https://tinyurl.com/y3dm3h86 PS C:\Users\Peter\Dropbox\My PC (Peter-Desktop)\Documents\escape> Test.py print("Hello") From tjreedy at udel.edu Mon Dec 21 14:35:27 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Mon, 21 Dec 2020 14:35:27 -0500 Subject: How do you find what exceptions a class can throw? In-Reply-To: References: <20201220221532.GA14120@cskk.homeip.net> <12ee97ce-2c08-4e71-a554-57e5465517cfn@googlegroups.com> <0ad701d6d743$87c42e10$974c8a30$@verizon.net> Message-ID: On 12/21/2020 4:06 AM, Chris Green wrote: > Avi Gross wrote: >> The original question sounded like someone was asking what errors might be >> thrown for a routine they wrote that used other components that might >> directly throw exceptions or called yet others, ad nauseum. >> > OP here. The original question was because I wanted to trap timout > errors when connectiing to a POP3 server in a very simple little > program that collects mail and runs it through a filter before > delivering it. > Thus I simply needed to know what the 'name' of the exception was so I > could trap only timeouts. ... > It didn't seem such a difficult question when I asked it! :-) Please acknowledge that this is *not* what you asked. "I am using poplib.POP3_SSL() and I want to know what exceptions can be thrown when I instantiate it. " If you had just asked "What is the name of a possible timeout error" someone would have answered just that. -- Terry Jan Reedy From vincent.vande.vyvre at telenet.be Mon Dec 21 05:11:53 2020 From: vincent.vande.vyvre at telenet.be (Vincent Vande Vyvre) Date: Mon, 21 Dec 2020 11:11:53 +0100 Subject: Pickling issue. Message-ID: <07115ace-b3a0-d5bd-2c31-7f613ee98958@telenet.be> Hi, I've an object that I want to serialise with pickle. When I reload the object the attributes of this object are correctly fixed except one of these. This attribute (value) define a simple string. Example: --------------------------------------------- tag =? XmpTag('Xmp.dc.format', 'image/jpeg') tag.key 'Xmp.dc.format' tag.type 'MIMEType' tag.value 'image/jpeg' s = pickle.dumps(tag) t = pickle.loads(s) t.key 'Xmp.dc.format'???? # Correct t.type 'MIMEType'????????? # Correct t.value ('image', 'jpeg')?? # Not correct --------------------------------------------- Tested with Python-3.8 An idea ? From avigross at verizon.net Mon Dec 21 16:22:02 2020 From: avigross at verizon.net (Avi Gross) Date: Mon, 21 Dec 2020 16:22:02 -0500 Subject: How do you find what exceptions a class can throw? In-Reply-To: References: <20201220221532.GA14120@cskk.homeip.net> <12ee97ce-2c08-4e71-a554-57e5465517cfn@googlegroups.com> <0ad701d6d743$87c42e10$974c8a30$@verizon.net> Message-ID: <066801d6d7df$54beaf30$fe3c0d90$@verizon.net> I agree Chris, that your original question is quite to the point. But is it always? If you do something that tries to read a file (such as opening a database to send queries) on a remote server, how many different things might time out for various reasons? Some may resolve if you keep trying and some attempts may make it worse if everybody is pounding away resulting in a denial of service attack scenario. Some people dealing with situations come up with more detailed attempts such as choosing a random interval before trying again. Protocols like the Post Office Protocol often already have built-in techniques like that in the protocol and the timeout may be caused by something in your chain not being set to wait long enough. So your attempt to retry a few times may well work. I wonder if a backup method would be to switch to using IMAP as many mail archives now support a way to approach them using several such interfaces, albeit perhaps to different destinations and other changes. But hat is not a trivial change to use as just an alternate. Trying again may work, albeit trying 100 times per second may not help if a server is rebooting or is out of memory or file space or other resources ... I will say that if your function calls A() which calls B() and so on and the timeout happens at any place long the way or even at Z() then it is quite possible you may not get a specific exception back. Z() may indeed send back a TIMEOUT1 exception but then E() may intercept it and return a GENERIC_FAILURE12 exception. Then B() may retry a few times and finally return a I_GIVE_UP_TRY LATER123 exception. You likely are depending on a module you have no control over that uses other modules. But in your case, it may indeed be that simple. Just a thought. You can write some code that catches every possible exception then carefully logs all details, and then perhaps quits. If you run your code many times and even cause reasons for it to fail, you may develop some knowledge of some of the exceptions that make it through back to your call and then you can change your code to specifically handle only those you have some idea what to do about. As mentioned, you have traceback info that may help you figure out where the exceptions come from or even why. Good luck. -----Original Message----- From: Python-list On Behalf Of Chris Green Sent: Monday, December 21, 2020 4:06 AM To: python-list at python.org Subject: Re: How do you find what exceptions a class can throw? Avi Gross wrote: > The original question sounded like someone was asking what errors > might be thrown for a routine they wrote that used other components > that might directly throw exceptions or called yet others, ad nauseum. > OP here. The original question was because I wanted to trap timout errors when connectiing to a POP3 server in a very simple little program that collects mail and runs it through a filter before delivering it. Thus I simply needed to know what the 'name' of the exception was so I could trap only timeouts. Timeout errors are (probably) 'soft' errors which merit a retry, most other errors when trying to connect to a POP server would be unrecoverable (POP syntax, wrong name, wrong password, etc.). It didn't seem such a difficult question when I asked it! :-) -- Chris Green ? -- https://mail.python.org/mailman/listinfo/python-list From bgailer at gmail.com Mon Dec 21 19:57:51 2020 From: bgailer at gmail.com (Bob Gailer) Date: Mon, 21 Dec 2020 19:57:51 -0500 Subject: Pickling issue. In-Reply-To: <07115ace-b3a0-d5bd-2c31-7f613ee98958@telenet.be> References: <07115ace-b3a0-d5bd-2c31-7f613ee98958@telenet.be> Message-ID: On Mon, Dec 21, 2020, 3:03 PM Vincent Vande Vyvre < vincent.vande.vyvre at telenet.be> wrote: > Hi, > > I've an object that I want to serialise with pickle. > When I reload the object the attributes of this object are correctly > fixed except one of these. > > This attribute (value) define a simple string. > > Example: > --------------------------------------------- > tag = XmpTag('Xmp.dc.form'image/jpeg') I am not familiar with XmpTag. Where might I get the containing module? tag.key > 'Xmp.dc.format' > tag.type > 'MIMEType' > tag.value > 'image/jpeg' > > s = pickle.dumps(tag) > t = pickle.loads(s) > t.key > 'Xmp.dc.format' # Correct > t.type > 'MIMEType' # Correct > t.value > ('image', 'jpeg') # Not correct > --------------------------------------------- > > Tested with Python-3.8 > > An idea ? > -- > https://mail.python.org/mailman/listinfo/python-list > From walkmore99 at gmail.com Tue Dec 22 06:16:52 2020 From: walkmore99 at gmail.com (Walk More) Date: Tue, 22 Dec 2020 03:16:52 -0800 (PST) Subject: Use dot notation to call a function without using parentheses Message-ID: I am trying to use dot notation to call a function without using parentheses, see code section with *** I have looked into SimpleNamespace, namedTuple, dataclass... but no luck. Below is my sample code to date. Any suggestions? class MyTest: def __init__(self): self.page1 = Page() self.page1.top = Counts() #self.page1.middle = Layout() #self.page1.bottom = Layout() # access of variables created on the fly using dot notation work. self.page1.top.item1 = 5 self.page1.top.name1 = "Harry" print ("Variables created on the fly: ", self.page1.top.item1, self.page1.top.name1) # access of a predefined class variable using dot notation work. print ("Start of predefined class variable access: ", self.page1.top.totalCount) self.page1.top.totalCount = 22 self.page1.top.totalCount = self.page1.top.totalCount + 3 print ("End of predefined class variable access: ", self.page1.top.totalCount) # function calls using parentheses using dot notation work. print ("Start of function calls: ", self.page1.top.getRunningSum()) self.page1.top.addRunningSum(5) self.page1.top.addRunningSum(200) endValue = self.page1.top.getRunningSum() print ("End of function calls: ", endValue) # *** This is the syntax I would like to use. *** # function calls not using parentheses DO NOT WORK using dot notation. self.page1.top.addRunningSum = 6 t = self.page1.top.getRunningSum print (t) class Page (): def __init__ (self): pass class Counts(): def __init__ (self): self.totalCount = 0 def addRunningSum(self, indata): self.totalCount = self.totalCount + indata def getRunningSum (self): return self.totalCount if __name__ == "__main__": MyTest() #end of program From walkmore99 at gmail.com Tue Dec 22 07:15:53 2020 From: walkmore99 at gmail.com (Walk More) Date: Tue, 22 Dec 2020 04:15:53 -0800 (PST) Subject: Use dot notation to call a function without using parentheses In-Reply-To: <5fe1d8e3$0$8940$426a74cc@news.free.fr> References: <5fe1d8e3$0$8940$426a74cc@news.free.fr> Message-ID: On Tuesday, December 22, 2020 at 6:31:08 AM UTC-5, Python wrote: > Walk More wrote: > > I am trying to use dot notation to call a function without using parentheses, see code section with *** > > I have looked into SimpleNamespace, namedTuple, dataclass... but no luck. > > Below is my sample code to date. > > Any suggestions? > accessors. > > class myClass: > @property > def data(self): > print('read data attribute') > return self._data > @data.setter > def data(self, value): > print('write data attribute') > self._data = value > def __init__(self, data=None): > self.data = data > > o = myClass('spam') > > print(o.data) > > o.data = 'ham' > > output: > > write data attribute > read data attribute > spam > write data attribute Python, Thank you very much for your solution. From python at mrabarnett.plus.com Tue Dec 22 07:20:01 2020 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 22 Dec 2020 12:20:01 +0000 Subject: Use dot notation to call a function without using parentheses In-Reply-To: References: Message-ID: <0d7271ff-06d0-7940-7893-351379ef7fe4@mrabarnett.plus.com> On 2020-12-22 11:16, Walk More wrote: > I am trying to use dot notation to call a function without using parentheses, see code section with *** > I have looked into SimpleNamespace, namedTuple, dataclass... but no luck. > Below is my sample code to date. > Any suggestions? > > > > class MyTest: > def __init__(self): > self.page1 = Page() > self.page1.top = Counts() > #self.page1.middle = Layout() > #self.page1.bottom = Layout() > > # access of variables created on the fly using dot notation work. > self.page1.top.item1 = 5 > self.page1.top.name1 = "Harry" > print ("Variables created on the fly: ", self.page1.top.item1, self.page1.top.name1) > > > # access of a predefined class variable using dot notation work. > print ("Start of predefined class variable access: ", self.page1.top.totalCount) > self.page1.top.totalCount = 22 > self.page1.top.totalCount = self.page1.top.totalCount + 3 > print ("End of predefined class variable access: ", self.page1.top.totalCount) > > > # function calls using parentheses using dot notation work. > print ("Start of function calls: ", self.page1.top.getRunningSum()) > self.page1.top.addRunningSum(5) > self.page1.top.addRunningSum(200) > endValue = self.page1.top.getRunningSum() > print ("End of function calls: ", endValue) > > > # *** This is the syntax I would like to use. *** > # function calls not using parentheses DO NOT WORK using dot notation. > self.page1.top.addRunningSum = 6 > t = self.page1.top.getRunningSum > print (t) > > > class Page (): > def __init__ (self): > pass > > > class Counts(): > def __init__ (self): > self.totalCount = 0 > > def addRunningSum(self, indata): > self.totalCount = self.totalCount + indata > > def getRunningSum (self): > return self.totalCount > > > if __name__ == "__main__": > MyTest() > > #end of program > It would be simpler just to access the totalCount attribute directly, but, in answer to your question, you can make it a property: @property def getRunningSum(self): return self.totalCount and you'll then need to remove the parenthese where you're calling it. From cl at isbd.net Tue Dec 22 10:10:56 2020 From: cl at isbd.net (Chris Green) Date: Tue, 22 Dec 2020 15:10:56 +0000 Subject: Installing Python (2.7) 'by hand' on Ubuntu - possible? Message-ID: <0te9bh-52nv.ln1@esprimo.zbmc.eu> I have (as discussed here) a printer utility that uses Python 2 and I can't update it to Python 3 because it has a .so library file which is compiled for Python 2. I think I have exhausted all the possibilities for converting it to Python 3 so now I'm looking at how to keep it working on my [x]ubuntu Linux systems as Python 2.7 becomes unsupported. How realistic/possible would it be to run the utility in a separate environment with its own copies of Python2 and any modules and libraries needed? I would install these 'by hand', i.e. not using 'apt' so they would stay as installed even as my system gets upgraded. There would obviously be *some* dependencies on the system libraries but I think they'd be pretty low level and thus their interfaces would be very unlikely to change for a long time so I should be able to run my old Python2.7 and the Python modules needed for the utility for quite a few years anyway (the printer it supports will wear out eventually!). -- Chris Green ? From torriem at gmail.com Tue Dec 22 11:19:55 2020 From: torriem at gmail.com (Michael Torrie) Date: Tue, 22 Dec 2020 09:19:55 -0700 Subject: Installing Python (2.7) 'by hand' on Ubuntu - possible? In-Reply-To: <0te9bh-52nv.ln1@esprimo.zbmc.eu> References: <0te9bh-52nv.ln1@esprimo.zbmc.eu> Message-ID: <302033ef-5b6e-dd67-5323-19437fd84b37@gmail.com> On 12/22/20 8:10 AM, Chris Green wrote: > I have (as discussed here) a printer utility that uses Python 2 and I > can't update it to Python 3 because it has a .so library file which is > compiled for Python 2. I think I have exhausted all the possibilities > for converting it to Python 3 so now I'm looking at how to keep it > working on my [x]ubuntu Linux systems as Python 2.7 becomes unsupported. > > How realistic/possible would it be to run the utility in a separate > environment with its own copies of Python2 and any modules and > libraries needed? I would install these 'by hand', i.e. not using > 'apt' so they would stay as installed even as my system gets upgraded. > > There would obviously be *some* dependencies on the system libraries > but I think they'd be pretty low level and thus their interfaces would > be very unlikely to change for a long time so I should be able to run > my old Python2.7 and the Python modules needed for the utility for > quite a few years anyway (the printer it supports will wear out > eventually!). Probably your best bet is to build a container image (perhaps a snap) around with a distro that has Python 2.7 in it to house your app. That way you've got everything you need including the required system libraries. Right now you could build a image of it based on Ubuntu 20.04 which has python 2.7 as an optional installable package. Sure you could build Python 2.7 for as long as the compatible compilers and other dependent libraries are available. I expect RHEL to keep building python 2.7 for another 10 years. Ubuntu 20.04 will continue to ship python 2.7 as an optional package for another 5 years at least. There are ways even besides containers that work. With some scripts to set up custom library paths and trees of custom libraries, you can run old binary software on newer distros even. With some help from the interwebs, I am able to run WordPerfect 8 for Linux on my Fedora 32 box. That was released back in the kernel 2.0 days, before the transition to glibc. From grant.b.edwards at gmail.com Tue Dec 22 10:48:43 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Tue, 22 Dec 2020 15:48:43 -0000 (UTC) Subject: Installing Python (2.7) 'by hand' on Ubuntu - possible? References: <0te9bh-52nv.ln1@esprimo.zbmc.eu> Message-ID: On 2020-12-22, Chris Green wrote: > I have (as discussed here) a printer utility that uses Python 2 and I > can't update it to Python 3 because it has a .so library file which is > compiled for Python 2. I think I have exhausted all the possibilities > for converting it to Python 3 so now I'm looking at how to keep it > working on my [x]ubuntu Linux systems as Python 2.7 becomes unsupported. > > How realistic/possible would it be to run the utility in a separate > environment with its own copies of Python2 and any modules and > libraries needed? That depends on the modules and libraries needed. If it's just python2, it should be pretty easy. If it needs things like GTK or Qt, it gets a _lot_ harder. -- Grant From cl at isbd.net Tue Dec 22 11:44:42 2020 From: cl at isbd.net (Chris Green) Date: Tue, 22 Dec 2020 16:44:42 +0000 Subject: Installing Python (2.7) 'by hand' on Ubuntu - possible? References: <0te9bh-52nv.ln1@esprimo.zbmc.eu> <302033ef-5b6e-dd67-5323-19437fd84b37@gmail.com> Message-ID: Michael Torrie wrote: > On 12/22/20 8:10 AM, Chris Green wrote: > > I have (as discussed here) a printer utility that uses Python 2 and I > > can't update it to Python 3 because it has a .so library file which is > > compiled for Python 2. I think I have exhausted all the possibilities > > for converting it to Python 3 so now I'm looking at how to keep it > > working on my [x]ubuntu Linux systems as Python 2.7 becomes unsupported. > > > > How realistic/possible would it be to run the utility in a separate > > environment with its own copies of Python2 and any modules and > > libraries needed? I would install these 'by hand', i.e. not using > > 'apt' so they would stay as installed even as my system gets upgraded. > > > > There would obviously be *some* dependencies on the system libraries > > but I think they'd be pretty low level and thus their interfaces would > > be very unlikely to change for a long time so I should be able to run > > my old Python2.7 and the Python modules needed for the utility for > > quite a few years anyway (the printer it supports will wear out > > eventually!). > > Probably your best bet is to build a container image (perhaps a snap) > around with a distro that has Python 2.7 in it to house your app. That > way you've got everything you need including the required system > libraries. Right now you could build a image of it based on Ubuntu > 20.04 which has python 2.7 as an optional installable package. > I have it running on 20.04 (with a couple of compatibility packages from a PPA) but I know I start hitting problems as soon as I move to 20.10. So that does sound like an excellent idea. Where can I find information about building container type things like snap? -- Chris Green ? From torriem at gmail.com Tue Dec 22 12:10:21 2020 From: torriem at gmail.com (Michael Torrie) Date: Tue, 22 Dec 2020 10:10:21 -0700 Subject: Installing Python (2.7) 'by hand' on Ubuntu - possible? In-Reply-To: References: <0te9bh-52nv.ln1@esprimo.zbmc.eu> <302033ef-5b6e-dd67-5323-19437fd84b37@gmail.com> Message-ID: <3a57b1de-c402-4376-ffee-d4b82dbf88e4@gmail.com> On 12/22/20 9:44 AM, Chris Green wrote: > I have it running on 20.04 (with a couple of compatibility packages > from a PPA) but I know I start hitting problems as soon as I move to > 20.10. So that does sound like an excellent idea. Where can I find > information about building container type things like snap? Good question. A quick search reveals this potential starting place: https://ubuntu.com/tutorials/create-your-first-snap Also https://snapcraft.io/docs/python-plugin https://snapcraft.io/docs/python-apps That's all I know. Sorry I suggested a solution I know nothing about! From grant.b.edwards at gmail.com Tue Dec 22 12:18:31 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Tue, 22 Dec 2020 17:18:31 -0000 (UTC) Subject: Installing Python (2.7) 'by hand' on Ubuntu - possible? References: <0te9bh-52nv.ln1@esprimo.zbmc.eu> Message-ID: On 2020-12-22, Chris Green wrote: > [...] > > How realistic/possible would it be to run the utility in a separate > environment with its own copies of Python2 and any modules and > libraries needed? I would install these 'by hand', i.e. not using > 'apt' so they would stay as installed even as my system gets upgraded. If you do have it running on a Linux system, then there are tools to "bundle" it with all the required libraries. The one that I've used most recently is cx_freeze (I generally use it to create bundles for Windows): https://cx-freeze.readthedocs.io/en/latest/index.html If you want to use it for a 2.7 app, you'd need to use 5.1 -- Grant From rosuav at gmail.com Tue Dec 22 13:32:50 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 23 Dec 2020 05:32:50 +1100 Subject: Installing Python (2.7) 'by hand' on Ubuntu - possible? In-Reply-To: <0te9bh-52nv.ln1@esprimo.zbmc.eu> References: <0te9bh-52nv.ln1@esprimo.zbmc.eu> Message-ID: On Wed, Dec 23, 2020 at 2:21 AM Chris Green wrote: > > I have (as discussed here) a printer utility that uses Python 2 and I > can't update it to Python 3 because it has a .so library file which is > compiled for Python 2. I think I have exhausted all the possibilities > for converting it to Python 3 so now I'm looking at how to keep it > working on my [x]ubuntu Linux systems as Python 2.7 becomes unsupported. > > How realistic/possible would it be to run the utility in a separate > environment with its own copies of Python2 and any modules and > libraries needed? I would install these 'by hand', i.e. not using > 'apt' so they would stay as installed even as my system gets upgraded. > It shouldn't be too hard to grab the source code for Python 2.7 and install it that way. The first step would be to ask apt to install all the build dependencies of Python 3; the same libraries will be important for building Python 2 (bar a couple that got added more recently, but that won't affect anything). Once you get it built, you can either just install it as is, or build yourself a package (with checkinstall or something) to be able to uninstall later. Personally, I'd just install it directly, but that's me. ChrisA From cl at isbd.net Tue Dec 22 13:38:04 2020 From: cl at isbd.net (Chris Green) Date: Tue, 22 Dec 2020 18:38:04 +0000 Subject: Installing Python (2.7) 'by hand' on Ubuntu - possible? References: <0te9bh-52nv.ln1@esprimo.zbmc.eu> Message-ID: Grant Edwards wrote: > On 2020-12-22, Chris Green wrote: > > [...] > > > > How realistic/possible would it be to run the utility in a separate > > environment with its own copies of Python2 and any modules and > > libraries needed? I would install these 'by hand', i.e. not using > > 'apt' so they would stay as installed even as my system gets upgraded. > > If you do have it running on a Linux system, then there are tools to > "bundle" it with all the required libraries. The one that I've used > most recently is cx_freeze (I generally use it to create bundles for > Windows): > > https://cx-freeze.readthedocs.io/en/latest/index.html > > If you want to use it for a 2.7 app, you'd need to use 5.1 > That looks a good approach, thank you. -- Chris Green ? From grant.b.edwards at gmail.com Tue Dec 22 13:58:52 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Tue, 22 Dec 2020 18:58:52 -0000 (UTC) Subject: Installing Python (2.7) 'by hand' on Ubuntu - possible? References: <0te9bh-52nv.ln1@esprimo.zbmc.eu> Message-ID: On 2020-12-22, Chris Green wrote: > Grant Edwards wrote: >> On 2020-12-22, Chris Green wrote: >> > [...] >> > >> > How realistic/possible would it be to run the utility in a separate >> > environment with its own copies of Python2 and any modules and >> > libraries needed? I would install these 'by hand', i.e. not using >> > 'apt' so they would stay as installed even as my system gets upgraded. >> >> If you do have it running on a Linux system, then there are tools to >> "bundle" it with all the required libraries. The one that I've used >> most recently is cx_freeze (I generally use it to create bundles for >> Windows): >> >> https://cx-freeze.readthedocs.io/en/latest/index.html >> >> If you want to use it for a 2.7 app, you'd need to use 5.1 > > That looks a good approach, thank you. I should have mentioned that bundlers like cx_freeze require that you have the Python source for the main app. I don't remember if you mentioned source or not... -- Grant From cl at isbd.net Tue Dec 22 14:24:19 2020 From: cl at isbd.net (Chris Green) Date: Tue, 22 Dec 2020 19:24:19 +0000 Subject: Installing Python (2.7) 'by hand' on Ubuntu - possible? References: <0te9bh-52nv.ln1@esprimo.zbmc.eu> Message-ID: <3ot9bh-o5m01.ln1@esprimo.zbmc.eu> Grant Edwards wrote: > On 2020-12-22, Chris Green wrote: > > Grant Edwards wrote: > >> On 2020-12-22, Chris Green wrote: > >> > [...] > >> > > >> > How realistic/possible would it be to run the utility in a separate > >> > environment with its own copies of Python2 and any modules and > >> > libraries needed? I would install these 'by hand', i.e. not using > >> > 'apt' so they would stay as installed even as my system gets upgraded. > >> > >> If you do have it running on a Linux system, then there are tools to > >> "bundle" it with all the required libraries. The one that I've used > >> most recently is cx_freeze (I generally use it to create bundles for > >> Windows): > >> > >> https://cx-freeze.readthedocs.io/en/latest/index.html > >> > >> If you want to use it for a 2.7 app, you'd need to use 5.1 > > > > That looks a good approach, thank you. > > I should have mentioned that bundlers like cx_freeze require that you > have the Python source for the main app. I don't remember if you > mentioned source or not... > Yes, I do have the Python source. The only thing I don't have the source for is a .so file and that's why I can't simply migrate the program(s) from Python 2 to Python 3. -- Chris Green ? From grant.b.edwards at gmail.com Tue Dec 22 14:41:44 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Tue, 22 Dec 2020 19:41:44 -0000 (UTC) Subject: Installing Python (2.7) 'by hand' on Ubuntu - possible? References: <0te9bh-52nv.ln1@esprimo.zbmc.eu> <3ot9bh-o5m01.ln1@esprimo.zbmc.eu> Message-ID: On 2020-12-22, Chris Green wrote: > Grant Edwards wrote: > >> I should have mentioned that bundlers like cx_freeze require that you >> have the Python source for the main app. I don't remember if you >> mentioned source or not... > > Yes, I do have the Python source. The only thing I don't have the > source for is a .so file and that's why I can't simply migrate the > program(s) from Python 2 to Python 3. I think cx_freeze should be able to do the job. It tries to auto-detect what libraries and Python modules are needed, but sometimes you have manually add one or two to the list. -- Grant From mirkok.lists at googlemail.com Tue Dec 22 16:12:34 2020 From: mirkok.lists at googlemail.com (Mirko) Date: Tue, 22 Dec 2020 22:12:34 +0100 Subject: Installing Python (2.7) 'by hand' on Ubuntu - possible? In-Reply-To: <3ot9bh-o5m01.ln1@esprimo.zbmc.eu> References: <0te9bh-52nv.ln1@esprimo.zbmc.eu> <3ot9bh-o5m01.ln1@esprimo.zbmc.eu> Message-ID: <5FE26142.5090209@googlemail.com> On 22.12.2020 at 20:24 Chris Green wrote: > Yes, I do have the Python source. The only thing I don't have the > source for is a .so file and that's why I can't simply migrate the > program(s) from Python 2 to Python 3. > If it's just one .so and that library is compatible with basic libs such as glibc and has no further big dependencies, then there may be a simpler way than cx_freeze or even snap/docker/etc. Python 2 will likely be available for quite some more years as an optional package. But even with a self-compiled version, you should be able to put the required libraries somewhere and set LD_LIBRARY_PATH or maybe LD_PRELOAD accordingly. For a few depending libs, this works well, but it gets really nasty if glibc or big frameworks such as GTK are involved. From rhettprince at gmail.com Tue Dec 22 18:57:14 2020 From: rhettprince at gmail.com (Rhett Prince) Date: Tue, 22 Dec 2020 18:57:14 -0500 Subject: sqlalchemy blows up and puts in addresses instead of data when mixing fields from different dataframes Message-ID: <000701d6d8be$2c567de0$850379a0$@gmail.com> sqlalchemy blows up and puts in addresses instead of data when mixing fields from different dataframes when composing a class derived from model, populating fields from different dataframes blows up.fields from one data frame are corrupted after session add and session commit fields from another dataframe are fine. building final class object with single dataframe from data frame with the issue alone is just fine. data from the data frame survives session.add and session.commit data is only corrupted when data comes from two different data frame sources field 1 comes from data frame a field 2 comes from dataframe b after session.add session.commit first field from source 1 is corrupted. data from source 2 is fine. again when data source 1 is used by itself with out a second source data from dataframe 1 survives session.add and session.commit. is this a defect in sqlalchemy or in pandas. o From jcasale at activenetwerx.com Tue Dec 22 23:04:24 2020 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Wed, 23 Dec 2020 04:04:24 +0000 Subject: pexpect with kadmin Message-ID: <57b0a153b1884f3a8f12215183c6ab9e@activenetwerx.com> Anyone ever used pexpect with tooling like kadmin and have insight into how to manage interacting with it? After setting up debug logging, I was able to adjust the expect usage to get the input and output logs to at least appear correct when setting a password for a principal, however even with a successful return code from kadmin, there is some discrepancy and the credential is not being set right. When run manually, the credentials work fine, it's almost as if kadmin is swallowing the newline from pexpect within the password. I am using python 3.5 from Windows, over plink.exe, onto a rhel 7 server. Unfortunately, I am stuck with all the levels of indirection. Thanks, jlc From cl at isbd.net Wed Dec 23 04:03:27 2020 From: cl at isbd.net (Chris Green) Date: Wed, 23 Dec 2020 09:03:27 +0000 Subject: Installing Python (2.7) 'by hand' on Ubuntu - possible? References: <0te9bh-52nv.ln1@esprimo.zbmc.eu> <3ot9bh-o5m01.ln1@esprimo.zbmc.eu> <5FE26142.5090209@googlemail.com> Message-ID: Mirko wrote: > On 22.12.2020 at 20:24 Chris Green wrote: > > > Yes, I do have the Python source. The only thing I don't have the > > source for is a .so file and that's why I can't simply migrate the > > program(s) from Python 2 to Python 3. > > > > If it's just one .so and that library is compatible with basic libs > such as glibc and has no further big dependencies, then there may be > a simpler way than cx_freeze or even snap/docker/etc. > > Python 2 will likely be available for quite some more years as an > optional package. But even with a self-compiled version, you should > be able to put the required libraries somewhere and set > LD_LIBRARY_PATH or maybe LD_PRELOAD accordingly. For a few depending > libs, this works well, but it gets really nasty if glibc or big > frameworks such as GTK are involved. Unfortunately GTK is involved, the utility pops up a GUI that uses Gtk2, that's part of the can of worms that this has become because of the non-trivial migration of GTK from Python 2 to Python 3. As I said I have the Python source and it's not particularly difficult to move that from Python 2 to Python 3, the killer is a .so compiled for Python 2. -- Chris Green ? From barry at barrys-emacs.org Wed Dec 23 10:00:19 2020 From: barry at barrys-emacs.org (Barry Scott) Date: Wed, 23 Dec 2020 15:00:19 +0000 Subject: pexpect with kadmin In-Reply-To: <57b0a153b1884f3a8f12215183c6ab9e@activenetwerx.com> References: <57b0a153b1884f3a8f12215183c6ab9e@activenetwerx.com> Message-ID: <7F3D51C0-60A3-44BE-AB00-54C788117F95@barrys-emacs.org> > On 23 Dec 2020, at 04:04, Joseph L. Casale wrote: > > Anyone ever used pexpect with tooling like kadmin and have > insight into how to manage interacting with it? > > After setting up debug logging, I was able to adjust the expect > usage to get the input and output logs to at least appear correct > when setting a password for a principal, however even with a > successful return code from kadmin, there is some discrepancy > and the credential is not being set right. > > When run manually, the credentials work fine, it's almost as if > kadmin is swallowing the newline from pexpect within the password. > > I am using python 3.5 from Windows, over plink.exe, onto a rhel > 7 server. Unfortunately, I am stuck with all the levels of indirection. If you have windows 10 can you use Windows Subsystem for Linux (WSL) to install one of the Linux distros and use that? Barry > > Thanks, > jlc > -- > https://mail.python.org/mailman/listinfo/python-list > From vincent.vandevyvre at oqapy.eu Wed Dec 23 03:31:00 2020 From: vincent.vandevyvre at oqapy.eu (vincent.vandevyvre at oqapy.eu) Date: Wed, 23 Dec 2020 03:31:00 -0500 (EST) Subject: Pickling issue. Message-ID: <20201223092247.7kNn2400E5Fqe7q01kNnAN@xavier.telenet-ops.be> On 22/12/20 01:57, Bob Gailer wrote: > > > On Mon, Dec 21, 2020, 3:03 PM Vincent Vande Vyvre wrote: > > Hi, > > I've an object that I want to serialise with pickle. > When I reload the object the attributes of this object are correctly > fixed except one of these. > > This attribute (value) define a simple string. > > Example: > --------------------------------------------- > tag = XmpTag('Xmp.dc.form'image/jpeg') > > > I am not familiar with XmpTag. Where might I get the containing module? > > ... skip > Yes, it's available with pip: https://pypi.org/project/py3exiv2/ If you want to test it, just add from pyexiv2.xmp import XmpTag to my example. and the source is here: https://bazaar.launchpad.net/~vincent-vandevyvre/py3exiv2/trunk/view/head:/py3exiv2/src/pyexiv2/xmp.py This is a Python-3 binding of the lib exiv2, the wrapper source code is here: https://bazaar.launchpad.net/~vincent-vandevyvre/py3exiv2/trunk/view/head:/py3exiv2/src/exiv2wrapper.cpp#L359 exiv2 doc is here: https://www.exiv2.org/doc/classExiv2_1_1Xmpdatum.html Sorry for the late response but it seems a moderation problem with my account. Vincent From sersadaka1 at outlook.com Wed Dec 23 12:03:51 2020 From: sersadaka1 at outlook.com (Sadaka Technology) Date: Wed, 23 Dec 2020 09:03:51 -0800 (PST) Subject: using regex for password validation Message-ID: hello guys, I have this pattern for password validation (regex): I want these rules to be applied: Minimum 8 characters. The alphabets must be between [a-z] At least one alphabet should be of Upper Case [A-Z] At least 1 number or digit between [0-9]. At least 1 character from [ _ or @ or $ ]. and this pattern: passwordpattern = "^(?=.[a-z])(?=.[A-Z])(?=.\d)(?=.[@$])[A-Za-z\d@$!%?&]{8,}.$" my only issue is that I want to add the symbol () and symbol(.) in the pattern where only it accepts $ and @, I tried adding generally like [@_$] not working From mats at wichmann.us Wed Dec 23 13:46:36 2020 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 23 Dec 2020 11:46:36 -0700 Subject: using regex for password validation In-Reply-To: References: Message-ID: On 12/23/20 10:03 AM, Sadaka Technology wrote: > hello guys, > > I have this pattern for password validation (regex): > > I want these rules to be applied: > > Minimum 8 characters. > The alphabets must be between [a-z] > At least one alphabet should be of Upper Case [A-Z] > At least 1 number or digit between [0-9]. > At least 1 character from [ _ or @ or $ ]. > > and this pattern: > > passwordpattern = "^(?=.[a-z])(?=.[A-Z])(?=.\d)(?=.[@$])[A-Za-z\d@$!%?&]{8,}.$" > > my only issue is that I want to add the symbol () and symbol(.) in the pattern where only it accepts $ and @, I tried adding generally like [@_$] not working > I'm not going to answer your question, don't have the brainpower at the moment to disentangle your regex. Therein comes the source of the (unasked-for) comment: if looking at a regex gives you a headache - and worse, it doesn't work as you hope, you probably want to solve a problem another way. If you're enforcing a password policy (and this isn't a homework question, where the rules conveniently don't change over time), I'd claim you're better off writing a readable routine that applies the policy in such a way that you can accommodate changes to the policy. What if someone decides that the non-alnum set can also include a comma or other characters? What if there's a different constraint applied to the first character of the password? (both of those are moderately common). Telling someone the password they tried to propose doesn't meet the policy isn't performance sensitive, since it is a human-interactive process, so it's okay to be a little slower and a lot clearer (that's not even a Python issue!) If you're going to stick with a regex, run the completed regex through one of the online validators, and paste its analysis (they usually give you a breakdown of what each piece means) as a comment, so some future programmer has a hope... From python at mrabarnett.plus.com Wed Dec 23 14:03:50 2020 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 23 Dec 2020 19:03:50 +0000 Subject: using regex for password validation In-Reply-To: References: Message-ID: On 2020-12-23 17:03, Sadaka Technology wrote: > hello guys, > > I have this pattern for password validation (regex): > > I want these rules to be applied: > > Minimum 8 characters. > The alphabets must be between [a-z] > At least one alphabet should be of Upper Case [A-Z] > At least 1 number or digit between [0-9]. > At least 1 character from [ _ or @ or $ ]. > > and this pattern: > > passwordpattern = "^(?=.[a-z])(?=.[A-Z])(?=.\d)(?=.[@$])[A-Za-z\d@$!%?&]{8,}.$" > > my only issue is that I want to add the symbol () and symbol(.) in the pattern where only it accepts $ and @, I tried adding generally like [@_$] not working > Your pattern: ^ Matches at start of string (?=.[a-z]) Matches any character and then one [a-z] (?=.[A-Z]) Matches any character and then one [A-Z] (?=.\d) Matches any character and then one digit (?=.[@$]) Matches any character and then one of [@$] [A-Za-z\d@$!%?&]{8,} Matches 8 or more of [A-Za-z\d@$!%?&]{8,} . Matches any character $ Matche at end of string The pattern will never match because the second character cannot be one of [a-z] _and_ one of [A-Z] _and_ a digit _and_ one of [@$] _at the same time_. I'm not sure what you mean by "The alphabets must be between [a-z]" (all letters lower case?) and also "At least one alphabet should be of Upper Case [A-Z]" (at least one upper case letter). I'm guessing you mean that all letters must be [A-Za-z], but at least one of them must be [A-Z]. Also, what do you mean by "symbol () and symbol(.)"; I see the "." between the second parentheses in the second one, but nothing between the first. Anyway, how about this pattern: ^(?=.*[A-Z])(?=.*[0-9])(?=.*[_@$])[A-Za-z0-9@$_!%?&]{8,}$ From grant.b.edwards at gmail.com Wed Dec 23 15:41:01 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Wed, 23 Dec 2020 20:41:01 -0000 (UTC) Subject: using regex for password validation References: Message-ID: On 2020-12-23, Mats Wichmann wrote: > Telling someone the password they tried to propose doesn't meet the > policy isn't performance sensitive, since it is a human-interactive > process, so it's okay to be a little slower and a lot clearer (that's > not even a Python issue!) You're far, far better off writing a function that tests each rule separately, so that you can tell the user _why_ the password isn't allowed. If you use a regex, it's just pass/fail. The user won't have any idea how to fix the problem. -- Grant Edwards grant.b.edwards Yow! With YOU, I can be at MYSELF ... We don't NEED gmail.com Dan Rather ... From rosuav at gmail.com Wed Dec 23 17:03:53 2020 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 24 Dec 2020 09:03:53 +1100 Subject: using regex for password validation In-Reply-To: References: Message-ID: On Thu, Dec 24, 2020 at 4:09 AM Sadaka Technology wrote: > > hello guys, > > I have this pattern for password validation (regex): > > I want these rules to be applied: > > Minimum 8 characters. > The alphabets must be between [a-z] > At least one alphabet should be of Upper Case [A-Z] > At least 1 number or digit between [0-9]. > At least 1 character from [ _ or @ or $ ]. > > and this pattern: > > passwordpattern = "^(?=.[a-z])(?=.[A-Z])(?=.\d)(?=.[@$])[A-Za-z\d@$!%?&]{8,}.$" > > my only issue is that I want to add the symbol () and symbol(.) in the pattern where only it accepts $ and @, I tried adding generally like [@_$] not working > Easy solution: passwordpattern = ".{11,}" This mandates more security than the one you're using, AND it's far less frustrating for users. Please stop inflicting horrific password rules on the world. Especially, requiring one "symbol" - where "symbol" is always defined differently from one place to another (and in your case, you're offering just three valid options) - causes weaker passwords and more frustration. Just don't do it. ChrisA From jcasale at activenetwerx.com Wed Dec 23 17:07:09 2020 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Wed, 23 Dec 2020 22:07:09 +0000 Subject: pexpect with kadmin In-Reply-To: <7F3D51C0-60A3-44BE-AB00-54C788117F95@barrys-emacs.org> References: <57b0a153b1884f3a8f12215183c6ab9e@activenetwerx.com> <7F3D51C0-60A3-44BE-AB00-54C788117F95@barrys-emacs.org> Message-ID: <61e0387bd9ab42a4ae90ec6d70b4e75d@activenetwerx.com> > If you have windows 10 can you use Windows Subsystem for Linux (WSL) > to install one of the Linux distros and use that? Interesting idea, sadly I am too far past the deadline on this to go through the red tape needed to get that in place. Thanks, jlc From PythonList at DancesWithMice.info Wed Dec 23 17:41:15 2020 From: PythonList at DancesWithMice.info (dn) Date: Thu, 24 Dec 2020 11:41:15 +1300 Subject: using regex for password validation In-Reply-To: References: Message-ID: <36c7f24e-5410-26a2-6070-74336e71ffdb@DancesWithMice.info> On 24/12/2020 06:03, Sadaka Technology wrote: > hello guys, > > I have this pattern for password validation (regex): > > I want these rules to be applied: > > Minimum 8 characters. > The alphabets must be between [a-z] > At least one alphabet should be of Upper Case [A-Z] > At least 1 number or digit between [0-9]. > At least 1 character from [ _ or @ or $ ]. > > and this pattern: > > passwordpattern = "^(?=.[a-z])(?=.[A-Z])(?=.\d)(?=.[@$])[A-Za-z\d@$!%?&]{8,}.$" > > my only issue is that I want to add the symbol () and symbol(.) in the pattern where only it accepts $ and @, I tried adding generally like [@_$] not working A quick web.search reveals, quite evidently, loads of people attempt to solve this problem with ever more-powerful RegExs. (and ever more perplexing questions on SO, etc) There's something seductive about RegEx-s to the average ComSc student. The challenge of wielding such control, so concisely. APL or Lisp programming anyone? I recall positively-devouring Jeff Friedl's book - with expectations of 'changing the world'... [back down to earth] These days I seldom use them (NB ActiveState do?did a (recommended) 'cheat sheet', a copy of which resides in my desk-file as crib-notes) Contrarily, a RegEx may be quite the wrong tool for the job. Partially because such expressions are difficult to understand - either someone else's code or my own from the proverbial six-months back(!); and partially here we're attempting to solve multiple problems in one go. (I'm writing this from the perspective of 'Apprentice' professionals or a ComSc student - with any/all due apologies and respect to the OP) There is much virtue in saying that every Python routine should solve one problem (and only one!), and do that well. Similarly, the scientific method as applied to software development is to break each problem into smaller, more manageable problems (per ardua) - and thus, more recognisable solutions (and we're back to me banging-the-drum of readability). Here's the problem-solution: def validate_password( attempt:str )->bool: ... (Oh yeah, wow!) Obviously(!) this (larger) routine will contain more (smaller, more manageable) routines. We can follow the format, exactly as outlined in the specification (or homework assignment, as appropriate): > Minimum 8 characters. def validate_length( rule:int, attempt:str )->bool: > The alphabets must be between [a-z] def validate_lower_case( attempt:str )->bool: # see note, below > At least one alphabet should be of Upper Case [A-Z] def validate_upper_case( attempt:str )->bool: # also, see note, below > At least 1 number or digit between [0-9]. def validate_numeric( attempt:str )->bool: # again, see note, below > At least 1 character from [ _ or @ or $ ]. def validate_specials( rule:Set, attempt:str )->bool: There were five specifications, so there are five (sub) routines, called in-turn by validate_password() (a "decision ladder") - with a fast-drop, should you wish. Hang-on though, look at how much 'work' is involved, compared with a single line of RegEx! Why go to such bother? There's several reasons. Notice how the spec has become code? "Readability" is not merely the appearance and communication-quality of one's code, but the transfer of ideas across levels, or layers, of detail! Notice that the above have a parameter "rule". Why? (and that's not (only) the question: "why don't we encode these as constants within the function?") If you've 'been around' for a while, you will have noticed that password rules keep changing, over time, presuming that becoming more 'strict', will make the system more secure. (am not going to discuss the hope of solving (largely) social problems with technological solutions!) What would be the impact of a 'make it strict-er' business-rule change (specification) on the one-line RegEx solution? Persisting with the long-way around:- A frequent call is to increase the minimum-length of passwords. How could we do this? Using RegEx, adjust the counter - but which part is the 'counter'? Alternately, here, reading the code we find validate_length() (or the documentation where "rule" is defined/given its value) and change the value of the integer. QED! (and by "QED" I mean: this is a job which could be given to the newest of Junior Programmers, with a high confidence of (rapid) success) Similarly, in the above structure, validate_specials() expects to be given a 'rule' which is currently: { '[', '_', '@', '$', ']', } How easy would it be to add another character, eg "#" or "?"; when your system goes international and is being used by folk with European-variant keyboards? Is extending the set easier (and more likely to retain fidelity) than fiddling with a RegEx? [and here's the note] If our ambitions include dreams of 'world domination', then we can extend exactly the same idea of "rule" to the other three routines! Whilst we 'start' with (say) the ASCII character definitions of a-z, we will *be able* to extend into accented characters such as "?" - which really would promote us to take a r?le on the world-stage. (hah!) From a 'business'/users' perspective: note that the five routines could easily be extended should further business-rules be demanded. From a code-perspective: note that either "in" could be used to detect presence (but not so easily 'count', eg minimum of two lower-case letters), or we could persist with RegEx solution(s) - in which case, by breaking the larger problem into smaller ones, the RegEx complexity-level falls to that which mere-mortals may comprehend! Now let's stoop to allowing that although programmers are *the* most important people in the world, we should consider our users - just once in a while. Thus, lets consider UX ("User Experience"). Most of us hate situations when we are asked to furnish a password but 'get it wrong' - particularly those sites which fail to tell us 'the rules' BEFORE we offer our preference! If we're going to be nice to our users, from where do we express these "rules"? If the rule is hard-coded, then the user-advice must also be hard-coded - and what do we say about having 'the same code' in multiple locations? (see also "DRY principle"). How could one state "the rules" *once*, and in such a fashion that they can be used for UX output and a RegEx? Second UX-consideration (and its a 'biggie'!): if a password 'fails', how can we take the 'result' from a large and complex RegEx, and explain to the user which [multiple] of the five requirements was/were not met? A failure in the RegEx above tells the system not to proceed, but doesn't tell the user is a letter is missing, a digit, ... RegEx is extremely powerful, but 'power' is seductive - just because we can do something doesn't make it a good idea! The Spiderman rule applies... -- Regards =dn From 2QdxY4RzWzUUiLuE at potatochowder.com Wed Dec 23 18:20:25 2020 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Wed, 23 Dec 2020 17:20:25 -0600 Subject: using regex for password validation In-Reply-To: <36c7f24e-5410-26a2-6070-74336e71ffdb@DancesWithMice.info> References: <36c7f24e-5410-26a2-6070-74336e71ffdb@DancesWithMice.info> Message-ID: On 2020-12-24 at 11:41:15 +1300, dn via Python-list wrote: > On 24/12/2020 06:03, Sadaka Technology wrote: > > hello guys, > > > > I have this pattern for password validation (regex): [...] > > passwordpattern = "^(?=.[a-z])(?=.[A-Z])(?=.\d)(?=.[@$])[A-Za-z\d@$!%?&]{8,}.$" > > > > my only issue is that I want to add the symbol () and symbol(.) in > > the pattern where only it accepts $ and @, I tried adding generally > > like [@_$] not working [...] Is it my imagination, or does a password in which the only lower case letter is at the beginning fail? > Contrarily, a RegEx may be quite the wrong tool for the job. Partially > because such expressions are difficult to understand - either someone > else's code or my own from the proverbial six-months back(!); and > partially here we're attempting to solve multiple problems in one go. "[M]ay be quite"? You are far too kind, dn. > If our ambitions include dreams of 'world domination', then we can > extend exactly the same idea of "rule" to the other three routines! > Whilst we 'start' with (say) the ASCII character definitions of a-z, > we will *be able* to extend into accented characters such as "?" - > which really would promote us to take a r?le on the world-stage. > (hah!) If you're going to wander out of ASCII, then don't forget to address Unicode confusables. Nothing is more embarrassing than scribbling your complicated password on a sticky note and then not being able to tell the o's from the ?'s. ;-) > If we're going to be nice to our users, from where do we express these > "rules"? If the rule is hard-coded, then the user-advice must also be > hard-coded - and what do we say about having 'the same code' in > multiple locations? (see also "DRY principle"). How could one state > "the rules" *once*, and in such a fashion that they can be used for UX > output and a RegEx? That's the beauty of a regular expression: it's both human and computer readable. Just show the user the regular expression(s) you used. Oh, wait. Sorry. Scratch that. Thanks, dn, for saying all of that (including what I snipped) out loud. From rosuav at gmail.com Wed Dec 23 18:25:27 2020 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 24 Dec 2020 10:25:27 +1100 Subject: using regex for password validation In-Reply-To: <36c7f24e-5410-26a2-6070-74336e71ffdb@DancesWithMice.info> References: <36c7f24e-5410-26a2-6070-74336e71ffdb@DancesWithMice.info> Message-ID: On Thu, Dec 24, 2020 at 9:42 AM dn via Python-list wrote: > Hang-on though, look at how much 'work' is involved, compared with a > single line of RegEx! Why go to such bother? There's several reasons. Good question! Look at this alternative: def validate_password(attempt): return len(attempt) >= 11 Wow! So much easier. Only one function needed AND it's more secure! > A frequent call is to increase the minimum-length of passwords. How > could we do this? Using RegEx, adjust the counter - but which part is > the 'counter'? In my example here, it's pretty easy to find! > If our ambitions include dreams of 'world domination', then we can > extend exactly the same idea of "rule" to the other three routines! > Whilst we 'start' with (say) the ASCII character definitions of a-z, we > will *be able* to extend into accented characters such as "?" - which > really would promote us to take a r?le on the world-stage. > (hah!) Wow! It wins on that too! And even better - it counts Cyrillic letters as letters, it counts Greek letters as letters, and it counts Arabic letters as letters too! Isn't it so much easier than a regex? > If we're going to be nice to our users, from where do we express these > "rules"? If the rule is hard-coded, then the user-advice must also be > hard-coded - and what do we say about having 'the same code' in multiple > locations? (see also "DRY principle"). How could one state "the rules" > *once*, and in such a fashion that they can be used for UX output and a > RegEx? Very very good point. I think "Passwords must be at least eleven characters long" is a problem, because you would need to *manually* translate the number "11" into the word "eleven". So the best way would be to use "Passwords must be at least {minlength} characters long" and then you know that it's going to correlate. > Second UX-consideration (and its a 'biggie'!): if a password 'fails', > how can we take the 'result' from a large and complex RegEx, and explain > to the user which [multiple] of the five requirements was/were not met? > A failure in the RegEx above tells the system not to proceed, but > doesn't tell the user is a letter is missing, a digit, ... > True, very true. Once again, a win for simplicity: with only one rule, it's easy to know which one you ran up against. ChrisA From rosuav at gmail.com Wed Dec 23 18:29:30 2020 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 24 Dec 2020 10:29:30 +1100 Subject: using regex for password validation In-Reply-To: References: <36c7f24e-5410-26a2-6070-74336e71ffdb@DancesWithMice.info> Message-ID: On Thu, Dec 24, 2020 at 10:21 AM <2QdxY4RzWzUUiLuE at potatochowder.com> wrote: > If you're going to wander out of ASCII, then don't forget to address > Unicode confusables. Nothing is more embarrassing than scribbling your > complicated password on a sticky note and then not being able to tell > the o's from the ?'s. ;-) TBH I don't think that's really our consideration. My recommendation is: First do a basic Unicode normalization (probably NFC, but there are good arguments for NFD instead), then just use it as-is. Everything else is the user's choice. And you shouldn't ever have to worry about a maximum length; after any checks such as "both passwords must be the same" (on account creation), the only thing you'll need to do is encode it UTF-8 and hand it to bcrypt. But by using simpler password requirements (an 11-character minimum is good in 2020, but maybe in the future you might want to extend that to 12), you reduce the temptation to use confusable letters in it. Context is everything. ChrisA From PythonList at DancesWithMice.info Wed Dec 23 20:28:24 2020 From: PythonList at DancesWithMice.info (dn) Date: Thu, 24 Dec 2020 14:28:24 +1300 Subject: using regex for password validation In-Reply-To: References: <36c7f24e-5410-26a2-6070-74336e71ffdb@DancesWithMice.info> Message-ID: <0988d584-6fea-a95a-610a-4c713093e313@DancesWithMice.info> On 24/12/2020 12:20, 2QdxY4RzWzUUiLuE at potatochowder.com wrote: > On 2020-12-24 at 11:41:15 +1300, > dn via Python-list wrote: >> On 24/12/2020 06:03, Sadaka Technology wrote: >>> hello guys, >>> >>> I have this pattern for password validation (regex): > > [...] > Is it my imagination, or does a password in which the only lower case > letter is at the beginning fail? As mentioned, I don't use RegEx so-often and rely upon a crib-sheet. What I could?should have added, is that there are many web-sites which enable one to enter a RegEx and some sample data, for immediate verification. Very handy! >> Contrarily, a RegEx may be quite the wrong tool for the job. Partially >> because such expressions are difficult to understand - either someone >> else's code or my own from the proverbial six-months back(!); and >> partially here we're attempting to solve multiple problems in one go. > > "[M]ay be quite"? You are far too kind, dn. The people on this list often help me, so... Whereas I prefer to use str.functions, others may have their own opinion. To some degree it's one of those 'horses for courses' situations - and as illustrated, if the specs are tightened a bit further, it may well be that a 'minimum of two upper-case characters' rule would be easier to check with a RegEx! >> If our ambitions include dreams of 'world domination', then we can >> extend exactly the same idea of "rule" to the other three routines! >> Whilst we 'start' with (say) the ASCII character definitions of a-z, >> we will *be able* to extend into accented characters such as "?" - >> which really would promote us to take a r?le on the world-stage. >> (hah!) > > If you're going to wander out of ASCII, then don't forget to address > Unicode confusables. Nothing is more embarrassing than scribbling your > complicated password on a sticky note and then not being able to tell > the o's from the ?'s. ;-) ?k! >> If we're going to be nice to our users, from where do we express these >> "rules"? If the rule is hard-coded, then the user-advice must also be >> hard-coded - and what do we say about having 'the same code' in >> multiple locations? (see also "DRY principle"). How could one state >> "the rules" *once*, and in such a fashion that they can be used for UX >> output and a RegEx? > > That's the beauty of a regular expression: it's both human and computer > readable. Just show the user the regular expression(s) you used. Oh, > wait. Sorry. Scratch that. > > Thanks, dn, for saying all of that (including what I snipped) out loud. I've finished 'official work' for the year - compliments of the season! -- Regards =dn From PythonList at DancesWithMice.info Wed Dec 23 20:54:26 2020 From: PythonList at DancesWithMice.info (dn) Date: Thu, 24 Dec 2020 14:54:26 +1300 Subject: using regex for password validation In-Reply-To: References: <36c7f24e-5410-26a2-6070-74336e71ffdb@DancesWithMice.info> Message-ID: <4245998a-d696-d6b6-c1ff-9702fd6fd641@DancesWithMice.info> On 24/12/2020 12:25, Chris Angelico wrote: > On Thu, Dec 24, 2020 at 9:42 AM dn via Python-list > wrote: >> Hang-on though, look at how much 'work' is involved, compared with a >> single line of RegEx! Why go to such bother? There's several reasons. > > Good question! Look at this alternative: > > def validate_password(attempt): > return len(attempt) >= 11 > > Wow! So much easier. Only one function needed AND it's more secure! You and I have discussed such topics before @Chris. However, we both know that if the client specifies something (and we can't moderate such), we deliver accordingly - per Alfred Lord Tennyson. What we don't know is the OP's wiggle-room with his/her 'client' - which may be zero if the 'client' is an assignment-grade! However, the discussion 'beyond' the OP's immediate question is very necessary! >> A frequent call is to increase the minimum-length of passwords. How >> could we do this? Using RegEx, adjust the counter - but which part is >> the 'counter'? > > In my example here, it's pretty easy to find! In a 'global definition' block or buried in the code-base? >> If our ambitions include dreams of 'world domination', then we can >> extend exactly the same idea of "rule" to the other three routines! >> Whilst we 'start' with (say) the ASCII character definitions of a-z, we >> will *be able* to extend into accented characters such as "?" - which >> really would promote us to take a r?le on the world-stage. >> (hah!) > > Wow! It wins on that too! And even better - it counts Cyrillic letters > as letters, it counts Greek letters as letters, and it counts Arabic > letters as letters too! Isn't it so much easier than a regex? - but wouldn't you agree that attempt == "x"*12 is no safer than "xxxx"? So, maybe a length-rule without any other consideration is 'weak-beer'? (speaking of beer, and for the benefit of non-Australians, and people everywhere who did learn their abc-s, "xxxx" is how @Chris spells "beer"!) NB probably not suitable for office-viewing: https://www.youtube.com/watch?v=mtwkDGlpWJk - cheers @Chris! Speaking of Australian humor:- >> If we're going to be nice to our users, from where do we express these >> "rules"? If the rule is hard-coded, then the user-advice must also be >> hard-coded - and what do we say about having 'the same code' in multiple >> locations? (see also "DRY principle"). How could one state "the rules" >> *once*, and in such a fashion that they can be used for UX output and a >> RegEx? > > Very very good point. I think "Passwords must be at least eleven > characters long" is a problem, because you would need to *manually* > translate the number "11" into the word "eleven". So the best way > would be to use "Passwords must be at least {minlength} characters > long" and then you know that it's going to correlate. Now you're just being plain mischievous! >> Second UX-consideration (and its a 'biggie'!): if a password 'fails', >> how can we take the 'result' from a large and complex RegEx, and explain >> to the user which [multiple] of the five requirements was/were not met? >> A failure in the RegEx above tells the system not to proceed, but >> doesn't tell the user is a letter is missing, a digit, ... > > True, very true. Once again, a win for simplicity: with only one rule, > it's easy to know which one you ran up against. The 'one rule' I try to live-by, is not to attempt 'important stuff' in which I have insufficient knowledge*. Rather than strain my brain (and spend an inordinate amount of time) deciding if/how to authenticate and authorise users, and then coding same, I'd rather pass the task to a TechSec specialist! * which *may* make me seem less like Dilbert, and more Wally https://en.wikipedia.org/wiki/List_of_Dilbert_characters -- Regards =dn From rosuav at gmail.com Wed Dec 23 21:17:25 2020 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 24 Dec 2020 13:17:25 +1100 Subject: using regex for password validation In-Reply-To: <4245998a-d696-d6b6-c1ff-9702fd6fd641@DancesWithMice.info> References: <36c7f24e-5410-26a2-6070-74336e71ffdb@DancesWithMice.info> <4245998a-d696-d6b6-c1ff-9702fd6fd641@DancesWithMice.info> Message-ID: On Thu, Dec 24, 2020 at 12:56 PM dn via Python-list wrote: > > On 24/12/2020 12:25, Chris Angelico wrote: > > On Thu, Dec 24, 2020 at 9:42 AM dn via Python-list > > wrote: > >> Hang-on though, look at how much 'work' is involved, compared with a > >> single line of RegEx! Why go to such bother? There's several reasons. > > > > Good question! Look at this alternative: > > > > def validate_password(attempt): > > return len(attempt) >= 11 > > > > Wow! So much easier. Only one function needed AND it's more secure! > > You and I have discussed such topics before @Chris. However, we both > know that if the client specifies something (and we can't moderate > such), we deliver accordingly - per Alfred Lord Tennyson. > > What we don't know is the OP's wiggle-room with his/her 'client' - which > may be zero if the 'client' is an assignment-grade! The OP said: > I want these rules to be applied: That means one of two things. Either it's a homework assignment and s/he is dishonestly pretending that it isn't one, or the OP invented the rules. There's nothing about "my client asked me to guard with these exact rules and I want to use a regex so I can have the exact same validation done by the web browser before it gets sent to the server". Don't assume justifications that aren't supported by evidence. > >> A frequent call is to increase the minimum-length of passwords. How > >> could we do this? Using RegEx, adjust the counter - but which part is > >> the 'counter'? > > > > In my example here, it's pretty easy to find! > > In a 'global definition' block or buried in the code-base? Either way would work. Either way is easier than digging through a regex. > >> If our ambitions include dreams of 'world domination', then we can > >> extend exactly the same idea of "rule" to the other three routines! > >> Whilst we 'start' with (say) the ASCII character definitions of a-z, we > >> will *be able* to extend into accented characters such as "?" - which > >> really would promote us to take a r?le on the world-stage. > >> (hah!) > > > > Wow! It wins on that too! And even better - it counts Cyrillic letters > > as letters, it counts Greek letters as letters, and it counts Arabic > > letters as letters too! Isn't it so much easier than a regex? > > - but wouldn't you agree that > > attempt == "x"*12 > > is no safer than "xxxx"? So, maybe a length-rule without any other > consideration is 'weak-beer'? Would you say that "12345Aa$" is a weak password, despite fitting the requirements? What if the password is the person's name? What if the password hint is "the password is 'Sw at rdf1sh'"? It's not our job to stop the user from creating a weak password - just to encourage the use of better passwords. A length rule on its own is sufficient to cover a lot of cases, and no regex is sufficient to cover all cases. > (speaking of beer, and for the benefit of non-Australians, and people > everywhere who did learn their abc-s, "xxxx" is how @Chris spells "beer"!) > NB probably not suitable for office-viewing: > https://www.youtube.com/watch?v=mtwkDGlpWJk - cheers @Chris! Actually I don't, that's a myth :) ChrisA From stackflowauto at gmail.com Fri Dec 25 20:26:50 2020 From: stackflowauto at gmail.com (stackf...@gmail.com) Date: Fri, 25 Dec 2020 17:26:50 -0800 (PST) Subject: unable to launch python3.8 -m idlelib.idle Message-ID: <6c87291f-108c-4b14-957e-9dd000e3b725n@googlegroups.com> unable to launch python3.8 -m idlelib.idle. getting below error msg. I am new to python. kindly help. python3.8 -m idlelib.idle Traceback (most recent call last): File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/runpy.py", line 194, in _run_module_as_main return _run_code(code, main_globals, None, File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/runpy.py", line 87, in _run_code exec(code, run_globals) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/idlelib/idle.py", line 13, in from idlelib.pyshell import main # This is subject to change File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/idlelib/pyshell.py", line 56, in from idlelib import rpc File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/idlelib/rpc.py", line 73, in class RPCServer(socketserver.TCPServer): AttributeError: module 'socketserver' has no attribute 'TCPServer' From tjreedy at udel.edu Fri Dec 25 21:33:31 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Fri, 25 Dec 2020 21:33:31 -0500 Subject: unable to launch python3.8 -m idlelib.idle In-Reply-To: <6c87291f-108c-4b14-957e-9dd000e3b725n@googlegroups.com> References: <6c87291f-108c-4b14-957e-9dd000e3b725n@googlegroups.com> Message-ID: On 12/25/2020 8:26 PM, stackf... at gmail.com wrote: > unable to launch python3.8 -m idlelib.idle. getting below error msg. I am new to python. kindly help. One should include OS with failure questions and perhaps how installed. Appears to be macOS, installed with ??? > python3.8 -m idlelib.idle For 3.x, '.idle' is not needed. > File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/idlelib/rpc.py", line 73, in > class RPCServer(socketserver.TCPServer): > AttributeError: module 'socketserver' has no attribute 'TCPServer' https://docs.python.org/3.8/library/socketserver.html#socketserver.TCPServer It is very much supposed to, so you installation seems faulty. I am running IDLE on macOS with 3.8, 3.9, and 3.10, installed with the python.org installer. This is one of the few circumstances for which I suggest re-installing. -- Terry Jan Reedy From rosuav at gmail.com Fri Dec 25 23:44:28 2020 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 26 Dec 2020 15:44:28 +1100 Subject: unable to launch python3.8 -m idlelib.idle In-Reply-To: References: <6c87291f-108c-4b14-957e-9dd000e3b725n@googlegroups.com> Message-ID: On Sat, Dec 26, 2020 at 2:32 PM Terry Reedy wrote: > > On 12/25/2020 8:26 PM, stackf... at gmail.com wrote: > > unable to launch python3.8 -m idlelib.idle. getting below error msg. I am new to python. kindly help. > > One should include OS with failure questions and perhaps how installed. > Appears to be macOS, installed with ??? > > > python3.8 -m idlelib.idle > > For 3.x, '.idle' is not needed. > > > File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/idlelib/rpc.py", line 73, in > > class RPCServer(socketserver.TCPServer): > > AttributeError: module 'socketserver' has no attribute 'TCPServer' > > https://docs.python.org/3.8/library/socketserver.html#socketserver.TCPServer > It is very much supposed to, so you installation seems faulty. I am > running IDLE on macOS with 3.8, 3.9, and 3.10, installed with the > python.org installer. > > This is one of the few circumstances for which I suggest re-installing. > Or seeing if you have a socketserver.py in the current directory. ChrisA From rshepard at appl-ecosys.com Sat Dec 26 12:13:13 2020 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Sat, 26 Dec 2020 09:13:13 -0800 (PST) Subject: Installing python3 modules Message-ID: Running Slackware-14.2/x86_64 here. I'm trying to learn if any installed applications are still dependent on Python2 (version 2.7.17 installed) as its EOL is this coming Thursday and I want to clean out all Python2 modules and replace them with their Python3 versions (3.9 installed here). This raises several questions. First, I had to remove, reinstall, and upgrade pip. The pip web page says it's compatible with python2 and 3 through 3.8. Does this mean it still does not support Python3.9? Second, pip installed itself in /usr/lib64/python2/site-packages/, not the python3.9/site-packages/ directory. There's not a pip3 so how do I get pip and all other python modules in the python3.9/site-packages/ directory? As an occasional coder (for my own business uses) I'm far from an advanced python user. TIA, Rich From barry at barrys-emacs.org Sat Dec 26 12:56:47 2020 From: barry at barrys-emacs.org (Barry Scott) Date: Sat, 26 Dec 2020 17:56:47 +0000 Subject: Installing python3 modules In-Reply-To: References: Message-ID: <8BBA95A7-0515-4F30-B6E2-C332B5499F0E@barrys-emacs.org> > On 26 Dec 2020, at 17:13, Rich Shepard wrote: > > Running Slackware-14.2/x86_64 here. I'm trying to learn if any installed > applications are still dependent on Python2 (version 2.7.17 installed) as > its EOL is this coming Thursday and I want to clean out all Python2 modules > and replace them with their Python3 versions (3.9 installed here). This > raises several questions. > > First, I had to remove, reinstall, and upgrade pip. The pip web page says > it's compatible with python2 and 3 through 3.8. Does this mean it still does > not support Python3.9? It works great with 3.9. which web psge did you see the claim on? Barry > > Second, pip installed itself in /usr/lib64/python2/site-packages/, not the > python3.9/site-packages/ directory. There's not a pip3 so how do I get pip > and all other python modules in the python3.9/site-packages/ directory? > > As an occasional coder (for my own business uses) I'm far from an advanced > python user. > > TIA, > > Rich > -- > https://mail.python.org/mailman/listinfo/python-list > From mats at wichmann.us Sat Dec 26 13:50:16 2020 From: mats at wichmann.us (Mats Wichmann) Date: Sat, 26 Dec 2020 11:50:16 -0700 Subject: Installing python3 modules In-Reply-To: References: Message-ID: <9ec67d43-e010-c858-0df7-a52926b6fa06@wichmann.us> On 12/26/20 10:13 AM, Rich Shepard wrote: > Running Slackware-14.2/x86_64 here. I'm trying to learn if any installed > applications are still dependent on Python2 (version 2.7.17 installed) as > its EOL is this coming Thursday and I want to clean out all Python2 modules > and replace them with their Python3 versions (3.9 installed here). This > raises several questions. > > First, I had to remove, reinstall, and upgrade pip. The pip web page says > it's compatible with python2 and 3 through 3.8. Does this mean it still > does > not support Python3.9? pip supports 3.9 fine, and is just about to lose support for 2.x entirely. > > Second, pip installed itself in /usr/lib64/python2/site-packages/, not the > python3.9/site-packages/ directory. There's not a pip3 so how do I get pip > and all other python modules in the python3.9/site-packages/ directory? this sounds like a Slack packaging issue, have you checked with appropriate forums_ From rshepard at appl-ecosys.com Sat Dec 26 14:29:30 2020 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Sat, 26 Dec 2020 11:29:30 -0800 (PST) Subject: Installing python3 modules In-Reply-To: <9ec67d43-e010-c858-0df7-a52926b6fa06@wichmann.us> References: <9ec67d43-e010-c858-0df7-a52926b6fa06@wichmann.us> Message-ID: On Sat, 26 Dec 2020, Mats Wichmann wrote: > pip supports 3.9 fine, and is just about to lose support for 2.x entirely. Mats, Yes, it does. > this sounds like a Slack packaging issue, have you checked with appropriate > forums_ It's apparently a local issue: my python3 packages ended up in /usr/lib/python2.7/site-packages/ rather than //usr/lib64/python3.9/site-packages/. I'm rebuilding all installed python3 packages. Stay well, Rich From sersadaka1 at outlook.com Sat Dec 26 07:03:40 2020 From: sersadaka1 at outlook.com (Sadaka Technology) Date: Sat, 26 Dec 2020 04:03:40 -0800 (PST) Subject: Pyrebase auth Message-ID: I am using signup method: user_signup = auth.create_user_with_email_and_password(email, password) and my firebase rules are: { "rules": { ".read": false, ".write": false, "$localId": { ".write": "auth.uid === $localId", ".read": "auth.uid === $localId" } } } I used: data = {"item1":"hat","item2":"car"} results = db.child("users").update(data, user['idToken']) the only way to patch (update) is to use: ".read": true, ".write": true, which means that anyone can read or write in my database where I only want the user to write or read if his idtoken or localid is authorized, even if data is outside his region for ex: database: "number_of_users":"2" "userlocalid": {"item1":"hat"} {"item2":"car"} From rshepard at appl-ecosys.com Sat Dec 26 13:33:54 2020 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Sat, 26 Dec 2020 10:33:54 -0800 (PST) Subject: Installing python3 modules In-Reply-To: <8BBA95A7-0515-4F30-B6E2-C332B5499F0E@barrys-emacs.org> References: <8BBA95A7-0515-4F30-B6E2-C332B5499F0E@barrys-emacs.org> Message-ID: On Sat, 26 Dec 2020, Barry Scott wrote: > It works great with 3.9. which web psge did you see the claim on? Barry, I don't recall which pip3 installation page it was. But I used 'python3 get-pip.py' and that worked. Stay well, Rich From tjreedy at udel.edu Sat Dec 26 13:51:02 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Sat, 26 Dec 2020 13:51:02 -0500 Subject: Installing python3 modules In-Reply-To: References: Message-ID: On 12/26/2020 12:13 PM, Rich Shepard wrote: > Running Slackware-14.2/x86_64 here. I'm trying to learn if any installed > applications are still dependent on Python2 (version 2.7.17 installed) as > its EOL is this coming Thursday and I want to clean out all Python2 modules > and replace them with their Python3 versions (3.9 installed here). This > raises several questions. > > First, I had to remove, reinstall, and upgrade pip. The pip web page says > it's compatible with python2 and 3 through 3.8. Does this mean it still > does > not support Python3.9? > > Second, pip installed itself in /usr/lib64/python2/site-packages/, not the > python3.9/site-packages/ directory. Pip is a python code run by a python interpreter. It installs itself in the site-packages of the python you use to run it. 'pythonx -m ensurepip' will make sure some pip is available for pythonx. 'pythonx -m pip' will then run the pythonx pip and manipulate the contents of its site-packages. > There's not a pip3 Separate 'pip' executables can be ambiguous as to which python they will invoke. Some people consider them a mistake. > so how do I get pip > and all other python modules in the python3.9/site-packages/ directory? See above. Run pip with python3.9, however that is spelled on a particular system. I don't know if all the modules you want have versions compatible with 3.9, but anything actively maintained should. The 3.8 versions of pure python modules will often run with 3.9 without change, even if not yet certified to do so by the authors. -- Terry Jan Reedy From rshepard at appl-ecosys.com Sat Dec 26 14:40:31 2020 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Sat, 26 Dec 2020 11:40:31 -0800 (PST) Subject: Installing python3 modules In-Reply-To: References: Message-ID: On Sat, 26 Dec 2020, Terry Reedy wrote: > Separate 'pip' executables can be ambiguous as to which python they will > invoke. Some people consider them a mistake. Terry, Until there's no more python2 it can remain confusing. I found part, if not all, of my problem. The SlackBuild scripts for multi-version python modules (such as Pygment) have install instructions for both python2 and python3, in that order. Since there's a python2 version installed the script installs Pygment (and others) there and not also in the python3 site-packages/ directory. >> so how do I get pip >> and all other python modules in the python3.9/site-packages/ directory? Fixed. Thanks, Rich From songbird at anthive.com Sat Dec 26 19:26:26 2020 From: songbird at anthive.com (songbird) Date: Sat, 26 Dec 2020 19:26:26 -0500 Subject: Debian testing and virtual environment error message Message-ID: Simlar to Rich's asking about how to deal with python3.9 I'm not able to to get my virtual environment set up to work now and I'm not sure how to go about fixing this. As it is testing I may have broken it somehow but I do not know how to fix this. I asked on the Debian user mailing list and nobody had any response/ideas. Note, this isn't a production system and I don't mind it being temporarily broken, but I also would like to know what is going on and how to fix this sort of thing. I do have python-is-python3 package installed and there are no python2 programs anywhere on this system that I know of. When i run the command: ===== $ cd /home/me/src/salsa $ python -m venv env setting up virtual environment /home/me/src/salsa/env The virtual environment was not created successfully because ensurepip is not available. On Debian/Ubuntu systems, you need to install the python3-venv package using the following command. apt-get install python3-venv You may need to use sudo with that command. After installing the python3-venv package, recreate your virtual environment. Failing command: ['/home/me/src/salsa/env/bin/python', '-Im', 'ensurepip', '--upgrade', '--default-pip'] ===== The package mentioned is installed: ===== $ dpkg -l | grep python3-venv ii python3-venv 3.9.0-4 amd64 pyvenv-3 binary for python3 (default python3 version) ===== Also the following looks interesting but I'm not sure why there is no 3.9 version available: ===== $ dpkg -l | grep python-is ii python-is-python3 3.8.6-3 all symlinks /usr/bin/python to python3 # su - entered password # apt-get install python-is-python3 -t unstable Reading package lists... Done Building dependency tree Reading state information... Done python-is-python3 is already the newest version (3.8.6-3). 0 upgraded, 0 newly installed, 0 to remove and 250 not upgraded. ===== any ideas? :) thanks! songbird From rosuav at gmail.com Sat Dec 26 20:58:33 2020 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 27 Dec 2020 12:58:33 +1100 Subject: Debian testing and virtual environment error message In-Reply-To: References: Message-ID: On Sun, Dec 27, 2020 at 11:31 AM songbird wrote: > > > Simlar to Rich's asking about how to deal with python3.9 > I'm not able to to get my virtual environment set up to work > now and I'm not sure how to go about fixing this. > > As it is testing I may have broken it somehow but I do not > know how to fix this. > > I asked on the Debian user mailing list and nobody had any > response/ideas. > > Note, this isn't a production system and I don't mind it > being temporarily broken, but I also would like to know what > is going on and how to fix this sort of thing. > > I do have python-is-python3 package installed and there are > no python2 programs anywhere on this system that I know of. > What does this say? $ which python ChrisA From songbird at anthive.com Sat Dec 26 21:16:30 2020 From: songbird at anthive.com (songbird) Date: Sat, 26 Dec 2020 21:16:30 -0500 Subject: Debian testing and virtual environment error message References: Message-ID: Chris Angelico wrote: ... > $ which python /usr/bin/python for both user and root looking at /usr/bin it looks like: lrwxrwxrwx 1 root root 7 Nov 3 03:20 python -> python3 lrwxrwxrwx 1 root root 9 Dec 6 05:36 python3 -> python3.9 -rwxr-xr-x 1 root root 5479736 Dec 8 02:51 python3.9 thanks, songbird From songbird at anthive.com Sat Dec 26 22:05:51 2020 From: songbird at anthive.com (songbird) Date: Sat, 26 Dec 2020 22:05:51 -0500 Subject: Debian testing and virtual environment error message References: Message-ID: songbird wrote: ... > The package mentioned is installed: > > >===== > > $ dpkg -l | grep python3-venv > ii python3-venv 3.9.0-4 amd64 pyvenv-3 binary for python3 (default python3 version) > here is something i missed including in my first post, but i don't know if this matters: ii python3.9-venv 3.9.1-1 amd64 Interactive high-level object-oriented language (pyvenv binary, version 3.9) songbird From songbird at anthive.com Sun Dec 27 10:54:30 2020 From: songbird at anthive.com (songbird) Date: Sun, 27 Dec 2020 10:54:30 -0500 Subject: Debian testing and virtual environment error message References: Message-ID: Chris Angelico wrote: ok, i got it to work. i noticed that there was a 3.8 version of distutils that was not upgraded to 3.9 so once i specifically pulled that in from the unstable Debian distribution then it upgraded and my creation of a new virtual environment would work without errors. so for some reason there are some python packages in unstable that had not get gotten to testing. thanks for replying. :) for the record this was what i did: apt-get install python3-distutils -t unstable Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: libpython3-all-dbg (3.9.1-1) libpython3-all-dev (3.9.1-1) libpython3-dbg (3.9.1-1) libpython3-dev (3.9.1-1) libpython3-stdlib (3.9.1-1) python3 (3.9.1-1) python3-all (3.9.1-1) python3-all-dbg (3.9.1-1) python3-all-dev (3.9.1-1) python3-dbg (3.9.1-1) python3-dev (3.9.1-1) python3-lib2to3 (3.9.1-1) python3-minimal (3.9.1-1) python3-venv (3.9.1-1) Suggested packages: python3-doc (3.9.1-1) python3-tk (3.9.1-1) The following packages will be upgraded: libpython3-all-dbg (3.9.0-4 => 3.9.1-1) libpython3-all-dev (3.9.0-4 => 3.9.1-1) libpython3-dbg (3.9.0-4 => 3.9.1-1) libpython3-dev (3.9.0-4 => 3.9.1-1) libpython3-stdlib (3.9.0-4 => 3.9.1-1) python3 (3.9.0-4 => 3.9.1-1) python3-all (3.9.0-4 => 3.9.1-1) python3-all-dbg (3.9.0-4 => 3.9.1-1) python3-all-dev (3.9.0-4 => 3.9.1-1) python3-dbg (3.9.0-4 => 3.9.1-1) python3-dev (3.9.0-4 => 3.9.1-1) python3-distutils (3.8.6-1 => 3.9.1-1) python3-lib2to3 (3.8.6-1 => 3.9.1-1) python3-minimal (3.9.0-4 => 3.9.1-1) python3-venv (3.9.0-4 => 3.9.1-1) 15 upgraded, 0 newly installed, 0 to remove and 222 not upgraded. songbird From rosuav at gmail.com Sun Dec 27 11:04:02 2020 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 28 Dec 2020 03:04:02 +1100 Subject: Debian testing and virtual environment error message In-Reply-To: References: Message-ID: On Mon, Dec 28, 2020 at 2:56 AM songbird wrote: > > Chris Angelico wrote: > > ok, i got it to work. i noticed that there was a 3.8 > version of distutils that was not upgraded to 3.9 so once > i specifically pulled that in from the unstable Debian > distribution then it upgraded and my creation of a new > virtual environment would work without errors. > Ah, yep, that makes sense. I was a tad concerned about the mismatch of versions, but honestly, I don't think I've ever installed Python from testing or unstable (unless I'm running the entire distro on testing). It's much much easier and safer to keep the system Python untouched, and then build my own from source; my "python3" command, at the moment, runs 3.10 pre-alpha. ChrisA From songbird at anthive.com Sun Dec 27 12:11:13 2020 From: songbird at anthive.com (songbird) Date: Sun, 27 Dec 2020 12:11:13 -0500 Subject: Debian testing and virtual environment error message References: Message-ID: Chris Angelico wrote: > On Mon, Dec 28, 2020 at 2:56 AM songbird wrote: ...needed to pull a few more things from unstable... > Ah, yep, that makes sense. I was a tad concerned about the mismatch of > versions, but honestly, I don't think I've ever installed Python from > testing or unstable (unless I'm running the entire distro on testing). > It's much much easier and safer to keep the system Python untouched, > and then build my own from source; my "python3" command, at the > moment, runs 3.10 pre-alpha. it seems that if there is a dependency between these than it should have be declared so they won't migrate to testing independently. i'm not sure it is worth filing a bug about since the transition is not completed yet anyways. i run testing on my day to day system because i do want to find bugs before they make it to stable, especially for the things i use every day. i'm not using the testing distribution for hard production tasks so if it breaks and i do need to get on-line i have a few other different bootable partitions or even a USB stick just in case. songbird From christian at python.org Sun Dec 27 16:45:20 2020 From: christian at python.org (Christian Heimes) Date: Sun, 27 Dec 2020 22:45:20 +0100 Subject: Debian testing and virtual environment error message In-Reply-To: References: Message-ID: On 27/12/2020 04.05, songbird wrote: > songbird wrote: > ... >> The package mentioned is installed: >> >> >> ===== >> >> $ dpkg -l | grep python3-venv >> ii python3-venv 3.9.0-4 amd64 pyvenv-3 binary for python3 (default python3 version) >> > > here is something i missed including in my first post, but i don't > know if this matters: > > ii python3.9-venv 3.9.1-1 amd64 Interactive high-level object-oriented language (pyvenv binary, version 3.9) Don't worry, you are not the first person that ran into this issue. Debian's packaging of Python has caused multiple issues. I have reported some issues to downstream Debian/Ubuntu. You can find a list of all known issues at https://gist.github.com/tiran/2dec9e03c6f901814f6d1e8dad09528e Christian From sersadaka1 at outlook.com Mon Dec 28 06:43:43 2020 From: sersadaka1 at outlook.com (Sadaka Technology) Date: Mon, 28 Dec 2020 03:43:43 -0800 (PST) Subject: kivy,,, assigning global variable Message-ID: class main(..): def init.....: super..... button = Button(on_release=self.on_click) def on_click(self,screen,*args) self.clear_widgets() if screen == '2nd': float = 2nd() elif screen == '1st': float = 1st() self.add_widget(float) class 2nd(...): string_text = StringProperty() def init.....: super..... Text = TextInput(text=self.string_text) button=Button(on_release=self.on_click) def on_click self.parent.on_click('1st') class 1st(...): ............ #my only issue is in class 2nd() how can I change the value of the variable string_text, if I am clearing widgets and adding widget again in parent class ( main()), then string_text will again equal to empty , I tried to add string_text variable in main() but the same issue I am getting, how can I save the string_text in 2nd() if am removing it and adding it again ? From Bischoop at vimart.net Mon Dec 28 11:31:33 2020 From: Bischoop at vimart.net (Bischoop) Date: Mon, 28 Dec 2020 16:31:33 -0000 (UTC) Subject: Which method to check if string index is queal to character. Message-ID: I'd like to check if there's "@" in a string and wondering if any method is better/safer than others. I was told on one occasion that I should use is than ==, so how would be on this example. s = 'this at mail.is' I want check if string is a valid email address. code ''' import time email = "ten at mail.tu" start_time = time.time() for i in range(len(email)): print('@' in email[i]) print ("My program took", time.time() - start_time, "to run") print('----------') start_time = time.time() for i in range(len(email)): print(email[i] == '@') print ("My program took", time.time() - start_time, "to run") print('----------') start_time = time.time() if '@' in email: print('True') print ("My program took", time.time() - start_time, "to run") ''' From Marco.Sulla.Python at gmail.com Mon Dec 28 12:46:19 2020 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Mon, 28 Dec 2020 18:46:19 +0100 Subject: Which method to check if string index is queal to character. In-Reply-To: References: Message-ID: On Mon, 28 Dec 2020 at 17:37, Bischoop wrote: > > I'd like to check if there's "@" in a string and wondering if any method > is better/safer than others. I was told on one occasion that I should > use is than ==, so how would be on this example. > > s = 'this at mail.is' You could do simply if "@" in s: but probably what you really want is a regular expression. From python at mrabarnett.plus.com Mon Dec 28 13:32:00 2020 From: python at mrabarnett.plus.com (MRAB) Date: Mon, 28 Dec 2020 18:32:00 +0000 Subject: Which method to check if string index is queal to character. In-Reply-To: References: Message-ID: <425e7ddc-615d-786e-f516-5c4848c86621@mrabarnett.plus.com> On 2020-12-28 16:31, Bischoop wrote: > I'd like to check if there's "@" in a string and wondering if any method > is better/safer than others. I was told on one occasion that I should > use is than ==, so how would be on this example. > [snip] The shortest and quickest way to check whether "@" is in my_string is: "@" in my_string From Bischoop at vimart.net Mon Dec 28 12:37:36 2020 From: Bischoop at vimart.net (Bischoop) Date: Mon, 28 Dec 2020 17:37:36 -0000 (UTC) Subject: Which method to check if string index is queal to character. References: Message-ID: On 2020-12-28, Stefan Ram wrote: > > "@" in s > That's what I thought. >>I want check if string is a valid email address. > > I suggest to first try and define "valid email address" in English. > > A valid email address consists of an email prefix and an email domain, both in acceptable formats. The prefix appears to the left of the @ symbol. The domain appears to the right of the @ symbol. For example, in the address example at mail.com, "example" is the email prefix, and "mail.com" is the email domain. -- Thanks From tjreedy at udel.edu Mon Dec 28 12:43:27 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Mon, 28 Dec 2020 12:43:27 -0500 Subject: Which method to check if string index is queal to character. In-Reply-To: References: Message-ID: On 12/28/2020 11:31 AM, Bischoop wrote: > I'd like to check if there's "@" in a string Use the obvious "'@' in string". > and wondering if any method is better/safer than others. Any special purpose method built into the language is likely to be fastest. Safest? What danger are you worried about? > I was told on one occasion that I should > use is than ==, so how would be on this example. 'is' is for detecting an exact match with a particular, singular object. In particular, None, False, or True or user created objects meant for such use. > s = 'this at mail.is' > I want check if string is a valid email address. There are two levels of validity: has the form of an address, which is much more complicated than the presence of an '@', and corresponds to a real email account. > > code ''' > import time > > email = "ten at mail.tu" > > start_time = time.time() > for i in range(len(email)): > print('@' in email[i]) This scans the entire string in a slow way, then indirectly performs '@' == char in a slow way. > print ("My program took", time.time() - start_time, "to run") > > > print('----------') > start_time = time.time() > for i in range(len(email)): > print(email[i] == '@') Slightly better, does comparison directly. for c in email: print(c == '@') Faster and better way to scan. for c in email: print(c == '@') break Stops at first '@'. '@' in email does the same, but should be slightly faster as it implements loop and break in the interpreter's implementation language. > print ("My program took", time.time() - start_time, "to run") > print('----------') > start_time = time.time() > if '@' in email: > print('True') > > print ("My program took", time.time() - start_time, "to run") > > ''' > -- Terry Jan Reedy From rosuav at gmail.com Mon Dec 28 14:23:31 2020 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 29 Dec 2020 06:23:31 +1100 Subject: Which method to check if string index is queal to character. In-Reply-To: References: Message-ID: On Tue, Dec 29, 2020 at 6:18 AM Bischoop wrote: > > On 2020-12-28, Stefan Ram wrote: > > > > "@" in s > > > > That's what I thought. > > >>I want check if string is a valid email address. > > > > I suggest to first try and define "valid email address" in English. > > > > > > A valid email address consists of an email prefix and an email domain, > both in acceptable formats. The prefix appears to the left of the @ symbol. > The domain appears to the right of the @ symbol. > For example, in the address example at mail.com, "example" is the email prefix, > and "mail.com" is the email domain. > To see if it's a valid email address, send email to it and get the person to verify receipt. Beyond that, all you can really check is that it has an at sign in it (since a local address isn't usually useful in contexts where you'd want to check). So the check you are already looking at is sufficient. ChrisA From mats at wichmann.us Mon Dec 28 15:08:22 2020 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 28 Dec 2020 13:08:22 -0700 Subject: Which method to check if string index is queal to character. In-Reply-To: References: Message-ID: On 12/28/20 10:46 AM, Marco Sulla wrote: > On Mon, 28 Dec 2020 at 17:37, Bischoop wrote: >> >> I'd like to check if there's "@" in a string and wondering if any method >> is better/safer than others. I was told on one occasion that I should >> use is than ==, so how would be on this example. >> >> s = 'this at mail.is' > > You could do simply > > if "@" in s: > > but probably what you really want is a regular expression. > Will add that Yes, you should always validate your inputs, but No, the presence of an @ sign in a text string is not sufficient to know it's a valid email address. Unfortunately validating that is hard. From Richard at Damon-Family.org Mon Dec 28 15:27:41 2020 From: Richard at Damon-Family.org (Richard Damon) Date: Mon, 28 Dec 2020 15:27:41 -0500 Subject: Which method to check if string index is queal to character. In-Reply-To: References: Message-ID: On 12/28/20 3:08 PM, Mats Wichmann wrote: > On 12/28/20 10:46 AM, Marco Sulla wrote: >> On Mon, 28 Dec 2020 at 17:37, Bischoop wrote: >>> >>> I'd like to check if there's "@" in a string and wondering if any >>> method >>> is better/safer than others. I was told on one occasion that I should >>> use is than ==, so how would be on this example. >>> >>> s = 'this at mail.is' >> >> You could do simply >> >> if "@" in s: >> >> but probably what you really want is a regular expression. >> > > Will add that Yes, you should always validate your inputs, but No, the > presence of an @ sign in a text string is not sufficient to know it's > a valid email address. Unfortunately validating that is hard. > Validating that it meets the SYNTAX of an email address isn't THAT hard, but there are a number of edge cases to worry about. Validating that it is a working email address (presumably after verifying that it has a proper syntax) is much harder, and basically requires trying to send to the address, and to really confirm that it is good requires them to do something actively with a message you send them. And then nothing says the address will continue to be valid. -- Richard Damon From torriem at gmail.com Mon Dec 28 16:52:03 2020 From: torriem at gmail.com (Michael Torrie) Date: Mon, 28 Dec 2020 14:52:03 -0700 Subject: Which method to check if string index is queal to character. In-Reply-To: References: Message-ID: On 12/28/20 10:37 AM, Bischoop wrote: > A valid email address consists of an email prefix and an email domain, > both in acceptable formats. The prefix appears to the left of the @ symbol. > The domain appears to the right of the @ symbol. > For example, in the address example at mail.com, "example" is the email prefix, > and "mail.com" is the email domain. Seems so simple, yet at least half the web sites I try to use get it wrong. There's an entire RFC on this topic. Drives me crazy when a web site insists that myaddress+suffix at domain.com is not a valid address. It certainly is! From torriem at gmail.com Mon Dec 28 16:55:59 2020 From: torriem at gmail.com (Michael Torrie) Date: Mon, 28 Dec 2020 14:55:59 -0700 Subject: Which method to check if string index is queal to character. In-Reply-To: References: Message-ID: <87a6a88f-398b-34ed-b614-766381cb720a@gmail.com> On 12/28/20 10:46 AM, Marco Sulla wrote: > On Mon, 28 Dec 2020 at 17:37, Bischoop wrote: >> >> I'd like to check if there's "@" in a string and wondering if any method >> is better/safer than others. I was told on one occasion that I should >> use is than ==, so how would be on this example. >> >> s = 'this at mail.is' > > You could do simply > > if "@" in s: > > but probably what you really want is a regular expression. https://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx/ From PythonList at DancesWithMice.info Mon Dec 28 16:56:01 2020 From: PythonList at DancesWithMice.info (dn) Date: Tue, 29 Dec 2020 10:56:01 +1300 Subject: Which method to check if string index is queal to character. In-Reply-To: References: Message-ID: On 29/12/2020 09:27, Richard Damon wrote: > On 12/28/20 3:08 PM, Mats Wichmann wrote: >> On 12/28/20 10:46 AM, Marco Sulla wrote: >>> On Mon, 28 Dec 2020 at 17:37, Bischoop wrote: ... >>> but probably what you really want is a regular expression. because... >> Will add that Yes, you should always validate your inputs, but No, the >> presence of an @ sign in a text string is not sufficient to know it's >> a valid email address. Unfortunately validating that is hard. > Validating that it meets the SYNTAX of an email address isn't THAT hard, > but there are a number of edge cases to worry about. > > Validating that it is a working email address (presumably after > verifying that it has a proper syntax) is much harder, and basically > requires trying to send to the address, and to really confirm that it is > good requires them to do something actively with a message you send > them. And then nothing says the address will continue to be valid. (am assuming the in/is question has been answered) Looking at my email server log, I see messages addressed to "fd0d8f761aab at danceswithmice.info" - which have been rejected. That spurious-address features an "@". It is a perfectly-formed email address. The domain-name is correct - and can be quickly verified as in-existence. However the account-name is a total fabrication. (is someone trying to put a 'hex' on me?) Accordingly, the advice that the only way to check if an email address is 'correct', is to see if it is accepted by the receiving-server. However, you can't (shouldn't be able to!) pierce that veil, to be able to prove/see for yourself! That is why many subscription-systems send an initial email message and ask the receiver to confirm receipt by 'clicking on the link provided'! Per previous RegEx discussions 'here': there are plenty of examples/attempts floating around the Internet. Absolutely none of which comes with a guarantee! To quote the famous con-man/men/women: if you believe any such stories, come and see me about buying into the Brooklyn Bridge/some agricultural (marsh) land/the next best thing... For many years, many of the RegEx-s circulating were so precise that they only recognised the original TLDs such as .com and .org. For years after .info was introduced, sites would tell me that my email address was 'illegal'. Leaving me to ask: do I really exist?, am I but part of some imaginary universe? (no comments about my Hobbit-feet, please!) After such disparagement it is worth remembering that there are checks and there are checks! It depends upon the purpose of the check, or the level-of-detail/accuracy desired! When accepting user-data it *is* worth (even "necessary") performing a 'sanity-check'. Per @Chris, if the user doesn't enter two 'words' separated by an @-sign, and the second 'word' doesn't include at least one dot/period/stop, then it seems quite probable that our user has made a typo! This is why some sites require an email address to be entered twice. (but copy-paste anyone?) Going much further than a typo-reducing/sanity-check is, per @Richard, considerably harder - and ultimately cannot guarantee an address. Thus, indulges in a sub-field of cyber-alchemy! -- Regards =dn From cs at cskk.id.au Mon Dec 28 17:02:12 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Tue, 29 Dec 2020 09:02:12 +1100 Subject: Which method to check if string index is queal to character. In-Reply-To: References: Message-ID: On 28Dec2020 13:08, Mats Wichmann wrote: >On 12/28/20 10:46 AM, Marco Sulla wrote: >>On Mon, 28 Dec 2020 at 17:37, Bischoop wrote: >>>I'd like to check if there's "@" in a string and wondering if any >>>method is better/safer than others. Others have pointed out: '@' in s >Will add that Yes, you should always validate your inputs, but No, the >presence of an @ sign in a text string is not sufficient to know it's a >valid email address. Unfortunately validating that is hard. Validating that it is a functional email address is hard, involves delivering email and then finding out if it was delivered. A proper syntax check requires parsing an RFC5322 address grammar: https://tools.ietf.org/rfcmarkup/5322#section-3.4 Fortunately, Python ships with one of those in the email.utils module. The parseaddr() function will parse a single address, and getaddresses() will parse a list of addresses such as might be in a To: header line. They work well - I've been filing my email based on these for years - MANY thousands of messages. Cheers, Cameron Simpson From rosuav at gmail.com Mon Dec 28 17:05:43 2020 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 29 Dec 2020 09:05:43 +1100 Subject: Which method to check if string index is queal to character. In-Reply-To: References: Message-ID: On Tue, Dec 29, 2020 at 8:57 AM dn via Python-list wrote: > After such disparagement it is worth remembering that there are checks > and there are checks! It depends upon the purpose of the check, or the > level-of-detail/accuracy desired! > > When accepting user-data it *is* worth (even "necessary") performing a > 'sanity-check'. Per @Chris, if the user doesn't enter two 'words' > separated by an @-sign, and the second 'word' doesn't include at least > one dot/period/stop, then it seems quite probable that our user has made > a typo! This is why some sites require an email address to be entered > twice. (but copy-paste anyone?) I wouldn't even ask for a dot in the second half, actually. Yes, it's uncommon to have no dot, but it's fully legal, and not worth wrestling with. Considering the vast number of typos that *wouldn't* trip a filter, and the relatively small number that would, it's generally not worth putting too much validation in. Checking for the presence of "@" is a good way to check that it's an email address and not, say, the URL of someone's webmail service, but other than that, there's really not a lot that's worth checking. OTOH, if you're trying to recognize email addresses in plain text (say, in chat messages) so that you can autolink them, that's completely different. Same with URLs (eg https://example.com/foo) - you, as a human, can see that the URL should have ended at the "/foo", but technically "/foo)" is perfectly legal. So if you're validating, "/foo)" should be permitted, but if you're detecting, it should stop at "/foo". ChrisA From Richard at Damon-Family.org Mon Dec 28 17:59:21 2020 From: Richard at Damon-Family.org (Richard Damon) Date: Mon, 28 Dec 2020 17:59:21 -0500 Subject: Which method to check if string index is queal to character. In-Reply-To: References: Message-ID: On 12/28/20 4:52 PM, Michael Torrie wrote: > On 12/28/20 10:37 AM, Bischoop wrote: >> A valid email address consists of an email prefix and an email domain, >> both in acceptable formats. The prefix appears to the left of the @ symbol. >> The domain appears to the right of the @ symbol. >> For example, in the address example at mail.com, "example" is the email prefix, >> and "mail.com" is the email domain. > Seems so simple, yet at least half the web sites I try to use get it > wrong. There's an entire RFC on this topic. Drives me crazy when a web > site insists that myaddress+suffix at domain.com is not a valid address. > It certainly is! Yes, it really is fairly straight forward to do it right, but it does have details that need to be checked carefully (It is significantly harder if the email address can also contain comments or display names, but just a base email address isn't that hard). Many people do still get it wrong. -- Richard Damon From grant.b.edwards at gmail.com Mon Dec 28 16:49:03 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 28 Dec 2020 21:49:03 -0000 (UTC) Subject: Which method to check if string index is queal to character. References: Message-ID: On 2020-12-28, Bischoop wrote: > On 2020-12-28, Stefan Ram wrote: >> >> "@" in s >> > > That's what I thought. > >>>I want check if string is a valid email address. >> >> I suggest to first try and define "valid email address" in English. > > A valid email address consists of an email prefix and an email domain, > both in acceptable formats. Well, that's assuming that bang routing/addresses aren't allowed. :) -- Grant From torriem at gmail.com Mon Dec 28 16:54:14 2020 From: torriem at gmail.com (Michael Torrie) Date: Mon, 28 Dec 2020 14:54:14 -0700 Subject: Which method to check if string index is queal to character. In-Reply-To: References: Message-ID: <3f2d0d98-e638-fee5-a957-606dae023b05@gmail.com> On 12/28/20 1:27 PM, Richard Damon wrote: > Validating that it meets the SYNTAX of an email address isn't THAT hard, > but there are a number of edge cases to worry about. Yes one would think that, but in my experience half of all web sites get it wrong, insisting that my perfectly valid and RFC-compliant email address is not a proper email address. From avigross at verizon.net Mon Dec 28 18:01:03 2020 From: avigross at verizon.net (Avi Gross) Date: Mon, 28 Dec 2020 18:01:03 -0500 Subject: Which method to check if string index is queal to character. In-Reply-To: References: Message-ID: <045e01d6dd6d$517f4f80$f47dee80$@verizon.net> This may be a nit, but can we agree all valid email addresses as used today have more than an @ symbol? I see it as requiring at least one character before the @ that come from a list of allowed characters (perhaps not ASCII) but does not include the symbol @ again. It is normally followed by some minimal number of characters and maybe a period and one of the currently valid domains like .com or .it but the latter gets tricky as it can look like user at abd.def.att.com or other long variations where only the final component must be testable in the program. The lack of an at-sign suggests it is not an email address. The lack of anything before or after also seems to disqualify it. You may be able to add more conditions but as noted, having more than one at-sign may also disqualify it. I am sure someone has some complex regular expressions that they think matches only potentially valid strings but, of course, as noted by Chris, to really validate that an address works might require sending something and validating a human replied and that can be quite task. -----Original Message----- From: Python-list On Behalf Of Chris Angelico Sent: Monday, December 28, 2020 2:24 PM To: Python Subject: Re: Which method to check if string index is queal to character. On Tue, Dec 29, 2020 at 6:18 AM Bischoop wrote: > > On 2020-12-28, Stefan Ram wrote: > > > > "@" in s > > > > That's what I thought. > > >>I want check if string is a valid email address. > > > > I suggest to first try and define "valid email address" in English. > > > > > > A valid email address consists of an email prefix and an email domain, > both in acceptable formats. The prefix appears to the left of the @ symbol. > The domain appears to the right of the @ symbol. > For example, in the address example at mail.com, "example" is the email > prefix, and "mail.com" is the email domain. > To see if it's a valid email address, send email to it and get the person to verify receipt. Beyond that, all you can really check is that it has an at sign in it (since a local address isn't usually useful in contexts where you'd want to check). So the check you are already looking at is sufficient. ChrisA -- https://mail.python.org/mailman/listinfo/python-list From rosuav at gmail.com Mon Dec 28 20:02:04 2020 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 29 Dec 2020 12:02:04 +1100 Subject: Which method to check if string index is queal to character. In-Reply-To: <045e01d6dd6d$517f4f80$f47dee80$@verizon.net> References: <045e01d6dd6d$517f4f80$f47dee80$@verizon.net> Message-ID: On Tue, Dec 29, 2020 at 10:08 AM Avi Gross via Python-list wrote: > > This may be a nit, but can we agree all valid email addresses as used today > have more than an @ symbol? > > I see it as requiring at least one character before the @ that come from a > list of allowed characters (perhaps not ASCII) but does not include the > symbol @ again. It is normally followed by some minimal number of characters > and maybe a period and one of the currently valid domains like .com or .it > but the latter gets tricky as it can look like user at abd.def.att.com or other > long variations where only the final component must be testable in the > program. There can be an @ in the first part of the address, and the domain may well not have a dot. > The lack of an at-sign suggests it is not an email address. The lack of > anything before or after also seems to disqualify it. You may be able to add > more conditions but as noted, having more than one at-sign may also > disqualify it. Lack of an at sign means it's a local address that can't be routed over the internet, and in many contexts, it's reasonable to exclude those. But two isn't illegal. > I am sure someone has some complex regular expressions that they think > matches only potentially valid strings but, of course, as noted by Chris, to > really validate that an address works might require sending something and > validating a human replied and that can be quite task. > Yes, many such regexes exist, and they are *all wrong*. Without exception. I don't think it's actually possible for a regex to perfectly match all (syntactically) valid email addresses and nothing else. ChrisA From avigross at verizon.net Mon Dec 28 20:37:42 2020 From: avigross at verizon.net (Avi Gross) Date: Mon, 28 Dec 2020 20:37:42 -0500 Subject: Which method to check if string index is queal to character. In-Reply-To: References: <045e01d6dd6d$517f4f80$f47dee80$@verizon.net> Message-ID: <063501d6dd83$33b48090$9b1d81b0$@verizon.net> Thanks, Chris, I am not actually up-to-date on such messaging issues but not shocked at what you wrote. Years ago I recall most messages going out of my workplace looked like machine!machine2!ihnp4!more!evenmore!user with no @ in sight and as you mention, you may want to send to a domain and have it send to a subdomain so a multiple @ may make sense and so on. I note we have some places like groups.io that disguise the @ in your original email address so you can still see who it is from, even though it is in some sense from them but to actually use the email address in your own mailer, you need to substitute it back in. I think we all agree that unless there is further standardization, an email address can easily be rejected that is otherwise usable in some context and that one in proper format (by some definition) will fail in that context. The original question actually focused more narrowly on a good way to find if a character existed in a string for which regular expressions need not apply and most email addresses re short enough that techniques to speed up the search may not be useful unless all the program does is search millions of email addresses for the presence. Dropping out, ... -----Original Message----- From: Python-list On Behalf Of Chris Angelico Sent: Monday, December 28, 2020 8:02 PM To: Python Subject: Re: Which method to check if string index is queal to character. On Tue, Dec 29, 2020 at 10:08 AM Avi Gross via Python-list wrote: > > This may be a nit, but can we agree all valid email addresses as used > today have more than an @ symbol? > > I see it as requiring at least one character before the @ that come > from a list of allowed characters (perhaps not ASCII) but does not > include the symbol @ again. It is normally followed by some minimal > number of characters and maybe a period and one of the currently > valid domains like .com or .it but the latter gets tricky as it can > look like user at abd.def.att.com or other long variations where only the > final component must be testable in the program. There can be an @ in the first part of the address, and the domain may well not have a dot. > The lack of an at-sign suggests it is not an email address. The lack > of anything before or after also seems to disqualify it. You may be > able to add more conditions but as noted, having more than one at-sign > may also disqualify it. Lack of an at sign means it's a local address that can't be routed over the internet, and in many contexts, it's reasonable to exclude those. But two isn't illegal. > I am sure someone has some complex regular expressions that they think > matches only potentially valid strings but, of course, as noted by > Chris, to really validate that an address works might require sending > something and validating a human replied and that can be quite task. > Yes, many such regexes exist, and they are *all wrong*. Without exception. I don't think it's actually possible for a regex to perfectly match all (syntactically) valid email addresses and nothing else. ChrisA -- https://mail.python.org/mailman/listinfo/python-list From Bischoop at vimart.net Mon Dec 28 20:48:16 2020 From: Bischoop at vimart.net (Bischoop) Date: Tue, 29 Dec 2020 01:48:16 -0000 (UTC) Subject: Which method to check if string index is queal to character. References: Message-ID: On 2020-12-28, Mats Wichmann wrote: > On 12/28/20 10:46 AM, Marco Sulla wrote: >> On Mon, 28 Dec 2020 at 17:37, Bischoop wrote: >>> >>> I'd like to check if there's "@" in a string and wondering if any method >>> is better/safer than others. I was told on one occasion that I should >>> use is than ==, so how would be on this example. >>> >>> s = 'this at mail.is' >> >> You could do simply >> >> if "@" in s: >> >> but probably what you really want is a regular expression. >> > > Will add that Yes, you should always validate your inputs, but No, the > presence of an @ sign in a text string is not sufficient to know it's a > valid email address. Unfortunately validating that is hard. > Nah, by saying if is valid I meant exeactly if there's "@", I could add yet if endswith() but at this point @ is enough. Yes the only possible way for full validation would be just sending email and waiting for reply. From Richard at Damon-Family.org Mon Dec 28 21:01:42 2020 From: Richard at Damon-Family.org (Richard Damon) Date: Mon, 28 Dec 2020 21:01:42 -0500 Subject: Which method to check if string index is queal to character. In-Reply-To: References: <045e01d6dd6d$517f4f80$f47dee80$@verizon.net> Message-ID: <1eb5b91f-e713-374f-4349-b99dd1b29d82@Damon-Family.org> On 12/28/20 8:02 PM, Chris Angelico wrote: > > Yes, many such regexes exist, and they are *all wrong*. Without > exception. I don't think it's actually possible for a regex to > perfectly match all (syntactically) valid email addresses and nothing > else. > > ChrisA Since Email addresses are allowed to have (comments) in them, and comments are allowed to nest, I think it takes something stronger than a regex to fully process them, but takes something that can handle a recursive grammar. I think that is the only thing that absolutely prevents using a regex (but not sure about it) but some of the rules will make things messy and need to use alternation and repetition. The one other thing that might block a regex is I think there is an upper limits to how long the address (or its parts) are allowed to be, and testing that at the same time as the other patterns is probably beyond what a regex could handle. -- Richard Damon From Bischoop at vimart.net Mon Dec 28 20:51:29 2020 From: Bischoop at vimart.net (Bischoop) Date: Tue, 29 Dec 2020 01:51:29 -0000 (UTC) Subject: Which method to check if string index is queal to character. References: <87a6a88f-398b-34ed-b614-766381cb720a@gmail.com> Message-ID: On 2020-12-28, Michael Torrie wrote: > On 12/28/20 10:46 AM, Marco Sulla wrote: >> On Mon, 28 Dec 2020 at 17:37, Bischoop wrote: >>> >>> I'd like to check if there's "@" in a string and wondering if any method >>> is better/safer than others. I was told on one occasion that I should >>> use is than ==, so how would be on this example. >>> >>> s = 'this at mail.is' >> >> You could do simply >> >> if "@" in s: >> >> but probably what you really want is a regular expression. > > https://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx/ > Interested article. -- Thanks From jcasale at activenetwerx.com Mon Dec 28 21:56:16 2020 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Tue, 29 Dec 2020 02:56:16 +0000 Subject: asyncio cancellation pattern Message-ID: <6e17b6d6d5e7482bbd84de8ecec2c31b@activenetwerx.com> I've started writing some asyncio code in lieu of using threads and managing concurrency and primitives manually. Having spent a lot of time using c#'s async implementation, I am struggling to see an elegant pattern for implementing cancellation. With the necessity for the loop (that of which I understand) and the disconnect between context and tasks, how does one act on a failure within a task and invoke cancellation upwards. Collecting all tasks and cancelling everything is not appropriate, they may not necessarily all be part of the graph that needs cancelling. In c#, we have several patterns available using a cancellation token source and either passing the token (event only) into the task, or the token source into the task execution context for signaling during a failure. Does an easier way then manually creating tasks from coroutines and tracking them explicitly exist? Thanks, jlc From nospam at please.ty Tue Dec 29 04:53:01 2020 From: nospam at please.ty (jak) Date: Tue, 29 Dec 2020 10:53:01 +0100 Subject: Which method to check if string index is queal to character. References: Message-ID: Il 29/12/2020 02:48, Bischoop ha scritto: > On 2020-12-28, Mats Wichmann wrote: >> On 12/28/20 10:46 AM, Marco Sulla wrote: >>> On Mon, 28 Dec 2020 at 17:37, Bischoop wrote: >>>> >>>> I'd like to check if there's "@" in a string and wondering if any method >>>> is better/safer than others. I was told on one occasion that I should >>>> use is than ==, so how would be on this example. >>>> >>>> s = 'this at mail.is' >>> >>> You could do simply >>> >>> if "@" in s: >>> >>> but probably what you really want is a regular expression. >>> >> >> Will add that Yes, you should always validate your inputs, but No, the >> presence of an @ sign in a text string is not sufficient to know it's a >> valid email address. Unfortunately validating that is hard. >> > > Nah, by saying if is valid I meant exeactly if there's "@", I could add > yet if endswith() but at this point @ is enough. > Yes the only possible way for full validation would be just sending > email and waiting for reply. > you could try this way: # ----------- from dns import resolver as dns emails=['john.doe at fakeserver.bah', 'john.doe at gmail.com'] for ue in emails: try: mxl = dns.resolve(ue.split('@')[1], 'MX') except: print(f'{ue}: bad mail server') else: if len(mxl) > 0: print(f'{ue}: valid mail server') # ----------- ... so, having verified the sever, you should only worry about the name. From sapna.intell at gmail.com Tue Dec 29 05:52:15 2020 From: sapna.intell at gmail.com (Priya Singh) Date: Tue, 29 Dec 2020 02:52:15 -0800 (PST) Subject: 2 sample chi-square test Message-ID: <4601f428-a77a-4105-8f14-0aea561e0f4fn@googlegroups.com> Hi all, I have two spectra with wavelength, flux, and error on flux. I want to find out the variability of these two spectra based on the 2 sample Chi-square test. I am using following code: def compute_chi2_var(file1,file2,zemi,vmin,vmax): w1,f1,e1,c1,vel1 = get_spec_vel(dir_data+file1,zemi) id1 = np.where(np.logical_and(vel1 >= vmin, vel1 < vmax))[0] w2,f2,e2,c2,vel2 = get_spec_vel(dir_data+file2,zemi) id2 = np.where(np.logical_and(vel2 >= vmin, vel2 < vmax))[0] f_int = interp1d(w1[id1], f1[id1]/c1[id1], kind='cubic') e_int = interp1d(w1[id1], e1[id1]/c1[id1], kind='cubic') f_obs,e_obs = f_int(w2[id2]), e_int(w2[id2]) f_exp, e_exp = f2[id2]/c2[id2], e2[id2]/c2[id2] e_net = e_obs**2 + e_exp**2 chi_square = np.sum( (f_obs**2 - f_exp**2)/e_net ) dof = len(f_obs) - 1 pval = 1 - stats.chi2.cdf( chi_square, dof) print('%.10E' % pval) NN = 320 compute_chi2_var(file7[NN],file14[NN],zemi[NN],vmin[NN],vmax[NN]) I am running this code on many files, and I want to grab those pair of spectra where, the p-value of chi-squa is less than 10^(-8), for the change to be unlikely due to a random occurrence. Is my code right concept-wise? Because the chi-squ value is coming out to be very large (positive and negative), such that my p-value is always between 1 and 0 which I know from other's results not correct. Can anyone suggest me is the concept of 2-sample chi-squ applied by me is correct or not? I thank you all in advance. From nikhilclt87 at gmail.com Tue Dec 29 08:38:53 2020 From: nikhilclt87 at gmail.com (nikhil k) Date: Tue, 29 Dec 2020 05:38:53 -0800 (PST) Subject: How to copy the entire outlook message content in python Message-ID: Hello All, I'm a beginner trying to achieve the below in my python script: Can anyone help me on this? I'm stuck at step2. 1. Input: A locally saved outlook mail (*.msg) path 2. Go to the path and Copy the entire body of the mail 3. Create a new mail and paste the contents into new mail 4. send it manually # ======================================================== # ======================= Script Start ====================== # ======================================================== import win32com.client as win32 ########### Functions def getMailBody(msgFile): start_text = "" end_text = "" with open(msgFile) as f: data=f.read() return data[data.find(start_text):data.find(end_text)+len(end_text)] def releaseMail(body, subject, recipient): outlook = win32.Dispatch('outlook.application') mail = outlook.CreateItem(0) mail.To = recipient mail.Subject = subject mail.HtmlBody = body mail.Display(True) ############### Main ################ msgFile = "C:\\RELM\\testMsg.msg" mailTo = "mymail at myserver.com" mailSubject = "Test message" mailBody = getMailBody(msgFile) releaseMail(mailBody, mailSubject, mailRecipient) # ======================================================== # ======================== Script End ======================= # ======================================================== Below is the error I'm getting. ============================================== File "C:\Python\Python38-32\lib\encodings\cp1252.py", line 23, in decode return codecs.charmap_decode(input,self.errors,decoding_table)[0] UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 924: character maps to From cl at isbd.net Tue Dec 29 09:03:00 2020 From: cl at isbd.net (Chris Green) Date: Tue, 29 Dec 2020 14:03:00 +0000 Subject: How to uninstall python 2 package specifically? Message-ID: I have two (or maybe even three) versions of Click installed:- /usr/local/lib/python2.7/dist-packages/click /usr/local/lib/python3.7/dist-packages/click /usr/lib/python3/dist-packages/click I run [x]ubuntu. How can I uninstall those extra versions of click (which have presumably been installed by pip, how would I know?). -- Chris Green ? From cl at isbd.net Tue Dec 29 09:48:39 2020 From: cl at isbd.net (Chris Green) Date: Tue, 29 Dec 2020 14:48:39 +0000 Subject: Is there any way to check/de-cruft/update Python packages installed using pip? Message-ID: <77srbh-fgf3.ln1@esprimo.zbmc.eu> I seem to have quite a lot of old python packages installed over the years using pip and would like, if I can. to clear some of them out. Is there any way to tell if a python package was installed by me directly using pip or was installed from the [x]ubuntu repositories? 'pip list' just tells me every python package that's installed and this really isn't much help. Can one uninstall older versions? For example I seem to have three versions of Click installed:- /usr/local/lib/python2.7/dist-packages/click /usr/local/lib/python3.7/dist-packages/click /usr/lib/python3/dist-packages/click Presumably the ones in /usr/local have been pulled in as dependencies when installing something else using pip, the /usr/lib one has been installed from the Ubuntu repositories (again as a dependency). How can I remove the ones in /usr/local? If one updates a package using pip will it move it as appropriate from (for example) /usr/local/lib/python3.7 to /usr/local/lib/python3.8? Can pip (or some other tool) tell me what other python packages depend on one I'm considering uninstalling? If there are any tools/utilities one can install to check these things out I'd love to know about them. -- Chris Green ? From cl at isbd.net Tue Dec 29 10:10:01 2020 From: cl at isbd.net (Chris Green) Date: Tue, 29 Dec 2020 15:10:01 +0000 Subject: Why do I have both /usr/lib/python3 and /usr/lib/python3.8? Message-ID: <9ftrbh-97i3.ln1@esprimo.zbmc.eu> Why are there both /usr/lib/python3 and /usr/lib/python3.8 on my x[ubuntu] system? /usr/lib/python3 has just the dist-packages directory in it, /usr/lib/python3.8 has lots of individual python files in it as well as quite a number of directories. There's also a /usr/lib/python3.9 directory even though Ubuntu hasn't moved to python3.9 yet. -- Chris Green ? From pkpearson at nowhere.invalid Tue Dec 29 11:47:45 2020 From: pkpearson at nowhere.invalid (Peter Pearson) Date: 29 Dec 2020 16:47:45 GMT Subject: 2 sample chi-square test References: <4601f428-a77a-4105-8f14-0aea561e0f4fn@googlegroups.com> Message-ID: On Tue, 29 Dec 2020 02:52:15 -0800 (PST), Priya Singh wrote: [snip] > I have two spectra with wavelength, flux, and error on flux. I want to > find out the variability of these two spectra based on the 2 sample > Chi-square test. I am using following code: > > def compute_chi2_var(file1,file2,zemi,vmin,vmax): > w1,f1,e1,c1,vel1 = get_spec_vel(dir_data+file1,zemi) > id1 = np.where(np.logical_and(vel1 >= vmin, vel1 < vmax))[0] > w2,f2,e2,c2,vel2 = get_spec_vel(dir_data+file2,zemi) > id2 = np.where(np.logical_and(vel2 >= vmin, vel2 < vmax))[0] > f_int = interp1d(w1[id1], f1[id1]/c1[id1], kind='cubic') > e_int = interp1d(w1[id1], e1[id1]/c1[id1], kind='cubic') > f_obs,e_obs = f_int(w2[id2]), e_int(w2[id2]) > f_exp, e_exp = f2[id2]/c2[id2], e2[id2]/c2[id2] > e_net = e_obs**2 + e_exp**2 > chi_square = np.sum( (f_obs**2 - f_exp**2)/e_net ) > dof = len(f_obs) - 1 > pval = 1 - stats.chi2.cdf( chi_square, dof) > print('%.10E' % pval) > > NN = 320 > compute_chi2_var(file7[NN],file14[NN],zemi[NN],vmin[NN],vmax[NN]) > > > I am running this code on many files, and I want to grab those pair of > spectra where, the p-value of chi-squa is less than 10^(-8), for the > change to be unlikely due to a random occurrence. > > Is my code right concept-wise? Because the chi-squ value is coming out > to be very large (positive and negative), such that my p-value is > always between 1 and 0 which I know from other's results not correct. > > Can anyone suggest me is the concept of 2-sample chi-squ applied by me > is correct or not? 1. This is not really a Python question, is it? 2. Recommendation: test your chi-squared code on simpler sample data. 3. Observation: P-values *are* normally between 0 and 1. 4. Observation: chi-squared values are never negative. 5. Recommendation: Learn a little about the chi-squared distribution (but not on a Python newsgroup). The chi-squared distribution with N degrees of freedom is the distribution expected for a quantity that is the sum of the squares of N normally distributed random variables with mean 0 and standard deviation 1. If you expect f_obs to equal f_exp plus some normally distributed noise with mean 0 and standard deviation sigma, then (f_obs-f_exp)/sigma should be normally distributed with mean 0 and standard deviation 1. 6. Observation: (f_obs**2 - f_exp**2)/e_net is probably not what you want, since it can be negative. You probably want something like (f_obs-f_exp)**2/e_net. But don't take my word for it. Good luck. -- To email me, substitute nowhere->runbox, invalid->com. From pkpearson at nowhere.invalid Tue Dec 29 12:07:06 2020 From: pkpearson at nowhere.invalid (Peter Pearson) Date: 29 Dec 2020 17:07:06 GMT Subject: How to copy the entire outlook message content in python References: Message-ID: On Tue, 29 Dec 2020 05:38:53 -0800 (PST), nikhil k wrote: ...[snip]... > import win32com.client as win32 > > ########### Functions > def getMailBody(msgFile): > start_text = "" > end_text = "" > with open(msgFile) as f: > data=f.read() > return data[data.find(start_text):data.find(end_text)+len(end_text)] ...[snip]... > > > Below is the error I'm getting. >============================================== > File "C:\Python\Python38-32\lib\encodings\cp1252.py", line 23, in decode > return codecs.charmap_decode(input,self.errors,decoding_table)[0] > UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 924: character maps to I'm not completely sure that it's the f.read() call that produces the error, because you cut out the earlier lines of the error message, but . . . I think the problem is that the data in the file you're reading do not represent a valid "encoding" of any character string, using whatever encoding convention Python thinks you want to use. Maybe Python is assuming you're using ASCII encoding; 0x81 is certainly not a valid ASCII character. I don't know how Outlook represents messages in its .msg files; it's possible it packs ASCII text along with binary data. Maybe you can find a Python package that reads .msg files. Maybe you could read the file as a bytestring instead of as a character string. -- To email me, substitute nowhere->runbox, invalid->com. From rshepard at appl-ecosys.com Tue Dec 29 13:11:32 2020 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Tue, 29 Dec 2020 10:11:32 -0800 (PST) Subject: Learning why module will not load Message-ID: Running Slackware-14.2/x86_64 and python-3.9.1. Installed are six-1.14.0-x86_64-1_SBo and python3-six-1.13.0-x86_64-1_SBo (I don't know if the latter is required because six is supposed to be available for python2 and python3.) However, python3 doesn't find either one: $ python3 Python 3.9.1 (default, Dec 26 2020, 11:21:00) [GCC 5.5.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import six Traceback (most recent call last): File "", line 1, in ModuleNotFoundError: No module named 'six' >>> import python3_six Traceback (most recent call last): File "", line 1, in ModuleNotFoundError: No module named 'python3_six' How do I diagnose why neither module is found? TIA, Rich From mats at wichmann.us Tue Dec 29 13:12:53 2020 From: mats at wichmann.us (Mats Wichmann) Date: Tue, 29 Dec 2020 11:12:53 -0700 Subject: Is there any way to check/de-cruft/update Python packages installed using pip? In-Reply-To: <77srbh-fgf3.ln1@esprimo.zbmc.eu> References: <77srbh-fgf3.ln1@esprimo.zbmc.eu> Message-ID: On 12/29/20 7:48 AM, Chris Green wrote: > I seem to have quite a lot of old python packages installed over the > years using pip and would like, if I can. to clear some of them out. > > > Is there any way to tell if a python package was installed by me > directly using pip or was installed from the [x]ubuntu repositories? > 'pip list' just tells me every python package that's installed and > this really isn't much help. > > > Can one uninstall older versions? For example I seem to have > three versions of Click installed:- > > /usr/local/lib/python2.7/dist-packages/click > /usr/local/lib/python3.7/dist-packages/click > /usr/lib/python3/dist-packages/click > > Presumably the ones in /usr/local have been pulled in as dependencies > when installing something else using pip, the /usr/lib one has been > installed from the Ubuntu repositories (again as a dependency). How > can I remove the ones in /usr/local? > > > If one updates a package using pip will it move it as appropriate from > (for example) /usr/local/lib/python3.7 to /usr/local/lib/python3.8? > > > Can pip (or some other tool) tell me what other python packages depend > on one I'm considering uninstalling? > > > If there are any tools/utilities one can install to check these things > out I'd love to know about them. There are some tools (on pypi naturally) for fiddling with installed packages, but for starters try these two: python -m pip help list python -m pip help show show will list dependencies, among other bits of info. For older versions, you to use the matching version of Python python2.7 -m pip show click From cl at isbd.net Tue Dec 29 13:21:14 2020 From: cl at isbd.net (Chris Green) Date: Tue, 29 Dec 2020 18:21:14 +0000 Subject: Is there any way to check/de-cruft/update Python packages installed using pip? References: <77srbh-fgf3.ln1@esprimo.zbmc.eu> Message-ID: Mats Wichmann wrote: > On 12/29/20 7:48 AM, Chris Green wrote: > > > > If there are any tools/utilities one can install to check these things > > out I'd love to know about them. > > There are some tools (on pypi naturally) for fiddling with installed > packages, but for starters try these two: > > python -m pip help list > python -m pip help show > > show will list dependencies, among other bits of info. > > For older versions, you to use the matching version of Python > > python2.7 -m pip show click > Ah, of course, run pip using the python version that matches what you want to remove, obvious really! :-) Thanks. -- Chris Green ? From tjreedy at udel.edu Tue Dec 29 13:31:36 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Tue, 29 Dec 2020 13:31:36 -0500 Subject: Learning why module will not load In-Reply-To: References: Message-ID: On 12/29/2020 1:11 PM, Rich Shepard wrote: > Running Slackware-14.2/x86_64 and python-3.9.1. Installed are > six-1.14.0-x86_64-1_SBo and python3-six-1.13.0-x86_64-1_SBo (I don't > know if > the latter is required because six is supposed to be available for python2 > and python3.) Packages have to be installed for a particular Python binary in order for that binary to import the package. > However, python3 doesn't find either one: > > $ python3 > Python 3.9.1 (default, Dec 26 2020, 11:21:00) [GCC 5.5.0] on linux > Type "help", "copyright", "credits" or "license" for more information. >>>> import six > Traceback (most recent call last): > ? File "", line 1, in > ModuleNotFoundError: No module named 'six' >>>> import python3_six > Traceback (most recent call last): > ? File "", line 1, in > ModuleNotFoundError: No module named 'python3_six' > > How do I diagnose why neither module is found? Those packages apparently are not installed for that 3.9.1 binary. -- Terry Jan Reedy From funkyhat at gmail.com Tue Dec 29 13:43:39 2020 From: funkyhat at gmail.com (Matt Wheeler) Date: Tue, 29 Dec 2020 18:43:39 +0000 Subject: Is there any way to check/de-cruft/update Python packages installed using pip? In-Reply-To: <77srbh-fgf3.ln1@esprimo.zbmc.eu> References: <77srbh-fgf3.ln1@esprimo.zbmc.eu> Message-ID: On 29 Dec 2020, 14:48 +0000, Chris Green , wrote: > I seem to have quite a lot of old python packages installed over the > years using pip and would like, if I can. to clear some of them out. > > > Is there any way to tell if a python package was installed by me > directly using pip or was installed from the [x]ubuntu repositories? > 'pip list' just tells me every python package that's installed and > this really isn't much help. > > > Can one uninstall older versions? For example I seem to have > three versions of Click installed:- > > /usr/local/lib/python2.7/dist-packages/click > /usr/local/lib/python3.7/dist-packages/click > /usr/lib/python3/dist-packages/click Everything under one of these directories comes from apt/dpkg packages. Packages installed using pip will be installed in a directory called site-packages, not dist-packages To confirm this you can try?the command `dpkg -S `, which will tell you which package a file belongs to > > If one updates a package using pip will it move it as appropriate from > (for example) /usr/local/lib/python3.7 to /usr/local/lib/python3.8? No, each version of pip will completely ignore any packages installed for a different version of Python > Can pip (or some other tool) tell me what other python packages depend > on one I'm considering uninstalling? pipdeptree can do this > If there are any tools/utilities one can install to check these things > out I'd love to know about them. > > -- > Chris Green > ? > -- > https://mail.python.org/mailman/listinfo/python-list From pankaj at codeisgreat.org Tue Dec 29 13:36:32 2020 From: pankaj at codeisgreat.org (Pankaj Jangid) Date: Wed, 30 Dec 2020 00:06:32 +0530 Subject: How to uninstall python 2 package specifically? References: Message-ID: Chris Green writes: > I have two (or maybe even three) versions of Click installed:- > > /usr/local/lib/python2.7/dist-packages/click > /usr/local/lib/python3.7/dist-packages/click > /usr/lib/python3/dist-packages/click > > I run [x]ubuntu. > > How can I uninstall those extra versions of click (which have > presumably been installed by pip, how would I know?). For python2 package use pip, for python3 packages use pip3. From rshepard at appl-ecosys.com Tue Dec 29 15:50:00 2020 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Tue, 29 Dec 2020 12:50:00 -0800 (PST) Subject: Learning why module will not load In-Reply-To: References: Message-ID: On Tue, 29 Dec 2020, Terry Reedy wrote: > Packages have to be installed for a particular Python binary in order for > that binary to import the package. Terry, I forgot about this as I don't often upgrade Python. > Those packages apparently are not installed for that 3.9.1 binary. This will be corrected today. Thanks. Stay well, Rich From cl at isbd.net Tue Dec 29 16:02:48 2020 From: cl at isbd.net (Chris Green) Date: Tue, 29 Dec 2020 21:02:48 +0000 Subject: Is there any way to check/de-cruft/update Python packages installed using pip? References: <77srbh-fgf3.ln1@esprimo.zbmc.eu> Message-ID: Matt Wheeler wrote: > On 29 Dec 2020, 14:48 +0000, Chris Green , wrote: > > I seem to have quite a lot of old python packages installed over the > > years using pip and would like, if I can. to clear some of them out. > > > > > > Is there any way to tell if a python package was installed by me > > directly using pip or was installed from the [x]ubuntu repositories? > > 'pip list' just tells me every python package that's installed and > > this really isn't much help. > > > > > > Can one uninstall older versions? For example I seem to have > > three versions of Click installed:- > > > > /usr/local/lib/python2.7/dist-packages/click > > /usr/local/lib/python3.7/dist-packages/click > > /usr/lib/python3/dist-packages/click > > Everything under one of these directories comes from apt/dpkg packages. > Packages installed using pip will be installed in a directory called site-packages, > not dist-packages > > To confirm this you can try?the command `dpkg -S `, which will tell > you which package a file belongs to > Aaaahhhhh!!!! :-) I hadn't realised *that* was the significance of dist-packages and site-packages, thank you very much, that helps a huge amount. > > > > > If one updates a package using pip will it move it as appropriate from > > (for example) /usr/local/lib/python3.7 to /usr/local/lib/python3.8? > > No, each version of pip will completely ignore any packages installed for > a different version of Python Again something I hadn't really understood before but obvious when you think about it. Thank you again. -- Chris Green ? From cl at isbd.net Tue Dec 29 16:20:17 2020 From: cl at isbd.net (Chris Green) Date: Tue, 29 Dec 2020 21:20:17 +0000 Subject: I'm finally disentangled from Python 2, thank you everyone Message-ID: Well, it has taken me a while, but I now seem to have finally detached myself from any Python 2 dependencies on my various systems. Firstly may I say thank you to everyone who has helped me with this (and with other issues) here on the Python list, you are a friendly and helpful group of people. I run (mostly) xubuntu systems and, as of xubuntu 20.04 Python 2 should have gone. First I changed all of my code to use Python 3, this was mostly pretty trivial (like my code in many ways!), the only slightly difficult areas were the changes to Gtk and the string->bytes thing which I had a problem with but, with help from here, was sorted fairly easily. As regards installed software on my laptop it was easy, I don't quite know when it all went but I didn't have to do anything, the current xubuntu 20.10 installation has no Python 2 on it at all. On my desktop machine it was a bit more difficult because of the Oki scanner utility which I have asked about quite a lot here. It has a .so file built for Python 2 which I couldn't convert. In the end (following ideas from here) I have packaged it using cx-freeze so that the utility and all the libraries etc. that it needs are run 'as a package' with all the old Python 2 dependencies inside the package. It took me a while to get it all packaged but it is now done and the utility runs successfully on my desktop which is 'Python 2 free' (except of course for files within the Oki utility package). Phew! :-) ... and thanks again for all the help and support here. -- Chris Green ? From barry at barrys-emacs.org Tue Dec 29 16:50:21 2020 From: barry at barrys-emacs.org (Barry) Date: Tue, 29 Dec 2020 21:50:21 +0000 Subject: Learning why module will not load In-Reply-To: References: Message-ID: > On 29 Dec 2020, at 18:14, Rich Shepard wrote: > > ?Running Slackware-14.2/x86_64 and python-3.9.1. Installed are > six-1.14.0-x86_64-1_SBo and python3-six-1.13.0-x86_64-1_SBo (I don't know if > the latter is required because six is supposed to be available for python2 > and python3.) > > However, python3 doesn't find either one: > > $ python3 > Python 3.9.1 (default, Dec 26 2020, 11:21:00) [GCC 5.5.0] on linux > Type "help", "copyright", "credits" or "license" for more information. >>>> import six > Traceback (most recent call last): > File "", line 1, in > ModuleNotFoundError: No module named 'six' >>>> import python3_six > Traceback (most recent call last): > File "", line 1, in > ModuleNotFoundError: No module named 'python3_six' > > How do I diagnose why neither module is found? I do this to to debug odd import issues: $ python3.9 -v ... >>> import six The output will show the attempts python makes to find the six module. Barry > > TIA, > > Rich > > > -- > https://mail.python.org/mailman/listinfo/python-list > From rshepard at appl-ecosys.com Tue Dec 29 17:13:30 2020 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Tue, 29 Dec 2020 14:13:30 -0800 (PST) Subject: Learning why module will not load In-Reply-To: References: Message-ID: On Tue, 29 Dec 2020, Barry wrote: > I do this to to debug odd import issues: > $ python3.9 -v > ... >>>> import six > The output will show the attempts python makes to find the six module. Barry, Thank you. It's not finding six and I am rebuilding all python3 packages since almost none were build using python-3.9.1. Stay well, Rich From cs at cskk.id.au Tue Dec 29 18:11:19 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Wed, 30 Dec 2020 10:11:19 +1100 Subject: I'm finally disentangled from Python 2, thank you everyone In-Reply-To: References: Message-ID: On 29Dec2020 21:20, Chris Green wrote: >Well, it has taken me a while, but I now seem to have finally detached >myself from any Python 2 dependencies on my various systems. [...] >On my desktop machine it was a bit more difficult because of the Oki >scanner utility which I have asked about quite a lot here. It has a >.so file built for Python 2 which I couldn't convert. In the end >(following ideas from here) I have packaged it using cx-freeze so that >the utility and all the libraries etc. that it needs are run 'as a >package' with all the old Python 2 dependencies inside the package. >[...] Could I ask you to write up a post on what you did here? I've never used cx-freeze but it sounds like a useful thing for keeping legacy stuff functioning. A writeup from someone who's actually used it for that would be welcome. Cheers, Cameron Simpson From cl at isbd.net Wed Dec 30 05:58:42 2020 From: cl at isbd.net (Chris Green) Date: Wed, 30 Dec 2020 10:58:42 +0000 Subject: I'm finally disentangled from Python 2, thank you everyone References: Message-ID: <243ubh-lr94.ln1@esprimo.zbmc.eu> > Could I ask you to write up a post on what you did here? I've never used > cx-freeze but it sounds like a useful thing for keeping legacy stuff > functioning. A writeup from someone who's actually used it for that > would be welcome. > Of course, here is what I wrote in my 'self help' Dokuwiki wiki about it. It refers specifically to the OKI software I wanted to keep using but it should be fairly easy to apply a similar process to other software. I asked on the Python newsgroup and the one suggestion that seemed feasible was to package the OKI software with all its dependencies on a system which still has Gtk2 and Python 2 and then install the whole package on esprimo. After a bit of looking around at Snap, Appimage and such I found cx_freeze which is aimed specifically at Python. The latest version doesn't support Python 2 but 5.1.1 does, so this is how I've have done it.... * Install xubuntu 18.04 on my old Revo system (has to be 64-bit), 18.04 is still in support. (has to be 64-bit simply because the final target is 64-bit) * Install cx_freeze 5.1.1 on Revo * Install the Oki software on Revo, check that it works, pulls in lots of libraries and packages. * Run 'cxfreeze /usr/libexec/okimfputl/scantool.py' (scantool.py is the utility I want to run on systems without Python 2) * Copy the resulting 'dist' directory to the target system, name isn't critical Then the fun starts. There's quite a few more libraries and packages are required and the scan daemon needs to be runnable. (The scan daemon was, fortunately, just a compiled program so ran 'as is' without issues) Files needed in /usr/libexec/okimfputl and /usr/libexec/okimfpdrv """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" There are a lot of hard coded references to /usr/libexec/okimfputl and /usr/libexec/okimfpdrv, it **might** be possible to change all these but I decided it would be less painful to use a couple of symbolic links to locations in /usr/local/libexec and put the required files in /usr/local/libexec/okimfputl and /usr/local/libexec/okimfpdrv. I discovered what files are needed in these directories by simply running scantool on the target and fixing each error as it arose. Other Python package and library files """"""""""""""""""""""""""""""""""""" I have installed the "dist" created by cxfreeze in /usr/local/libexec/okicxfreeze. The executable to run is thus /usr/local/libexec/okicxfreeze/scantool. There are also a few .so libraries and Python packages needed, as above I just found these by running scantool and fixing each error as it appeared. The system library files are put in /usr/local/lib, you have to run ldconfig after each file is put there. The Python packages (including the dreaded pyscand.so) have to be put in the working directory when scantool is run, so I have put them in /usr/local/libexec/okicxfreeze where the scantool executable is. I hope the above is useful. As I said it refers specifically to the scantool.py that I needed for my Oki scanner but I think the description is general enough to be useful. The basic process is:- Find (or create) a system where the software you want to run works OK. Install cx-freeze 5.1.1 on that system and run 'cxfreeze ' Check that the executable created by cxfreeze works on the system you built it on Copy the executable (and its 'dist' environment) to the target where you want to run it Try and run it on the target Iteratively work through the errors it throws up when you run it, in my case these were:- Missing .so system library files, copy them from the build system to somewhere they will be found on the target. You could put them in a 'private to the package' directory and set LD_LIBRARY_PATH or do as I did and put them in a standard library location (and run ldconfig after adding each). Missing Python packages, in my case this included the dreaded pyscand.so, I just put them in the 'package' directory with the executable and in the script that calls the executable set the directory so they are found. Data files. In my case these had locations which were hard coded into all the various scripts along with scantool.py. I *could* have changed all the code before building but that would have been a bit messy and error prone and there was no guarantee that there weren't some addresses hard coded in the executable files and libraries so I just (as you can see above) set up the required directories and put the required files there. In my case this was just three or four configuration files and four .png image files. Note: It seems that what cxfreeze does is to create the *Python* environment needed to run a program. It assumes that standard system .so files will be available on the target (e.g. libc etc.). It doesn't check to see if any 'non-standard' .so files are needed. The ones I had to copy across were all specific Oki ones that came with the Oki utility software. I'm not quite clear why there were (just two) Python package files that didn't get included - one was pyscand.so (maybe because it was a .so) the other was a .py though. If anyone wants further information or clarification feel free to ask, here or direct to my E-Mail if you want, though keeping it here makes sense so everyone can benefit. -- Chris Green ? From as at sci.fi Wed Dec 30 02:28:14 2020 From: as at sci.fi (Anssi Saari) Date: Wed, 30 Dec 2020 09:28:14 +0200 Subject: Why do I have both /usr/lib/python3 and /usr/lib/python3.8? References: <9ftrbh-97i3.ln1@esprimo.zbmc.eu> Message-ID: Chris Green writes: > Why are there both /usr/lib/python3 and /usr/lib/python3.8 on my > x[ubuntu] system? While it's more of an Ubuntu (or Debian) question better asked in some relevant Linux forum, in the end it's because some package managers decided to do that. You can use commands like these to see which packages put stuff in which directory: dpkg -S /usr/lib/python3.8 dpkg -S /usr/lib/python3 On my Debian system the corresponding output looks like this: $ dpkg -S /usr/lib/python3.7 python3.7, libpython3.7-minimal:amd64, python3-tk:amd64, libpython3.7-dev:amd64, libpython3.7-stdlib:amd64, libpython3.7:amd64, python3-distutils, python3-lib2to3: /usr/lib/python3.7 $ dpkg -S /usr/lib/python3 python3-scipy, python3-opengl, python3-statsmodels, iotop, python3-reportlab-accel:amd64, python3-magic, python3-pkg-resources, python3-kiwisolver, python3.7, python3-pandas-lib, python3-kerberos, python3-lz4, python3-renderpm:amd64, python3-numexpr, python3-cffi-backend, python3-crypto, python3-tables, python3-rencode, python3-gi, python3-dbus, devscripts, python3-gpg, python3-pyasn1, python3-py, python3-eyed3, pdfarranger, python3-pip, python3-virtualenv, xpra, python3-pandas, python3-pil:amd64, python3-requests, python3-urllib3, python3-psutil, python3-paramiko, python3-netifaces, python3-patsy, python3-gssapi, python3-sklearn, python3-cycler, python3-sip, python3-cairo:amd64, python3-six, python3-chardet, python3-nose, python3-debian, python3-wheel, python3-attr, python3-soupsieve, python3-bcrypt, python3-bs4, python3-sklearn-lib, python3-scour, python3-setuptools, python3-entrypoints, python3-gi-cairo, python3-cups, python3-keyrings.alt, python3-pluggy, python3-tz, python3-ifaddr, python3-joblib, python3-cvxopt, python3-secretstorage, python3-reportlab, python3-more-itertools, python3-keyring, python3-asn1crypto, python3-html5lib, python3-dns, python3-decorator, python3-dateutil, meson, python3-pexpect, python3-idna, python3-seaborn, lsb-release, python3-numpy, python3-brotli, python3-tables-lib, python3-lxml:amd64, python3-pytest, python3-simplejson, python3-nacl, python3-zeroconf, python3-xdg, python3-libvoikko, python3-gst-1.0, python3-pypdf2, python3-evdev, python3-matplotlib, python3-statsmodels-lib, python3-cryptography, python3-certifi, python3-atomicwrites, python3-pyparsing, python3-ptyprocess, python3-webencodings, piper, python3-uno, python3-apt, python3-setproctitle:amd64, hplip: /usr/lib/python3 So I'd say as a rule stuff relevant to the specific version of python goes in the specific version directory (i.e. /usr/lib/python3.8 in your case) and python software packages in general go in /usr/lib/python3. From cl at isbd.net Wed Dec 30 12:02:37 2020 From: cl at isbd.net (Chris Green) Date: Wed, 30 Dec 2020 17:02:37 +0000 Subject: Why do I have both /usr/lib/python3 and /usr/lib/python3.8? References: <9ftrbh-97i3.ln1@esprimo.zbmc.eu> Message-ID: Anssi Saari wrote: > Chris Green writes: > > > Why are there both /usr/lib/python3 and /usr/lib/python3.8 on my > > x[ubuntu] system? > > While it's more of an Ubuntu (or Debian) question better asked in some > relevant Linux forum, in the end it's because some package managers > decided to do that. You can use commands like these to see which > packages put stuff in which directory: > > dpkg -S /usr/lib/python3.8 > dpkg -S /usr/lib/python3 > > On my Debian system the corresponding output looks like this: > > $ dpkg -S /usr/lib/python3.7 > python3.7, libpython3.7-minimal:amd64, python3-tk:amd64, > libpython3.7-dev:amd64, libpython3.7-stdlib:amd64, libpython3.7:amd64, > python3-distutils, python3-lib2to3: /usr/lib/python3.7 > > $ dpkg -S /usr/lib/python3 > python3-scipy, python3-opengl, python3-statsmodels, iotop, > python3-reportlab-accel:amd64, python3-magic, python3-pkg-resources, > python3-kiwisolver, python3.7, python3-pandas-lib, python3-kerberos, > python3-lz4, python3-renderpm:amd64, python3-numexpr, > python3-cffi-backend, python3-crypto, python3-tables, python3-rencode, > python3-gi, python3-dbus, devscripts, python3-gpg, python3-pyasn1, > python3-py, python3-eyed3, pdfarranger, python3-pip, python3-virtualenv, > xpra, python3-pandas, python3-pil:amd64, python3-requests, > python3-urllib3, python3-psutil, python3-paramiko, python3-netifaces, > python3-patsy, python3-gssapi, python3-sklearn, python3-cycler, > python3-sip, python3-cairo:amd64, python3-six, python3-chardet, > python3-nose, python3-debian, python3-wheel, python3-attr, > python3-soupsieve, python3-bcrypt, python3-bs4, python3-sklearn-lib, > python3-scour, python3-setuptools, python3-entrypoints, > python3-gi-cairo, python3-cups, python3-keyrings.alt, python3-pluggy, > python3-tz, python3-ifaddr, python3-joblib, python3-cvxopt, > python3-secretstorage, python3-reportlab, python3-more-itertools, > python3-keyring, python3-asn1crypto, python3-html5lib, python3-dns, > python3-decorator, python3-dateutil, meson, python3-pexpect, > python3-idna, python3-seaborn, lsb-release, python3-numpy, > python3-brotli, python3-tables-lib, python3-lxml:amd64, python3-pytest, > python3-simplejson, python3-nacl, python3-zeroconf, python3-xdg, > python3-libvoikko, python3-gst-1.0, python3-pypdf2, python3-evdev, > python3-matplotlib, python3-statsmodels-lib, python3-cryptography, > python3-certifi, python3-atomicwrites, python3-pyparsing, > python3-ptyprocess, python3-webencodings, piper, python3-uno, > python3-apt, python3-setproctitle:amd64, hplip: /usr/lib/python3 > > So I'd say as a rule stuff relevant to the specific version of python > goes in the specific version directory (i.e. /usr/lib/python3.8 in your > case) and python software packages in general go in /usr/lib/python3. > Yes, there are some oddities though, for example python3.7 seems to be installed in both locations (python3.8 in my case). -- Chris Green ? From auriocus at gmx.de Wed Dec 30 12:39:34 2020 From: auriocus at gmx.de (Christian Gollwitzer) Date: Wed, 30 Dec 2020 18:39:34 +0100 Subject: I'm finally disentangled from Python 2, thank you everyone In-Reply-To: <243ubh-lr94.ln1@esprimo.zbmc.eu> References: <243ubh-lr94.ln1@esprimo.zbmc.eu> Message-ID: Am 30.12.20 um 11:58 schrieb Chris Green: >> Could I ask you to write up a post on what you did here? I've never used >> cx-freeze but it sounds like a useful thing for keeping legacy stuff >> functioning. A writeup from someone who's actually used it for that >> would be welcome. >> > Of course, here is what I wrote in my 'self help' Dokuwiki wiki about it. It refers > specifically to the OKI software I wanted to keep using but it should be fairly > easy to apply a similar process to other software. > > > I asked on the Python newsgroup and the one suggestion that seemed feasible was to > package the OKI software with all its dependencies on a system which still has Gtk2 > and Python 2 and then install the whole package on esprimo. > > After a bit of looking around at Snap, Appimage and such I found cx_freeze which is > aimed specifically at Python. The latest version doesn't support Python 2 but 5.1.1 > does, so this is how I've have done it.... > > * Install xubuntu 18.04 on my old Revo system (has to be 64-bit), 18.04 is still in support. (has to be 64-bit simply because the final target is 64-bit) > * Install cx_freeze 5.1.1 on Revo > * Install the Oki software on Revo, check that it works, pulls in lots of libraries and packages. > * Run 'cxfreeze /usr/libexec/okimfputl/scantool.py' (scantool.py is the utility I want to run on systems without Python 2) > * Copy the resulting 'dist' directory to the target system, name isn't critical > > Then the fun starts. There's quite a few more libraries and packages are required > and the scan daemon needs to be runnable. (The scan daemon was, fortunately, just > a compiled program so ran 'as is' without issues) > > Files needed in /usr/libexec/okimfputl and /usr/libexec/okimfpdrv > """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" > There are a lot of hard coded references to /usr/libexec/okimfputl and > /usr/libexec/okimfpdrv, it **might** be possible to change all these but > I decided it would be less painful to use a couple of symbolic links > to locations in /usr/local/libexec and put the required files in > /usr/local/libexec/okimfputl and /usr/local/libexec/okimfpdrv. > > I discovered what files are needed in these directories by simply running > scantool on the target and fixing each error as it arose. > > Other Python package and library files > """"""""""""""""""""""""""""""""""""" > I have installed the "dist" created by cxfreeze in /usr/local/libexec/okicxfreeze. The executable to run is thus /usr/local/libexec/okicxfreeze/scantool. > > There are also a few .so libraries and Python packages needed, as above I > just found these by running scantool and fixing each error as it appeared. > The system library files are put in /usr/local/lib, you have to run ldconfig > after each file is put there. The Python packages (including the dreaded > pyscand.so) have to be put in the working directory when scantool is run, > so I have put them in /usr/local/libexec/okicxfreeze where the scantool > executable is. > > > I hope the above is useful. As I said it refers specifically to the scantool.py > that I needed for my Oki scanner but I think the description is general enough to > be useful. > > The basic process is:- > > Find (or create) a system where the software you want to run works OK. > > Install cx-freeze 5.1.1 on that system and run 'cxfreeze ' > > Check that the executable created by cxfreeze works on the system you built it on > > Copy the executable (and its 'dist' environment) to the target where you want to run it > > Try and run it on the target > > Iteratively work through the errors it throws up when you run it, in my case these were:- > > Missing .so system library files, copy them from the build system to somewhere > they will be found on the target. You could put them in a 'private to the > package' directory and set LD_LIBRARY_PATH or do as I did and put them in > a standard library location (and run ldconfig after adding each). I've used pyinstaller in the past, and it seems to do a better job with that. It usually copies all the sytem libraries, too, but would fail with /usr/libexec/okimfputl & friends Christian From markbdusted at gmail.com Wed Dec 30 13:35:18 2020 From: markbdusted at gmail.com (Mark Bachman) Date: Wed, 30 Dec 2020 13:35:18 -0500 Subject: bCNC Message-ID: I have installed Python 3.9.0 and 3.9.1 in an effort to install bCNC. After entering the cmd prompt for installing bCNC the reply indicates intsall was successful. However when trying to launch bCNC with command prompt I get the following reply. Microsoft Windows [Version 10.0.19041.685] (c) 2020 Microsoft Corporation. All rights reserved. C:\Users\------------->py -m bCNC new-config Utils ** On entry to DGEBAL parameter number 3 had an illegal value ** On entry to DGEHRD parameter number 2 had an illegal value ** On entry to DORGHR DORGQR parameter number 2 had an illegal value ** On entry to DHSEQR parameter number 4 had an illegal value Traceback (most recent call last): File "C:\Users\--------\AppData\Local\Programs\Python\Python39\lib\runpy.py", line 197, in _run_module_as_main return _run_code(code, main_globals, None, File "C:\Users\---------\AppData\Local\Programs\Python\Python39\lib\runpy.py", line 87, in _run_code exec(code, run_globals) File "C:\Users\----------\AppData\Local\Programs\Python\Python39\lib\site-packages\bCNC\__main__.py", line 60, in from CNC import WAIT, CNC, GCode File "C:\Users\-----------\AppData\Local\Programs\Python\Python39\lib\site-packages\bCNC\CNC.py", line 25, in from svgcode import SVGcode File "C:\Users\---------\AppData\Local\Programs\Python\Python39\lib\site-packages\bCNC\lib\svgcode.py", line 13, in import numpy File "C:\Users\---------\AppData\Local\Programs\Python\Python39\lib\site-packages\numpy\__init__.py", line 305, in _win_os_check() File "C:\Users\-----------\AppData\Local\Programs\Python\Python39\lib\site-packages\numpy\__init__.py", line 302, in _win_os_check raise RuntimeError(msg.format(__file__)) from None RuntimeError: The current Numpy installation ('C:\\Users\\----------\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\numpy\\__init__.py') fails to pass a sanity check due to a bug in the windows runtime. See this issue for more information: https://tinyurl.com/y3dm3h86 C:\Users\--------------> Any help would be greatly appreciated. -- Thanks Mark Bachman People love chopping wood. In this activity one immediately sees results. Albert Einstein From rshepard at appl-ecosys.com Wed Dec 30 14:12:50 2020 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Wed, 30 Dec 2020 11:12:50 -0800 (PST) Subject: ipython missing required module with python-3.9.1 Message-ID: Using the installed Python3-3.9.1 I rebuilt all python3 modules, including python3-prompt_toolkit-3.0.8, python3-ipython-7.19.0, and ipython_genutils. Trying to invoke ipython results in a not-found module: $ ipython Traceback (most recent call last): File "/usr/bin/ipython", line 4, in from IPython import start_ipython File "/usr/lib64/python3.9/site-packages/IPython/__init__.py", line 56, in from .terminal.embed import embed File "/usr/lib64/python3.9/site-packages/IPython/terminal/embed.py", line 16, in from IPython.terminal.interactiveshell import TerminalInteractiveShell File "/usr/lib64/python3.9/site-packages/IPython/terminal/interactiveshell.py", line 21, in from prompt_toolkit.formatted_text import PygmentsTokens ModuleNotFoundError: No module named 'prompt_toolkit.formatted_text' Running python3 from the command line I see there is no formatted_text in prompt_toolkit: >>> dir(prompt_toolkit) ['AbortAction', 'Application', 'CommandLineInterface', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', 'application', 'auto_suggest', 'buffer', 'buffer_mapping', 'cache', 'clipboard', 'completion', 'document', 'enums', 'eventloop', 'filters', 'history', 'input', 'interface', 'key_binding', 'keys', 'layout', 'mouse_events', 'output', 'prompt', 'prompt_async', 'reactive', 'renderer', 'search_state', 'selection', 'shortcuts', 'styles', 'terminal', 'token', 'utils', 'validation'] >>> from prompt_toolkit import formatted_text Traceback (most recent call last): File "", line 1, in ImportError: cannot import name 'formatted_text' from 'prompt_toolkit' (/usr/lib64/python3.9/site-packages/prompt_toolkit/__init__.py) What am I missing here? TIA, Rich From python at mrabarnett.plus.com Wed Dec 30 15:10:24 2020 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 30 Dec 2020 20:10:24 +0000 Subject: bCNC In-Reply-To: References: Message-ID: On 2020-12-30 18:35, Mark Bachman wrote: > I have installed Python 3.9.0 and 3.9.1 in an effort to install bCNC. > After entering the cmd prompt for installing bCNC the reply indicates > intsall was successful. > However when trying to launch bCNC with command prompt I get the following > reply. > Microsoft Windows [Version 10.0.19041.685] > (c) 2020 Microsoft Corporation. All rights reserved. > > C:\Users\------------->py -m bCNC > new-config Utils > ** On entry to DGEBAL parameter number 3 had an illegal value > ** On entry to DGEHRD parameter number 2 had an illegal value > ** On entry to DORGHR DORGQR parameter number 2 had an illegal value > ** On entry to DHSEQR parameter number 4 had an illegal value > Traceback (most recent call last): > File > "C:\Users\--------\AppData\Local\Programs\Python\Python39\lib\runpy.py", > line 197, in _run_module_as_main > return _run_code(code, main_globals, None, > File > "C:\Users\---------\AppData\Local\Programs\Python\Python39\lib\runpy.py", > line 87, in _run_code > exec(code, run_globals) > File > "C:\Users\----------\AppData\Local\Programs\Python\Python39\lib\site-packages\bCNC\__main__.py", > line 60, in > from CNC import WAIT, CNC, GCode > File > "C:\Users\-----------\AppData\Local\Programs\Python\Python39\lib\site-packages\bCNC\CNC.py", > line 25, in > from svgcode import SVGcode > File > "C:\Users\---------\AppData\Local\Programs\Python\Python39\lib\site-packages\bCNC\lib\svgcode.py", > line 13, in > import numpy > File > "C:\Users\---------\AppData\Local\Programs\Python\Python39\lib\site-packages\numpy\__init__.py", > line 305, in > _win_os_check() > File > "C:\Users\-----------\AppData\Local\Programs\Python\Python39\lib\site-packages\numpy\__init__.py", > line 302, in _win_os_check > raise RuntimeError(msg.format(__file__)) from None > RuntimeError: The current Numpy installation > ('C:\\Users\\----------\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\numpy\\__init__.py') > fails to pass a sanity check due to a bug in the windows runtime. See this > issue for more information: https://tinyurl.com/y3dm3h86 > > C:\Users\--------------> > > Any help would be greatly appreciated. > Did you read the page at https://tinyurl.com/y3dm3h86? Basically, it's a known bug. Use numpy 1.19.3 instead of numpy 1.19.4: py -m pip uninstall numpy py -m pip install numpy==1.19.3 From mishazakacura at gmail.com Wed Dec 30 16:14:26 2020 From: mishazakacura at gmail.com (BearGod777) Date: Wed, 30 Dec 2020 21:14:26 +0000 Subject: help Message-ID: every time i try and open a .py file it just ciomes up with either modify, uninstall or repair. i have tried every single one of these and i have tried to install another version (it couldnt run on that version) and it just doesnt load up. if i try and open a new file it works but if i try and open a file that my friend made it just comes up with those options. please help ReplyForward From ikorot01 at gmail.com Wed Dec 30 18:19:00 2020 From: ikorot01 at gmail.com (Igor Korot) Date: Wed, 30 Dec 2020 17:19:00 -0600 Subject: help In-Reply-To: References: Message-ID: Hi, On Wed, Dec 30, 2020 at 4:40 PM BearGod777 wrote: > > every time i try and open a .py file How are you trying to open the py file? Also - I presume you are using Windows 10 + latest version of python, right? Thank you. > ReplyForward > -- > https://mail.python.org/mailman/listinfo/python-list From Bischoop at vimart.net Wed Dec 30 18:20:08 2020 From: Bischoop at vimart.net (Bischoop) Date: Wed, 30 Dec 2020 23:20:08 -0000 (UTC) Subject: Which method to check if string index is queal to character. References: Message-ID: On 2020-12-29, jak wrote: > > you could try this way: > > # ----------- > from dns import resolver as dns > > emails=['john.doe at fakeserver.bah', > 'john.doe at gmail.com'] > > for ue in emails: > try: > mxl = dns.resolve(ue.split('@')[1], 'MX') > except: > print(f'{ue}: bad mail server') > else: > if len(mxl) > 0: > print(f'{ue}: valid mail server') > # ----------- > > ... so, having verified the sever, you should only worry about the name. I actually have tried, that's good idea. -- Thanks From mats at wichmann.us Wed Dec 30 19:51:57 2020 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 30 Dec 2020 17:51:57 -0700 Subject: help In-Reply-To: References: Message-ID: On 12/30/20 2:14 PM, BearGod777 wrote: > every time i try and open a .py file it just ciomes up with either modify, > uninstall or repair. i have tried every single one of these and i have > tried to install another version (it couldnt run on that version) and it > just doesnt load up. if i try and open a new file it works but if i try and > open a file that my friend made it just comes up with those options. please > help you're rerunning the installer, don't do that. that sounds rude. but isn't meant to be. somehow in recent times, the installer program - whose job it is indeed to install, uninstall, repair - is getting picked up by Windows when you try to run Python in certain ways - the installer should certainly not be getting associated with .py files as the way to run them. It might help diagnose how this happens if you describe what you're doing ("try and open a .py file" doesn't say enough, how are you trying to open it?) open a command shell (cmd.exe or powershell) and run your script foo.py with "py foo.py", assuming you chose to install the Python Launcher, which you should do if using the Python that comes from python.org. From khoroshyy at gmail.com Thu Dec 31 05:43:22 2020 From: khoroshyy at gmail.com (Petro) Date: Thu, 31 Dec 2020 02:43:22 -0800 (PST) Subject: Control stript which is runing in background. Message-ID: <5d0d4112-3473-4248-8ffe-271c35e081c5n@googlegroups.com> Hi. I would like to make something like this: A python script would run headlessly in the background. I would like to control the script from the command line using other python scripts or from the python shell. >From time to time I would ask the main script to create a popup window with an image or a plot. What would be the proper way to approach it. How to make communication between two scripts? Thank you. Petro. From python at mrabarnett.plus.com Thu Dec 31 07:29:06 2020 From: python at mrabarnett.plus.com (MRAB) Date: Thu, 31 Dec 2020 12:29:06 +0000 Subject: Control stript which is runing in background. In-Reply-To: <5d0d4112-3473-4248-8ffe-271c35e081c5n@googlegroups.com> References: <5d0d4112-3473-4248-8ffe-271c35e081c5n@googlegroups.com> Message-ID: <052a1bff-46ff-0cd1-10c7-87b4053b2199@mrabarnett.plus.com> On 2020-12-31 10:43, Petro wrote: > Hi. > I would like to make something like this: > A python script would run headlessly in the background. > I would like to control the script from the command line using other python scripts or from the python shell. > From time to time I would ask the main script to create a popup window with an image or a plot. > What would be the proper way to approach it. How to make communication between two scripts? > For communication, a socket would work. There are examples of a simple socket server and a simple socket client in the Python docs for the 'socket' module. From garabik-news-2005-05 at kassiopeia.juls.savba.sk Thu Dec 31 09:36:06 2020 From: garabik-news-2005-05 at kassiopeia.juls.savba.sk (garabik-news-2005-05 at kassiopeia.juls.savba.sk) Date: Thu, 31 Dec 2020 14:36:06 +0000 (UTC) Subject: ANN: unicode 2.8 Message-ID: unicode is a simple python command line utility that displays properties for a given unicode character, or searches unicode database for a given name. It was written with Linux in mind, but should work almost everywhere (including MS Windows and MacOSX), UTF-8 console is recommended. ?p??pu??s ?po???u? ??? ?o ?sn p??u??p? pu? s?ld???u???d ??? ?u??????suo??p loo? ??????p??p ?u?ll??x? u? s?? ?I ?s?u??od?po? ?u???????p ?l???ld?o? ?u??sn ?l???? 's?d?l? ?o ?????s ??l?????s ?ll?ns??? o?u?? ?x?? ??? ????uo? o? p??pu??s ?po???u? ??? ?o ???od lln? ??? s???oldx? ???? '????l???n ,?po????d, osl? su????uo? ??????d ??? Changes since previous versions: * display ASCII table (either traditional with --ascii or the new EU?UK Trade and Cooperation Agreement version with --brexit-ascii) * minor bug fixes URL: http://kassiopeia.juls.savba.sk/~garabik/software/unicode.html License: GPL v3 Installation: pip install unicode -- ----------------------------------------------------------- | Radovan Garab?k http://kassiopeia.juls.savba.sk/~garabik/ | | __..--^^^--..__ garabik @ kassiopeia.juls.savba.sk | ----------------------------------------------------------- Antivirus alert: file .signature infected by signature virus. Hi! I'm a signature virus! Copy me into your signature file to help me spread! From mishazakacura at gmail.com Thu Dec 31 10:11:01 2020 From: mishazakacura at gmail.com (BearGod777) Date: Thu, 31 Dec 2020 15:11:01 +0000 Subject: help In-Reply-To: References: Message-ID: i am trying to open it by just left clicking the file in file explorer and i tried right clicking it and then pressing open with python 3.9.1 64-bit On Thu, 31 Dec 2020 at 00:52, Mats Wichmann wrote: > On 12/30/20 2:14 PM, BearGod777 wrote: > > every time i try and open a .py file it just ciomes up with either > modify, > > uninstall or repair. i have tried every single one of these and i have > > tried to install another version (it couldnt run on that version) and it > > just doesnt load up. if i try and open a new file it works but if i try > and > > open a file that my friend made it just comes up with those options. > please > > help > > you're rerunning the installer, don't do that. > > that sounds rude. but isn't meant to be. somehow in recent times, the > installer program - whose job it is indeed to install, uninstall, repair > - is getting picked up by Windows when you try to run Python in certain > ways - the installer should certainly not be getting associated with .py > files as the way to run them. It might help diagnose how this happens if > you describe what you're doing ("try and open a .py file" doesn't say > enough, how are you trying to open it?) > > open a command shell (cmd.exe or powershell) and run your script foo.py > with "py foo.py", assuming you chose to install the Python Launcher, > which you should do if using the Python that comes from python.org. > > > > From mats at wichmann.us Thu Dec 31 12:06:39 2020 From: mats at wichmann.us (Mats Wichmann) Date: Thu, 31 Dec 2020 10:06:39 -0700 Subject: help In-Reply-To: References: Message-ID: <46b11e77-ac1c-3071-3a07-8b23fb0c898c@wichmann.us> On 12/31/20 8:11 AM, BearGod777 wrote: > i am trying to open it by just left clicking the file in file explorer and > i tried right clicking it and then pressing open with python 3.9.1 64-bit That *shouldn't* open the installer... (you can actually remove the installer file once you're done installing, it can maybe reduce some confusion). What you're doing is going to give you probably unexpected results anyway. Here's why: (when it's set up properly) when clicking from explorer Windows will create a window to run the Python interpreter in, and when your script finishes, Python quits. Windows will take that as a clue that the window is no longer needed, and it will be discarded. This will usually have the visual effect of a window flashing onto the screen and then vanishing, as if things were broken, but they're not. Only a Python script that is written to manage a display window, is going to stay around. An old is to add an input() call at the end of your script, so it waits for you to hit the enter key before finishing, and that will leave the window open) Either run your scripts from a command shell... Or use an editor or IDE that has an integrated way to run your programs there in the editor's environment - here the IDE manages the windows so you don't get the opens-then-closes effect. Hope this helps. From nospam at please.ty Thu Dec 31 12:07:31 2020 From: nospam at please.ty (jak) Date: Thu, 31 Dec 2020 18:07:31 +0100 Subject: Control stript which is runing in background. References: <5d0d4112-3473-4248-8ffe-271c35e081c5n@googlegroups.com> Message-ID: Il 31/12/2020 11:43, Petro ha scritto: > Hi. > I would like to make something like this: > A python script would run headlessly in the background. > I would like to control the script from the command line using other python scripts or from the python shell. > From time to time I would ask the main script to create a popup window with an image or a plot. > What would be the proper way to approach it. How to make communication between two scripts? > Thank you. > Petro. > using named pipes would be an alternative. A small example that produces an echo for windows. For linux it's simpler using os.mkfifo: # --------------------- import win32pipe as wp, win32file as wf pfile = r'\\.\pipe\mypipe' how = 0 data: bytes while True: pipe = wp.CreateNamedPipe(pfile, wp.PIPE_ACCESS_DUPLEX, wp.PIPE_TYPE_BYTE | wp.PIPE_READMODE_BYTE | wp.PIPE_WAIT, wp.PIPE_UNLIMITED_INSTANCES, 0xffff, 0xffff, 0, None) if pipe: wp.ConnectNamedPipe(pipe, None) while True: try: rv, data = wf.ReadFile(pipe, 1024) except: wf.CloseHandle(pipe) break else: print(data.decode(), end='') else: break # --------------------- you can pass commands to it this way too: $> echo "print log" > \\.\pipe\mypipe From tjreedy at udel.edu Thu Dec 31 14:50:09 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Thu, 31 Dec 2020 14:50:09 -0500 Subject: ANN: unicode 2.8 In-Reply-To: References: Message-ID: On 12/31/2020 9:36 AM, garabik-news-2005-05 at kassiopeia.juls.savba.sk wrote: > unicode is a simple python command line utility that displays > properties for a given unicode character, or searches > unicode database for a given name. ... > Changes since previous versions: > > * display ASCII table (either traditional with --ascii or the new > EU?UK Trade and Cooperation Agreement version with --brexit-ascii) Are you reproducing it with bugs included? How is that of any use to anyone? A tweet linking the treaty annex page https://twitter.com/thejsa_/status/1343291595899207681 A stackoverflow question and discussion of the bugs and oddities. https://politics.stackexchange.com/questions/61178/why-does-the-eu-uk-trade-deal-have-the-7-bit-ascii-table-as-an-appendix The likely answer is that the treaty writers copy-pasted from decades-old docs and could not be bothered to link to the actual ISO standard. -- Terry Jan Reedy From cs at cskk.id.au Thu Dec 31 16:43:50 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Fri, 1 Jan 2021 08:43:50 +1100 Subject: Control stript which is runing in background. In-Reply-To: References: Message-ID: On 31Dec2020 18:07, jak wrote: >Il 31/12/2020 11:43, Petro ha scritto: >>I would like to make something like this: >>A python script would run headlessly in the background. >>I would like to control the script from the command line using other python scripts or from the python shell. >> From time to time I would ask the main script to create a popup window with an image or a plot. >>What would be the proper way to approach it. How to make communication between two scripts? > >using named pipes would be an alternative. A small example that >produces an echo for windows. A Windows named pipe seems to be more like a UNIX-side "UNIX domain socket" than a UNIX side "named pipe". >For linux it's simpler using os.mkfifo: Not really. For Linux (and of course other UNIXen) you really want a UNIX domain socket, not a a name pipe (as from mkfifo). The reason is that a socket (and a Windows pipe, from my limited understanding) creates a new distinct connection when you open it. (The other end has to accept that connection, at least in UNIX). The problem with a UNIX pipe is that every client (your command line control script) _share_ the same pipe - if two scripts un at once there will be a failure. If you contrive some locking scheme then you can share a named pipe in UNIX because only once client will use the pipe at a time. Just something to keep in mind. Cheers, Cameron Simpson From nospam at please.ty Thu Dec 31 18:26:09 2020 From: nospam at please.ty (jak) Date: Fri, 1 Jan 2021 00:26:09 +0100 Subject: Control stript which is runing in background. References: Message-ID: Il 31/12/2020 22:43, Cameron Simpson ha scritto: > On 31Dec2020 18:07, jak wrote: >> Il 31/12/2020 11:43, Petro ha scritto: >>> I would like to make something like this: >>> A python script would run headlessly in the background. >>> I would like to control the script from the command line using other python scripts or from the python shell. >>> From time to time I would ask the main script to create a popup window with an image or a plot. >>> What would be the proper way to approach it. How to make communication between two scripts? >> >> using named pipes would be an alternative. A small example that >> produces an echo for windows. > > A Windows named pipe seems to be more like a UNIX-side "UNIX domain > socket" than a UNIX side "named pipe". > >> For linux it's simpler using os.mkfifo: > > Not really. For Linux (and of course other UNIXen) you really want a > UNIX domain socket, not a a name pipe (as from mkfifo). > > The reason is that a socket (and a Windows pipe, from my limited > understanding) creates a new distinct connection when you open it. (The > other end has to accept that connection, at least in UNIX). > ----------------- > The problem with a UNIX pipe is that every client (your command line > control script) _share_ the same pipe - if two scripts un at once there > will be a failure. If you contrive some locking scheme then you can > share a named pipe in UNIX because only once client will use the pipe at > a time. > This is not completely true, in fact requests can be queued as they would be with sockets and it is their real job. The most important difference is that sockets are a limited resource on a system. > Just something to keep in mind. > > Cheers, > Cameron Simpson > From bob at mellowood.ca Thu Dec 31 17:46:16 2020 From: bob at mellowood.ca (Bob van der Poel) Date: Thu, 31 Dec 2020 15:46:16 -0700 Subject: Funny error message Message-ID: When I run python from the command line and generate an error I get the following: Python 3.8.5 (default, Jul 28 2020, 12:59:40) [GCC 9.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> z /home/bob/.local/lib/python3.8/site-packages/requests/__init__.py:89: RequestsDependencyWarning: urllib3 (1.24.3) or chardet (4.0.0) doesn't match a supported version! warnings.warn("urllib3 ({}) or chardet ({}) doesn't match a supported " Traceback (most recent call last): File "", line 1, in NameError: name 'z' is not defined I understand "z in not defined" ... but what's with the warnings? -- **** 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 nospam at please.ty Thu Dec 31 18:45:52 2020 From: nospam at please.ty (jak) Date: Fri, 1 Jan 2021 00:45:52 +0100 Subject: Control stript which is runing in background. References: Message-ID: ... but this won't be the problem the OP may encounter if its intention is to create a script to command another one that is running. It will be sufficient to limit the write permissions to the pipe file to himself ... perhaps protecting the pipe file inside a directory with stickibits set. From 2QdxY4RzWzUUiLuE at potatochowder.com Thu Dec 31 18:58:24 2020 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Thu, 31 Dec 2020 17:58:24 -0600 Subject: Control stript which is runing in background. In-Reply-To: References: Message-ID: On 2021-01-01 at 00:45:52 +0100, Regarding "Re: Control stript which is runing in background.," jak wrote: > ... but this won't be the problem the OP may encounter if its intention is > to create a script to command another one that is running. It will be > sufficient to limit the write permissions to the pipe file to himself ... > perhaps protecting the pipe file inside a directory with stickibits set. Most of the time, I have several shells open, often with their own background jobs running. Limiting write permission on the pipe to "me" wouldn't prevent concurrent access. From nospam at please.ty Thu Dec 31 19:21:48 2020 From: nospam at please.ty (jak) Date: Fri, 1 Jan 2021 01:21:48 +0100 Subject: Control stript which is runing in background. References: Message-ID: Il 01/01/2021 00:58, 2QdxY4RzWzUUiLuE at potatochowder.com ha scritto: > Most of the time, I have several shells open, often with their own > background jobs running. Limiting write permission on the pipe to "me" > wouldn't prevent concurrent access. This is true but there would be no difference if this happened through a socket. From cs at cskk.id.au Thu Dec 31 19:43:43 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Fri, 1 Jan 2021 11:43:43 +1100 Subject: Control stript which is runing in background. In-Reply-To: References: Message-ID: On 01Jan2021 01:21, jak wrote: >Il 01/01/2021 00:58, 2QdxY4RzWzUUiLuE at potatochowder.com ha scritto: >>Most of the time, I have several shells open, often with their own >>background jobs running. Limiting write permission on the pipe to "me" >>wouldn't prevent concurrent access. > >This is true but there would be no difference if this happened through >a socket. Accessing a socket makes a distinct separate data connection - other openers do not conflict with it. That's the critical difference between a socket and a pipe in terms of functionality, and why sockets have a connect/accept step. Cheers, Cameron Simpson From nospam at please.ty Thu Dec 31 21:43:43 2020 From: nospam at please.ty (jak) Date: Fri, 1 Jan 2021 03:43:43 +0100 Subject: Control stript which is runing in background. References: Message-ID: Il 01/01/2021 01:43, Cameron Simpson ha scritto: > On 01Jan2021 01:21, jak wrote: >> Il 01/01/2021 00:58, 2QdxY4RzWzUUiLuE at potatochowder.com ha scritto: >>> Most of the time, I have several shells open, often with their own >>> background jobs running. Limiting write permission on the pipe to "me" >>> wouldn't prevent concurrent access. >> >> This is true but there would be no difference if this happened through >> a socket. > > Accessing a socket makes a distinct separate data connection - other > openers do not conflict with it. That's the critical difference between > a socket and a pipe in terms of functionality, and why sockets have a > connect/accept step. > > Cheers, > Cameron Simpson > Maybe the fact that I'm not English and I don't know the language well doesn't allow me to express myself clearly. Try it one more time: The OP would like to give some command to a script that is running. How? With a script that sends commands to it. One of the ways, as mentioned, is by using a mini socket server. Given the needs of the OP and the fact that sockets are a limited resource in a system, I took the liberty of proposing a simple alternative: using a named pipe, also because, IMO, sockets, in this case, are an overkill. with a few lines of code in a thread in the running script they can allow it to receive commands: #----------------- import os, errno fnpipe = 'cmdpipe' try: os.mkfifo(fnpipe) except OSError as e: if e.errno != errno.EEXIST: raise while True: with open(fnpipe, 'rt', 1) as fifo: for line in fifo: print(line, ends='') #----------------- Running the command: $ cat bible.txt > cmdpipe & cat bible.txt > cmdpipe & cat bible.txt > cmdpipe the three texts do not mix. IMO, the OP should be enough. after that, I know that a pipe is more like a queue than a soket and in this case a socket, IMO, is wasted. greetings, hoping to have been clearer than before. From 2QdxY4RzWzUUiLuE at potatochowder.com Thu Dec 31 22:14:41 2020 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Thu, 31 Dec 2020 21:14:41 -0600 Subject: Control stript which is runing in background. In-Reply-To: References: Message-ID: On 2021-01-01 at 03:43:43 +0100, Regarding "Re: Control stript which is runing in background.," jak wrote: > Il 01/01/2021 01:43, Cameron Simpson ha scritto: > > On 01Jan2021 01:21, jak wrote: > > > Il 01/01/2021 00:58, 2QdxY4RzWzUUiLuE at potatochowder.com ha scritto: > > > > Most of the time, I have several shells open, often with their own > > > > background jobs running. Limiting write permission on the pipe to "me" > > > > wouldn't prevent concurrent access. > > > > > > This is true but there would be no difference if this happened through > > > a socket. > > > > Accessing a socket makes a distinct separate data connection - other > > openers do not conflict with it. That's the critical difference between > > a socket and a pipe in terms of functionality, and why sockets have a > > connect/accept step. > > > > Cheers, > > Cameron Simpson > > > > Maybe the fact that I'm not English and I don't know the language well > doesn't allow me to express myself clearly. Try it one more time: > The OP would like to give some command to a script that is running. How? > With a script that sends commands to it. One of the ways, as mentioned, > is by using a mini socket server. Given the needs of the OP and the fact > that sockets are a limited resource in a system, I took the liberty of > proposing a simple alternative: using a named pipe, also because, IMO, > sockets, in this case, are an overkill. with a few lines of code in a > thread in the running script they can allow it to receive commands: > #----------------- > import os, errno > > fnpipe = 'cmdpipe' > > try: > os.mkfifo(fnpipe) > except OSError as e: > if e.errno != errno.EEXIST: > raise > while True: > with open(fnpipe, 'rt', 1) as fifo: > for line in fifo: > print(line, ends='') > #----------------- > > Running the command: > > $ cat bible.txt > cmdpipe & cat bible.txt > cmdpipe & cat bible.txt > > cmdpipe > > the three texts do not mix. IMO, the OP should be enough. after that, I > know that a pipe is more like a queue than a soket and in this case a > socket, IMO, is wasted. Only the OP knows for sure. :-) Does the server send data back to the client that made the request? Are the requests (and the responses, if any) small enough to be sent/received atomically? *If* the answers are no and yes, then you're right, a named pipe would be good enough. If not, then a socket *might* be better. Until the OP clarifies, we can't tell. > greetings, hoping to have been clearer than before. I think you were clear enough before, but you may not have considered things the OP did not specify. One of the hardest parts of software development is understanding and specifying the actual problem to be solved. I've never done that in a second language (I'm nowhere near fluent in anything other than English); I can only imagine the extra layers of complexity. From PythonList at DancesWithMice.info Thu Dec 31 23:25:24 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Fri, 1 Jan 2021 17:25:24 +1300 Subject: Funny error message In-Reply-To: References: Message-ID: On 1/1/21 11:46 AM, Bob van der Poel wrote: > When I run python from the command line and generate an error I get the > following: > > Python 3.8.5 (default, Jul 28 2020, 12:59:40) > [GCC 9.3.0] on linux > Type "help", "copyright", "credits" or "license" for more information. >>>> z > /home/bob/.local/lib/python3.8/site-packages/requests/__init__.py:89: > RequestsDependencyWarning: urllib3 (1.24.3) or chardet (4.0.0) doesn't > match a supported version! > warnings.warn("urllib3 ({}) or chardet ({}) doesn't match a supported " > Traceback (most recent call last): > File "", line 1, in > NameError: name 'z' is not defined > > I understand "z in not defined" ... but what's with the warnings? The implication is that there is a version-mismatch between Python 3.8 and whichever urllib3 and chardet libraries currently installed. Recommend updating the system, container, or venv: either Python, pip3 of the two and/or requests or html-parser [as appropriate to the installed libraries - see below], or both/all. System here runs as-expected: dn $ ... python Python 3.9.1 (default, Dec 8 2020, 00:00:00) [GCC 10.2.1 20201125 (Red Hat 10.2.1-9)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> z Traceback (most recent call last): File "", line 1, in NameError: name 'z' is not defined >>> import chardet >>> import urllib3 >>> exit() dn $ ... pip show chardet urllib3 Name: chardet Version: 3.0.4 Summary: Universal encoding detector for Python 2 and 3 Home-page: https://github.com/chardet/chardet Author: Mark Pilgrim Author-email: mark at diveintomark.org License: LGPL Location: /usr/lib/python3.9/site-packages Requires: Required-by: html5-parser, requests --- Name: urllib3 Version: 1.25.8 Summary: HTTP library with thread-safe connection pooling, file post, and more. Home-page: https://urllib3.readthedocs.io/ Author: Andrey Petrov Author-email: andrey.petrov at shazow.net License: MIT Location: /usr/lib/python3.9/site-packages Requires: Required-by: requests -- Regards =dn