From simon.n.connah at protonmail.com Wed Nov 1 06:09:16 2023 From: simon.n.connah at protonmail.com (Simon Connah) Date: Wed, 01 Nov 2023 10:09:16 +0000 Subject: Checking if email is valid Message-ID: Hi, I'm building a simple project using smtplib and have a question. I've been doing unit testing but I'm not sure how to check if an email message is valid. Using regex sounds like a bad idea to me and the other options I found required paying for third party services. Could someone push me in the right direction please? I just want to find out if a string is a valid email address. Thank you. Simon. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 249 bytes Desc: OpenPGP digital signature URL: From simon.n.connah at protonmail.com Wed Nov 1 07:35:01 2023 From: simon.n.connah at protonmail.com (Simon Connah) Date: Wed, 01 Nov 2023 11:35:01 +0000 Subject: Checking if email is valid In-Reply-To: References: Message-ID: OK. I've been doing some reading and that you should avoid regex to check email addresses. So what I was thinking was something like this: if type(email_recipient) != email.message.Message: I just don't know why that particular line isn't working. Thank you! ------- Original Message ------- On Wednesday, 1 November 2023 at 10:09, Simon Connah wrote: > > > Hi, > > I'm building a simple project using smtplib and have a question. I've been doing unit testing but I'm not sure how to check if an email message is valid. Using regex sounds like a bad idea to me and the other options I found required paying for third party services. > > Could someone push me in the right direction please? I just want to find out if a string is a valid email address. > > Thank you. > > Simon. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 249 bytes Desc: OpenPGP digital signature URL: From rosuav at gmail.com Wed Nov 1 14:26:17 2023 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 2 Nov 2023 05:26:17 +1100 Subject: Checking if email is valid In-Reply-To: References: Message-ID: On Thu, 2 Nov 2023 at 05:21, Simon Connah via Python-list wrote: > > Could someone push me in the right direction please? I just want to find out if a string is a valid email address. There is only one way to know that a string is a valid email address, and that's to send an email to it. What is your goal though? For example, if you're trying to autolink email addresses in text, you don't really care whether it's valid, only that it looks like an address. ChrisA From jon+usenet at unequivocal.eu Wed Nov 1 14:36:17 2023 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Wed, 1 Nov 2023 18:36:17 -0000 (UTC) Subject: Checking if email is valid References: Message-ID: On 2023-11-01, Chris Angelico wrote: > On Thu, 2 Nov 2023 at 05:21, Simon Connah via Python-list > wrote: >> Could someone push me in the right direction please? I just want to >> find out if a string is a valid email address. > > There is only one way to know that a string is a valid email address, > and that's to send an email to it. > > What is your goal though? For example, if you're trying to autolink > email addresses in text, you don't really care whether it's valid, > only that it looks like an address. There's often value in even only partially-effective checks though. With an email address you can easily check to see if it has an "@", and if the stuff after the "@" is a syntactically valid domain name. You can also go a bit further and check to see if the domain has an MX record, and if it doesn't then it is extremely unlikely that the address is valid. From rosuav at gmail.com Wed Nov 1 15:11:03 2023 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 2 Nov 2023 06:11:03 +1100 Subject: Checking if email is valid In-Reply-To: References: Message-ID: On Thu, 2 Nov 2023 at 06:02, Jon Ribbens via Python-list wrote: > > On 2023-11-01, Chris Angelico wrote: > > On Thu, 2 Nov 2023 at 05:21, Simon Connah via Python-list > > wrote: > >> Could someone push me in the right direction please? I just want to > >> find out if a string is a valid email address. > > > > There is only one way to know that a string is a valid email address, > > and that's to send an email to it. > > > > What is your goal though? For example, if you're trying to autolink > > email addresses in text, you don't really care whether it's valid, > > only that it looks like an address. > > There's often value in even only partially-effective checks though. > With an email address you can easily check to see if it has an "@", > and if the stuff after the "@" is a syntactically valid domain name. > You can also go a bit further and check to see if the domain has an > MX record, and if it doesn't then it is extremely unlikely that the > address is valid. Yeah, which is why I asked about the goal. (You may also note that I worded the prior statement very carefully: You cannot know that it IS valid without sending email to it, but there can be ways to know that it CANNOT BE valid.) In the vast majority of contexts, local addresses can be ignored, so an email address will have to include an at sign. I wouldn't bother with a syntax check on the domain portion, though; just check for a couple of possible formats (IP literal), and if it looks like a domain name, do the MX lookup. That said, though, there are certain contexts where you can be a LOT more restrictive, such as the autolinking example I mentioned; it's fine to exclude some unusual email addresses when all you're doing is offering a small convenience. ChrisA From mats at wichmann.us Wed Nov 1 16:12:19 2023 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 1 Nov 2023 14:12:19 -0600 Subject: Checking if email is valid In-Reply-To: References: Message-ID: <7ed7867d-dcd0-49d7-b39e-8dd7dd8fd776@wichmann.us> On 11/1/23 05:35, Simon Connah via Python-list wrote: > OK. I've been doing some reading and that you should avoid regex to check email addresses. So what I was thinking was something like this: To be a little more specific, Avoid Rolling Your Own RegEx. It's very tricky, and you will get it subtly wrong. All depending, as others have said, on what level of "validation" you're after. From PythonList at DancesWithMice.info Wed Nov 1 16:35:18 2023 From: PythonList at DancesWithMice.info (dn) Date: Thu, 2 Nov 2023 09:35:18 +1300 Subject: Checking if email is valid In-Reply-To: References: Message-ID: <1024be9c-6a20-4a2b-b14c-2d7a6a1bc791@DancesWithMice.info> On 02/11/2023 00.35, Simon Connah via Python-list wrote: > OK. I've been doing some reading and that you should avoid regex to check email addresses. This operation used to be a BIG THING back in the days of 'everyone' building PHP web-sites. When there were only a handful of TLDs (top-level domain names, eg the country-codes* such as .nz and .uk plus the generics such as .com and .net. Accordingly, one could hold the entire list for convenience of checking. However when IANA (the outfit responsible for the Root Zone Database and especially ICANN realised that there was money to be made, they allowed more and more TLDs. Keeping-up became a rat-race! Indeed, I've held another .info domain for twenty years, and used to suffer for my 'bleeding edge' daring - quite recently someone (who should remain name-less, and a few other less-es) sent me an email telling me how to log-in, but their log-in process wouldn't accept the 'illegal' address. Ummmmmmmmm... All together now: "a little bit of knowledge is a dangerous thing"! So what I was thinking was something like this: > > if type(email_recipient) != email.message.Message: > > I just don't know why that particular line isn't working. Will need more context. What is the objective? What is the source/pre-processing of these data-items. (etc) * Left-out .au, (a less important geo-TLD) to wind-up @Chris... -- Regards, =dn From verstotene at news.eternal-september.org Wed Nov 1 16:40:59 2023 From: verstotene at news.eternal-september.org (De ongekruisigde) Date: Wed, 1 Nov 2023 20:40:59 -0000 (UTC) Subject: Checking if email is valid References: <7ed7867d-dcd0-49d7-b39e-8dd7dd8fd776@wichmann.us> Message-ID: On 2023-11-01, Mats Wichmann wrote: > On 11/1/23 05:35, Simon Connah via Python-list wrote: >> OK. I've been doing some reading and that you should avoid regex to check email addresses. So what I was thinking was something like this: > > To be a little more specific, Avoid Rolling Your Own RegEx. It's very > tricky, and you will get it subtly wrong. Use e.g.: https://gitea.ksol.io/karolyi/py3-validate-email From grant.b.edwards at gmail.com Wed Nov 1 17:08:20 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Wed, 01 Nov 2023 14:08:20 -0700 (PDT) Subject: Checking if email is valid References: =?utf-8?q?=3Cnze9mu-VI8ExA3VA9RA07qMo9Oj03xuWoTe-FL6N=5FAbOGK0QC?= =?utf-8?q?6LdqaeKq-OvcrilFYqqT5tc9LsvSqHRKDYMGaBXzlVzyOdX9Ae0Xp=5FACtg=3D?= =?utf-8?q?=40protonmail=2Ecom=3E?= Message-ID: <6542be44.050a0220.e7b44.2143@mx.google.com> On 2023-11-01, Simon Connah via Python-list wrote: > I'm building a simple project using smtplib and have a > question. I've been doing unit testing but I'm not sure how to check > if an email message is valid. Send an e-mail using it? If the right person gets the e-mail, then it's valid? > Using regex sounds like a bad idea to me and the other options I > found required paying for third party services. > > Could someone push me in the right direction please? I just want to > find out if a string is a valid email address. You'll have to define "valid". Valid syntactically according to ? Will be accepted by an SMTP server somewhere? Corresponds to a real person? Make sure it has an '@' in it. Possibly require at least one '.' after the '@'. Trying to do anything more than that is just wasting your time and annoying the mule. From rosuav at gmail.com Wed Nov 1 17:17:58 2023 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 2 Nov 2023 08:17:58 +1100 Subject: Checking if email is valid In-Reply-To: <6542be44.050a0220.e7b44.2143@mx.google.com> References: <6542be44.050a0220.e7b44.2143@mx.google.com> Message-ID: On Thu, 2 Nov 2023 at 08:09, Grant Edwards via Python-list wrote: > Make sure it has an '@' in it. Possibly require at least one '.' > after the '@'. No guarantee that there'll be a dot after the at. (Technically there's no guarantee of an at sign either, but email addresses without at signs are local-only, so in many contexts, you can assume there needs to be an at.) So the regex to match all valid email addresses that aren't local-only is... drumroll please... r"@" ChrisA From grant.b.edwards at gmail.com Wed Nov 1 17:50:43 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Wed, 01 Nov 2023 14:50:43 -0700 (PDT) Subject: Checking if email is valid References: =?utf-8?q?=3Cnze9mu-VI8ExA3VA9RA07qMo9Oj03xuWoTe-FL6N=5FAbOGK0QC?= =?utf-8?q?6LdqaeKq-OvcrilFYqqT5tc9LsvSqHRKDYMGaBXzlVzyOdX9Ae0Xp=5FACtg=3D?= =?utf-8?q?=40protonmail=2Ecom=3E?= <6542be44.050a0220.e7b44.2143@mx.google.com> Message-ID: <6542c833.920a0220.6922f.1485@mx.google.com> On 2023-11-01, Chris Angelico via Python-list wrote: > On Thu, 2 Nov 2023 at 08:09, Grant Edwards via Python-list > wrote: >> Make sure it has an '@' in it. Possibly require at least one '.' >> after the '@'. > > No guarantee that there'll be a dot after the at. Ah, I forgot about defaulting to a local domain if one is omitted. Will MTAs do that these days? > (Technically there's no guarantee of an at sign either, but email > addresses without at signs are local-only, so in many contexts, you > can assume there needs to be an at.) > > So the regex to match all valid email addresses that aren't > local-only is... drumroll please... > > r"@" Unless you want to support UUCP or X400 addresses... :) From rosuav at gmail.com Wed Nov 1 17:55:27 2023 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 2 Nov 2023 08:55:27 +1100 Subject: Checking if email is valid In-Reply-To: <6542c833.920a0220.6922f.1485@mx.google.com> References: <6542be44.050a0220.e7b44.2143@mx.google.com> <6542c833.920a0220.6922f.1485@mx.google.com> Message-ID: On Thu, 2 Nov 2023 at 08:52, Grant Edwards via Python-list wrote: > > On 2023-11-01, Chris Angelico via Python-list wrote: > > On Thu, 2 Nov 2023 at 08:09, Grant Edwards via Python-list > > wrote: > > >> Make sure it has an '@' in it. Possibly require at least one '.' > >> after the '@'. > > > > No guarantee that there'll be a dot after the at. > > Ah, I forgot about defaulting to a local domain if one is > omitted. Will MTAs do that these days? Yeah they will; but that'll depend on the exact server you send to, whereas if you have a domain part, all you need is some server that accepts mail for forwarding. > > (Technically there's no guarantee of an at sign either, but email > > addresses without at signs are local-only, so in many contexts, you > > can assume there needs to be an at.) > > > > So the regex to match all valid email addresses that aren't > > local-only is... drumroll please... > > > > r"@" > > Unless you want to support UUCP or X400 addresses... > > :) Yyyyyyyyeah I think we can assume SMTP these days :) ChrisA From torriem at gmail.com Wed Nov 1 20:57:04 2023 From: torriem at gmail.com (Michael Torrie) Date: Wed, 1 Nov 2023 18:57:04 -0600 Subject: Checking if email is valid In-Reply-To: References: Message-ID: <9dc28317-d2be-4632-a452-5c5fd6871fc3@gmail.com> On 11/1/23 04:09, Simon Connah via Python-list wrote: > Hi, > > I'm building a simple project using smtplib and have a question. I've been doing unit testing but I'm not sure how to check if an email message is valid. Using regex sounds like a bad idea to me and the other options I found required paying for third party services. > > Could someone push me in the right direction please? I just want to find out if a string is a valid email address. If I had a nickle for every time a web site claimed my email address wasn't valid I'd be a rich person. Seems like most attempts at solving this little problem fall short! From cs at cskk.id.au Wed Nov 1 20:55:52 2023 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 2 Nov 2023 11:55:52 +1100 Subject: Checking if email is valid In-Reply-To: <6542be44.050a0220.e7b44.2143@mx.google.com> References: <6542be44.050a0220.e7b44.2143@mx.google.com> Message-ID: On 01Nov2023 14:08, Grant Edwards wrote: >On 2023-11-01, Simon Connah via Python-list wrote: >> I'm building a simple project using smtplib and have a >> question. I've been doing unit testing but I'm not sure how to check >> if an email message is valid. [...] >> Could someone push me in the right direction please? I just want to >> find out if a string is a valid email address. I confess that I punt "syntactically valid" to email.utils.getaddresses: https://docs.python.org/3/library/email.utils.html#email.utils.getaddresses "Deliverable"? I'm prepared to just send to it and hope not to get a bounce; delivery of email is, after all, asynchronous. (Even if it were going direct to the primary MX, I still hand it to the local mail system to deal with.) "A real person or entity"? A lot of systems do the round trip thing: here's a special unique and opaue URL,please visit it to confirm receipt of this email (implying email is 'real"). You see this a lot when signing up for things. And for plenty of things I generate a random throw away address at mailinator.com (looking at you, every "catch up" free online TV streaming service who still wants me to log in). Cheers, Cameron Simpson From darcy at Vex.Net Wed Nov 1 21:56:30 2023 From: darcy at Vex.Net (D'Arcy Cain) Date: Wed, 1 Nov 2023 21:56:30 -0400 Subject: Checking if email is valid In-Reply-To: References: <6542be44.050a0220.e7b44.2143@mx.google.com> Message-ID: <04e7696b-536e-4fcd-9d48-414623cd815a@Vex.Net> On 2023-11-01 17:17, Chris Angelico via Python-list wrote: > On Thu, 2 Nov 2023 at 08:09, Grant Edwards via Python-list > wrote: >> Make sure it has an '@' in it. Possibly require at least one '.' >> after the '@'. > > No guarantee that there'll be a dot after the at. (Technically there's > no guarantee of an at sign either, but email addresses without at > signs are local-only, so in many contexts, you can assume there needs > to be an at.) druid!darcy - doesn't work any more but not because it is syntactically incorrect. Remember the good old days when we were able to test if an address existed without sending? That was before the black hats discovered the Internet. -- D'Arcy J.M. Cain System Administrator, Vex.Net http://www.Vex.Net/ IM:darcy at Vex.Net VoIP: sip:darcy at Vex.Net From hobson42 at gmail.com Wed Nov 1 23:48:49 2023 From: hobson42 at gmail.com (Ian Hobson) Date: Thu, 2 Nov 2023 10:48:49 +0700 Subject: Checking if email is valid In-Reply-To: References: Message-ID: <4eee91d7-7336-4796-a362-2011cc44dafd@gmail.com> See https://www.linuxjournal.com/article/9585?page=0,0 On 01/11/2023 17:09, Simon Connah via Python-list wrote: > Hi, > > I'm building a simple project using smtplib and have a question. I've been doing unit testing but I'm not sure how to check if an email message is valid. Using regex sounds like a bad idea to me and the other options I found required paying for third party services. > > Could someone push me in the right direction please? I just want to find out if a string is a valid email address. > > Thank you. > > Simon. > > -- Ian Hobson Tel (+66) 626 544 695 From avi.e.gross at gmail.com Thu Nov 2 00:18:56 2023 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Thu, 2 Nov 2023 00:18:56 -0400 Subject: Checking if email is valid In-Reply-To: <04e7696b-536e-4fcd-9d48-414623cd815a@Vex.Net> References: <6542be44.050a0220.e7b44.2143@mx.google.com> <04e7696b-536e-4fcd-9d48-414623cd815a@Vex.Net> Message-ID: <00de01da0d43$b2cb2a80$18617f80$@gmail.com> Yes, it would be nice if there was a syntax for sending a test message sort of like an ACK that is not delivered to the recipient but merely results in some status being sent back such as DELIVERABLE or NO SUCH USER or even MAILBOX FULL. An issue with the discussion that may be worth considering is that some email addresses are not always valid or may not be valid yet but will be activated later. If I plan on opening a business unit which DNS will later support as specific.category.mycompany.com.au and we first want to write some code and test it and roll everything out later, then a test for user at specific.category.mycompany.com.au could fail some tests now but may be fine later. Or what if I turn my machine off on weekends and when it boots, it sets up to be able to receive mail. Is the address only sometimes valid? We cannot be sure what rules may change and for all we know, they will select other UNICODE symbols to replace @ for use by countries not having an @ on keyboards in the local language or support some syntax like {AT} to be usable ... I even wonder about a service along the lines of tinyurl where you register a potentially long or complex or hard to type name and get a short readable one instead that is just used to provide a re-direct or even changed periodically to dynamically point to where you want them now, such for the current day of the week. I can easily imagine them making a funny looking email address such as user at TINYqwerty that may not pas your current test or one that looks valid to you but maps into an invalid or even null address. BTW, checking if an email is valid is much wider as a concept than whether the email address looks like a possible address. A big check sometimes made if if the headers in the message and various formatting issues look reasonable or issues about attachments and even if it is passed by SPAM detectors. This discussion is just about if an email address LOOKS possibly valid or should not be accepted. I note earlier iterations of email had addressed like mach1!mach2!mach3!ihnp4!mach5!mach6!user or even mach1!mach2!user at mach3 and I remember tools that analyzed what other machines various machines claimed to have a direct connection to and tried to figure out a connection from your source to destination, perhaps a shorter one or maybe a less expensive one. Hence machines like ihnp4 and various universities that were densely connected to others got lots of traffic. In that scenario, validity had another meaning. -----Original Message----- From: Python-list On Behalf Of D'Arcy Cain via Python-list Sent: Wednesday, November 1, 2023 9:57 PM To: python-list at python.org Subject: Re: Checking if email is valid On 2023-11-01 17:17, Chris Angelico via Python-list wrote: > On Thu, 2 Nov 2023 at 08:09, Grant Edwards via Python-list > wrote: >> Make sure it has an '@' in it. Possibly require at least one '.' >> after the '@'. > > No guarantee that there'll be a dot after the at. (Technically there's > no guarantee of an at sign either, but email addresses without at > signs are local-only, so in many contexts, you can assume there needs > to be an at.) druid!darcy - doesn't work any more but not because it is syntactically incorrect. Remember the good old days when we were able to test if an address existed without sending? That was before the black hats discovered the Internet. -- D'Arcy J.M. Cain System Administrator, Vex.Net http://www.Vex.Net/ IM:darcy at Vex.Net VoIP: sip:darcy at Vex.Net -- https://mail.python.org/mailman/listinfo/python-list From rosuav at gmail.com Thu Nov 2 02:04:36 2023 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 2 Nov 2023 17:04:36 +1100 Subject: Checking if email is valid In-Reply-To: <00de01da0d43$b2cb2a80$18617f80$@gmail.com> References: <6542be44.050a0220.e7b44.2143@mx.google.com> <04e7696b-536e-4fcd-9d48-414623cd815a@Vex.Net> <00de01da0d43$b2cb2a80$18617f80$@gmail.com> Message-ID: On Thu, 2 Nov 2023 at 15:20, AVI GROSS via Python-list wrote: > > Yes, it would be nice if there was a syntax for sending a test message sort > of like an ACK that is not delivered to the recipient but merely results in > some status being sent back such as DELIVERABLE or NO SUCH USER or even > MAILBOX FULL. > Yes, it would! Spammers would be able to use this syntax to figure out exactly which addresses actually have real people connected to it. It would save them so much trouble! Brilliant idea. ChrisA From simon.n.connah at protonmail.com Thu Nov 2 02:42:57 2023 From: simon.n.connah at protonmail.com (Simon Connah) Date: Thu, 02 Nov 2023 06:42:57 +0000 Subject: Checking if email is valid In-Reply-To: <6542be44.050a0220.e7b44.2143@mx.google.com> References: <6542be44.050a0220.e7b44.2143@mx.google.com> Message-ID: > > On 2023-11-01, Simon Connah via Python-list python-list at python.org wrote: > > > I'm building a simple project using smtplib and have a > > question. I've been doing unit testing but I'm not sure how to check > > if an email message is valid. > > > Send an e-mail using it? If the right person gets the e-mail, then > it's valid? > > > Using regex sounds like a bad idea to me and the other options I > > found required paying for third party services. > > > > Could someone push me in the right direction please? I just want to > > find out if a string is a valid email address. > OK. It is going to take me some time to get round to every reply here so please bear with me. Basically I'm writing unit tests and one of them passess in a string with an invalid email address. I need to be able to check the string to see if it is a valid email so that the unit test passess. > > You'll have to define "valid". Valid syntactically according to > ? Will be accepted by an SMTP server somewhere? Corresponds to > > a real person? > > Make sure it has an '@' in it. Possibly require at least one '.' > after the '@'. > > Trying to do anything more than that is just wasting your time and > annoying the mule. > Valid as in conforms to the standard. Although having looked at the standard that might be more difficult than originally planned. Simon. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 249 bytes Desc: OpenPGP digital signature URL: From cs at cskk.id.au Thu Nov 2 02:41:56 2023 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 2 Nov 2023 17:41:56 +1100 Subject: Checking if email is valid In-Reply-To: References: Message-ID: On 02Nov2023 17:04, Chris Angelico wrote: >On Thu, 2 Nov 2023 at 15:20, AVI GROSS via Python-list > wrote: >> Yes, it would be nice if there was a syntax for sending a test >> message sort >> of like an ACK that is not delivered to the recipient but merely results in >> some status being sent back such as DELIVERABLE or NO SUCH USER or even >> MAILBOX FULL. > >Yes, it would! Spammers would be able to use this syntax to figure out >exactly which addresses actually have real people connected to it. It >would save them so much trouble! Brilliant idea. Hmm. IIRC... https://datatracker.ietf.org/doc/html/rfc2821#section-4.1.1.6 I think a lot of mail receivers don't honour this one, for exactly the reasons above. Cheers, Cameron Simpson From simon.n.connah at protonmail.com Thu Nov 2 02:46:47 2023 From: simon.n.connah at protonmail.com (Simon Connah) Date: Thu, 02 Nov 2023 06:46:47 +0000 Subject: Checking if email is valid In-Reply-To: References: Message-ID: <-9noVuOpUQAkPbuiynyonZmXsAiNxRiuOlqaSXQrxmsQreDAE5R-MIt72P3SLBqmntdEd5QI2eSl969CcTVWUUz416g4T8nqC8xB1wZxkCc=@protonmail.com> > > > On Thu, 2 Nov 2023 at 05:21, Simon Connah via Python-list > python-list at python.org wrote: > > > Could someone push me in the right direction please? I just want to find out if a string is a valid email address. > > > There is only one way to know that a string is a valid email address, > and that's to send an email to it. > > What is your goal though? For example, if you're trying to autolink > email addresses in text, you don't really care whether it's valid, > only that it looks like an address. > My goal is to make a simple mailing list platform. I guess I could just send email to an address and if it bounces then I can remove it from the database. Thing is I'm not sure how close to a real email address an email has to be in order to be bounced. If it was completely wrong it might just swallowed up. Simon. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 249 bytes Desc: OpenPGP digital signature URL: From simon.n.connah at protonmail.com Thu Nov 2 02:51:12 2023 From: simon.n.connah at protonmail.com (Simon Connah) Date: Thu, 02 Nov 2023 06:51:12 +0000 Subject: Checking if email is valid In-Reply-To: References: Message-ID: > > On 2023-11-01, Chris Angelico rosuav at gmail.com wrote: > > > On Thu, 2 Nov 2023 at 05:21, Simon Connah via Python-list > > python-list at python.org wrote: > > > > > Could someone push me in the right direction please? I just want to > > > find out if a string is a valid email address. > > > > There is only one way to know that a string is a valid email address, > > and that's to send an email to it. > > > > What is your goal though? For example, if you're trying to autolink > > email addresses in text, you don't really care whether it's valid, > > only that it looks like an address. > > > There's often value in even only partially-effective checks though. > With an email address you can easily check to see if it has an "@", > and if the stuff after the "@" is a syntactically valid domain name. > You can also go a bit further and check to see if the domain has an > MX record, and if it doesn't then it is extremely unlikely that the > address is valid. > -- > https://mail.python.org/mailman/listinfo/python-list Apparently UTF-8 characters are allowed in email addresses now. That is going to lead to a whole new level of pain for determining if an email address is correct. Simon. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 249 bytes Desc: OpenPGP digital signature URL: From rosuav at gmail.com Thu Nov 2 02:56:26 2023 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 2 Nov 2023 17:56:26 +1100 Subject: Checking if email is valid In-Reply-To: <-9noVuOpUQAkPbuiynyonZmXsAiNxRiuOlqaSXQrxmsQreDAE5R-MIt72P3SLBqmntdEd5QI2eSl969CcTVWUUz416g4T8nqC8xB1wZxkCc=@protonmail.com> References: <-9noVuOpUQAkPbuiynyonZmXsAiNxRiuOlqaSXQrxmsQreDAE5R-MIt72P3SLBqmntdEd5QI2eSl969CcTVWUUz416g4T8nqC8xB1wZxkCc=@protonmail.com> Message-ID: On Thu, 2 Nov 2023 at 17:47, Simon Connah wrote: > > My goal is to make a simple mailing list platform. I guess I could just send email to an address and if it bounces then I can remove it from the database. Thing is I'm not sure how close to a real email address an email has to be in order to be bounced. If it was completely wrong it might just swallowed up. > Every address is completely separate. There is no "closeness". Just send email to an address. ChrisA From rosuav at gmail.com Thu Nov 2 02:57:49 2023 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 2 Nov 2023 17:57:49 +1100 Subject: Checking if email is valid In-Reply-To: References: Message-ID: On Thu, 2 Nov 2023 at 17:47, Cameron Simpson via Python-list wrote: > > On 02Nov2023 17:04, Chris Angelico wrote: > >On Thu, 2 Nov 2023 at 15:20, AVI GROSS via Python-list > > wrote: > >> Yes, it would be nice if there was a syntax for sending a test > >> message sort > >> of like an ACK that is not delivered to the recipient but merely results in > >> some status being sent back such as DELIVERABLE or NO SUCH USER or even > >> MAILBOX FULL. > > > >Yes, it would! Spammers would be able to use this syntax to figure out > >exactly which addresses actually have real people connected to it. It > >would save them so much trouble! Brilliant idea. > > Hmm. IIRC... > > https://datatracker.ietf.org/doc/html/rfc2821#section-4.1.1.6 > > I think a lot of mail receivers don't honour this one, for exactly the > reasons above. Yeah, and it also won't tell you if the mailbox is full, or unattended, or if the email would be rejected or discarded for any other reason. Which means it's not even all that useful if it IS implemented. ChrisA From PythonList at DancesWithMice.info Thu Nov 2 03:11:27 2023 From: PythonList at DancesWithMice.info (dn) Date: Thu, 2 Nov 2023 20:11:27 +1300 Subject: Checking if email is valid In-Reply-To: <-9noVuOpUQAkPbuiynyonZmXsAiNxRiuOlqaSXQrxmsQreDAE5R-MIt72P3SLBqmntdEd5QI2eSl969CcTVWUUz416g4T8nqC8xB1wZxkCc=@protonmail.com> References: <-9noVuOpUQAkPbuiynyonZmXsAiNxRiuOlqaSXQrxmsQreDAE5R-MIt72P3SLBqmntdEd5QI2eSl969CcTVWUUz416g4T8nqC8xB1wZxkCc=@protonmail.com> Message-ID: On 02/11/2023 19.46, Simon Connah via Python-list wrote: >> On Thu, 2 Nov 2023 at 05:21, Simon Connah via Python-list >> python-list at python.org wrote: >> > >>> Could someone push me in the right direction please? I just want to find out if a string is a valid email address. >> > >> > >> There is only one way to know that a string is a valid email address, >> and that's to send an email to it. >> > >> What is your goal though? For example, if you're trying to autolink >> email addresses in text, you don't really care whether it's valid, >> only that it looks like an address. >> > > > My goal is to make a simple mailing list platform. I guess I could just send email to an address and if it bounces then I can remove it from the database. Thing is I'm not sure how close to a real email address an email has to be in order to be bounced. If it was completely wrong it might just swallowed up. Exactly! Build a complementary script which inspects the returned/bounced messages, and removes those addresses. Given that the list of addresses is built from people signing-up in the first place, one has to presume that people know their own addresses and can type - there's no real defence against 'stupid'*. It's not as if you are making-up addresses yourself (in many jurisdictions it is illegal without opt-in). An email address: account at domain, has to be accurate in two ways: 1 the domain - otherwise the DNS (Domain Name System) won't be able to locate the destination email server 2 the account - otherwise the email server won't know to which mail-box the message should be delivered. The (1) is why there was some suggestion of using MX records (but may as well just send the message). The problem with (2) is that some servers will 'bounce' a message, but others will let it die silently (not wanting to add to email-spam by sending stuff 'back' if the message was spam in the first place!) The exception to (2) is a "catch-all" address, which accepts every message not addressed to a (legal) mail-box. These are sometimes used to deal with messages addressed to a staff-member who has left (for example). However, are somewhat problematic because they pick-up tons of garbage (eg earlier today I received a message to 456789 at domain.tld. This is not, and never has been, a mail-box on the domain; but would drop into a catch-all mail-box. It would be an unusual MailAdmin inspecting a catch-all address, who would return a mis-addressed email to its source. If the message was addressed to Smon at domain.tld, I'd be more likely to assume it was for you, and forward it to you (in the expectation that you'd fix the problem with the sender...). However, ... There are some large businesses doing what you've outlined. They have not solved this problem - and not through lack of trying! * as fast as you make something idiot-proof, the world will show you an 'improved' class of idiot! -- Regards, =dn From simon.n.connah at protonmail.com Thu Nov 2 03:13:55 2023 From: simon.n.connah at protonmail.com (Simon Connah) Date: Thu, 02 Nov 2023 07:13:55 +0000 Subject: Checking if email is valid In-Reply-To: <4eee91d7-7336-4796-a362-2011cc44dafd@gmail.com> References: <4eee91d7-7336-4796-a362-2011cc44dafd@gmail.com> Message-ID: > > > See https://www.linuxjournal.com/article/9585?page=0,0 > That looks painful to maintain! -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 249 bytes Desc: OpenPGP digital signature URL: From PythonList at DancesWithMice.info Thu Nov 2 03:16:58 2023 From: PythonList at DancesWithMice.info (dn) Date: Thu, 2 Nov 2023 20:16:58 +1300 Subject: Checking if email is valid In-Reply-To: References: <-9noVuOpUQAkPbuiynyonZmXsAiNxRiuOlqaSXQrxmsQreDAE5R-MIt72P3SLBqmntdEd5QI2eSl969CcTVWUUz416g4T8nqC8xB1wZxkCc=@protonmail.com> Message-ID: <2d3d9fab-3a28-46ea-94df-94d8b41f4cc4@DancesWithMice.info> On 02/11/2023 19.56, Chris Angelico via Python-list wrote: > On Thu, 2 Nov 2023 at 17:47, Simon Connah wrote: >> >> My goal is to make a simple mailing list platform. I guess I could just send email to an address and if it bounces then I can remove it from the database. Thing is I'm not sure how close to a real email address an email has to be in order to be bounced. If it was completely wrong it might just swallowed up. >> > > Every address is completely separate. There is no "closeness". Just > send email to an address. Agreed. However, with names that are frequently misspelled or which are commonly-spelled slightly differently, the 'trick' is to anticipate problems and set up aliases which forward messages to the correct address*. eg Kelvin -> Kevlin Niel, Neal, Neale (etc) -> Neil (in the same way that GoodLookingGuy at mydomain -> me, or (more likely) MailAdmin -> me) * however, this can end-up perpetuating the mistake, rather than correcting... -- Regards, =dn From RealGrizzlyAdams at vivaldi.net Thu Nov 2 03:09:34 2023 From: RealGrizzlyAdams at vivaldi.net (Grizzy Adams) Date: Thu, 02 Nov 2023 07:09:34 -0000 Subject: Checking if email is valid In-Reply-To: <-9noVuOpUQAkPbuiynyonZmXsAiNxRiuOlqaSXQrxmsQreDAE5R-MIt72P3SLBqmntdEd5QI2eSl969CcTVWUUz416g4T8nqC8xB1wZxkCc=@protonmail.com> Message-ID: <65434B2E.24279.2699A7@RealGrizzlyAdams.vivaldi.net> Thursday, November 02, 2023 at 6:46, Simon Connah via Python-list wrote: Re: Checking if email is valid (at least in part) >My goal is to make a simple mailing list platform. I guess I could just send >email to an address and if it bounces then I can remove it from the database. That function is "built in" with many email clients, I use a modified version to move probably dead addresses to a "bounced" folder, from there I can build a Dlist with one click and test again later, even later I add these addresss to a larger Dlist to filter for mail from known bad/dead addresses From simon.n.connah at protonmail.com Thu Nov 2 03:28:19 2023 From: simon.n.connah at protonmail.com (Simon Connah) Date: Thu, 02 Nov 2023 07:28:19 +0000 Subject: Checking if email is valid In-Reply-To: <2d3d9fab-3a28-46ea-94df-94d8b41f4cc4@DancesWithMice.info> References: <-9noVuOpUQAkPbuiynyonZmXsAiNxRiuOlqaSXQrxmsQreDAE5R-MIt72P3SLBqmntdEd5QI2eSl969CcTVWUUz416g4T8nqC8xB1wZxkCc=@protonmail.com> <2d3d9fab-3a28-46ea-94df-94d8b41f4cc4@DancesWithMice.info> Message-ID: > Agreed. > > However, with names that are frequently misspelled or which are > commonly-spelled slightly differently, the 'trick' is to anticipate > problems and set up aliases which forward messages to the correct address*. > > eg Kelvin -> Kevlin > > Niel, Neal, Neale (etc) -> Neil > > > (in the same way that GoodLookingGuy at mydomain -> me, > > or (more likely) MailAdmin -> me) > > > > * however, this can end-up perpetuating the mistake, rather than > correcting... > > -- > Regards, > =dn I'm not sure that would be practical. As I'm setting up a mailing list server I don't know if someone in the future is going to need to use one of those aliases and testing manually would be tedious. Simon. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 249 bytes Desc: OpenPGP digital signature URL: From PythonList at DancesWithMice.info Thu Nov 2 03:51:32 2023 From: PythonList at DancesWithMice.info (dn) Date: Thu, 2 Nov 2023 20:51:32 +1300 Subject: Checking if email is valid In-Reply-To: References: <-9noVuOpUQAkPbuiynyonZmXsAiNxRiuOlqaSXQrxmsQreDAE5R-MIt72P3SLBqmntdEd5QI2eSl969CcTVWUUz416g4T8nqC8xB1wZxkCc=@protonmail.com> <2d3d9fab-3a28-46ea-94df-94d8b41f4cc4@DancesWithMice.info> Message-ID: On 02/11/2023 20.28, Simon Connah wrote: > I'm not sure that would be practical. As I'm setting up a mailing list server I don't know if someone in the future is going to need to use one of those aliases and testing manually would be tedious. Please re-read. Discussion is about "closeness". Thus, what you might expect from email servers and Admins, NOT what you should do. That part should be quite evident by now! -- Regards, =dn From alan at csail.mit.edu Thu Nov 2 02:29:06 2023 From: alan at csail.mit.edu (Alan Bawden) Date: Thu, 02 Nov 2023 02:29:06 -0400 Subject: Checking if email is valid References: <6542be44.050a0220.e7b44.2143@mx.google.com> <04e7696b-536e-4fcd-9d48-414623cd815a@Vex.Net> <00de01da0d43$b2cb2a80$18617f80$@gmail.com> Message-ID: <86pm0su0r1.fsf@williamsburg.bawden.org> Chris Angelico writes: On Thu, 2 Nov 2023 at 15:20, AVI GROSS via Python-list wrote: > Yes, it would be nice if there was a syntax for sending a test > message sort of like an ACK that is not delivered to the recipient > but merely results in some status being sent back such as > DELIVERABLE or NO SUCH USER or even MAILBOX FULL. Yes, it would! Spammers would be able to use this syntax to figure out exactly which addresses actually have real people connected to it. It would save them so much trouble! Brilliant idea. That sounds like the SMTP "VRFY" command. And spammers _did_ abuse it in exactly this manner. And so pretty much every mail server in the world disabled VRFY sometime in the 90s. - Alan From dan at djph.net Thu Nov 2 05:56:43 2023 From: dan at djph.net (Dan Purgert) Date: Thu, 2 Nov 2023 09:56:43 -0000 (UTC) Subject: Checking if email is valid References: <-9noVuOpUQAkPbuiynyonZmXsAiNxRiuOlqaSXQrxmsQreDAE5R-MIt72P3SLBqmntdEd5QI2eSl969CcTVWUUz416g4T8nqC8xB1wZxkCc=@protonmail.com> Message-ID: On 2023-11-02, dn wrote: > On 02/11/2023 19.46, Simon Connah via Python-list wrote: >> [...] >> My goal is to make a simple mailing list platform. I guess I could >> just send email to an address and if it bounces then I can remove it >> from the database. Thing is I'm not sure how close to a real email >> address an email has to be in order to be bounced. If it was >> completely wrong it might just swallowed up. > > Exactly! > > Build a complementary script which inspects the returned/bounced > messages, and removes those addresses. > > Given that the list of addresses is built from people signing-up in the > first place, one has to presume that people know their own addresses and > can type - there's no real defence against 'stupid'*. It's not as if you > are making-up addresses yourself (in many jurisdictions it is illegal > without opt-in). Isn't opt-in usually to the effect of "send a message with the subject SUBSCRIBE to listname-requests at mailinglist.domain.tld " ? Then the trick becomes filtering out the spam; but the "is the email valid" check is somewhat done as a matter of processing that inbound subscribe message. -- |_|O|_| |_|_|O| Github: https://github.com/dpurgert |O|O|O| PGP: DDAB 23FB 19FA 7D85 1CC1 E067 6D65 70E5 4CE7 2860 From cl at isbd.net Thu Nov 2 06:58:00 2023 From: cl at isbd.net (Chris Green) Date: Thu, 2 Nov 2023 10:58:00 +0000 Subject: pip/pip3 confusion and keeping up to date Message-ID: I have a couple of systems which used to have python2 as well as python3 but as Ubuntu and Debian verions have moved on they have finally eliminated all dependencies on python2. So they now have only python3 and there is no python executable in PATH. There's still both /usr/bin/pip and /usr/bin/pip3 but they're identical so presuably I can now simply use pip and it will be a python3 pip. So, going on from this, how do I do the equivalent of "apt update; apt upgrade" for my globally installed pip packages? -- Chris Green ? From jon+usenet at unequivocal.eu Thu Nov 2 07:27:38 2023 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Thu, 2 Nov 2023 11:27:38 -0000 (UTC) Subject: Checking if email is valid References: <6542be44.050a0220.e7b44.2143@mx.google.com> <04e7696b-536e-4fcd-9d48-414623cd815a@Vex.Net> Message-ID: On 2023-11-02, D'Arcy Cain wrote: > On 2023-11-01 17:17, Chris Angelico via Python-list wrote: >> On Thu, 2 Nov 2023 at 08:09, Grant Edwards via Python-list >> wrote: >>> Make sure it has an '@' in it. Possibly require at least one '.' >>> after the '@'. >> >> No guarantee that there'll be a dot after the at. (Technically there's >> no guarantee of an at sign either, but email addresses without at >> signs are local-only, so in many contexts, you can assume there needs >> to be an at.) > > druid!darcy - doesn't work any more but not because it is syntactically > incorrect. > > Remember the good old days when we were able to test if an address > existed without sending? That was before the black hats discovered the > Internet. I remember the good old days when we were able to send email. From darcy at Vex.Net Thu Nov 2 08:43:53 2023 From: darcy at Vex.Net (D'Arcy Cain) Date: Thu, 2 Nov 2023 08:43:53 -0400 Subject: Checking if email is valid In-Reply-To: References: <6542be44.050a0220.e7b44.2143@mx.google.com> <04e7696b-536e-4fcd-9d48-414623cd815a@Vex.Net> <00de01da0d43$b2cb2a80$18617f80$@gmail.com> Message-ID: <19615214-44e4-45a0-9c23-60930ad7b5a9@Vex.Net> On 2023-11-02 02:04, Chris Angelico via Python-list wrote: > On Thu, 2 Nov 2023 at 15:20, AVI GROSS via Python-list > wrote: >> >> Yes, it would be nice if there was a syntax for sending a test message sort >> of like an ACK that is not delivered to the recipient but merely results in >> some status being sent back such as DELIVERABLE or NO SUCH USER or even >> MAILBOX FULL. >> > > Yes, it would! Spammers would be able to use this syntax to figure out > exactly which addresses actually have real people connected to it. It > would save them so much trouble! Brilliant idea. Which is exactly why we stopped doing it. In fact, mailing software may even have a control to turn it back on but definitely it doesn't reply to the request as delivered. -- D'Arcy J.M. Cain System Administrator, Vex.Net http://www.Vex.Net/ IM:darcy at Vex.Net VoIP: sip:darcy at Vex.Net From simon.n.connah at protonmail.com Thu Nov 2 09:53:23 2023 From: simon.n.connah at protonmail.com (Simon Connah) Date: Thu, 02 Nov 2023 13:53:23 +0000 Subject: Checking if email is valid In-Reply-To: References: <-9noVuOpUQAkPbuiynyonZmXsAiNxRiuOlqaSXQrxmsQreDAE5R-MIt72P3SLBqmntdEd5QI2eSl969CcTVWUUz416g4T8nqC8xB1wZxkCc=@protonmail.com> <2d3d9fab-3a28-46ea-94df-94d8b41f4cc4@DancesWithMice.info> Message-ID: > Please re-read. > Discussion is about "closeness". > Thus, what you might expect from email servers and Admins, NOT what you > should do. That part should be quite evident by now! > My apologies for making a mistake. Simon. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 249 bytes Desc: OpenPGP digital signature URL: From avi.e.gross at gmail.com Thu Nov 2 10:40:01 2023 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Thu, 2 Nov 2023 10:40:01 -0400 Subject: Checking if email is valid In-Reply-To: References: <6542be44.050a0220.e7b44.2143@mx.google.com> <04e7696b-536e-4fcd-9d48-414623cd815a@Vex.Net> <00de01da0d43$b2cb2a80$18617f80$@gmail.com> Message-ID: <005501da0d9a$764a33b0$62de9b10$@gmail.com> Yes, Chris, many things can be used for lesser purposes. Perhaps this could be like when people automate guessing passwords and one defense is to stop accepting after N bad guesses till some external method resets things. -----Original Message----- From: Python-list On Behalf Of Chris Angelico via Python-list Sent: Thursday, November 2, 2023 2:05 AM To: python-list at python.org Subject: Re: Checking if email is valid On Thu, 2 Nov 2023 at 15:20, AVI GROSS via Python-list wrote: > > Yes, it would be nice if there was a syntax for sending a test message sort > of like an ACK that is not delivered to the recipient but merely results in > some status being sent back such as DELIVERABLE or NO SUCH USER or even > MAILBOX FULL. > Yes, it would! Spammers would be able to use this syntax to figure out exactly which addresses actually have real people connected to it. It would save them so much trouble! Brilliant idea. ChrisA -- https://mail.python.org/mailman/listinfo/python-list From dieter at handshake.de Thu Nov 2 12:18:09 2023 From: dieter at handshake.de (Dieter Maurer) Date: Thu, 2 Nov 2023 17:18:09 +0100 Subject: pip/pip3 confusion and keeping up to date In-Reply-To: References: Message-ID: <25923.52161.918925.512734@ixdm.fritz.box> Chris Green wrote at 2023-11-2 10:58 +0000: > ... >So, going on from this, how do I do the equivalent of "apt update; apt >upgrade" for my globally installed pip packages? `pip list -o` will tell you for which packages there are upgrades available. `pip install -U ...` will upgrade packages. Be careful, though. With `apt`, you usually have (`apt`) sources representing a consistent package universe. Someone tests that package upgrades in this universe do not break other packages (in this universe). Because of this, upgrading poses low risk. `PyPI` does not guarantes consistency. A new package version may be incompatible to a previous one -- and with other package you have installed. I do not think that you would want to auto-upgrade all installed packages. From zigocut.tech at gmail.com Thu Nov 2 14:35:01 2023 From: zigocut.tech at gmail.com (Zigocut Technologies) Date: Thu, 2 Nov 2023 21:35:01 +0300 Subject: Errors Message-ID: Hello, I would like to develop Mobile Applications using the Kivy Python Framework but I am having difficulty and these are the errors I am finding " C:\WINDOWS\system32>python3 --version Python was not found; run without arguments to install from the Microsoft Store, or disable this shortcut from Settings > Manage App Execution Aliases." after installing Python 3.9 I also had another error is " WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno 11001] getaddrinfo failed')': /simple/kivy-deps-gstreamer-dev/" how can I go about these errors? I am running windows 10 Best Regards *Owner Zigocut Technologies * *+256774306868/701067528* From jon+usenet at unequivocal.eu Thu Nov 2 08:00:27 2023 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Thu, 2 Nov 2023 12:00:27 -0000 (UTC) Subject: Checking if email is valid References: <6542be44.050a0220.e7b44.2143@mx.google.com> Message-ID: On 2023-11-02, Simon Connah wrote: > Valid as in conforms to the standard. Although having looked at the > standard that might be more difficult than originally planned. Yes. Almost nobody actually implements "the standard" as in RFC 2822 section 3.4.1 (which can contain, for example, non-printable control characters, and comments), nor is it particularly clear that they should. So while checking against "the spec" might sound right, it's highly unlikely that it's what you actually want. Would you really want to allow: (jam today) "chris @ \"home\""@ (Chris's host.)public.example for example? And would you be able to do anything with it if you did? From darcy at Vex.Net Thu Nov 2 08:58:21 2023 From: darcy at Vex.Net (D'Arcy Cain) Date: Thu, 2 Nov 2023 08:58:21 -0400 Subject: Checking if email is valid In-Reply-To: <00de01da0d43$b2cb2a80$18617f80$@gmail.com> References: <6542be44.050a0220.e7b44.2143@mx.google.com> <04e7696b-536e-4fcd-9d48-414623cd815a@Vex.Net> <00de01da0d43$b2cb2a80$18617f80$@gmail.com> Message-ID: <87e117e0-68df-4e08-9eb5-338471a5890b@Vex.Net> On 2023-11-02 00:18, AVI GROSS via Python-list wrote: > Yes, it would be nice if there was a syntax for sending a test message sort > of like an ACK that is not delivered to the recipient but merely results in > some status being sent back such as DELIVERABLE or NO SUCH USER or even > MAILBOX FULL. It used to do that. The facility was very quickly turned off. > I note earlier iterations of email had addressed like > mach1!mach2!mach3!ihnp4!mach5!mach6!user or even mach1!mach2!user at mach3 and > I remember tools that analyzed what other machines various machines claimed > to have a direct connection to and tried to figure out a connection from > your source to destination, perhaps a shorter one or maybe a less expensive > one. Hence machines like ihnp4 and various universities that were densely > connected to others got lots of traffic. In that scenario, validity had > another meaning. Yep. It's called UUCP. It still exists. You can even do UUCP over TCP/IP. -- D'Arcy J.M. Cain System Administrator, Vex.Net http://www.Vex.Net/ IM:darcy at Vex.Net VoIP: sip:darcy at Vex.Net From jon+usenet at unequivocal.eu Thu Nov 2 10:55:55 2023 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Thu, 2 Nov 2023 14:55:55 -0000 (UTC) Subject: pip/pip3 confusion and keeping up to date References: Message-ID: On 2023-11-02, Chris Green wrote: > I have a couple of systems which used to have python2 as well as > python3 but as Ubuntu and Debian verions have moved on they have > finally eliminated all dependencies on python2. > > So they now have only python3 and there is no python executable in > PATH. > > There's still both /usr/bin/pip and /usr/bin/pip3 but they're > identical so presuably I can now simply use pip and it will be a > python3 pip. > > > So, going on from this, how do I do the equivalent of "apt update; apt > upgrade" for my globally installed pip packages? I'm not sure what that question has to do with everything that preceded it, but you don't want to install python packages globally using pip. Either install them with 'apt', or install them in a virtual environment. From jon+usenet at unequivocal.eu Thu Nov 2 12:35:28 2023 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Thu, 2 Nov 2023 16:35:28 -0000 (UTC) Subject: pip/pip3 confusion and keeping up to date References: <25923.52161.918925.512734@ixdm.fritz.box> Message-ID: On 2023-11-02, Dieter Maurer wrote: > Chris Green wrote at 2023-11-2 10:58 +0000: >> ... >>So, going on from this, how do I do the equivalent of "apt update; apt >>upgrade" for my globally installed pip packages? > > `pip list -o` will tell you for which packages there are upgrades > available. > `pip install -U ...` will upgrade packages. > > Be careful, though. > With `apt`, you usually have (`apt`) sources representing a consistent > package universe. Someone tests that package upgrades in this > universe do not break other packages (in this universe). > Because of this, upgrading poses low risk. > > `PyPI` does not guarantes consistency. A new package version > may be incompatible to a previous one -- and with other > package you have installed. > > I do not think that you would want to auto-upgrade all installed > packages. Indeed. What you're describing is a very unfortunate failing of pip. 'Upgrade' doesn't even follow requirements when you tell it what to upgrade - e.g. if you do "pip install foo" and foo requires "bar<2" so you end up with: Package Version ---------------------- --------- foo 1.0.0 bar 1.2.0 and then a new version 1.3.0 of bar comes out and you do "pip install -U foo", pip will not upgrade bar even though it could and should, because foo is already at the latest version so pip won't even look at its dependencies. Indeed there is no way of knowing that you should upgrade bar without manually following all the dependency graphs. ("pip list -o" will tell you there's a newer version, but that isn't the same - e.g. if the new version of bar was 2.0.0 then "pip list -o" will list it, but you should not upgrade to it.) You can do "pip install -I foo", which will pointlessly reinstall foo and then presumably upgrade bar as well, thus probably getting to the right result via a rather roundabout route, but I'm not sure if that does indeed work properly and if it is a reliable and recommended way of doing things. From torriem at gmail.com Thu Nov 2 16:17:13 2023 From: torriem at gmail.com (Michael Torrie) Date: Thu, 2 Nov 2023 14:17:13 -0600 Subject: Checking if email is valid In-Reply-To: References: <6542be44.050a0220.e7b44.2143@mx.google.com> Message-ID: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> On 11/2/23 00:42, Simon Connah via Python-list wrote: > Basically I'm writing unit tests and one of them passess in a string > with an invalid email address. I need to be able to check the string > to see if it is a valid email so that the unit test passess. If you truly have managed to code an RFC-compliant verifier, I commend you. > Valid as in conforms to the standard. Although having looked at the > standard that might be more difficult than originally planned. You'll have to read the relevant RFCs. Lots of corner cases! From what I can see virtually no one on the internet gets it right, judging by the number of times I have valid email addresses flagged as not valid by poor algorithms. From cl at isbd.net Thu Nov 2 17:16:49 2023 From: cl at isbd.net (Chris Green) Date: Thu, 2 Nov 2023 21:16:49 +0000 Subject: pip/pip3 confusion and keeping up to date References: Message-ID: <17gd1k-866j.ln1@esprimo.zbmc.eu> Jon Ribbens wrote: > On 2023-11-02, Chris Green wrote: > > I have a couple of systems which used to have python2 as well as > > python3 but as Ubuntu and Debian verions have moved on they have > > finally eliminated all dependencies on python2. > > > > So they now have only python3 and there is no python executable in > > PATH. > > > > There's still both /usr/bin/pip and /usr/bin/pip3 but they're > > identical so presuably I can now simply use pip and it will be a > > python3 pip. > > > > > > So, going on from this, how do I do the equivalent of "apt update; apt > > upgrade" for my globally installed pip packages? > > I'm not sure what that question has to do with everything that preceded > it, but you don't want to install python packages globally using pip. > Either install them with 'apt', or install them in a virtual environment. Why in a virtual environment? When I install a package whether from apt or from pip I want everyone/everything on my system to be able to use it. I do only install a few things using pip. -- Chris Green ? From cl at isbd.net Thu Nov 2 17:19:43 2023 From: cl at isbd.net (Chris Green) Date: Thu, 2 Nov 2023 21:19:43 +0000 Subject: pip/pip3 confusion and keeping up to date References: <25923.52161.918925.512734@ixdm.fritz.box> Message-ID: Jon Ribbens wrote: > On 2023-11-02, Dieter Maurer wrote: > > Chris Green wrote at 2023-11-2 10:58 +0000: > >> ... > >>So, going on from this, how do I do the equivalent of "apt update; apt > >>upgrade" for my globally installed pip packages? > > > > `pip list -o` will tell you for which packages there are upgrades > > available. > > `pip install -U ...` will upgrade packages. > > > > Be careful, though. > > With `apt`, you usually have (`apt`) sources representing a consistent > > package universe. Someone tests that package upgrades in this > > universe do not break other packages (in this universe). > > Because of this, upgrading poses low risk. > > > > `PyPI` does not guarantes consistency. A new package version > > may be incompatible to a previous one -- and with other > > package you have installed. > > > > I do not think that you would want to auto-upgrade all installed > > packages. > > Indeed. What you're describing is a very unfortunate failing of pip. > 'Upgrade' doesn't even follow requirements when you tell it what to > upgrade - e.g. if you do "pip install foo" and foo requires "bar<2" > so you end up with: > > Package Version > ---------------------- --------- > foo 1.0.0 > bar 1.2.0 > > and then a new version 1.3.0 of bar comes out and you do > "pip install -U foo", pip will not upgrade bar even though it could > and should, because foo is already at the latest version so pip won't > even look at its dependencies. > > Indeed there is no way of knowing that you should upgrade bar without > manually following all the dependency graphs. ("pip list -o" will tell > you there's a newer version, but that isn't the same - e.g. if the new > version of bar was 2.0.0 then "pip list -o" will list it, but you should > not upgrade to it.) > > You can do "pip install -I foo", which will pointlessly reinstall foo > and then presumably upgrade bar as well, thus probably getting to the > right result via a rather roundabout route, but I'm not sure if that > does indeed work properly and if it is a reliable and recommended way > of doing things. It is a bit of a minefield isn't it. I try to minimise my use of packages installed using pip for this very reason. Maybe the safest route would simply be to uninstall everything and then re-install it. ? From jon+usenet at unequivocal.eu Thu Nov 2 17:35:43 2023 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Thu, 2 Nov 2023 21:35:43 -0000 (UTC) Subject: pip/pip3 confusion and keeping up to date References: <17gd1k-866j.ln1@esprimo.zbmc.eu> Message-ID: On 2023-11-02, Chris Green wrote: > Jon Ribbens wrote: >> On 2023-11-02, Chris Green wrote: >> > I have a couple of systems which used to have python2 as well as >> > python3 but as Ubuntu and Debian verions have moved on they have >> > finally eliminated all dependencies on python2. >> > >> > So they now have only python3 and there is no python executable in >> > PATH. >> > >> > There's still both /usr/bin/pip and /usr/bin/pip3 but they're >> > identical so presuably I can now simply use pip and it will be a >> > python3 pip. >> > >> > >> > So, going on from this, how do I do the equivalent of "apt update; apt >> > upgrade" for my globally installed pip packages? >> >> I'm not sure what that question has to do with everything that preceded >> it, but you don't want to install python packages globally using pip. >> Either install them with 'apt', or install them in a virtual environment. > > Why in a virtual environment? When I install a package whether from > apt or from pip I want everyone/everything on my system to be able to > use it. Because pip barely plays well by itself, let alone with other package managers at the same time. > I do only install a few things using pip. Are they not available in your system's package manager? I guess you might get away with "sudo -H pip install -U foo" for a couple of things, if they don't have many dependencies. From jon+usenet at unequivocal.eu Thu Nov 2 17:38:33 2023 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Thu, 2 Nov 2023 21:38:33 -0000 (UTC) Subject: pip/pip3 confusion and keeping up to date References: <25923.52161.918925.512734@ixdm.fritz.box> Message-ID: On 2023-11-02, Chris Green wrote: > Jon Ribbens wrote: >> On 2023-11-02, Dieter Maurer wrote: >> > Chris Green wrote at 2023-11-2 10:58 +0000: >> >> ... >> >>So, going on from this, how do I do the equivalent of "apt update; apt >> >>upgrade" for my globally installed pip packages? >> > >> > `pip list -o` will tell you for which packages there are upgrades >> > available. >> > `pip install -U ...` will upgrade packages. >> > >> > Be careful, though. >> > With `apt`, you usually have (`apt`) sources representing a consistent >> > package universe. Someone tests that package upgrades in this >> > universe do not break other packages (in this universe). >> > Because of this, upgrading poses low risk. >> > >> > `PyPI` does not guarantes consistency. A new package version >> > may be incompatible to a previous one -- and with other >> > package you have installed. >> > >> > I do not think that you would want to auto-upgrade all installed >> > packages. >> >> Indeed. What you're describing is a very unfortunate failing of pip. >> 'Upgrade' doesn't even follow requirements when you tell it what to >> upgrade - e.g. if you do "pip install foo" and foo requires "bar<2" >> so you end up with: >> >> Package Version >> ---------------------- --------- >> foo 1.0.0 >> bar 1.2.0 >> >> and then a new version 1.3.0 of bar comes out and you do >> "pip install -U foo", pip will not upgrade bar even though it could >> and should, because foo is already at the latest version so pip won't >> even look at its dependencies. >> >> Indeed there is no way of knowing that you should upgrade bar without >> manually following all the dependency graphs. ("pip list -o" will tell >> you there's a newer version, but that isn't the same - e.g. if the new >> version of bar was 2.0.0 then "pip list -o" will list it, but you should >> not upgrade to it.) >> >> You can do "pip install -I foo", which will pointlessly reinstall foo >> and then presumably upgrade bar as well, thus probably getting to the >> right result via a rather roundabout route, but I'm not sure if that >> does indeed work properly and if it is a reliable and recommended way >> of doing things. > > It is a bit of a minefield isn't it. I try to minimise my use of > packages installed using pip for this very reason. Maybe the safest > route would simply be to uninstall everything and then re-install it. That is literally what I do quite often - completely erase the virtual env and then re-create it from scratch - because it seems to be the only / easiest way to upgrade the packages to the latest versions consistent with given dependencies. From mats at wichmann.us Thu Nov 2 18:07:33 2023 From: mats at wichmann.us (Mats Wichmann) Date: Thu, 2 Nov 2023 16:07:33 -0600 Subject: pip/pip3 confusion and keeping up to date In-Reply-To: References: Message-ID: <82c6f025-61dd-4557-84e7-bc4ddb43a0e7@wichmann.us> On 11/2/23 04:58, Chris Green via Python-list wrote: > I have a couple of systems which used to have python2 as well as > python3 but as Ubuntu and Debian verions have moved on they have > finally eliminated all dependencies on python2. > > So they now have only python3 and there is no python executable in > PATH. FWIW, for this you install the little stub package python-is-python3. Especially if you want to keep a python2 installation around - "python" will still be python3 in this case. > So, going on from this, how do I do the equivalent of "apt update; apt > upgrade" for my globally installed pip packages Odds are you don't want to. The internet is full of surprises about dependency problems when stuff is blindly updated; the set of Python packages in the apt repositories is carefully curated to avoid these problems - and this is part of the reason why sometimes certain such packages are irritatingly down-rev. From miked at dewhirst.com.au Thu Nov 2 18:30:42 2023 From: miked at dewhirst.com.au (Mike Dewhirst) Date: Fri, 03 Nov 2023 09:30:42 +1100 Subject: Checking if email is valid In-Reply-To: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> Message-ID: <4SLzJm1dwdznWHQ@mail.python.org> If i wanted an email verifier I would look at open source frameworks and see how they do it. Django comes to mind.--(Unsigned mail from my phone) -------- Original message --------From: Michael Torrie via Python-list Date: 3/11/23 07:23 (GMT+10:00) To: python-list at python.org Subject: Re: Checking if email is valid On 11/2/23 00:42, Simon Connah via Python-list wrote:> Basically I'm writing unit tests and one of them passess in a string > with an invalid email address. I need to be able to check the string > to see if it is a valid email so that the unit test passess.If you truly have managed to code an RFC-compliant verifier, I commend you.> Valid as in conforms to the standard. Although having looked at the> standard that might be more difficult than originally planned.You'll have to read the relevant RFCs.? Lots of corner cases!? From whatI can see virtually no one on the internet gets it right, judging by thenumber of times I have valid email addresses flagged as not valid bypoor algorithms.-- https://mail.python.org/mailman/listinfo/python-list From rosuav at gmail.com Thu Nov 2 20:44:50 2023 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 3 Nov 2023 11:44:50 +1100 Subject: Checking if email is valid In-Reply-To: References: <6542be44.050a0220.e7b44.2143@mx.google.com> Message-ID: On Fri, 3 Nov 2023 at 07:17, Jon Ribbens via Python-list wrote: > > On 2023-11-02, Simon Connah wrote: > > Valid as in conforms to the standard. Although having looked at the > > standard that might be more difficult than originally planned. > > Yes. Almost nobody actually implements "the standard" as in RFC 2822 > section 3.4.1 (which can contain, for example, non-printable control > characters, and comments), nor is it particularly clear that they > should. So while checking against "the spec" might sound right, it's > highly unlikely that it's what you actually want. Would you really > want to allow: > > (jam today) "chris @ \"home\""@ (Chris's host.)public.example > > for example? And would you be able to do anything with it if you did? If by checking against the spec you mean "sending an email to it with a code or magic link", then.... sure, allow that! It's still short enough to fit on one line, even. Seems fine to me. Of course, since that one is in the .example TLD, it's not actually going to succeed, but now I'm curious whether you could craft a mail server that mandates the Queen's rule of "jam tomorrow, jam yesterday, but never jam today". That part is technically a comment, but it's a clear violation of a royal decree, so that should cause the email to bounce. It's jam every OTHER day, and today isn't any OTHER day. ChrisA From avi.e.gross at gmail.com Thu Nov 2 21:19:41 2023 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Thu, 2 Nov 2023 21:19:41 -0400 Subject: Checking if email is valid In-Reply-To: <4SLzJm1dwdznWHQ@mail.python.org> References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <4SLzJm1dwdznWHQ@mail.python.org> Message-ID: <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> I have never had a need to check email but in my reading over the years, I am aware of modules of multiple kinds you can use to do things like parsing dates, URL and email addresses and probably many other such things into some kind of object and then you can use aspects of the object to do interesting things and perhaps change some and then ask for the object to be placed back into some other format such as text. My guess is that a first test of an email address might be to see if a decent module of that kind fills out the object to your satisfaction. You can then perhaps test parts of the object, rather than everything at once, to see if it is obviously invalid. As an example, what does user at alpha.......com with what seems to be lots of meaningless periods, get parsed into? This may be another approach that reuses what may be well-designed and tested shared software. I wonder if there are also such modules that do quite a bit of what is asked which is to reject a large class of badly formed addresses. You could, of course, take what survives and run additional screens. In the end, this is a bit like junkmail where some light-AI algorithms go over a corpus of messages that humans have curated as junk or not junk and make some statistical decisions that are nonetheless often wrong. In that case, many humans nastily declare thinks as SPAM just because they do not want to get such messages. If you blasted out email alerts every time a child seems to have been kidnapped to everyone in the nation, how long before many such messages would become designated as SPAM? So is there any work where people have taken a decent collection of email addresses used in the past that turned out to be syntactically valid or not, and trained an algorithm to recognize most of them properly? That trained algorithm could be shared and incorporated into your programs either as the only method, or one you use in special cases. -----Original Message----- From: Python-list On Behalf Of Mike Dewhirst via Python-list Sent: Thursday, November 2, 2023 6:31 PM To: python-list at python.org Subject: Re: Checking if email is valid If i wanted an email verifier I would look at open source frameworks and see how they do it. Django comes to mind.--(Unsigned mail from my phone) -------- Original message --------From: Michael Torrie via Python-list Date: 3/11/23 07:23 (GMT+10:00) To: python-list at python.org Subject: Re: Checking if email is valid On 11/2/23 00:42, Simon Connah via Python-list wrote:> Basically I'm writing unit tests and one of them passess in a string > with an invalid email address. I need to be able to check the string > to see if it is a valid email so that the unit test passess.If you truly have managed to code an RFC-compliant verifier, I commend you.> Valid as in conforms to the standard. Although having looked at the> standard that might be more difficult than originally planned.You'll have to read the relevant RFCs. Lots of corner cases! From whatI can see virtually no one on the internet gets it right, judging by thenumber of times I have valid email addresses flagged as not valid bypoor algorithms.-- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list From rosuav at gmail.com Fri Nov 3 01:42:45 2023 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 3 Nov 2023 16:42:45 +1100 Subject: Checking if email is valid In-Reply-To: <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <4SLzJm1dwdznWHQ@mail.python.org> <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> Message-ID: On Fri, 3 Nov 2023 at 12:21, AVI GROSS via Python-list wrote: > My guess is that a first test of an email address might be to see if a decent module of that kind fills out the object to your satisfaction. You can then perhaps test parts of the object, rather than everything at once, to see if it is obviously invalid. As an example, what does user at alpha.......com with what seems to be lots of meaningless periods, get parsed into? > What do you mean by "obviously invalid"? Have you read the RFC? ChrisA From cl at isbd.net Fri Nov 3 06:05:09 2023 From: cl at isbd.net (Chris Green) Date: Fri, 3 Nov 2023 10:05:09 +0000 Subject: pip/pip3 confusion and keeping up to date References: <17gd1k-866j.ln1@esprimo.zbmc.eu> Message-ID: Jon Ribbens wrote: > On 2023-11-02, Chris Green wrote: > > Jon Ribbens wrote: > >> On 2023-11-02, Chris Green wrote: > >> > I have a couple of systems which used to have python2 as well as > >> > python3 but as Ubuntu and Debian verions have moved on they have > >> > finally eliminated all dependencies on python2. > >> > > >> > So they now have only python3 and there is no python executable in > >> > PATH. > >> > > >> > There's still both /usr/bin/pip and /usr/bin/pip3 but they're > >> > identical so presuably I can now simply use pip and it will be a > >> > python3 pip. > >> > > >> > > >> > So, going on from this, how do I do the equivalent of "apt update; apt > >> > upgrade" for my globally installed pip packages? > >> > >> I'm not sure what that question has to do with everything that preceded > >> it, but you don't want to install python packages globally using pip. > >> Either install them with 'apt', or install them in a virtual environment. > > > > Why in a virtual environment? When I install a package whether from > > apt or from pip I want everyone/everything on my system to be able to > > use it. > > Because pip barely plays well by itself, let alone with other package > managers at the same time. > Well that's a criticism of pip rather than of how I use it! :-) OK, there are risks. > > I do only install a few things using pip. > > Are they not available in your system's package manager? > I guess you might get away with "sudo -H pip install -U foo" > for a couple of things, if they don't have many dependencies. I obviously check the package manager and also other sources which work through apt before resorting to using pip. The sort of thing I have to use pip for is software for odd I2C sensor devices and such. These rarely have any dependencies or they are all the same dependencies as the other I2C device software. So, hopefully, I won't hit any big problems. I have to say that so far I haven't been bitten. I would point out that this is mostly for a headless Beaglebone Black single board computer (comparable with a Raspberry Pi) with only a minimal 'console' installation of Debian so it's a pretty minimal system. -- Chris Green ? From jon+usenet at unequivocal.eu Fri Nov 3 06:51:28 2023 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Fri, 3 Nov 2023 10:51:28 -0000 (UTC) Subject: Checking if email is valid References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <4SLzJm1dwdznWHQ@mail.python.org> <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> Message-ID: On 2023-11-03, Chris Angelico wrote: > On Fri, 3 Nov 2023 at 12:21, AVI GROSS via Python-list > wrote: >> My guess is that a first test of an email address might be to see if >> a decent module of that kind fills out the object to your >> satisfaction. You can then perhaps test parts of the object, rather >> than everything at once, to see if it is obviously invalid. As an >> example, what does user at alpha.......com with what seems to be lots of >> meaningless periods, get parsed into? > > What do you mean by "obviously invalid"? Have you read the RFC? What do you mean by 'What do you mean by "obviously invalid"?' Have you read the RFC? From avi.e.gross at gmail.com Fri Nov 3 08:29:48 2023 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Fri, 3 Nov 2023 08:29:48 -0400 Subject: Checking if email is valid In-Reply-To: References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <4SLzJm1dwdznWHQ@mail.python.org> <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> Message-ID: <002601da0e51$6f883bf0$4e98b3d0$@gmail.com> Chris, I don't mean anything specific in the abstract approach I outlined as a possible alternative to using one complex regular expression. My suggestion was that some of the work could be done by the module you used and THEN you may test various parts of the rest. For example, perhaps another module lets you test if the domain name is registered. I have not read the RFC and have not worked on email applications in decades and am not offering specific advice. I am merely suggesting the possible use of existing software modules that may provide a better approach in weeding out SOME bad addresses. -----Original Message----- From: Python-list On Behalf Of Chris Angelico via Python-list Sent: Friday, November 3, 2023 1:43 AM To: python-list at python.org Subject: Re: Checking if email is valid On Fri, 3 Nov 2023 at 12:21, AVI GROSS via Python-list wrote: > My guess is that a first test of an email address might be to see if a decent module of that kind fills out the object to your satisfaction. You can then perhaps test parts of the object, rather than everything at once, to see if it is obviously invalid. As an example, what does user at alpha.......com with what seems to be lots of meaningless periods, get parsed into? > What do you mean by "obviously invalid"? Have you read the RFC? ChrisA -- https://mail.python.org/mailman/listinfo/python-list From Karsten.Hilbert at gmx.net Fri Nov 3 09:47:18 2023 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Fri, 3 Nov 2023 14:47:18 +0100 Subject: pip/pip3 confusion and keeping up to date In-Reply-To: References: <17gd1k-866j.ln1@esprimo.zbmc.eu> Message-ID: Am Thu, Nov 02, 2023 at 09:35:43PM -0000 schrieb Jon Ribbens via Python-list: Regardless of ... > Because pip barely plays well by itself, let alone with other package > managers at the same time. ... being true ... > > I do only install a few things using pip. > > Are they not available in your system's package manager? ... this clearly often answers to "no" for applications of any complexity. Is there a suggested proper path to deal with that (Debian is of interest to me here) ? Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B From dieter at handshake.de Fri Nov 3 12:26:06 2023 From: dieter at handshake.de (Dieter Maurer) Date: Fri, 3 Nov 2023 17:26:06 +0100 Subject: pip/pip3 confusion and keeping up to date In-Reply-To: References: <17gd1k-866j.ln1@esprimo.zbmc.eu> Message-ID: <25925.7966.521097.868744@ixdm.fritz.box> Karsten Hilbert wrote at 2023-11-3 14:47 +0100: > ... >> Are they not available in your system's package manager? > >... this clearly often answers to "no" for applications of >any complexity. > >Is there a suggested proper path to deal with that (Debian is >of interest to me here) ? Complex applications may maintain a set of "known workable versions" associated with the application's releases. They may describe those "known workable versions" in a `pip` constraint file. In this case, you can upgrade to a new application release by using this constraint file. From grant.b.edwards at gmail.com Fri Nov 3 12:57:34 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Fri, 03 Nov 2023 09:57:34 -0700 (PDT) Subject: Checking if email is valid References: =?utf-8?q?=3Cnze9mu-VI8ExA3VA9RA07qMo9Oj03xuWoTe-FL6N=5FAbOGK0QC?= =?utf-8?q?6LdqaeKq-OvcrilFYqqT5tc9LsvSqHRKDYMGaBXzlVzyOdX9Ae0Xp=5FACtg=3D?= =?utf-8?q?=40protonmail=2Ecom=3E?= <6542be44.050a0220.e7b44.2143@mx.google.com> =?utf-8?q?=3Cr0NlTIlUyGCuaJjYT?= =?utf-8?q?9d6E0PpLUzMUXrBTPnWdkUZ13sbrMnvfkhSInG9BiYBsfa4yZjfxX8BLVyQRRtp8O?= =?utf-8?q?kMFAatApkbr4T5tU3F7OX-aVM=3D=40protonmail=2Ecom=3E?= <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> Message-ID: <6545267e.920a0220.45517.10a5@mx.google.com> On 2023-11-02, Michael Torrie via Python-list wrote: > On 11/2/23 00:42, Simon Connah via Python-list wrote: > >> Valid as in conforms to the standard. Although having looked at the >> standard that might be more difficult than originally planned. > > You'll have to read the relevant RFCs. Lots of corner cases! From what > I can see virtually no one on the internet gets it right, judging by the > number of times I have valid email addresses flagged as not valid by > poor algorithms. I've wondered if there are addresses that violate the RFC (and would therefore be "correctly" rejected), but but in practice will work just fine. I've never spent enough time looking at the RFC to even propose test cases for that... -- Grant From simon.n.connah at protonmail.com Fri Nov 3 13:11:08 2023 From: simon.n.connah at protonmail.com (Simon Connah) Date: Fri, 03 Nov 2023 17:11:08 +0000 Subject: Checking if email is valid In-Reply-To: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> References: <6542be44.050a0220.e7b44.2143@mx.google.com> <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> Message-ID: > > > On 11/2/23 00:42, Simon Connah via Python-list wrote: > > > Basically I'm writing unit tests and one of them passess in a string > > with an invalid email address. I need to be able to check the string > > to see if it is a valid email so that the unit test passess. > > > If you truly have managed to code an RFC-compliant verifier, I commend you. Sorry I wasn't clear. I haven't written anything of the sort but I was looking to see if there was a third party option but from feedback in this thread it appears that way is considered a bad option. Simon. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 249 bytes Desc: OpenPGP digital signature URL: From list1 at tompassin.net Fri Nov 3 15:12:39 2023 From: list1 at tompassin.net (Thomas Passin) Date: Fri, 3 Nov 2023 15:12:39 -0400 Subject: Checking if email is valid In-Reply-To: References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <4SLzJm1dwdznWHQ@mail.python.org> <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> Message-ID: On 11/3/2023 6:51 AM, Jon Ribbens via Python-list wrote: > On 2023-11-03, Chris Angelico wrote: >> On Fri, 3 Nov 2023 at 12:21, AVI GROSS via Python-list >> wrote: >>> My guess is that a first test of an email address might be to see if >>> a decent module of that kind fills out the object to your >>> satisfaction. You can then perhaps test parts of the object, rather >>> than everything at once, to see if it is obviously invalid. As an >>> example, what does user at alpha.......com with what seems to be lots of >>> meaningless periods, get parsed into? >> >> What do you mean by "obviously invalid"? Have you read the RFC? > > What do you mean by 'What do you mean by "obviously invalid"?' > Have you read the RFC? About reading the RFC, there's this ... but read the comments too ... https://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx/ From simon.n.connah at protonmail.com Sat Nov 4 04:51:14 2023 From: simon.n.connah at protonmail.com (Simon Connah) Date: Sat, 04 Nov 2023 08:51:14 +0000 Subject: Checking if email is valid In-Reply-To: References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <4SLzJm1dwdznWHQ@mail.python.org> <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> Message-ID: > > On 11/3/2023 6:51 AM, Jon Ribbens via Python-list wrote: > > > On 2023-11-03, Chris Angelico rosuav at gmail.com wrote: > > > > > On Fri, 3 Nov 2023 at 12:21, AVI GROSS via Python-list > > > python-list at python.org wrote: > > > > > > > My guess is that a first test of an email address might be to see if > > > > a decent module of that kind fills out the object to your > > > > satisfaction. You can then perhaps test parts of the object, rather > > > > than everything at once, to see if it is obviously invalid. As an > > > > example, what does user at alpha.......com with what seems to be lots of > > > > meaningless periods, get parsed into? > > > > > > What do you mean by "obviously invalid"? Have you read the RFC? > > > > What do you mean by 'What do you mean by "obviously invalid"?' > > Have you read the RFC? > > > About reading the RFC, there's this ... but read the comments too ... > > https://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx/ > > Wow. I'm half tempted to make a weird email address to see how many websites get it wrong. Thank you for the link. Simon. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 249 bytes Desc: OpenPGP digital signature URL: From simon.n.connah at protonmail.com Sat Nov 4 05:01:32 2023 From: simon.n.connah at protonmail.com (Simon Connah) Date: Sat, 04 Nov 2023 09:01:32 +0000 Subject: Checking if email is valid In-Reply-To: References: <6542be44.050a0220.e7b44.2143@mx.google.com> Message-ID: > > > On 2023-11-02, Simon Connah simon.n.connah at protonmail.com wrote: > > > Valid as in conforms to the standard. Although having looked at the > > standard that might be more difficult than originally planned. > > > Yes. Almost nobody actually implements "the standard" as in RFC 2822 > section 3.4.1 (which can contain, for example, non-printable control > characters, and comments), nor is it particularly clear that they > should. So while checking against "the spec" might sound right, it's > highly unlikely that it's what you actually want. Would you really > want to allow: > > (jam today) "chris @ \"home\""@ (Chris's host.)public.example > > for example? And would you be able to do anything with it if you did? As I said in another post it would be interesting to see what broke when you tried to use an esoteric email address in the wild. Maybe when I'm bored :D. Simon. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 249 bytes Desc: OpenPGP digital signature URL: From torriem at gmail.com Sat Nov 4 12:19:14 2023 From: torriem at gmail.com (Michael Torrie) Date: Sat, 4 Nov 2023 10:19:14 -0600 Subject: Checking if email is valid In-Reply-To: References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <4SLzJm1dwdznWHQ@mail.python.org> <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> Message-ID: On 11/4/23 02:51, Simon Connah via Python-list wrote: > Wow. I'm half tempted to make a weird email address to see how many websites get it wrong. > > Thank you for the link. Nearly all websites seem to reject simple correct email addresses such as myemail+sometext at example.domain. I like to use this kind of email address when I can to help me filter out the inevitable spam that comes from companies selling off my address even after claiming they won't. So I suspect that nearly all websites are going to reject other kinds of weird email addresses you can create that are actually correct. From Karsten.Hilbert at gmx.net Fri Nov 3 09:44:27 2023 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Fri, 3 Nov 2023 14:44:27 +0100 Subject: pip/pip3 confusion and keeping up to date In-Reply-To: <82c6f025-61dd-4557-84e7-bc4ddb43a0e7@wichmann.us> References: <82c6f025-61dd-4557-84e7-bc4ddb43a0e7@wichmann.us> Message-ID: Am Thu, Nov 02, 2023 at 04:07:33PM -0600 schrieb Mats Wichmann via Python-list: > >So they now have only python3 and there is no python executable in > >PATH. > > FWIW, for this you install the little stub package python-is-python3. Especially if you > want to keep a python2 installation around - "python" will still be python3 in this > case. Since you seem knowledgeable in this area: Do you know of a resource for learning the *canonical* way of packaging a Python application for installation via apt which - needs some packages available via apt - needs some packages only available via pip - needs some packages newer than what is available via apt ? Thanks, Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B From jon+usenet at unequivocal.eu Fri Nov 3 09:53:32 2023 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Fri, 3 Nov 2023 13:53:32 -0000 (UTC) Subject: pip/pip3 confusion and keeping up to date References: <17gd1k-866j.ln1@esprimo.zbmc.eu> Message-ID: On 2023-11-03, Karsten Hilbert wrote: > Am Thu, Nov 02, 2023 at 09:35:43PM -0000 schrieb Jon Ribbens via Python-list: > > Regardless of ... > >> Because pip barely plays well by itself, let alone with other package >> managers at the same time. > > ... being true ... > >> > I do only install a few things using pip. >> >> Are they not available in your system's package manager? > > ... this clearly often answers to "no" for applications of > any complexity. > > Is there a suggested proper path to deal with that (Debian is > of interest to me here) ? Yes, as previously mentioned, use virtual environments. These days they don't even need to be "activated". For package 'foo' for example you could create /usr/local/lib/foo, under which you would create a virtual environment and install the 'foo' package inside it, and then you could do: ln -s /usr/local/lib/foo/env/bin/foo /usr/local/bin/foo and then you could just type 'foo' to run it. From bart.kuijer at ziggo.nl Sat Nov 4 12:37:30 2023 From: bart.kuijer at ziggo.nl (bart.kuijer) Date: Sat, 04 Nov 2023 17:37:30 +0100 Subject: Python-list Digest, Vol 242, Issue 3 In-Reply-To: Message-ID: <20231104173728.zJeKqYrYbFCD5zJeKq16gl@csmtp5-prd-nl1-vfz.edge.unified.services> I don 't understand the meaning of this mail?Verzonden vanaf mijn Galaxy -------- Oorspronkelijk bericht --------Van: python-list-request at python.org Datum: 04-11-23 17:01 (GMT+01:00) Aan: python-list at python.org Onderwerp: Python-list Digest, Vol 242, Issue 3 Send Python-list mailing list submissions to python-list at python.orgTo subscribe or unsubscribe via the World Wide Web, visit https://mail.python.org/mailman/listinfo/python-listor, via email, send a message with subject or body 'help' to python-list-request at python.orgYou can reach the person managing the list at python-list-owner at python.orgWhen replying, please edit your Subject line so it is more specificthan "Re: Contents of Python-list digest..." From grant.b.edwards at gmail.com Sun Nov 5 00:39:29 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Sat, 04 Nov 2023 21:39:29 -0700 (PDT) Subject: Checking if email is valid References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <4SLzJm1dwdznWHQ@mail.python.org> <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> =?utf-8?q?=3CMx55woazM?= =?utf-8?q?nLDymJMOEfKPZ1QqPpdzYCq5IynLBt3KDiTEY7EZ58=5FZKGcHNWXmD7mfCprd6cM?= =?utf-8?q?-FSE6FH2He83fCJKpSXEosC-U=5FeQj1VY7gI=3D=40protonmail=2Ecom=3E?= Message-ID: <65471c81.920a0220.a88bf.2427@mx.google.com> On 2023-11-04, Michael Torrie via Python-list wrote: > On 11/4/23 02:51, Simon Connah via Python-list wrote: > >> Wow. I'm half tempted to make a weird email address to see how many >> websites get it wrong. In my experience, they don't have to be very weird at all. >> Thank you for the link. > > Nearly all websites seem to reject simple correct email addresses > such as myemail+sometext at example.domain. I like to use this kind of > email address when I can to help me filter out the inevitable spam > that comes from companies selling off my address even after claiming > they won't. I've always suspected that's intentional. They refuse those sorts of e-mail addresses because they know that's what they are used for. If they allowed "plus suffixed" e-mail addresses, then all the crap they want to send to you would go into /dev/null where it belongs -- and we can't have that! > So I suspect that nearly all websites are going to reject other > kinds of weird email addresses you can create that are actually > correct. Definitely. Syntactic e-mail address "validation" is one of the most useless and widely broken things on the Interwebs. People who do anything other than require an '@' (and optionally make you enter the same @-containing string twice) are deluding themselves. -- Grant From darcy at VybeNetworks.com Sun Nov 5 05:28:19 2023 From: darcy at VybeNetworks.com (D'Arcy Cain) Date: Sun, 5 Nov 2023 05:28:19 -0500 Subject: Checking if email is valid In-Reply-To: <65471c81.920a0220.a88bf.2427@mx.google.com> References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <4SLzJm1dwdznWHQ@mail.python.org> <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> Message-ID: <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> On 2023-11-05 00:39, Grant Edwards via Python-list wrote: > Definitely. Syntactic e-mail address "validation" is one of the most > useless and widely broken things on the Interwebs. People who do > anything other than require an '@' (and optionally make you enter the > same @-containing string twice) are deluding themselves. And don't get me started on phone number validation. The most annoying thing to me, though, is sites that reject names that have an apostrophe in them. I hate being told that my name, that I have been using for over seventy years, is invalid. OK, now that I am started, what else? Oh yah. Look at your credit card. The number has spaces in it. Why do I have to remove them. If you don't like them then you are a computer, just remove them. When do we stop working for computers and have the computers start working for us? -- D'Arcy J.M. Cain Vybe Networks Inc. http://www.VybeNetworks.com/ IM:darcy at Vex.Net VoIP: sip:darcy at VybeNetworks.com From avi.e.gross at gmail.com Sun Nov 5 08:06:39 2023 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Sun, 5 Nov 2023 08:06:39 -0500 Subject: Checking if email is valid In-Reply-To: <65471c81.920a0220.a88bf.2427@mx.google.com> References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <4SLzJm1dwdznWHQ@mail.python.org> <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> Message-ID: <003301da0fe8$ea52b890$bef829b0$@gmail.com> Grant (and others), I am asking about the overall programming process of dealing with email addresses beyond checking the string for some validity. You mentioned requiring you type in your email twice as one example. I generally do a copy/paste to avoid typing or have my browser fill it in. Rarely the code is set to force me to actually type it in. And I note sites that force me to do too much typing of any kind or make me jump through hoops like having to get an email or text with a secondary number to type in or make me look at pictures and find the right ones and so on, encourage me to not use them much. There is a price for taking away convenience even if you see it as some form of security. Yes, there are tradeoffs. It really may be important to know what you want from your email addresses. If I sign YOU up for something like the Word of the day in a dozen languages by supplying your valid email address, then checking if it looks valid is less useful than sending an email to that address and asking the recipient to opt-in and verify they legitimately want it. If you want to ensure that your newsletter is still wanted, you may do something similar every year or so to everyone, or perhaps just those that have not had activity. If a mailbox starts rejecting messages, perhaps you send messages to their secondary contact info or just remove them. There are many such strategies and some may be way harder to implement than a simple and perhaps simplistic syntax check. I do wonder how much it sometimes matters when we see real-world scenarios where people who died a decade ago remain on voter registration rolls. If my mailing list has a few hundred bad emails on it, the costs of sending may be small albeit dealing with rejection messages may clog my logs. As for fake email addresses, there are many ways to play that game that are unlikely to be caught. Will they realize there is nobody at erewhon at gmail.com? If you want to know if someone is going to sell your hello.there at gmail.com address could you supply hell.other.e at gmail.com and then monitor mail that you will still receive as it seems google ignores periods in your email name? And, since others generally see the above as distinct, you can even use such a method to sign up for something multiple times. Complexity leaves room for loopholes. Still, obviously there are good reasons to do what you can to do some validation at many points along the way and especially when it may be critical. Asking someone to type in a new password twice when they cannot easily see what they are typing, is obviously useful as the consequence of losing it is high. Are getting the email addresses right as important? I know my wife registered a fairly common name of the jane.doe at gmail.com variety that is now useless as it keeps receiving messages someone provided or typed in wrong that were supposed to go to janedoe@ or doe.jane@ or janedoe123@ or j.doe@ and so on. These include receipts, subscriptions to newsletters and much more. Some are inadvertent but the reality is she stopped using that email as it is now mostly full of SPAM as the others ... -----Original Message----- From: Python-list On Behalf Of Grant Edwards via Python-list Sent: Sunday, November 5, 2023 12:39 AM To: python-list at python.org Subject: Re: Checking if email is valid On 2023-11-04, Michael Torrie via Python-list wrote: > On 11/4/23 02:51, Simon Connah via Python-list wrote: > >> Wow. I'm half tempted to make a weird email address to see how many >> websites get it wrong. In my experience, they don't have to be very weird at all. >> Thank you for the link. > > Nearly all websites seem to reject simple correct email addresses > such as myemail+sometext at example.domain. I like to use this kind of > email address when I can to help me filter out the inevitable spam > that comes from companies selling off my address even after claiming > they won't. I've always suspected that's intentional. They refuse those sorts of e-mail addresses because they know that's what they are used for. If they allowed "plus suffixed" e-mail addresses, then all the crap they want to send to you would go into /dev/null where it belongs -- and we can't have that! > So I suspect that nearly all websites are going to reject other > kinds of weird email addresses you can create that are actually > correct. Definitely. Syntactic e-mail address "validation" is one of the most useless and widely broken things on the Interwebs. People who do anything other than require an '@' (and optionally make you enter the same @-containing string twice) are deluding themselves. -- Grant -- https://mail.python.org/mailman/listinfo/python-list From gheskett at shentel.net Sun Nov 5 09:56:00 2023 From: gheskett at shentel.net (gene heskett) Date: Sun, 5 Nov 2023 09:56:00 -0500 Subject: Checking if email is valid In-Reply-To: <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <4SLzJm1dwdznWHQ@mail.python.org> <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> Message-ID: On 11/5/23 05:32, D'Arcy Cain via Python-list wrote: > On 2023-11-05 00:39, Grant Edwards via Python-list wrote: >> Definitely. Syntactic e-mail address "validation" is one of the most >> useless and widely broken things on the Interwebs.? People who do >> anything other than require an '@' (and optionally make you enter the >> same @-containing string twice) are deluding themselves. > > And don't get me started on phone number validation.? The most annoying > thing to me, though, is sites that reject names that have an apostrophe > in them.? I hate being told that my name, that I have been using for > over seventy years, is invalid. > > OK, now that I am started, what else?? Oh yah.? Look at your credit > card.? The number has spaces in it.? Why do I have to remove them.? If > you don't like them then you are a computer, just remove them. > > When do we stop working for computers and have the computers start > working for us? > If this is being voted on, pretend you are in Georgia, vote often and early. Best question of the century. Cheers, Gene Heskett. -- "There are four boxes to be used in defense of liberty: soap, ballot, jury, and ammo. Please use in that order." -Ed Howdershelt (Author, 1940) If we desire respect for the law, we must first make the law respectable. - Louis D. Brandeis From grant.b.edwards at gmail.com Sun Nov 5 12:34:25 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Sun, 05 Nov 2023 09:34:25 -0800 (PST) Subject: Checking if email is valid References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <4SLzJm1dwdznWHQ@mail.python.org> <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> =?utf-8?q?=3CMx55woazM?= =?utf-8?q?nLDymJMOEfKPZ1QqPpdzYCq5IynLBt3KDiTEY7EZ58=5FZKGcHNWXmD7mfCprd6cM?= =?utf-8?q?-FSE6FH2He83fCJKpSXEosC-U=5FeQj1VY7gI=3D=40protonmail=2Ecom=3E?= <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> Message-ID: <6547d221.050a0220.c5340.1e8f@mx.google.com> On 2023-11-05, D'Arcy Cain via Python-list wrote: > On 2023-11-05 00:39, Grant Edwards via Python-list wrote: >> Definitely. Syntactic e-mail address "validation" is one of the most >> useless and widely broken things on the Interwebs. People who do >> anything other than require an '@' (and optionally make you enter the >> same @-containing string twice) are deluding themselves. > > And don't get me started on phone number validation. I can see how the truley dim-witted might forget that other countries have phone numbers with differing lengths and formatting/punctuation, but there are tons of sites where it takes multiple tries when entering even a bog-standard USA 10-0digit phone nubmer because they are completely flummuxed by an area code in parens or hyphens in the usual places (or lack of hyhpens in the usual places). This stuff isn't that hard, people... > The most annoying thing to me, though, is sites that reject names > that have an apostrophe in them. I hate being told that my name, > that I have been using for over seventy years, is invalid. > > OK, now that I am started, what else? Oh yah. Look at your credit > card. The number has spaces in it. Why do I have to remove them. If > you don't like them then you are a computer, just remove them. Indeed. There is a tiny but brightly burning kernel of hate in my heart for web sites (and their developers) that refuse to accept credit card numbers entered with spaces _as_they_are_shown_on_the_card_! I've concluded that using PHP causes debilitating and irreversible brain damage. > When do we stop working for computers and have the computers start > working for us? -- Grant From jon+usenet at unequivocal.eu Sun Nov 5 07:48:04 2023 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Sun, 5 Nov 2023 12:48:04 -0000 (UTC) Subject: Checking if email is valid References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <4SLzJm1dwdznWHQ@mail.python.org> <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> Message-ID: On 2023-11-05, D'Arcy Cain wrote: > On 2023-11-05 00:39, Grant Edwards via Python-list wrote: >> Definitely. Syntactic e-mail address "validation" is one of the most >> useless and widely broken things on the Interwebs. People who do >> anything other than require an '@' (and optionally make you enter the >> same @-containing string twice) are deluding themselves. > > And don't get me started on phone number validation. The most annoying > thing to me, though, is sites that reject names that have an apostrophe > in them. I hate being told that my name, that I have been using for > over seventy years, is invalid. Sometimes I think that these sorts of stupid, wrong, validation are the fault of idiot managers. When it's apostrophes though I'm suspicious that it may be idiot programmers who don't know how to prevent SQL injection attacks without just saying "ban all apostrophes everywhere". Or perhaps it's idiot "security consultancies" who make it a tick-box requirement. > OK, now that I am started, what else? Oh yah. Look at your credit > card. The number has spaces in it. Why do I have to remove them. If > you don't like them then you are a computer, just remove them. Yes, this is also very stupid and annoying. Does nobody who works for the companies making these sorts of websites ever use their own, or indeed anyone else's, website? Another one that's become popular recently is the sort of annoying website that insists on "email 2FA", i.e. you try to login and then they send you an email with a 6-digit code in that you have to enter to authenticate yourself. So you go to your mail client and double-click on the number to select it, and stupid thing (A) happens: for no sane reason, the computer selects the digits *and also an invisible space after them*. Then you copy the digits into the web form, then invisible space tags along for the ride, and stupid thing (B) happens: the web server rejects the code because of the trailing space. Honestly I don't understand why every web application platform doesn't automatically strip all leading and trailing whitespace on user input by default. It's surely incredibly rare that it's sensible to preserve it. (I see Django eventually got around to this in version 1.9.) From jon+usenet at unequivocal.eu Sun Nov 5 07:59:12 2023 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Sun, 5 Nov 2023 12:59:12 -0000 (UTC) Subject: pip/pip3 confusion and keeping up to date References: <82c6f025-61dd-4557-84e7-bc4ddb43a0e7@wichmann.us> Message-ID: On 2023-11-03, Karsten Hilbert wrote: > Am Thu, Nov 02, 2023 at 04:07:33PM -0600 schrieb Mats Wichmann via Python-list: >> >So they now have only python3 and there is no python executable in >> >PATH. >> >> FWIW, for this you install the little stub package python-is-python3. >> Especially if you want to keep a python2 installation around - >> "python" will still be python3 in this case. > > Since you seem knowledgeable in this area: Do you know of a > resource for learning the *canonical* way of packaging a > Python application for installation via apt which > > - needs some packages available via apt > - needs some packages only available via pip > - needs some packages newer than what is available via apt > > ? I suspect the answer to that is that you would have to: * create packages yourself for the unpackaged dependencies * create a dependency graph of *every* Python package in the package repository (whether or not the package is relevant to what you're doing) * work out what versions of every Python package are required in order to have a dependency graph that can be successfully resolved, taking into account the requirements of your new package also * contact every single maintainer of every single one of the packages that needs updating and persuade them to update their packages and reassure them that you are getting all the other package maintainers to update their packages accordingly and that you have a plan and that you know what you're doing ... screen fades to black, title card "3 years later", fade in to ... * publish your package From work.22102 at outlook.com Sun Nov 5 08:37:44 2023 From: work.22102 at outlook.com (office officce) Date: Sun, 5 Nov 2023 13:37:44 +0000 Subject: Help Message-ID: which python version is better to be used and how to make sure it works on my window 10 because i downloaded it and it never worked so I uninstall to do that again please can you give me the steps on how it will work perfectly from Kenny From jon+usenet at unequivocal.eu Sun Nov 5 11:04:21 2023 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Sun, 5 Nov 2023 16:04:21 -0000 (UTC) Subject: pip/pip3 confusion and keeping up to date References: <82c6f025-61dd-4557-84e7-bc4ddb43a0e7@wichmann.us> Message-ID: On 2023-11-05, Chris Green wrote: > Jon Ribbens wrote: >> On 2023-11-03, Karsten Hilbert wrote: >> > Am Thu, Nov 02, 2023 at 04:07:33PM -0600 schrieb Mats Wichmann via Python-list: >> >> >So they now have only python3 and there is no python executable in >> >> >PATH. >> >> >> >> FWIW, for this you install the little stub package python-is-python3. >> >> Especially if you want to keep a python2 installation around - >> >> "python" will still be python3 in this case. >> > >> > Since you seem knowledgeable in this area: Do you know of a >> > resource for learning the *canonical* way of packaging a >> > Python application for installation via apt which >> > >> > - needs some packages available via apt >> > - needs some packages only available via pip >> > - needs some packages newer than what is available via apt >> > >> > ? >> >> I suspect the answer to that is that you would have to: >> >> * create packages yourself for the unpackaged dependencies >> * create a dependency graph of *every* Python package in the package >> repository (whether or not the package is relevant to what you're doing) >> * work out what versions of every Python package are required in order >> to have a dependency graph that can be successfully resolved, taking >> into account the requirements of your new package also >> * contact every single maintainer of every single one of the packages >> that needs updating and persuade them to update their packages and >> reassure them that you are getting all the other package maintainers >> to update their packages accordingly and that you have a plan and >> that you know what you're doing >> >> ... screen fades to black, title card "3 years later", fade in to ... >> >> * publish your package >> > Surely it's not that bad, the vast bulk of Debian, Ubuntu and other > distributions are installed via systems that sort out dependencies once > given a particular package's requirements. Python is surely not > unique in its dependency requirements. I think there's a lot of work that goes on behind the scenes to keep the entire package set consistent so that you don't end up in the situation where, e.g. package A depends on D<2.0 and package B requires D>=2.0 and therefore you can't install A and B at the same time (and trying to avoid as much as possible the hacky situation where you have two packages for D, one for <2.0 and another called D2 for >=2.0). From jon+usenet at unequivocal.eu Sun Nov 5 12:45:35 2023 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Sun, 5 Nov 2023 17:45:35 -0000 (UTC) Subject: Checking if email is valid References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <4SLzJm1dwdznWHQ@mail.python.org> <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> <6547d221.050a0220.c5340.1e8f@mx.google.com> Message-ID: On 2023-11-05, Grant Edwards wrote: > On 2023-11-05, D'Arcy Cain via Python-list wrote: >> On 2023-11-05 00:39, Grant Edwards via Python-list wrote: >>> Definitely. Syntactic e-mail address "validation" is one of the most >>> useless and widely broken things on the Interwebs. People who do >>> anything other than require an '@' (and optionally make you enter the >>> same @-containing string twice) are deluding themselves. >> >> And don't get me started on phone number validation. > > I can see how the truley dim-witted might forget that other countries > have phone numbers with differing lengths and formatting/punctuation, > but there are tons of sites where it takes multiple tries when > entering even a bog-standard USA 10-0digit phone nubmer because they > are completely flummuxed by an area code in parens or hyphens in the > usual places (or lack of hyhpens in the usual places). This stuff > isn't that hard, people... Indeed - you just do "pip install phonenumbers" :-) From mats at wichmann.us Sun Nov 5 13:57:35 2023 From: mats at wichmann.us (Mats Wichmann) Date: Sun, 5 Nov 2023 11:57:35 -0700 Subject: Checking if email is valid In-Reply-To: <6547d221.050a0220.c5340.1e8f@mx.google.com> References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <4SLzJm1dwdznWHQ@mail.python.org> <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> <6547d221.050a0220.c5340.1e8f@mx.google.com> Message-ID: <28524e60-77a9-4828-940d-fa4eb13eca8f@wichmann.us> On 11/5/23 10:34, Grant Edwards via Python-list wrote: > Indeed. There is a tiny but brightly burning kernel of hate in my > heart for web sites (and their developers) that refuse to accept > credit card numbers entered with spaces _as_they_are_shown_on_the_card_! > > I've concluded that using PHP causes debilitating and irreversible > brain damage. I think it's the attitude that speed of deployment is more important than any other factor, rather than just PHP :-) Plus a bunch of that stuff is also coded in the front end (aka Javascript). Phone numbers. Credit card numbers. Names (in my case - my wife has a hypenated surname which is almost as deadly as non-alpha characters in a name which was already mentioned in this diverging thread) and addresses. living rurally we have two addresses: a post office rural route box for USPS and a "street address" for anyone else. The former looks like "{locationID} Box {number}". The single word "Box" often triggers "we don't deliver to P.O. Boxes" - it's not a PO Box, and it's the only address USPS will deliver to, so get over yourself. Or triggers fraud detection alerts, because "billing address" != "shipping address". it's astonishing how bad so many websites are at what should be a fundamental function: taking in user-supplied data in order to do something valuable with it. From cl at isbd.net Sun Nov 5 10:00:41 2023 From: cl at isbd.net (Chris Green) Date: Sun, 5 Nov 2023 15:00:41 +0000 Subject: pip/pip3 confusion and keeping up to date References: <82c6f025-61dd-4557-84e7-bc4ddb43a0e7@wichmann.us> Message-ID: Jon Ribbens wrote: > On 2023-11-03, Karsten Hilbert wrote: > > Am Thu, Nov 02, 2023 at 04:07:33PM -0600 schrieb Mats Wichmann via Python-list: > >> >So they now have only python3 and there is no python executable in > >> >PATH. > >> > >> FWIW, for this you install the little stub package python-is-python3. > >> Especially if you want to keep a python2 installation around - > >> "python" will still be python3 in this case. > > > > Since you seem knowledgeable in this area: Do you know of a > > resource for learning the *canonical* way of packaging a > > Python application for installation via apt which > > > > - needs some packages available via apt > > - needs some packages only available via pip > > - needs some packages newer than what is available via apt > > > > ? > > I suspect the answer to that is that you would have to: > > * create packages yourself for the unpackaged dependencies > * create a dependency graph of *every* Python package in the package > repository (whether or not the package is relevant to what you're doing) > * work out what versions of every Python package are required in order > to have a dependency graph that can be successfully resolved, taking > into account the requirements of your new package also > * contact every single maintainer of every single one of the packages > that needs updating and persuade them to update their packages and > reassure them that you are getting all the other package maintainers > to update their packages accordingly and that you have a plan and > that you know what you're doing > > ... screen fades to black, title card "3 years later", fade in to ... > > * publish your package > Surely it's not that bad, the vast bulk of Debian, Ubuntu and other distributions are installed via systems that sort out dependencies once given a particular package's requirements. Python is surely not unique in its dependency requirements. -- Chris Green ? From Karsten.Hilbert at gmx.net Sun Nov 5 17:19:00 2023 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Sun, 5 Nov 2023 23:19:00 +0100 Subject: pip/pip3 confusion and keeping up to date In-Reply-To: <25925.7966.521097.868744@ixdm.fritz.box> References: <17gd1k-866j.ln1@esprimo.zbmc.eu> <25925.7966.521097.868744@ixdm.fritz.box> Message-ID: Am Fri, Nov 03, 2023 at 05:26:06PM +0100 schrieb Dieter Maurer: > Karsten Hilbert wrote at 2023-11-3 14:47 +0100: > > ... > >> Are they not available in your system's package manager? > > > >... this clearly often answers to "no" for applications of > >any complexity. > > > >Is there a suggested proper path to deal with that (Debian is > >of interest to me here) ? > > Complex applications may maintain a set of "known workable versions" > associated with the application's releases. > They may describe those "known workable versions" in a `pip` constraint file. > In this case, you can upgrade to a new application release > by using this constraint file. Hello Dieter, do you happen to know where to read up on how to fit a pip constraint file into a Debian package creation workflow ? Thanks, Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B From Karsten.Hilbert at gmx.net Sun Nov 5 17:22:38 2023 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Sun, 5 Nov 2023 23:22:38 +0100 Subject: pip/pip3 confusion and keeping up to date In-Reply-To: References: <17gd1k-866j.ln1@esprimo.zbmc.eu> Message-ID: Am Fri, Nov 03, 2023 at 01:53:32PM -0000 schrieb Jon Ribbens via Python-list: > >> Are they not available in your system's package manager? > > > > ... this clearly often answers to "no" for applications of > > any complexity. > > > > Is there a suggested proper path to deal with that (Debian is > > of interest to me here) ? > > Yes, as previously mentioned, use virtual environments. > > These days they don't even need to be "activated". For package 'foo' > for example you could create /usr/local/lib/foo, under which you would > create a virtual environment and install the 'foo' package inside it, > and then you could do: > > ln -s /usr/local/lib/foo/env/bin/foo /usr/local/bin/foo > > and then you could just type 'foo' to run it. This all being nice and well, but: How does one "fill" that venv with packages from pip during apt-get install python3-app-of-interest ? Is the suggested way really to pip-install into this venv during apt-get install ? Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B From Karsten.Hilbert at gmx.net Sun Nov 5 17:29:24 2023 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Sun, 5 Nov 2023 23:29:24 +0100 Subject: pip/pip3 confusion and keeping up to date In-Reply-To: References: <82c6f025-61dd-4557-84e7-bc4ddb43a0e7@wichmann.us> Message-ID: Am Sun, Nov 05, 2023 at 03:00:41PM +0000 schrieb Chris Green via Python-list: > > * contact every single maintainer of every single one of the packages > > that needs updating and persuade them to update their packages and > > reassure them that you are getting all the other package maintainers > > to update their packages accordingly and that you have a plan and > > that you know what you're doing > > > > ... screen fades to black, title card "3 years later", fade in to ... > > > > * publish your package > > > Surely it's not that bad, the vast bulk of Debian, Ubuntu and other > distributions are installed via systems that sort out dependencies once > given a particular package's requirements. Python is surely not > unique in its dependency requirements. Oh, Debian does just fine in resolving dependencies it knows about within its .deb package universe. The problem arises when there's unpackaged modules required. The only answer seems to be to package such modules oneself. If that's been conquered a venv isn't even needed anymore. Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B From PythonList at DancesWithMice.info Sun Nov 5 18:25:22 2023 From: PythonList at DancesWithMice.info (dn) Date: Mon, 6 Nov 2023 12:25:22 +1300 Subject: Safe package removal Message-ID: <9271e0ea-e10c-4bb8-b264-c587008d1ca6@DancesWithMice.info> After thread: "pip/pip3 confusion and keeping up to date" Over the years?centuries, have added various packages, using all of: - distribution-installer (dnf/yum - per apt-get) - su pip install, and - (user) pip install Because Fedora-Linux can be upgraded in-place. an amount of 'crud' hangs-about 'forever'. Accordingly, python -m pip list --outdated shows about as many entries as python - m pip list! Have (comparatively recently) standardised that projects not inside a VM or Container, will be managed by Poetry. (It's working well!) Q1 Can all (user) pip installs be safely removed, 'just like that'? Q2 How can one ascertain if system (su/sudo) pip installed packages can be removed - or are used by the op-sys/some important application? Q3 Similarly, if one can uninstall those originally installed using the distribution-installer, or if something, somewhere, will 'break'? (yes, there's an upgrade to Fedora 38 in "The Backlog") -- Regards, =dn From jon+usenet at unequivocal.eu Sun Nov 5 20:17:11 2023 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Mon, 6 Nov 2023 01:17:11 -0000 (UTC) Subject: pip/pip3 confusion and keeping up to date References: <17gd1k-866j.ln1@esprimo.zbmc.eu> Message-ID: On 2023-11-05, Karsten Hilbert wrote: > Am Fri, Nov 03, 2023 at 01:53:32PM -0000 schrieb Jon Ribbens via Python-list: > >> >> Are they not available in your system's package manager? >> > >> > ... this clearly often answers to "no" for applications of >> > any complexity. >> > >> > Is there a suggested proper path to deal with that (Debian is >> > of interest to me here) ? >> >> Yes, as previously mentioned, use virtual environments. >> >> These days they don't even need to be "activated". For package 'foo' >> for example you could create /usr/local/lib/foo, under which you would >> create a virtual environment and install the 'foo' package inside it, >> and then you could do: >> >> ln -s /usr/local/lib/foo/env/bin/foo /usr/local/bin/foo >> >> and then you could just type 'foo' to run it. > > This all being nice and well, but: > > How does one "fill" that venv with packages from pip during > > apt-get install python3-app-of-interest > > ? > > Is the suggested way really to pip-install into this venv > during apt-get install ? I don't know what you mean by that. But if you install the apt packages and then create your venv with --system-site-packages then I believe your venv should be able to see the apt packages and import them. From darcy at VybeNetworks.com Sun Nov 5 20:22:49 2023 From: darcy at VybeNetworks.com (D'Arcy Cain) Date: Sun, 5 Nov 2023 19:22:49 -0600 Subject: Checking if email is valid In-Reply-To: References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <4SLzJm1dwdznWHQ@mail.python.org> <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> Message-ID: <603b5741-f74a-4639-a94c-5b5297bca427@VybeNetworks.com> On 2023-11-05 06:48, Jon Ribbens via Python-list wrote: > Sometimes I think that these sorts of stupid, wrong, validation are the > fault of idiot managers. When it's apostrophes though I'm suspicious > that it may be idiot programmers who don't know how to prevent SQL > injection attacks without just saying "ban all apostrophes everywhere". > Or perhaps it's idiot "security consultancies" who make it a tick-box > requirement. https://xkcd.com/327/ >> OK, now that I am started, what else? Oh yah. Look at your credit >> card. The number has spaces in it. Why do I have to remove them. If >> you don't like them then you are a computer, just remove them. > > Yes, this is also very stupid and annoying. Does nobody who works for > the companies making these sorts of websites ever use their own, or > indeed anyone else's, website? Gotta wonder for sure. It could also be the case of programmers depending on user input but the users insist on living with the bugs and/or working around them. We made crash reporting dead simple to report on and still users didn't bother. We would get the traceback and have to guess what the user was doing. > Honestly I don't understand why every web application platform doesn't > automatically strip all leading and trailing whitespace on user input > by default. It's surely incredibly rare that it's sensible to preserve > it. (I see Django eventually got around to this in version 1.9.) Yes, I have done that forever. Never had a complaint about it dropping characters. -- D'Arcy J.M. Cain Vybe Networks Inc. http://www.VybeNetworks.com/ IM:darcy at Vex.Net VoIP: sip:darcy at VybeNetworks.com From dieter at handshake.de Mon Nov 6 02:58:00 2023 From: dieter at handshake.de (Dieter Maurer) Date: Mon, 6 Nov 2023 08:58:00 +0100 Subject: pip/pip3 confusion and keeping up to date In-Reply-To: References: <17gd1k-866j.ln1@esprimo.zbmc.eu> <25925.7966.521097.868744@ixdm.fritz.box> Message-ID: <25928.40072.353056.140342@ixdm.fritz.box> Karsten Hilbert wrote at 2023-11-5 23:19 +0100: > ... >do you happen to know where to read up on how to fit a pip >constraint file into a Debian package creation workflow ? I have only rudimentary `apt` knowledge. I know it is quite flexible, e.g. it used to handle `flash` in a special way. I expect it flexible enough to load from `PyPI`. `apt` is essentially controlled by a set of `sources`. Each "source" describes a list of package distributions. A description contains metadata about the distribution including name, version, description, dependencies, incompatibilities, etc. Any integration would require you to define one or more "source"s, listing the distributions which should come from `PyPI`. This would allow you to specify potential upgrades at a central place, the "source"s, you control. It would not solve the more fundamental problem: to determine which versions are compatible with the universe of (all the "sources" described) package versions. I know that debian packagers create debian packages from Python distributions not using the approach sketched above and likely they have their reasons. You might want to discuss this on an `apt` related mailing list. From simon.n.connah at protonmail.com Mon Nov 6 03:57:28 2023 From: simon.n.connah at protonmail.com (Simon Connah) Date: Mon, 06 Nov 2023 08:57:28 +0000 Subject: Checking if email is valid In-Reply-To: <6547d221.050a0220.c5340.1e8f@mx.google.com> References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> <6547d221.050a0220.c5340.1e8f@mx.google.com> Message-ID: > I can see how the truley dim-witted might forget that other countries > have phone numbers with differing lengths and formatting/punctuation, > but there are tons of sites where it takes multiple tries when > entering even a bog-standard USA 10-0digit phone nubmer because they > are completely flummuxed by an area code in parens or hyphens in the > usual places (or lack of hyhpens in the usual places). This stuff > isn't that hard, people... The thing I truly hate is when you have two telephone number fields. One for landline and one for mobile. I mean who in hell has a landline these days? And not accepting your mobile number in the landline number field is just when I give up. Or having a landline only field that does not accept mobile phones. Simon. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 249 bytes Desc: OpenPGP digital signature URL: From bowman at montana.com Mon Nov 6 00:34:07 2023 From: bowman at montana.com (rbowman) Date: 6 Nov 2023 05:34:07 GMT Subject: Checking if email is valid References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <4SLzJm1dwdznWHQ@mail.python.org> <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> <603b5741-f74a-4639-a94c-5b5297bca427@VybeNetworks.com> Message-ID: On Sun, 5 Nov 2023 19:22:49 -0600, D'Arcy Cain wrote: > Gotta wonder for sure. It could also be the case of programmers > depending on user input but the users insist on living with the bugs > and/or working around them. We made crash reporting dead simple to > report on and still users didn't bother. We would get the traceback and > have to guess what the user was doing. We've found even if you directly ask the user often the answer is 'I dunno' or some mythology they have constructed to explain the problem. We had one site that reported if they hit the Enter key hard the query would work. It was a rather simple bug where the query would be randomly sent to the wrong interface. There is quite a bit of literature in psychology about intermittent reinforcement and the behavioral strategies that are developed. Works for rats, works for humans. From jon+usenet at unequivocal.eu Mon Nov 6 05:17:16 2023 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Mon, 6 Nov 2023 10:17:16 -0000 (UTC) Subject: Checking if email is valid References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <4SLzJm1dwdznWHQ@mail.python.org> <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> <603b5741-f74a-4639-a94c-5b5297bca427@VybeNetworks.com> Message-ID: On 2023-11-06, D'Arcy Cain wrote: > On 2023-11-05 06:48, Jon Ribbens via Python-list wrote: >> Sometimes I think that these sorts of stupid, wrong, validation are the >> fault of idiot managers. When it's apostrophes though I'm suspicious >> that it may be idiot programmers who don't know how to prevent SQL >> injection attacks without just saying "ban all apostrophes everywhere". >> Or perhaps it's idiot "security consultancies" who make it a tick-box >> requirement. > > https://xkcd.com/327/ Indeed. My point is that the correct way to solve this problem is not to declare vast swathes of valid inputs verboten, but to *not execute user input as code*. Controversial, I know. >>> OK, now that I am started, what else? Oh yah. Look at your credit >>> card. The number has spaces in it. Why do I have to remove them. If >>> you don't like them then you are a computer, just remove them. >> >> Yes, this is also very stupid and annoying. Does nobody who works for >> the companies making these sorts of websites ever use their own, or >> indeed anyone else's, website? > > Gotta wonder for sure. It could also be the case of programmers > depending on user input but the users insist on living with the bugs > and/or working around them. We made crash reporting dead simple to > report on and still users didn't bother. We would get the traceback and > have to guess what the user was doing. That was another thing that I used to find ridiculous, but seems to have improved somewhat in recent years - website error pages that said "please contact us to let us know about this error". I'm sorry, what? You want me to contact you to tell you about what your own website is doing? How does that make any sense? Websites should be self-reporting problems. (Not least because, as you say, people are absolutely terrible at reporting problems, with almost all bug reports reading effectively as "I was doing something that I'm not going to tell you and I as expecting something to happen which I'm not going to tell you, but instead something else happened, which I'm also not going to tell you".) From mats at wichmann.us Mon Nov 6 09:44:20 2023 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 6 Nov 2023 07:44:20 -0700 Subject: Checking if email is valid In-Reply-To: References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> <6547d221.050a0220.c5340.1e8f@mx.google.com> Message-ID: On 11/6/23 01:57, Simon Connah via Python-list wrote: > The thing I truly hate is when you have two telephone number fields. One for landline and one for mobile. I mean who in hell has a landline these days? People who live in places with spotty, or no, mobile coverage. We do exist. From c.buhtz at posteo.jp Mon Nov 6 07:47:57 2023 From: c.buhtz at posteo.jp (c.buhtz at posteo.jp) Date: Mon, 06 Nov 2023 12:47:57 +0000 Subject: Detect naming typos (AttributeError) in function names Message-ID: <5e41dd577da656946398652a83acb0be@posteo.de> Hello, I would like to know how to detect (e.g. via a linter) typos in function names imported from another module. Let's assume this given Python code snippet. import foo foo.baR() The package "foo" do contain a function named "bar()" (all lower case letters). The function "baR()" does not exist in "foo". This cause an AttributeError when run with a Python interpreter. The described error is not detected in my IDE (Emacs with eglot, pylsp and flake8) and not by flake8 on the shell. Because the involved tools do not look inside the "foo" package if "baR()" really exist. Can I fix this somehow? I am aware that this would get detected by a unit test. That is the way I do prefer in most cases. But sometimes not all code segments are covered by tests. I'm more interested in using a linter or something else for that. Kind Christian From jon+usenet at unequivocal.eu Mon Nov 6 10:23:27 2023 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Mon, 6 Nov 2023 15:23:27 -0000 (UTC) Subject: Checking if email is valid References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> <6547d221.050a0220.c5340.1e8f@mx.google.com> Message-ID: On 2023-11-06, Mats Wichmann wrote: > On 11/6/23 01:57, Simon Connah via Python-list wrote: >> The thing I truly hate is when you have two telephone number fields. >> One for landline and one for mobile. I mean who in hell has a >> landline these days? > > People who live in places with spotty, or no, mobile coverage. We do > exist. Catering for people in minority situations is, of course, important. Catering for people in the majority situation is probably important too. From python at mrabarnett.plus.com Mon Nov 6 13:07:34 2023 From: python at mrabarnett.plus.com (MRAB) Date: Mon, 6 Nov 2023 18:07:34 +0000 Subject: Checking if email is valid In-Reply-To: References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> <6547d221.050a0220.c5340.1e8f@mx.google.com> Message-ID: On 2023-11-06 08:57, Simon Connah via Python-list wrote: > >> I can see how the truley dim-witted might forget that other countries >> have phone numbers with differing lengths and formatting/punctuation, >> but there are tons of sites where it takes multiple tries when >> entering even a bog-standard USA 10-0digit phone nubmer because they >> are completely flummuxed by an area code in parens or hyphens in the >> usual places (or lack of hyhpens in the usual places). This stuff >> isn't that hard, people... > > The thing I truly hate is when you have two telephone number fields. One for landline and one for mobile. I mean who in hell has a landline these days? And not accepting your mobile number in the landline number field is just when I give up. Or having a landline only field that does not accept mobile phones. > I have a landline. It's also how I access the internet. From dieter at handshake.de Mon Nov 6 13:11:41 2023 From: dieter at handshake.de (Dieter Maurer) Date: Mon, 6 Nov 2023 19:11:41 +0100 Subject: Detect naming typos (AttributeError) in function names In-Reply-To: <5e41dd577da656946398652a83acb0be@posteo.de> References: <5e41dd577da656946398652a83acb0be@posteo.de> Message-ID: <25929.11357.456601.869600@ixdm.fritz.box> c.buhtz at posteo.jp wrote at 2023-11-6 12:47 +0000: >I would like to know how to detect (e.g. via a linter) typos in function >names imported from another module. One option is a test suite (--> Python's "unittest" package) with a sufficiently high coverage (near 100 %). From george at fischhof.hu Mon Nov 6 14:37:32 2023 From: george at fischhof.hu (George Fischhof) Date: Mon, 6 Nov 2023 20:37:32 +0100 Subject: Detect naming typos (AttributeError) in function names In-Reply-To: <25929.11357.456601.869600@ixdm.fritz.box> References: <5e41dd577da656946398652a83acb0be@posteo.de> <25929.11357.456601.869600@ixdm.fritz.box> Message-ID: Dieter Maurer via Python-list ezt ?rta (id?pont: 2023. nov. 6., H, 19:13): > c.buhtz at posteo.jp wrote at 2023-11-6 12:47 +0000: > >I would like to know how to detect (e.g. via a linter) typos in function > >names imported from another module. > > One option is a test suite (--> Python's "unittest" package) > with a sufficiently high coverage (near 100 %). > -- > https://mail.python.org/mailman/listinfo/python-list > Hi PyCharm IDE warns you, also vulture https://pypi.org/project/vulture/ finds dead code (not called / not used because of typo), and if you compile the code: https://docs.python.org/3/library/py_compile.html it will generate syntax error if non-existent function is called. linters can perhaps warn you (never had typos, because I use PyCharm) need to check the linters' doc BR, George From rosuav at gmail.com Mon Nov 6 14:58:30 2023 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 7 Nov 2023 06:58:30 +1100 Subject: Checking if email is valid In-Reply-To: References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <4SLzJm1dwdznWHQ@mail.python.org> <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> <603b5741-f74a-4639-a94c-5b5297bca427@VybeNetworks.com> Message-ID: On Tue, 7 Nov 2023 at 02:05, Jon Ribbens via Python-list wrote: > That was another thing that I used to find ridiculous, but seems to have > improved somewhat in recent years - website error pages that said "please > contact us to let us know about this error". I'm sorry, what? You want > me to contact you to tell you about what your own website is doing? How > does that make any sense? Websites should be self-reporting problems. Actually, I think those serve a very important purpose. The reports are almost certainly being discarded unread; the value of such a reporting system is to give the user the sensation that they've "done something" to "help". It makes some people feel better about running into a bug. But you're right, they serve little purpose in solving web site problems. ChrisA From mats at wichmann.us Mon Nov 6 13:45:41 2023 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 6 Nov 2023 11:45:41 -0700 Subject: Checking if email is valid In-Reply-To: References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> <6547d221.050a0220.c5340.1e8f@mx.google.com> Message-ID: <240a8097-8992-481e-b014-beac062e37d5@wichmann.us> On 11/6/23 08:23, Jon Ribbens via Python-list wrote: > On 2023-11-06, Mats Wichmann wrote: >> On 11/6/23 01:57, Simon Connah via Python-list wrote: >>> The thing I truly hate is when you have two telephone number fields. >>> One for landline and one for mobile. I mean who in hell has a >>> landline these days? >> >> People who live in places with spotty, or no, mobile coverage. We do >> exist. > > Catering for people in minority situations is, of course, important. > > Catering for people in the majority situation is probably important too. A good experience would do both, in a comfortable way for either. Continuing with the example, if you have a single phone number field, or let a mobile number be entered in a field marked for landline, you will probably assume you can text to that number. I see this all the time on signups that are attempting to provide some sort of 2FA - I enter the landline number and the website tries to text a verification code to it (rather have an authenticator app for 2FA anyway, but that's a different argument) Suggests maybe labeling should be something like: * Number you want to be called on * Number for texted security messages, if different Never seen that, though :-) From rosuav at gmail.com Mon Nov 6 15:23:01 2023 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 7 Nov 2023 07:23:01 +1100 Subject: Checking if email is valid In-Reply-To: <240a8097-8992-481e-b014-beac062e37d5@wichmann.us> References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> <6547d221.050a0220.c5340.1e8f@mx.google.com> <240a8097-8992-481e-b014-beac062e37d5@wichmann.us> Message-ID: On Tue, 7 Nov 2023 at 07:10, Mats Wichmann via Python-list wrote: > Suggests maybe labeling should be something like: > > * Number you want to be called on > * Number for texted security messages, if different > > Never seen that, though :-) > My responses would be: * Don't. * That's what cryptographic keys are for. :) ChrisA From Karsten.Hilbert at gmx.net Mon Nov 6 16:26:36 2023 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Mon, 6 Nov 2023 22:26:36 +0100 Subject: pip/pip3 confusion and keeping up to date In-Reply-To: References: <17gd1k-866j.ln1@esprimo.zbmc.eu> Message-ID: Am Mon, Nov 06, 2023 at 01:17:11AM -0000 schrieb Jon Ribbens via Python-list: > >> >> Are they not available in your system's package manager? > >> > > >> > ... this clearly often answers to "no" for applications of > >> > any complexity. > >> > > >> > Is there a suggested proper path to deal with that (Debian is > >> > of interest to me here) ? > >> > >> Yes, as previously mentioned, use virtual environments. > >> > > How does one "fill" that venv with packages from pip during > > > > apt-get install python3-app-of-interest > > > > ? > > > > Is the suggested way really to pip-install into this venv > > during apt-get install ? > > I don't know what you mean by that. But if you install the apt packages > and then create your venv with --system-site-packages then I believe > your venv should be able to see the apt packages and import them. The problem is when there's modules not available via apt as packages. In that case on needs to either package them or pip them into the venv suggested above. When they are apt-gettable no venv is needed in the first place. One would just install the application script like any other binary, and which loads apt-installed modules just so. Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B From Karsten.Hilbert at gmx.net Mon Nov 6 16:28:56 2023 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Mon, 6 Nov 2023 22:28:56 +0100 Subject: pip/pip3 confusion and keeping up to date In-Reply-To: <25928.40072.353056.140342@ixdm.fritz.box> References: <17gd1k-866j.ln1@esprimo.zbmc.eu> <25925.7966.521097.868744@ixdm.fritz.box> <25928.40072.353056.140342@ixdm.fritz.box> Message-ID: Am Mon, Nov 06, 2023 at 08:58:00AM +0100 schrieb Dieter Maurer: > I know that debian packagers create debian packages > from Python distributions not using the approach sketched above > and likely they have their reasons. > > You might want to discuss this on an `apt` related mailing list. Yeah, I guess. I know all this stuff about python modules being packaged for Debian and how apt handles dependencies etc etc. I had just hoped someone here might have a handy pointer for how to deal with modules having to be installed from pip for use with an apt-installed python-based application. Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B From mats at wichmann.us Mon Nov 6 16:43:47 2023 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 6 Nov 2023 14:43:47 -0700 Subject: pip/pip3 confusion and keeping up to date In-Reply-To: References: <17gd1k-866j.ln1@esprimo.zbmc.eu> <25925.7966.521097.868744@ixdm.fritz.box> <25928.40072.353056.140342@ixdm.fritz.box> Message-ID: <669042dc-a16a-4a56-b374-b39cd7b8f6d7@wichmann.us> On 11/6/23 14:28, Karsten Hilbert via Python-list wrote: > I had just hoped someone here might have a handy pointer for > how to deal with modules having to be installed from pip for > use with an apt-installed python-based application. That just shouldn't happen - such packages are supposed to be dependency-complete within the packaging universe in question. From jsf80238 at gmail.com Mon Nov 6 17:02:21 2023 From: jsf80238 at gmail.com (Jason Friedman) Date: Mon, 6 Nov 2023 15:02:21 -0700 Subject: Help In-Reply-To: References: Message-ID: On Sun, Nov 5, 2023 at 1:23?PM office officce via Python-list < python-list at python.org> wrote: > which python version is better to be used and how to make sure it works on > my window 10 because i downloaded it and it never worked so I uninstall to > do that again please can you give me the steps on how it will work perfectly > > If you are just starting out, the most recent version is 3.12 and is probably your best choice. When you say it never worked, can you describe in more detail what you did and what error messages you encountered? This mailing list does not accept screenshots. From Karsten.Hilbert at gmx.net Mon Nov 6 17:04:37 2023 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Mon, 6 Nov 2023 23:04:37 +0100 Subject: pip/pip3 confusion and keeping up to date In-Reply-To: <669042dc-a16a-4a56-b374-b39cd7b8f6d7@wichmann.us> References: <17gd1k-866j.ln1@esprimo.zbmc.eu> <25925.7966.521097.868744@ixdm.fritz.box> <25928.40072.353056.140342@ixdm.fritz.box> <669042dc-a16a-4a56-b374-b39cd7b8f6d7@wichmann.us> Message-ID: Am Mon, Nov 06, 2023 at 02:43:47PM -0700 schrieb Mats Wichmann via Python-list: > >I had just hoped someone here might have a handy pointer for > >how to deal with modules having to be installed from pip for > >use with an apt-installed python-based application. > > That just shouldn't happen - such packages are supposed to be dependency-complete within > the packaging universe in question. Yep, that's the preferable ideal world. Which doesn't happen (but that's not the fault of anyone around here, no harm intended). .From all the posts I gather the answer to my question is "simply": unpackaged-but-needed modules need to be packaged. Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B From list1 at tompassin.net Mon Nov 6 17:31:00 2023 From: list1 at tompassin.net (Thomas Passin) Date: Mon, 6 Nov 2023 17:31:00 -0500 Subject: pip/pip3 confusion and keeping up to date In-Reply-To: References: <17gd1k-866j.ln1@esprimo.zbmc.eu> <25925.7966.521097.868744@ixdm.fritz.box> <25928.40072.353056.140342@ixdm.fritz.box> <669042dc-a16a-4a56-b374-b39cd7b8f6d7@wichmann.us> Message-ID: On 11/6/2023 5:04 PM, Karsten Hilbert via Python-list wrote: > Am Mon, Nov 06, 2023 at 02:43:47PM -0700 schrieb Mats Wichmann via Python-list: > >>> I had just hoped someone here might have a handy pointer for >>> how to deal with modules having to be installed from pip for >>> use with an apt-installed python-based application. >> >> That just shouldn't happen - such packages are supposed to be dependency-complete within >> the packaging universe in question. > > Yep, that's the preferable ideal world. > > Which doesn't happen (but that's not the fault of anyone > around here, no harm intended). > > .From all the posts I gather the answer to my question is > "simply": unpackaged-but-needed modules need to be packaged. I think there is one aspect that isn't getting consideration here. And that is whether or not you want these packages installed in the default system Python install. You might not. Maybe you want to get the latest possible version of super-dooper-gui-helper, but one of its dependencies doesn't play well with the system Python libraries. Or ... but you get the point. There are probably many cases where you want *not* to install into the system Python world. So you would need to come up with an APT-based installer that doesn't do that. Obviously it's not unthinkable; it is just one more thing to figure out. From greg.ewing at canterbury.ac.nz Mon Nov 6 18:07:06 2023 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Tue, 7 Nov 2023 12:07:06 +1300 Subject: Checking if email is valid In-Reply-To: References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> <6547d221.050a0220.c5340.1e8f@mx.google.com> <240a8097-8992-481e-b014-beac062e37d5@wichmann.us> Message-ID: On 7/11/23 7:45 am, Mats Wichmann wrote: > Continuing with the example, if you have a single phone number field, or > let a mobile number be entered in a field marked for landline, you will > probably assume you can text to that number. But if the site can detect that you've entered a mobile number into the landline field or vice versa and reject it, then it can figure out whether it can text to a given numner or not without you having to tell it! -- Greg From greg.ewing at canterbury.ac.nz Mon Nov 6 18:11:18 2023 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Tue, 7 Nov 2023 12:11:18 +1300 Subject: Checking if email is valid In-Reply-To: References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <4SLzJm1dwdznWHQ@mail.python.org> <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> <603b5741-f74a-4639-a94c-5b5297bca427@VybeNetworks.com> Message-ID: On 6/11/23 6:34 pm, rbowman wrote: > We've found even if you directly ask the user often the answer is 'I > dunno' or some mythology they have constructed to explain the problem. This seems to apply to hardware issues as well. Louis Rossmann has a philosophy of "Never believe what the customer tells you." -- Greg From rosuav at gmail.com Mon Nov 6 18:20:05 2023 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 7 Nov 2023 10:20:05 +1100 Subject: Checking if email is valid In-Reply-To: References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> <6547d221.050a0220.c5340.1e8f@mx.google.com> <240a8097-8992-481e-b014-beac062e37d5@wichmann.us> Message-ID: On Tue, 7 Nov 2023 at 10:11, Greg Ewing via Python-list wrote: > > On 7/11/23 7:45 am, Mats Wichmann wrote: > > Continuing with the example, if you have a single phone number field, or > > let a mobile number be entered in a field marked for landline, you will > > probably assume you can text to that number. > > But if the site can detect that you've entered a mobile number into > the landline field or vice versa and reject it, then it can figure out > whether it can text to a given numner or not without you having > to tell it! > Oh yes, it totally can. Never mind that some mobile numbers are able to accept text messages but not calls, nor that some landline numbers can accept text messages as well as calls :) ChrisA From avi.e.gross at gmail.com Mon Nov 6 20:05:56 2023 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Mon, 6 Nov 2023 20:05:56 -0500 Subject: Checking if email is valid In-Reply-To: References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> <6547d221.050a0220.c5340.1e8f@mx.google.com> <240a8097-8992-481e-b014-beac062e37d5@wichmann.us> Message-ID: <00ae01da1116$9015ee40$b041cac0$@gmail.com> Just mildly noticing the topics discussed have wandered quite a bit away from Python, let alone even programming. Phone numbers are not what they used to be. They tend to be quite portable and in some ways can be chained so my house phone rings through to my cell phone but a text will not be forwarded. And, if I do not choose to read my texts, no amount of sending would enlighten me about your needs. I know people who get WhatsApp messages but not standard texts, for example. -----Original Message----- From: Python-list On Behalf Of Chris Angelico via Python-list Sent: Monday, November 6, 2023 6:20 PM To: python-list at python.org Subject: Re: Checking if email is valid On Tue, 7 Nov 2023 at 10:11, Greg Ewing via Python-list wrote: > > On 7/11/23 7:45 am, Mats Wichmann wrote: > > Continuing with the example, if you have a single phone number field, or > > let a mobile number be entered in a field marked for landline, you will > > probably assume you can text to that number. > > But if the site can detect that you've entered a mobile number into > the landline field or vice versa and reject it, then it can figure out > whether it can text to a given numner or not without you having > to tell it! > Oh yes, it totally can. Never mind that some mobile numbers are able to accept text messages but not calls, nor that some landline numbers can accept text messages as well as calls :) ChrisA -- https://mail.python.org/mailman/listinfo/python-list From bowman at montana.com Mon Nov 6 19:18:00 2023 From: bowman at montana.com (rbowman) Date: 7 Nov 2023 00:18:00 GMT Subject: Checking if email is valid References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <4SLzJm1dwdznWHQ@mail.python.org> <01b401da0df3$d2a4f150$77eed3f0$@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> <603b5741-f74a-4639-a94c-5b5297bca427@VybeNetworks.com> Message-ID: On Tue, 7 Nov 2023 12:11:18 +1300, Greg Ewing wrote: > On 6/11/23 6:34 pm, rbowman wrote: >> We've found even if you directly ask the user often the answer is 'I >> dunno' or some mythology they have constructed to explain the problem. > > This seems to apply to hardware issues as well. Louis Rossmann has a > philosophy of "Never believe what the customer tells you." Truer words... A customer called to report an industrial dielectric heater wasn't putting out full power. First question was 'Did you check the fuses?' since it was three phase but if you blew one leg it would still operate on reduced power. He assured me he had. I went through the rest of the common problems with no solution so the next day I flew out to the plant. I replaced the 30 amp fuse and all was good. The customer had a very expensive lesson in how to check fuses. At least with software you don't have to physically appear on site. From c.buhtz at posteo.jp Tue Nov 7 02:48:29 2023 From: c.buhtz at posteo.jp (c.buhtz at posteo.jp) Date: Tue, 07 Nov 2023 07:48:29 +0000 Subject: Detect naming typos (AttributeError) in function names In-Reply-To: <25929.11357.456601.869600@ixdm.fritz.box> References: <5e41dd577da656946398652a83acb0be@posteo.de> <25929.11357.456601.869600@ixdm.fritz.box> Message-ID: <5b5669bb5d87a7f2c15ecbf5b400d1c8@posteo.de> Hello Dieter, thanks for your reply. Am 06.11.2023 19:11 schrieb Dieter Maurer: > One option is a test suite (--> Python's "unittest" package) > with a sufficiently high coverage (near 100 %). Yes, that is the primary goal. But it is far away in the related project. I got a hint that "pylint" is able to detect problems like this. From Karsten.Hilbert at gmx.net Tue Nov 7 05:44:14 2023 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Tue, 7 Nov 2023 11:44:14 +0100 Subject: Aw: Re: pip/pip3 confusion and keeping up to date In-Reply-To: References: <17gd1k-866j.ln1@esprimo.zbmc.eu> <25925.7966.521097.868744@ixdm.fritz.box> <25928.40072.353056.140342@ixdm.fritz.box> <669042dc-a16a-4a56-b374-b39cd7b8f6d7@wichmann.us> Message-ID: > > .From all the posts I gather the answer to my question is > > "simply": unpackaged-but-needed modules need to be packaged. > > I think there is one aspect that isn't getting consideration here. And > that is whether or not you want these packages installed in the default > system Python install. You might not. Indeed, which is why all the fuzz about how to fill-in a venv from pip while installing with apt :-) With "properly" packaged modules one wouldn't risk (that much) system breakage, at any rate. > Maybe you want to get the latest > possible version of super-dooper-gui-helper, but one of its dependencies > doesn't play well with the system Python libraries. Or ... but you get > the point. There are probably many cases where you want *not* to > install into the system Python world. So you would need to come up with > an APT-based installer that doesn't do that. > > Obviously it's not unthinkable; Certainly not, it's just that I had hoped someone goes: look here and all of this ... > it is just one more thing to figure out. ... has been thought through before. Thanks, Karsten From list1 at tompassin.net Tue Nov 7 07:35:18 2023 From: list1 at tompassin.net (Thomas Passin) Date: Tue, 7 Nov 2023 07:35:18 -0500 Subject: Detect naming typos (AttributeError) in function names In-Reply-To: <5b5669bb5d87a7f2c15ecbf5b400d1c8@posteo.de> References: <5e41dd577da656946398652a83acb0be@posteo.de> <25929.11357.456601.869600@ixdm.fritz.box> <5b5669bb5d87a7f2c15ecbf5b400d1c8@posteo.de> Message-ID: <2391be9a-2917-4616-ab5b-23b30f26e286@tompassin.net> On 11/7/2023 2:48 AM, Christian Buhtz via Python-list wrote: > Hello Dieter, > > thanks for your reply. > > Am 06.11.2023 19:11 schrieb Dieter Maurer: >> One option is a test suite (--> Python's "unittest" package) >> with a sufficiently high coverage (near 100 %). > > Yes, that is the primary goal. But it is far away in the related project. > > I got a hint that "pylint" is able to detect problems like this. mypy can detect typos in names by noticing that they haven't been declared. For example, if you have a class NewClass(BaseClass), and BaseClass has a method findme(), but you call it as findMe(), mypy will tell you findMe does not exist in BaseClass. It can be annoying to get the options set right so you don't get too many undesired hits, but it's certainly doable. mypy can be slow, depending on your code. You could also simply run py_compile, which will try to compile the code. It will stop at the first error it finds. From grant.b.edwards at gmail.com Tue Nov 7 09:40:08 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Tue, 07 Nov 2023 06:40:08 -0800 (PST) Subject: Checking if email is valid References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> =?utf-8?q?=3CMx55woazM?= =?utf-8?q?nLDymJMOEfKPZ1QqPpdzYCq5IynLBt3KDiTEY7EZ58=5FZKGcHNWXmD7mfCprd6cM?= =?utf-8?q?-FSE6FH2He83fCJKpSXEosC-U=5FeQj1VY7gI=3D=40protonmail=2Ecom=3E?= <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> <6547d221.050a0220.c5340.1e8f@mx.google.com> =?utf-8?q?=3CyJsi4r7eq-eV9WBoh?= =?utf-8?q?gX7OmjxJG4ifGt4jIHNaG6T6ff=5F-craYEyzzfR1gsC94XLXKR6sLfmWg2rhsrK8?= =?utf-8?q?BU3kq0vB3V5mXdBlJPxkPcIHnIE=3D=40protonmail=2Ecom=3E?= <240a8097-8992-481e-b014-beac062e37d5@wichmann.us> Message-ID: <654a4c48.920a0220.e3e48.4611@mx.google.com> On 2023-11-06, Greg Ewing via Python-list wrote: > On 7/11/23 7:45 am, Mats Wichmann wrote: >> Continuing with the example, if you have a single phone number field, or >> let a mobile number be entered in a field marked for landline, you will >> probably assume you can text to that number. > > But if the site can detect that you've entered a mobile number into > the landline field or vice versa and reject it, then it can figure out > whether it can text to a given numner or not without you having > to tell it! Maybe. I'm pretty sure the last time I was in Australia, you could send/recieve text messages from landalines. And I've had mobile number that didn't support text messaging. If you, as a web developer, want the user to enter a text-message capable phone number, then ASK FOR THAT! From jon+usenet at unequivocal.eu Tue Nov 7 11:06:07 2023 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Tue, 7 Nov 2023 16:06:07 -0000 (UTC) Subject: Python Golf References: Message-ID: On 2023-11-07, Stefan Ram wrote: > I read this in a shell newsgroup: > > perl -anE '$s += $F[1]; END {say $s}' in > > , so I wrote > > py -c "import sys; print(sum(int(F.split()[1])for F in sys.stdin))" > to show that this is possible with Python too. > > But now people complain that it's longer than the Perl version. > > Do you see ways to make it shorter (beyond removing one space > after the semicolon ";")? It's a bit of an unfair competition given that, unlike Perl, Python is not designed to be an 'awk' replacement. Having said that, you could make it a bit shorter: py -c "print(sum(int(F.split()[1])for F in open(0)))" References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> <6547d221.050a0220.c5340.1e8f@mx.google.com> <240a8097-8992-481e-b014-beac062e37d5@wichmann.us> <654a4c48.920a0220.e3e48.4611@mx.google.com> Message-ID: On 2023-11-07 08:40, Grant Edwards via Python-list wrote: > If you, as a web developer, want the user to enter a text-message > capable phone number, then ASK FOR THAT! And you may as well ask if they even want you to send texts whether they can technically receive them or not. -- D'Arcy J.M. Cain Vybe Networks Inc. http://www.VybeNetworks.com/ IM:darcy at Vex.Net VoIP: sip:darcy at VybeNetworks.com From rob.cliffe at btinternet.com Sun Nov 5 19:51:03 2023 From: rob.cliffe at btinternet.com (Rob Cliffe) Date: Mon, 6 Nov 2023 00:51:03 +0000 Subject: Writing to clipboard in Python 3.11 Message-ID: <71d3e1c6-6efa-4f78-aef5-de3997e244f7@btinternet.com> Recently I switched from Python 3.8.3 to Python 3.11.4.? A strange problem appeared which was not there before: I am using the win32clipboard backage (part of pywin32), and when I use SetClipboardData() to write text which consists ENTIRELY OF DIGITS to the clipboard, I either get an error (not always the same error message) or a program crash.? The problem does not appear if I use SetClipboardText() instead. Sample program: from win32clipboard import * OpenClipboard() SetClipboardData(CF_UNICODETEXT, "A") SetClipboardData(CF_UNICODETEXT, "A0") SetClipboardData(CF_UNICODETEXT, "0A") SetClipboardText("0", CF_UNICODETEXT) print("OK so far") SetClipboardData(CF_UNICODETEXT, "0") CloseClipboard() Sample output: OK so far Traceback (most recent call last): ? File "R:\W.PY", line 8, in ??? SetClipboardData(CF_UNICODETEXT, "0") pywintypes.error: (0, 'SetClipboardData', 'No error message is available') I can get round the problem by using SetClipboardText().? But can anyone shed light on this? Best wishes Rob Cliffe From python at mrabarnett.plus.com Tue Nov 7 12:01:33 2023 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 7 Nov 2023 17:01:33 +0000 Subject: Writing to clipboard in Python 3.11 In-Reply-To: <71d3e1c6-6efa-4f78-aef5-de3997e244f7@btinternet.com> References: <71d3e1c6-6efa-4f78-aef5-de3997e244f7@btinternet.com> Message-ID: On 2023-11-06 00:51, Rob Cliffe via Python-list wrote: > Recently I switched from Python 3.8.3 to Python 3.11.4.? A strange > problem appeared which was not there before: > I am using the win32clipboard backage (part of pywin32), and when I use > SetClipboardData() to write text which consists ENTIRELY OF DIGITS to > the clipboard, I either get an error (not always the same error message) > or a program crash.? The problem does not appear if I use > SetClipboardText() instead. > Sample program: > > from win32clipboard import * > OpenClipboard() > SetClipboardData(CF_UNICODETEXT, "A") > SetClipboardData(CF_UNICODETEXT, "A0") > SetClipboardData(CF_UNICODETEXT, "0A") > SetClipboardText("0", CF_UNICODETEXT) > print("OK so far") > SetClipboardData(CF_UNICODETEXT, "0") > CloseClipboard() > > Sample output: > > OK so far > Traceback (most recent call last): > ? File "R:\W.PY", line 8, in > ??? SetClipboardData(CF_UNICODETEXT, "0") > pywintypes.error: (0, 'SetClipboardData', 'No error message is available') > > I can get round the problem by using SetClipboardText().? But can anyone > shed light on this? It also happens in Python 3.10, but not Python 3.9. From avi.e.gross at gmail.com Tue Nov 7 12:08:35 2023 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Tue, 7 Nov 2023 12:08:35 -0500 Subject: Python Golf In-Reply-To: References: Message-ID: <007701da119d$0b51d160$21f57420$@gmail.com> Discussions like this feel a bit silly after a while. How long something is to type on a command line is not a major issue and brevity can lead to being hard to remember too especially using obscure references. Consider that the Perl version as shown below does not need to import anything. If you had python import sys by default and perhaps even create a briefer alias for sys.stdin, then this gets shorter: py -c "import sys; print(sum(int(F.split()[1])for F in sys.stdin))" On Behalf Of Jon Ribbens via Python-list Sent: Tuesday, November 7, 2023 11:06 AM To: python-list at python.org Subject: Re: Python Golf On 2023-11-07, Stefan Ram wrote: > I read this in a shell newsgroup: > > perl -anE '$s += $F[1]; END {say $s}' in > > , so I wrote > > py -c "import sys; print(sum(int(F.split()[1])for F in sys.stdin))" > to show that this is possible with Python too. > > But now people complain that it's longer than the Perl version. > > Do you see ways to make it shorter (beyond removing one space > after the semicolon ";")? It's a bit of an unfair competition given that, unlike Perl, Python is not designed to be an 'awk' replacement. Having said that, you could make it a bit shorter: py -c "print(sum(int(F.split()[1])for F in open(0)))" References: <2d05ed9e-0c4f-152a-e072-f64d21da3b13@gmail.com> <65471c81.920a0220.a88bf.2427@mx.google.com> <97465127-448f-4aa1-af03-bc4196e6e4ed@VybeNetworks.com> <6547d221.050a0220.c5340.1e8f@mx.google.com> <240a8097-8992-481e-b014-beac062e37d5@wichmann.us> <654a4c48.920a0220.e3e48.4611@mx.google.com> Message-ID: <007401da119b$216a0410$643e0c30$@gmail.com> Text messages have taken a nasty turn and especially now that so many people have unlimited messages per month in their plan. People overuse them to the point where I opt out of some things like my home town notifications as they bombard me with other things I am not interested in. A major offender now is various forms of security which insist on not letting you into a web site for your bank or other resources unless they first send you an email or text message or perhaps a voice call with random digits to use as verification. Try sitting somewhere with your phone muted as all the beeps get annoying. There are many reasons for preferences and I know many people find it harder to reply to texts on their phone than to emails on a PC with a full keyboard. But all of this is not really here or there. We are talking more about user interface design than about programming, let alone about Python. What strikes me as a useful direction is for people to suggest what resources and methods in the Python world are helpful. Examples would be modules that have been tested and used that do things well such as validating phone numbers or emails, perhaps flexibly so that if a validation fails, they prompt the user asking if they are sure it is correct and maybe offer to let them type it in again for verification. Other ideas as stated recently are routines that don't just ask for a number but specify the purpose, and perhaps messages about what circumstances would trigger a use of the number, such as if fraud is detected, and get you to opt in or refuse. Reusable libraries of sorts, or good documentation of examples, would perhaps help make User Interface design and customer satisfaction better and show Python as a good way to do some kinds of programs. In that light, I wonder if it makes sense to NOT insist people give you their email address at all, and make it optional so they do not need to provide you with something bogus just to go on. -----Original Message----- From: Python-list On Behalf Of D'Arcy Cain via Python-list Sent: Tuesday, November 7, 2023 11:24 AM To: python-list at python.org Subject: Re: Checking if email is valid On 2023-11-07 08:40, Grant Edwards via Python-list wrote: > If you, as a web developer, want the user to enter a text-message > capable phone number, then ASK FOR THAT! And you may as well ask if they even want you to send texts whether they can technically receive them or not. -- D'Arcy J.M. Cain Vybe Networks Inc. http://www.VybeNetworks.com/ IM:darcy at Vex.Net VoIP: sip:darcy at VybeNetworks.com -- https://mail.python.org/mailman/listinfo/python-list From egon at frerich.eu Tue Nov 7 12:47:26 2023 From: egon at frerich.eu (Egon Frerich) Date: Tue, 7 Nov 2023 18:47:26 +0100 Subject: fCONV_AUSRICHTG is not defined - Why? Message-ID: I've no idea why this happens. In a module there are lists and definitions: ??? Felder = [ ??????? # Name?????? lg1? lg2 typ?? Ausrichtung Holen Pr?fen Pr?fvorg ??????? ["Jahr", 4, 5, "u", "", "right", "center"], ??????? ["Monat", 2, 5, "u", "", "right", "center"], ??????? ["Tag", 2, 3, "u", "", "right", "center"], ??????? ["Belegnr", 5, 7, "s", "", "right", "center"], ??????? ["Bank", 2, 4, "u", "", "center", "center"], ??????? ["Art", 2, 3, "u", "", "center", "center"], ??????? ["Aufg", 2, 4, "u", "", "center", "center"], ??????? ["Text", 25, 25, "s", "-", "left", "left"], ??????? ["Erg?nzung", 12, 12, "s", "-", "left", "left"], ??????? ["Betrag", 13, 13, "s", "", "right", "right"], ??????? ["W", 1, 2, "s", "", "center", "center"], ??????? ["WBetrag", 7, 7, "s", "", "right", "right"], ??????? ["Kurs", 6, 6, "s", "", "right", "right"], ??? ] ??? "Reihenfolge in der Dimension 1" ??? ( ??????? fJAHR, ??????? fMONAT, ??????? fTAG, ??????? fBELEGNR, ??????? fBANK, ??????? fART, ??????? fAUFGABE, ??????? fTEXT, ??????? fTEXTERG, ??????? fBETRAG, ??????? fWAEHRUNG, ??????? fBETRAGinWAEHRUNG, ??????? fUMRECHNUNGSKURS, ??? ) = list(range(13)) ??? "Reihenfolge in der Dimension 2" ??? ( ??????? fNAME, ??????? fLG1, ??????? fLG2, ??????? fTYP, ??????? fCONV_AUSRICHTG, ??????? fENTRY_AUSRICHTG, ??????? fTEXT_AUSRICHTUNG, ??????? fHOLFUNKT, ??????? fPRUEFFUNKT, ??????? fPRUEF_ARG, ??? ) = list(range(10)) Two lines with? test statements follow and the statement which produces an error: ??? print(Felder) ??? print(fJAHR, fNAME, fTYP, fCONV_AUSRICHTG) ??? akette = "%" + "%".join( ??????? ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in Felder]) The traceback shows: $ python3 testGeldspurGUI.py [['Jahr', 4, 5, 'u', '', 'right', 'center'], ['Monat', 2, 5, 'u', '', 'right', 'center'], ['Tag', 2, 3, 'u', '', 'right', 'center'], ['Belegnr', 5, 7, 's', '', 'right', 'center'], ['Bank', 2, 4, 'u', '', 'center', 'center'], ['Art', 2, 3, 'u', '', 'center', 'center'], ['Aufg', 2, 4, 'u', '', 'center', 'center'], ['Text', 25, 25, 's', '-', 'left', 'left'], ['Erg?nzung', 12, 12, 's', '-', 'left', 'left'], ['Betrag', 13, 13, 's', '', 'right', 'right'], ['W', 1, 2, 's', '', 'center', 'center'], ['WBetrag', 7, 7, 's', '', 'right', 'right'], ['Kurs', 6, 6, 's', '', 'right', 'right']] 0 0 3 4 Traceback (most recent call last): ? File "/home/egon/Entw/Geldspur/geldspur/testGeldspurGUI.py", line 15, in ??? from tests.testU2 import testU2 ? File "/home/egon/Entw/Geldspur/geldspur/tests/testU2.py", line 9, in ??? from gui.GUI_Konfig import GUIcfg ? File "/home/egon/Entw/Geldspur/geldspur/gui/GUI_Konfig.py", line 11, in ??? class GUIcfg: ? File "/home/egon/Entw/Geldspur/geldspur/gui/GUI_Konfig.py", line 90, in GUIcfg ??? ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in Felder]) ? File "/home/egon/Entw/Geldspur/geldspur/gui/GUI_Konfig.py", line 90, in ??? ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in Felder]) NameError: name 'fCONV_AUSRICHTG' is not defined You see "Felder" and with "0 0 3 4" the correct value 4 for fCONV_AUSRICHTG. But there is the NameError. What does mean? Is there a change from python2 to python3? Egon From list1 at tompassin.net Tue Nov 7 13:08:00 2023 From: list1 at tompassin.net (Thomas Passin) Date: Tue, 7 Nov 2023 13:08:00 -0500 Subject: Writing to clipboard in Python 3.11 In-Reply-To: <71d3e1c6-6efa-4f78-aef5-de3997e244f7@btinternet.com> References: <71d3e1c6-6efa-4f78-aef5-de3997e244f7@btinternet.com> Message-ID: <888b941b-b6d0-4969-9ea9-52c92371b930@tompassin.net> On 11/5/2023 7:51 PM, Rob Cliffe via Python-list wrote: > Recently I switched from Python 3.8.3 to Python 3.11.4.? A strange > problem appeared which was not there before: > I am using the win32clipboard backage (part of pywin32), and when I use > SetClipboardData() to write text which consists ENTIRELY OF DIGITS to > the clipboard, I either get an error (not always the same error message) > or a program crash.? The problem does not appear if I use > SetClipboardText() instead. > Sample program: > > from win32clipboard import * > OpenClipboard() > SetClipboardData(CF_UNICODETEXT, "A") > SetClipboardData(CF_UNICODETEXT, "A0") > SetClipboardData(CF_UNICODETEXT, "0A") > SetClipboardText("0", CF_UNICODETEXT) > print("OK so far") > SetClipboardData(CF_UNICODETEXT, "0") > CloseClipboard() > > Sample output: > > OK so far > Traceback (most recent call last): > ? File "R:\W.PY", line 8, in > ??? SetClipboardData(CF_UNICODETEXT, "0") > pywintypes.error: (0, 'SetClipboardData', 'No error message is available') > > I can get round the problem by using SetClipboardText().? But can anyone > shed light on this? No, but I use pyperclip. It's cross platform. Maybe it doesn't have this problem, though I don't know for sure. From PythonList at DancesWithMice.info Tue Nov 7 13:30:18 2023 From: PythonList at DancesWithMice.info (dn) Date: Wed, 8 Nov 2023 07:30:18 +1300 Subject: fCONV_AUSRICHTG is not defined - Why? In-Reply-To: References: Message-ID: On 08/11/2023 06.47, Egon Frerich via Python-list wrote: > I've no idea why this happens. In a module there are lists and definitions: ... > ??? ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in Felder]) > ? File "/home/egon/Entw/Geldspur/geldspur/gui/GUI_Konfig.py", line 90, > in > ??? ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in Felder]) > NameError: name 'fCONV_AUSRICHTG' is not defined > > You see "Felder" and with "0 0 3 4" the correct value 4 for > fCONV_AUSRICHTG. But there is the NameError. > > What does mean? Is there a change from python2 to python3? Works for me (Python 3.11 on Fedora-Linux 37) - both as a script, and simple/single import. What happens when you extract the second dimension's definitions into a module of their own, and import that (with/out less-sophisticated join)? -- Regards, =dn From jschwar at sbcglobal.net Tue Nov 7 13:52:28 2023 From: jschwar at sbcglobal.net (Jim Schwartz) Date: Tue, 7 Nov 2023 12:52:28 -0600 Subject: Writing to clipboard in Python 3.11 In-Reply-To: <888b941b-b6d0-4969-9ea9-52c92371b930@tompassin.net> References: <71d3e1c6-6efa-4f78-aef5-de3997e244f7@btinternet.com> <888b941b-b6d0-4969-9ea9-52c92371b930@tompassin.net> Message-ID: <017001da11ab$8e8f0b70$abad2250$@sbcglobal.net> It doesn't work in python 3.12.0 -----Original Message----- From: Python-list On Behalf Of Thomas Passin via Python-list Sent: Tuesday, November 7, 2023 12:08 PM To: python-list at python.org Subject: Re: Writing to clipboard in Python 3.11 On 11/5/2023 7:51 PM, Rob Cliffe via Python-list wrote: > Recently I switched from Python 3.8.3 to Python 3.11.4. A strange > problem appeared which was not there before: > I am using the win32clipboard backage (part of pywin32), and when I > use > SetClipboardData() to write text which consists ENTIRELY OF DIGITS to > the clipboard, I either get an error (not always the same error > message) or a program crash. The problem does not appear if I use > SetClipboardText() instead. > Sample program: > > from win32clipboard import * > OpenClipboard() > SetClipboardData(CF_UNICODETEXT, "A") > SetClipboardData(CF_UNICODETEXT, "A0") > SetClipboardData(CF_UNICODETEXT, "0A") SetClipboardText("0", > CF_UNICODETEXT) print("OK so far") SetClipboardData(CF_UNICODETEXT, > "0") > CloseClipboard() > > Sample output: > > OK so far > Traceback (most recent call last): > File "R:\W.PY", line 8, in > SetClipboardData(CF_UNICODETEXT, "0") > pywintypes.error: (0, 'SetClipboardData', 'No error message is > available') > > I can get round the problem by using SetClipboardText(). But can > anyone shed light on this? No, but I use pyperclip. It's cross platform. Maybe it doesn't have this problem, though I don't know for sure. -- https://mail.python.org/mailman/listinfo/python-list From list1 at tompassin.net Tue Nov 7 14:05:10 2023 From: list1 at tompassin.net (Thomas Passin) Date: Tue, 7 Nov 2023 14:05:10 -0500 Subject: fCONV_AUSRICHTG is not defined - Why? In-Reply-To: References: Message-ID: On 11/7/2023 12:47 PM, Egon Frerich via Python-list wrote: > I've no idea why this happens. In a module there are lists and definitions: > > ??? Felder = [ > ??????? # Name?????? lg1? lg2 typ?? Ausrichtung Holen Pr?fen Pr?fvorg > ??????? ["Jahr", 4, 5, "u", "", "right", "center"], > ??????? ["Monat", 2, 5, "u", "", "right", "center"], > ??????? ["Tag", 2, 3, "u", "", "right", "center"], > ??????? ["Belegnr", 5, 7, "s", "", "right", "center"], > ??????? ["Bank", 2, 4, "u", "", "center", "center"], > ??????? ["Art", 2, 3, "u", "", "center", "center"], > ??????? ["Aufg", 2, 4, "u", "", "center", "center"], > ??????? ["Text", 25, 25, "s", "-", "left", "left"], > ??????? ["Erg?nzung", 12, 12, "s", "-", "left", "left"], > ??????? ["Betrag", 13, 13, "s", "", "right", "right"], > ??????? ["W", 1, 2, "s", "", "center", "center"], > ??????? ["WBetrag", 7, 7, "s", "", "right", "right"], > ??????? ["Kurs", 6, 6, "s", "", "right", "right"], > ??? ] > ??? "Reihenfolge in der Dimension 1" > ??? ( > ??????? fJAHR, > ??????? fMONAT, > ??????? fTAG, > ??????? fBELEGNR, > ??????? fBANK, > ??????? fART, > ??????? fAUFGABE, > ??????? fTEXT, > ??????? fTEXTERG, > ??????? fBETRAG, > ??????? fWAEHRUNG, > ??????? fBETRAGinWAEHRUNG, > ??????? fUMRECHNUNGSKURS, > ??? ) = list(range(13)) > ??? "Reihenfolge in der Dimension 2" > ??? ( > ??????? fNAME, > ??????? fLG1, > ??????? fLG2, > ??????? fTYP, > ??????? fCONV_AUSRICHTG, > ??????? fENTRY_AUSRICHTG, > ??????? fTEXT_AUSRICHTUNG, > ??????? fHOLFUNKT, > ??????? fPRUEFFUNKT, > ??????? fPRUEF_ARG, > ??? ) = list(range(10)) > > > Two lines with? test statements follow and the statement which produces > an error: > > ??? print(Felder) > ??? print(fJAHR, fNAME, fTYP, fCONV_AUSRICHTG) > ??? akette = "%" + "%".join( > ??????? ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in > Felder]) > > The traceback shows: > > $ python3 testGeldspurGUI.py > [['Jahr', 4, 5, 'u', '', 'right', 'center'], ['Monat', 2, 5, 'u', '', > 'right', 'center'], ['Tag', 2, 3, 'u', '', 'right', 'center'], > ['Belegnr', 5, 7, 's', '', 'right', 'center'], ['Bank', 2, 4, 'u', '', > 'center', 'center'], ['Art', 2, 3, 'u', '', 'center', 'center'], > ['Aufg', 2, 4, 'u', '', 'center', 'center'], ['Text', 25, 25, 's', '-', > 'left', 'left'], ['Erg?nzung', 12, 12, 's', '-', 'left', 'left'], > ['Betrag', 13, 13, 's', '', 'right', 'right'], ['W', 1, 2, 's', '', > 'center', 'center'], ['WBetrag', 7, 7, 's', '', 'right', 'right'], > ['Kurs', 6, 6, 's', '', 'right', 'right']] > 0 0 3 4 > Traceback (most recent call last): > ? File "/home/egon/Entw/Geldspur/geldspur/testGeldspurGUI.py", line 15, > in > ??? from tests.testU2 import testU2 > ? File "/home/egon/Entw/Geldspur/geldspur/tests/testU2.py", line 9, in > > ??? from gui.GUI_Konfig import GUIcfg > ? File "/home/egon/Entw/Geldspur/geldspur/gui/GUI_Konfig.py", line 11, > in > ??? class GUIcfg: > ? File "/home/egon/Entw/Geldspur/geldspur/gui/GUI_Konfig.py", line 90, > in GUIcfg > ??? ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in Felder]) > ? File "/home/egon/Entw/Geldspur/geldspur/gui/GUI_Konfig.py", line 90, > in > ??? ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in Felder]) > NameError: name 'fCONV_AUSRICHTG' is not defined > > You see "Felder" and with "0 0 3 4" the correct value 4 for > fCONV_AUSRICHTG. But there is the NameError. > > What does mean? Is there a change from python2 to python3? You are using a syntax that I don't understand, but "listcomp" means a list comprehenson. From python at mrabarnett.plus.com Tue Nov 7 14:10:07 2023 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 7 Nov 2023 19:10:07 +0000 Subject: fCONV_AUSRICHTG is not defined - Why? In-Reply-To: References: Message-ID: On 2023-11-07 18:30, dn via Python-list wrote: > On 08/11/2023 06.47, Egon Frerich via Python-list wrote: >> I've no idea why this happens. In a module there are lists and definitions: > ... > >> ??? ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in Felder]) >> ? File "/home/egon/Entw/Geldspur/geldspur/gui/GUI_Konfig.py", line 90, >> in >> ??? ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in Felder]) >> NameError: name 'fCONV_AUSRICHTG' is not defined >> >> You see "Felder" and with "0 0 3 4" the correct value 4 for >> fCONV_AUSRICHTG. But there is the NameError. >> >> What does mean? Is there a change from python2 to python3? > > Works for me (Python 3.11 on Fedora-Linux 37) > - both as a script, and simple/single import. > > What happens when you extract the second dimension's definitions into a > module of their own, and import that (with/out less-sophisticated join)? > The missing detail is this line from the traceback: File "/home/egon/Entw/Geldspur/geldspur/gui/GUI_Konfig.py", line 11, in class GUIcfg: Here's a small example that shows the problem: ----8<---- #!python3.11 # -*- encoding: utf-8 -*- class Test: hello = "hello" print(hello) print([[zero] for _ in range(4)]) ----8<---- and its traceback: ----8<---- hello Traceback (most recent call last): File "C:\Projects\regex3\test_clipboard.py", line 4, in class Test: File "C:\Projects\regex3\test_clipboard.py", line 7, in Test print([zero for _ in range(4)]) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Projects\regex3\test_clipboard.py", line 7, in print([zero for _ in range(4)]) ^^^^ NameError: name 'zero' is not defined ----8<---- 'zero' is visible in: print(hello) but not in: print([zero for _ in range(4)]) Something to do with how scoping is implemented in comprehensions? From jschwar at sbcglobal.net Tue Nov 7 14:20:31 2023 From: jschwar at sbcglobal.net (Jim Schwartz) Date: Tue, 7 Nov 2023 13:20:31 -0600 Subject: fCONV_AUSRICHTG is not defined - Why? In-Reply-To: References: Message-ID: Where do you define fCONV_AUSRICHTG? It must be initialized or defined somewhere. Did you leave out a statement from the python 2 version? Sent from my iPhone > On Nov 7, 2023, at 1:06 PM, Thomas Passin via Python-list wrote: > > ?On 11/7/2023 12:47 PM, Egon Frerich via Python-list wrote: >> I've no idea why this happens. In a module there are lists and definitions: >> Felder = [ >> # Name lg1 lg2 typ Ausrichtung Holen Pr?fen Pr?fvorg >> ["Jahr", 4, 5, "u", "", "right", "center"], >> ["Monat", 2, 5, "u", "", "right", "center"], >> ["Tag", 2, 3, "u", "", "right", "center"], >> ["Belegnr", 5, 7, "s", "", "right", "center"], >> ["Bank", 2, 4, "u", "", "center", "center"], >> ["Art", 2, 3, "u", "", "center", "center"], >> ["Aufg", 2, 4, "u", "", "center", "center"], >> ["Text", 25, 25, "s", "-", "left", "left"], >> ["Erg?nzung", 12, 12, "s", "-", "left", "left"], >> ["Betrag", 13, 13, "s", "", "right", "right"], >> ["W", 1, 2, "s", "", "center", "center"], >> ["WBetrag", 7, 7, "s", "", "right", "right"], >> ["Kurs", 6, 6, "s", "", "right", "right"], >> ] >> "Reihenfolge in der Dimension 1" >> ( >> fJAHR, >> fMONAT, >> fTAG, >> fBELEGNR, >> fBANK, >> fART, >> fAUFGABE, >> fTEXT, >> fTEXTERG, >> fBETRAG, >> fWAEHRUNG, >> fBETRAGinWAEHRUNG, >> fUMRECHNUNGSKURS, >> ) = list(range(13)) >> "Reihenfolge in der Dimension 2" >> ( >> fNAME, >> fLG1, >> fLG2, >> fTYP, >> fCONV_AUSRICHTG, >> fENTRY_AUSRICHTG, >> fTEXT_AUSRICHTUNG, >> fHOLFUNKT, >> fPRUEFFUNKT, >> fPRUEF_ARG, >> ) = list(range(10)) >> Two lines with test statements follow and the statement which produces an error: >> print(Felder) >> print(fJAHR, fNAME, fTYP, fCONV_AUSRICHTG) >> akette = "%" + "%".join( >> ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in Felder]) >> The traceback shows: >> $ python3 testGeldspurGUI.py >> [['Jahr', 4, 5, 'u', '', 'right', 'center'], ['Monat', 2, 5, 'u', '', 'right', 'center'], ['Tag', 2, 3, 'u', '', 'right', 'center'], ['Belegnr', 5, 7, 's', '', 'right', 'center'], ['Bank', 2, 4, 'u', '', 'center', 'center'], ['Art', 2, 3, 'u', '', 'center', 'center'], ['Aufg', 2, 4, 'u', '', 'center', 'center'], ['Text', 25, 25, 's', '-', 'left', 'left'], ['Erg?nzung', 12, 12, 's', '-', 'left', 'left'], ['Betrag', 13, 13, 's', '', 'right', 'right'], ['W', 1, 2, 's', '', 'center', 'center'], ['WBetrag', 7, 7, 's', '', 'right', 'right'], ['Kurs', 6, 6, 's', '', 'right', 'right']] >> 0 0 3 4 >> Traceback (most recent call last): >> File "/home/egon/Entw/Geldspur/geldspur/testGeldspurGUI.py", line 15, in >> from tests.testU2 import testU2 >> File "/home/egon/Entw/Geldspur/geldspur/tests/testU2.py", line 9, in >> from gui.GUI_Konfig import GUIcfg >> File "/home/egon/Entw/Geldspur/geldspur/gui/GUI_Konfig.py", line 11, in >> class GUIcfg: >> File "/home/egon/Entw/Geldspur/geldspur/gui/GUI_Konfig.py", line 90, in GUIcfg >> ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in Felder]) >> File "/home/egon/Entw/Geldspur/geldspur/gui/GUI_Konfig.py", line 90, in >> ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in Felder]) >> NameError: name 'fCONV_AUSRICHTG' is not defined >> You see "Felder" and with "0 0 3 4" the correct value 4 for fCONV_AUSRICHTG. But there is the NameError. >> What does mean? Is there a change from python2 to python3? > > You are using a syntax that I don't understand, but "listcomp" means a list comprehenson. > > -- > https://mail.python.org/mailman/listinfo/python-list From jon+usenet at unequivocal.eu Tue Nov 7 14:08:06 2023 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Tue, 7 Nov 2023 19:08:06 -0000 (UTC) Subject: Python Golf References: <007701da119d$0b51d160$21f57420$@gmail.com> Message-ID: On 2023-11-07, wrote: > Discussions like this feel a bit silly after a while. How long > something is to type on a command line is not a major issue and > brevity can lead to being hard to remember too especially using > obscure references. Of course it's silly, that's why it's called "golf"! It would be basically insane to use open(0) instead of sys.stdin like this except where the length of the source code overrides all other considerations - which is essentially never, unless playing code golf... From PythonList at DancesWithMice.info Tue Nov 7 14:57:40 2023 From: PythonList at DancesWithMice.info (dn) Date: Wed, 8 Nov 2023 08:57:40 +1300 Subject: =?UTF-8?Q?Clearing_the_Deque_=E2=80=A2_Picturing_Python=E2=80=99s_?= =?UTF-8?Q?=60deque=60_data_structure?= Message-ID: <5d0fd65d-d1ab-412c-bf69-2c9d13cef879@DancesWithMice.info> You will be welcome to join us at our next (hybrid) meeting: Wednesday, 15 November 2023, 1815~2030 NZDT (0515~0730 UTC). How often do you use a deque*? ?Not very? is a common answer. Perhaps you?ve never used it. In this presentation, Stephen won?t try to convince you to use it more often. Instead, he?ll present a different perspective on what this data structure is, and how it differs from a list. The presentation will compare deques and lists in a visual manner, to help us understand why we may need a deque in certain situations. We?ll also explore some demonstration examples to highlight the differences in performance between the two data structures in different scenarios. *pronounced like ?deck" Audience: This presentation is ideal for those who have either never heard of deque, or have heard of it but never really used it or understood why it?s needed. The more experienced may find the visual story insightful. Stephen used to be a physicist, which is where he learned programming. After working in science and academia for over a decade, he decided to escape before it was too late. Since then, has focused exclusively on teaching coding and communicating about Python. A big part of his day is busy with running Codetoday?we teach Python coding to children between 7 and 16 years old (https://www.codetoday.co.uk/). He also runs courses for adults and corporate training programs, and particularly, writing about Python. He writes the articles he wished he had when learning. He publishes articles at The Python Coding Stack (https://thepythoncodingstack.substack.com/) and also wrote an online book (soon to be in other formats, too) for beginners, The Python Coding Book (https://thepythoncodingbook.com/). Please RSVP on Meetup.com (NZPUG Auckland Branch): https://www.meetup.com/nzpug-auckland/events/295433874/ -- Regards, =dn From python at mrabarnett.plus.com Tue Nov 7 15:29:43 2023 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 7 Nov 2023 20:29:43 +0000 Subject: fCONV_AUSRICHTG is not defined - Why? In-Reply-To: References: Message-ID: <453a4a28-696f-4999-a65e-c61fb4716310@mrabarnett.plus.com> On 2023-11-07 19:20, Jim Schwartz via Python-list wrote: > Where do you define fCONV_AUSRICHTG? It must be initialized or defined somewhere. Did you leave out a statement from the python 2 version? > It's given its value here: ( fNAME, fLG1, fLG2, fTYP, fCONV_AUSRICHTG, fENTRY_AUSRICHTG, fTEXT_AUSRICHTUNG, fHOLFUNKT, fPRUEFFUNKT, fPRUEF_ARG, ) = list(range(10)) > >> On Nov 7, 2023, at 1:06 PM, Thomas Passin via Python-list wrote: >> >> ?On 11/7/2023 12:47 PM, Egon Frerich via Python-list wrote: >>> I've no idea why this happens. In a module there are lists and definitions: >>> Felder = [ >>> # Name lg1 lg2 typ Ausrichtung Holen Pr?fen Pr?fvorg >>> ["Jahr", 4, 5, "u", "", "right", "center"], >>> ["Monat", 2, 5, "u", "", "right", "center"], >>> ["Tag", 2, 3, "u", "", "right", "center"], >>> ["Belegnr", 5, 7, "s", "", "right", "center"], >>> ["Bank", 2, 4, "u", "", "center", "center"], >>> ["Art", 2, 3, "u", "", "center", "center"], >>> ["Aufg", 2, 4, "u", "", "center", "center"], >>> ["Text", 25, 25, "s", "-", "left", "left"], >>> ["Erg?nzung", 12, 12, "s", "-", "left", "left"], >>> ["Betrag", 13, 13, "s", "", "right", "right"], >>> ["W", 1, 2, "s", "", "center", "center"], >>> ["WBetrag", 7, 7, "s", "", "right", "right"], >>> ["Kurs", 6, 6, "s", "", "right", "right"], >>> ] >>> "Reihenfolge in der Dimension 1" >>> ( >>> fJAHR, >>> fMONAT, >>> fTAG, >>> fBELEGNR, >>> fBANK, >>> fART, >>> fAUFGABE, >>> fTEXT, >>> fTEXTERG, >>> fBETRAG, >>> fWAEHRUNG, >>> fBETRAGinWAEHRUNG, >>> fUMRECHNUNGSKURS, >>> ) = list(range(13)) >>> "Reihenfolge in der Dimension 2" >>> ( >>> fNAME, >>> fLG1, >>> fLG2, >>> fTYP, >>> fCONV_AUSRICHTG, >>> fENTRY_AUSRICHTG, >>> fTEXT_AUSRICHTUNG, >>> fHOLFUNKT, >>> fPRUEFFUNKT, >>> fPRUEF_ARG, >>> ) = list(range(10)) >>> Two lines with test statements follow and the statement which produces an error: >>> print(Felder) >>> print(fJAHR, fNAME, fTYP, fCONV_AUSRICHTG) >>> akette = "%" + "%".join( >>> ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in Felder]) >>> The traceback shows: >>> $ python3 testGeldspurGUI.py >>> [['Jahr', 4, 5, 'u', '', 'right', 'center'], ['Monat', 2, 5, 'u', '', 'right', 'center'], ['Tag', 2, 3, 'u', '', 'right', 'center'], ['Belegnr', 5, 7, 's', '', 'right', 'center'], ['Bank', 2, 4, 'u', '', 'center', 'center'], ['Art', 2, 3, 'u', '', 'center', 'center'], ['Aufg', 2, 4, 'u', '', 'center', 'center'], ['Text', 25, 25, 's', '-', 'left', 'left'], ['Erg?nzung', 12, 12, 's', '-', 'left', 'left'], ['Betrag', 13, 13, 's', '', 'right', 'right'], ['W', 1, 2, 's', '', 'center', 'center'], ['WBetrag', 7, 7, 's', '', 'right', 'right'], ['Kurs', 6, 6, 's', '', 'right', 'right']] >>> 0 0 3 4 >>> Traceback (most recent call last): >>> File "/home/egon/Entw/Geldspur/geldspur/testGeldspurGUI.py", line 15, in >>> from tests.testU2 import testU2 >>> File "/home/egon/Entw/Geldspur/geldspur/tests/testU2.py", line 9, in >>> from gui.GUI_Konfig import GUIcfg >>> File "/home/egon/Entw/Geldspur/geldspur/gui/GUI_Konfig.py", line 11, in >>> class GUIcfg: >>> File "/home/egon/Entw/Geldspur/geldspur/gui/GUI_Konfig.py", line 90, in GUIcfg >>> ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in Felder]) >>> File "/home/egon/Entw/Geldspur/geldspur/gui/GUI_Konfig.py", line 90, in >>> ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in Felder]) >>> NameError: name 'fCONV_AUSRICHTG' is not defined >>> You see "Felder" and with "0 0 3 4" the correct value 4 for fCONV_AUSRICHTG. But there is the NameError. >>> What does mean? Is there a change from python2 to python3? >> >> You are using a syntax that I don't understand, but "listcomp" means a list comprehenson. >> From list1 at tompassin.net Tue Nov 7 15:56:58 2023 From: list1 at tompassin.net (Thomas Passin) Date: Tue, 7 Nov 2023 15:56:58 -0500 Subject: fCONV_AUSRICHTG is not defined - Why? In-Reply-To: <453a4a28-696f-4999-a65e-c61fb4716310@mrabarnett.plus.com> References: <453a4a28-696f-4999-a65e-c61fb4716310@mrabarnett.plus.com> Message-ID: <222b59a7-3790-4ada-9650-6e67d8d50d68@tompassin.net> On 11/7/2023 3:29 PM, MRAB via Python-list wrote: > On 2023-11-07 19:20, Jim Schwartz via Python-list wrote: >> Where do you define fCONV_AUSRICHTG? It must be initialized or defined >> somewhere. Did you leave out a statement from the python 2 version? >> > It's given its value here: > > ??? ( > ??????? fNAME, > ??????? fLG1, > ??????? fLG2, > ??????? fTYP, > ??????? fCONV_AUSRICHTG, > ??????? fENTRY_AUSRICHTG, > ??????? fTEXT_AUSRICHTUNG, > ??????? fHOLFUNKT, > ??????? fPRUEFFUNKT, > ??????? fPRUEF_ARG, > ??? ) = list(range(10)) This construction is a sneaky way to assign index numbers to list entries. A simplified example: >>> S1 = 'string 1' >>> S2 = 'string 2' >>> (fS1, fS2) = list(range(2)) >>> fS1 0 >>> >>> fS2 1 >> >>> On Nov 7, 2023, at 1:06 PM, Thomas Passin via Python-list >>> wrote: >>> >>> ?On 11/7/2023 12:47 PM, Egon Frerich via Python-list wrote: >>>> I've no idea why this happens. In a module there are lists and >>>> definitions: >>>> ??? Felder = [ >>>> ??????? # Name?????? lg1? lg2 typ?? Ausrichtung Holen Pr?fen Pr?fvorg >>>> ??????? ["Jahr", 4, 5, "u", "", "right", "center"], >>>> ??????? ["Monat", 2, 5, "u", "", "right", "center"], >>>> ??????? ["Tag", 2, 3, "u", "", "right", "center"], >>>> ??????? ["Belegnr", 5, 7, "s", "", "right", "center"], >>>> ??????? ["Bank", 2, 4, "u", "", "center", "center"], >>>> ??????? ["Art", 2, 3, "u", "", "center", "center"], >>>> ??????? ["Aufg", 2, 4, "u", "", "center", "center"], >>>> ??????? ["Text", 25, 25, "s", "-", "left", "left"], >>>> ??????? ["Erg?nzung", 12, 12, "s", "-", "left", "left"], >>>> ??????? ["Betrag", 13, 13, "s", "", "right", "right"], >>>> ??????? ["W", 1, 2, "s", "", "center", "center"], >>>> ??????? ["WBetrag", 7, 7, "s", "", "right", "right"], >>>> ??????? ["Kurs", 6, 6, "s", "", "right", "right"], >>>> ??? ] >>>> ??? "Reihenfolge in der Dimension 1" >>>> ??? ( >>>> ??????? fJAHR, >>>> ??????? fMONAT, >>>> ??????? fTAG, >>>> ??????? fBELEGNR, >>>> ??????? fBANK, >>>> ??????? fART, >>>> ??????? fAUFGABE, >>>> ??????? fTEXT, >>>> ??????? fTEXTERG, >>>> ??????? fBETRAG, >>>> ??????? fWAEHRUNG, >>>> ??????? fBETRAGinWAEHRUNG, >>>> ??????? fUMRECHNUNGSKURS, >>>> ??? ) = list(range(13)) >>>> ??? "Reihenfolge in der Dimension 2" >>>> ??? ( >>>> ??????? fNAME, >>>> ??????? fLG1, >>>> ??????? fLG2, >>>> ??????? fTYP, >>>> ??????? fCONV_AUSRICHTG, >>>> ??????? fENTRY_AUSRICHTG, >>>> ??????? fTEXT_AUSRICHTUNG, >>>> ??????? fHOLFUNKT, >>>> ??????? fPRUEFFUNKT, >>>> ??????? fPRUEF_ARG, >>>> ??? ) = list(range(10)) >>>> Two lines with? test statements follow and the statement which >>>> produces an error: >>>> ??? print(Felder) >>>> ??? print(fJAHR, fNAME, fTYP, fCONV_AUSRICHTG) >>>> ??? akette = "%" + "%".join( >>>> ??????? ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in >>>> Felder]) >>>> The traceback shows: >>>> $ python3 testGeldspurGUI.py >>>> [['Jahr', 4, 5, 'u', '', 'right', 'center'], ['Monat', 2, 5, 'u', >>>> '', 'right', 'center'], ['Tag', 2, 3, 'u', '', 'right', 'center'], >>>> ['Belegnr', 5, 7, 's', '', 'right', 'center'], ['Bank', 2, 4, 'u', >>>> '', 'center', 'center'], ['Art', 2, 3, 'u', '', 'center', 'center'], >>>> ['Aufg', 2, 4, 'u', '', 'center', 'center'], ['Text', 25, 25, 's', >>>> '-', 'left', 'left'], ['Erg?nzung', 12, 12, 's', '-', 'left', >>>> 'left'], ['Betrag', 13, 13, 's', '', 'right', 'right'], ['W', 1, 2, >>>> 's', '', 'center', 'center'], ['WBetrag', 7, 7, 's', '', 'right', >>>> 'right'], ['Kurs', 6, 6, 's', '', 'right', 'right']] >>>> 0 0 3 4 >>>> Traceback (most recent call last): >>>> ? File "/home/egon/Entw/Geldspur/geldspur/testGeldspurGUI.py", line >>>> 15, in >>>> ??? from tests.testU2 import testU2 >>>> ? File "/home/egon/Entw/Geldspur/geldspur/tests/testU2.py", line 9, >>>> in >>>> ??? from gui.GUI_Konfig import GUIcfg >>>> ? File "/home/egon/Entw/Geldspur/geldspur/gui/GUI_Konfig.py", line >>>> 11, in >>>> ??? class GUIcfg: >>>> ? File "/home/egon/Entw/Geldspur/geldspur/gui/GUI_Konfig.py", line >>>> 90, in GUIcfg >>>> ??? ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in >>>> Felder]) >>>> ? File "/home/egon/Entw/Geldspur/geldspur/gui/GUI_Konfig.py", line >>>> 90, in >>>> ??? ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in >>>> Felder]) >>>> NameError: name 'fCONV_AUSRICHTG' is not defined >>>> You see "Felder" and with "0 0 3 4" the correct value 4 for >>>> fCONV_AUSRICHTG. But there is the NameError. >>>> What does mean? Is there a change from python2 to python3? >>> >>> You are using a syntax that I don't understand, but "listcomp" means >>> a list comprehenson. >>> > From python at mrabarnett.plus.com Tue Nov 7 17:08:36 2023 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 7 Nov 2023 22:08:36 +0000 Subject: fCONV_AUSRICHTG is not defined - Why? In-Reply-To: <222b59a7-3790-4ada-9650-6e67d8d50d68@tompassin.net> References: <453a4a28-696f-4999-a65e-c61fb4716310@mrabarnett.plus.com> <222b59a7-3790-4ada-9650-6e67d8d50d68@tompassin.net> Message-ID: <5e7ff4e3-a94a-442d-9aad-29bf631a0211@mrabarnett.plus.com> On 2023-11-07 20:56, Thomas Passin via Python-list wrote: > On 11/7/2023 3:29 PM, MRAB via Python-list wrote: >> On 2023-11-07 19:20, Jim Schwartz via Python-list wrote: >>> Where do you define fCONV_AUSRICHTG? It must be initialized or defined >>> somewhere. Did you leave out a statement from the python 2 version? >>> >> It's given its value here: >> >> ??? ( >> ??????? fNAME, >> ??????? fLG1, >> ??????? fLG2, >> ??????? fTYP, >> ??????? fCONV_AUSRICHTG, >> ??????? fENTRY_AUSRICHTG, >> ??????? fTEXT_AUSRICHTUNG, >> ??????? fHOLFUNKT, >> ??????? fPRUEFFUNKT, >> ??????? fPRUEF_ARG, >> ??? ) = list(range(10)) > > > This construction is a sneaky way to assign index numbers to list > entries. A simplified example: > > >>> S1 = 'string 1' > >>> S2 = 'string 2' > >>> (fS1, fS2) = list(range(2)) > >>> fS1 > 0 > >>> > >>> fS2 > 1 > You don't need the 'list', though: range(...) will work on its own. [snip] From greg.ewing at canterbury.ac.nz Tue Nov 7 19:31:03 2023 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Wed, 8 Nov 2023 13:31:03 +1300 Subject: fCONV_AUSRICHTG is not defined - Why? In-Reply-To: References: Message-ID: On 8/11/23 8:10 am, MRAB wrote: > Something to do with how scoping is implemented in comprehensions? Yes, together with the way class scopes work during class construction. Behind the scenes, the body of a listcomp happens to be implemented as a nested function. Usually you don't notice this, but while a class is being built, its scope doesn't count as an enlosing scope for functions defined within the class. This is necessary, otherwise all of a class's attributes would be visible inside its methods, which isn't what we want. However, it leads to some odd corner cases, such as this one. There are various ways you could work around this. I would suggest moving the offending code outside the class and qualifying the constants it uses with the class name. -- Greg From miked at dewhirst.com.au Tue Nov 7 20:46:33 2023 From: miked at dewhirst.com.au (Mike Dewhirst) Date: Wed, 8 Nov 2023 12:46:33 +1100 Subject: Help In-Reply-To: References: Message-ID: <5bbf62e5-8fec-4628-a289-1bc82ee11fdd@dewhirst.com.au> On 7/11/2023 9:02 am, Jason Friedman via Python-list wrote: > On Sun, Nov 5, 2023 at 1:23?PM office officce via Python-list < > python-list at python.org> wrote: > >> which python version is better to be used and how to make sure it works on >> my window 10 because i downloaded it and it never worked so I uninstall to >> do that again please can you give me the steps on how it will work perfectly 1. Download from https://python.org (not Microsoft) and always choose the 64-bit stable version 2. Choose the installation location as C:\Python311 (avoid the default) 4. Accept other recommended installation options especially to include Python on the path (if offered) Guaranteed to work. Also, you will never have to uninstall. Install the next version in C:\Python312 etc In due course, investigate virtual environments so you can work on projects simultaneously using different versions of Python or different versions of various Python libraries. Good luck Mike >> >> > If you are just starting out, the most recent version is 3.12 and is > probably your best choice. > > When you say it never worked, can you describe in more detail what you did > and what error messages you encountered? > > This mailing list does not accept screenshots. -- Signed email is an absolute defence against phishing. This email has been signed with my private key. If you import my public key you can automatically decrypt my signature and be sure it came from me. Your email software can handle signing. -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature.asc Type: application/pgp-signature Size: 495 bytes Desc: OpenPGP digital signature URL: From jshem at yaxenu.org Tue Nov 7 20:26:13 2023 From: jshem at yaxenu.org (Julieta Shem) Date: Tue, 07 Nov 2023 22:26:13 -0300 Subject: on a tail-recursive square-and-multiply Message-ID: <87leb9rq6i.fsf@yaxenu.org> For the first time I'm trying to write a tail-recursive square-and-multiply and, even though it /seems/ to work, I'm not happy with what I wrote and I don't seem to understand it so well. --8<---------------cut here---------------start------------->8--- def sam(b, e, m, acc = 1): if e == 0: return acc if is_even(e): return sam(remainder(b * b, m), e//2, m, acc) else: return sam(b, e - 1, m, remainder(b * acc, m)) --8<---------------cut here---------------end--------------->8--- You see, I tried to use an accumulator, but I'm only accumulating when the exponent is odd. When it's even, I feel I'm forced to change the base into b * b mod m and leave the accumulator alone. This feels so unnatural to me. I feel I broke some symmetry there. I'm having to think of two cases --- when I change the accumulator and when I change the base. That seems too much for my small head. Can you help? From torriem at gmail.com Tue Nov 7 23:14:57 2023 From: torriem at gmail.com (Michael Torrie) Date: Tue, 7 Nov 2023 21:14:57 -0700 Subject: on a tail-recursive square-and-multiply In-Reply-To: <87leb9rq6i.fsf@yaxenu.org> References: <87leb9rq6i.fsf@yaxenu.org> Message-ID: On 11/7/23 18:26, Julieta Shem via Python-list wrote: > For the first time I'm trying to write a tail-recursive > square-and-multiply and, even though it /seems/ to work, I'm not happy > with what I wrote and I don't seem to understand it so well. > > --8<---------------cut here---------------start------------->8--- > def sam(b, e, m, acc = 1): > if e == 0: > return acc > if is_even(e): > return sam(remainder(b * b, m), e//2, m, acc) > else: > return sam(b, e - 1, m, remainder(b * acc, m)) > --8<---------------cut here---------------end--------------->8--- I don't see any definition of "remainder()" When you post to the list, please provide short but complete code, including a demonstration of using the code provided. That will help others understand what you are trying to do, and perhaps comment on your concerns. > You see, I tried to use an accumulator, but I'm only accumulating when > the exponent is odd. When it's even, I feel I'm forced to change the > base into b * b mod m and leave the accumulator alone. This feels so > unnatural to me. I feel I broke some symmetry there. I'm having to > think of two cases --- when I change the accumulator and when I change > the base. That seems too much for my small head. Can you help? I don't really understand the code either, so I cannot help much. From greg.ewing at canterbury.ac.nz Wed Nov 8 01:32:23 2023 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Wed, 8 Nov 2023 19:32:23 +1300 Subject: on a tail-recursive square-and-multiply In-Reply-To: <87leb9rq6i.fsf@yaxenu.org> References: <87leb9rq6i.fsf@yaxenu.org> Message-ID: On 8/11/23 2:26 pm, Julieta Shem wrote: > For the first time I'm trying to write a tail-recursive > square-and-multiply and, even though it /seems/ to work, I'm not happy > with what I wrote and I don't seem to understand it so well. Stepping back a bit, why do you feel the need to write this tail-recursively? Is it just an exercise? Note that Python doesn't optimise tail calls, so anything that can be done tail-recursively is probably better done iteratively. > > --8<---------------cut here---------------start------------->8--- > def sam(b, e, m, acc = 1): > if e == 0: > return acc > if is_even(e): > return sam(remainder(b * b, m), e//2, m, acc) > else: > return sam(b, e - 1, m, remainder(b * acc, m)) > --8<---------------cut here---------------end--------------->8--- > > You see, I tried to use an accumulator, but I'm only accumulating when > the exponent is odd. When it's even, I feel I'm forced to change the > base into b * b mod m and leave the accumulator alone. This feels so > unnatural to me. I feel I broke some symmetry there. I'm having to > think of two cases --- when I change the accumulator and when I change > the base. That seems too much for my small head. Can you help? Well, there are inherently two cases, and they're different, so I don't think you're doing anything wrong here. It was asymmetrical to begin with. If you were doing it iteratively you would also be leaving the accumulator alone when the exponent is even. -- Greg From egon at frerich.eu Wed Nov 8 03:24:18 2023 From: egon at frerich.eu (Egon Frerich) Date: Wed, 8 Nov 2023 09:24:18 +0100 Subject: fCONV_AUSRICHTG is not defined - Why? In-Reply-To: References: Message-ID: Am 07.11.23 um 20:10 schrieb MRAB via Python-list: > On 2023-11-07 18:30, dn via Python-list wrote: >> On 08/11/2023 06.47, Egon Frerich via Python-list wrote: >>> I've no idea why this happens. In a module there are lists and >>> definitions: >> ... >> >>> ???? ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in >>> Felder]) >>> ?? File "/home/egon/Entw/Geldspur/geldspur/gui/GUI_Konfig.py", line >>> 90, in >>> ???? ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in >>> Felder]) >>> NameError: name 'fCONV_AUSRICHTG' is not defined >>> >>> You see "Felder" and with "0 0 3 4" the correct value 4 for >>> fCONV_AUSRICHTG. But there is the NameError. >>> >>> What does mean? Is there a change from python2 to python3? >> >> Works for me (Python 3.11 on Fedora-Linux 37) >> - both as a script, and simple/single import. >> >> What happens when you extract the second dimension's definitions into a >> module of their own, and import that (with/out less-sophisticated join)? >> > The missing detail is this line from the traceback: > > ?? File "/home/egon/Entw/Geldspur/geldspur/gui/GUI_Konfig.py", line 11, > in > ???? class GUIcfg: > You are right. The list comprehension has to be outside the class. The scope rules have been changed python2 and python3. Egon > Here's a small example that shows the problem: > > ----8<---- > #!python3.11 > # -*- encoding: utf-8 -*- > > class Test: > ??? hello = "hello" > ??? print(hello) > ??? print([[zero] for _ in range(4)]) > ----8<---- > > and its traceback: > > ----8<---- > hello > Traceback (most recent call last): > ? File "C:\Projects\regex3\test_clipboard.py", line 4, in > ??? class Test: > ? File "C:\Projects\regex3\test_clipboard.py", line 7, in Test > ??? print([zero for _ in range(4)]) > ???????? ^^^^^^^^^^^^^^^^^^^^^^^^^^ > ? File "C:\Projects\regex3\test_clipboard.py", line 7, in > ??? print([zero for _ in range(4)]) > ?????????? ^^^^ > NameError: name 'zero' is not defined > ----8<---- > > 'zero' is visible in: > > ??? print(hello) > > but not in: > > ??? print([zero for _ in range(4)]) > > Something to do with how scoping is implemented in comprehensions? > From jshem at yaxenu.org Wed Nov 8 04:39:58 2023 From: jshem at yaxenu.org (Julieta Shem) Date: Wed, 08 Nov 2023 06:39:58 -0300 Subject: on a tail-recursive square-and-multiply References: <87leb9rq6i.fsf@yaxenu.org> Message-ID: <87a5roshw1.fsf@yaxenu.org> Greg Ewing writes: > On 8/11/23 2:26 pm, Julieta Shem wrote: >> For the first time I'm trying to write a tail-recursive >> square-and-multiply and, even though it /seems/ to work, I'm not happy >> with what I wrote and I don't seem to understand it so well. > > Stepping back a bit, why do you feel the need to write this > tail-recursively? Is it just an exercise? Yes --- an exercise. (It would be relevant if I were in a language that gives me tail-call optimization. I'm preparing myself for when that happens.) > Note that Python doesn't optimise tail calls, so anything that > can be done tail-recursively is probably better done iteratively. I agree. By the way, I once read or watched an interview with Guido van Rossum and and he was asked why not to tail-call optimize Python and the answer he gave --- IIRC --- was that tail-call optimization makes it harder for a beginner to understand a stack trace. I'm now interested in discovering whether that was his sole reason. Do you (or does anyone) know of any reference that I could look into? Thank you. >> --8<---------------cut here---------------start------------->8--- >> def sam(b, e, m, acc = 1): >> if e == 0: >> return acc >> if is_even(e): >> return sam(remainder(b * b, m), e//2, m, acc) >> else: >> return sam(b, e - 1, m, remainder(b * acc, m)) >> --8<---------------cut here---------------end--------------->8--- >> You see, I tried to use an accumulator, but I'm only accumulating >> when >> the exponent is odd. When it's even, I feel I'm forced to change the >> base into b * b mod m and leave the accumulator alone. This feels so >> unnatural to me. I feel I broke some symmetry there. I'm having to >> think of two cases --- when I change the accumulator and when I change >> the base. That seems too much for my small head. Can you help? > > Well, there are inherently two cases, and they're different, so > I don't think you're doing anything wrong here. It was asymmetrical > to begin with. If you were doing it iteratively you would also be > leaving the accumulator alone when the exponent is even. I think you're quite right and that was not clear until now. Here's my iterative version of the procedure: --8<---------------cut here---------------start------------->8--- def isam(b, e, m): r = 1 while e > 0: if is_even(e): b = remainder(b * b, m) e = e // 2 else: r = remainder(r * b, m) e = e - 1 return remainder(r, m) --8<---------------cut here---------------end--------------->8--- So, indeed, it is asymmetric. When it's even, I change the base. When it's odd, I change the /r/eturning value. Thank you so much. (*) The remainder function --8<---------------cut here---------------start------------->8--- def is_even(n): return remainder(n, 2) == 0 def remainder(a, b): return a % b --8<---------------cut here---------------end--------------->8--- From jshem at yaxenu.org Wed Nov 8 20:32:32 2023 From: jshem at yaxenu.org (Julieta Shem) Date: Wed, 08 Nov 2023 22:32:32 -0300 Subject: on a tail-recursive square-and-multiply References: <87leb9rq6i.fsf@yaxenu.org> <87a5roshw1.fsf@yaxenu.org> Message-ID: <87sf5fr9sf.fsf@yaxenu.org> Julieta Shem writes: [...] > I agree. By the way, I once read or watched an interview with Guido van > Rossum and and he was asked why not to tail-call optimize Python and the > answer he gave --- IIRC --- was that tail-call optimization makes it > harder for a beginner to understand a stack trace. I'm now interested > in discovering whether that was his sole reason. Do you (or does > anyone) know of any reference that I could look into? Thank you. It seems everyone refers Guido van Rossum's post at https://neopythonic.blogspot.com/2009/04/final-words-on-tail-calls.html >From the page, confuse-users is /not/ the only reason. After mentioning it first, he begins a second paragraph saying ``[t]he main issue here [...]'' and I wonder if by ``main issue'' he means something like --- the main /problem/ with tail-call optimization (for me) is [...]. --8<---------------cut here---------------start------------->8--- Personally, I think it is a fine feature for some languages, but I don't think it fits Python: The elimination of stack traces for some calls but not others would certainly confuse many users, who have not been raised with tail call religion but might have learned about call semantics by tracing through a few calls in a debugger. The main issue here is that I expect that in many cases tail calls are not of a recursive nature (neither direct nor indirect), so the elimination of stack frames doesn't do anything for the algorithmic complexity of the code, but it does make debugging harder. For example, if your have a function ending in something like this: if x > y: return some_call(z) else: return 42 and you end up in the debugger inside some_call() whereas you expected to have taken the other branch, with TCO as a feature your debugger can't tell you the value of x and y, because the stack frame has been eliminated. --8<---------------cut here---------------end--------------->8--- From loris.bennett at fu-berlin.de Fri Nov 10 04:15:51 2023 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Fri, 10 Nov 2023 10:15:51 +0100 Subject: SQL rollback of multiple inserts involving constraints Message-ID: <877cmqt1dk.fsf@zedat.fu-berlin.de> Hi, In my MariaDB database I have a table 'people' with 'uid' as the primary key and a table 'groups' with 'gid' as the primary key. I have a third table 'memberships' with 'uid' and 'gid' being the primary key and the constraint that values for 'uid' and 'gid' exist in the tables 'people' and 'groups', respectively. I am using SQLAlchemy and writing a method to setup a membership for a new person in a new group. I had assumed that I should be able to perform all three inserts (person, group, membership) with a single transaction and then rollback if there is a problem. However, the problem is that if the both the insert into 'people' and that into 'groups' are not first committed, the constraint on the insertion of the membership fails. What am I doing wrong? Apologies if this is actually an SQL question rather than something related to SQLAlchemy. Cheers, Loris -- This signature is currently under constuction. From jacob.kruger.work at gmail.com Fri Nov 10 11:03:34 2023 From: jacob.kruger.work at gmail.com (Jacob Kruger) Date: Fri, 10 Nov 2023 18:03:34 +0200 Subject: SQL rollback of multiple inserts involving constraints In-Reply-To: <877cmqt1dk.fsf@zedat.fu-berlin.de> References: <877cmqt1dk.fsf@zedat.fu-berlin.de> Message-ID: <9cd27924-cd96-8013-794c-97acbbd4562f@gmail.com> Think performing a session/transaction flush after the first two inserts should offer the workaround before you've committed all transaction actions to the database finally: https://medium.com/@oba2311/sqlalchemy-whats-the-difference-between-a-flush-and-commit-baec6c2410a9 HTH Jacob Kruger +2782 413 4791 "Resistance is futile!...Acceptance is versatile..." On 2023/11/10 11:15, Loris Bennett via Python-list wrote: > Hi, > > In my MariaDB database I have a table 'people' with 'uid' as the primary > key and a table 'groups' with 'gid' as the primary key. I have a third > table 'memberships' with 'uid' and 'gid' being the primary key and the > constraint that values for 'uid' and 'gid' exist in the tables 'people' > and 'groups', respectively. I am using SQLAlchemy and writing a method > to setup a membership for a new person in a new group. > > I had assumed that I should be able to perform all three inserts > (person, group, membership) with a single transaction and then rollback > if there is a problem. However, the problem is that if the both the > insert into 'people' and that into 'groups' are not first committed, the > constraint on the insertion of the membership fails. > > What am I doing wrong? > > Apologies if this is actually an SQL question rather than something > related to SQLAlchemy. > > Cheers, > > Loris > From phd at phdru.name Sat Nov 11 08:31:37 2023 From: phd at phdru.name (Oleg Broytman) Date: Sat, 11 Nov 2023 16:31:37 +0300 Subject: SQLObject 3.11.0 Message-ID: Hello! I'm pleased to announce version 3.11.0, the first stable release of branch 3.11 of SQLObject. What's new in SQLObject ======================= Features -------- * Continue working on ``SQLRelatedJoin`` aliasing introduced in 3.10.2. When a table joins with itself calling ``relJoinCol.filter(thisClass.q.column)`` raises ``ValueError`` hinting that an alias is required for filtering. * Test that ``idType`` is either ``int`` or ``str``. * Added ``sqlmeta.idSize``. This sets the size of integer column ``id`` for MySQL and PostgreSQL. Allowed values are ``'TINY'``, ``'SMALL'``, ``'MEDIUM'``, ``'BIG'``, ``None``; default is ``None``. For Postgres mapped to ``smallserial``/``serial``/``bigserial``. For other backends it's currently ignored. Feature request by Meet Gujrathi at https://stackoverflow.com/q/77360075/7976758 For a more complete list, please see the news: http://sqlobject.org/News.html What is SQLObject ================= SQLObject is a free and open-source (LGPL) Python 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. SQLObject supports a number of backends: MySQL/MariaDB (with a number of DB API drivers: ``MySQLdb``, ``mysqlclient``, ``mysql-connector``, ``PyMySQL``, ``mariadb``), PostgreSQL (``psycopg2``, ``PyGreSQL``, partially ``pg8000`` and ``py-postgresql``), SQLite (builtin ``sqlite``, ``pysqlite``); connections to other backends - Firebird, Sybase, MSSQL and MaxDB (also known as SAPDB) - are less debugged). Python 2.7 or 3.4+ is required. Where is SQLObject ================== Site: http://sqlobject.org Download: https://pypi.org/project/SQLObject/3.11.0 News and changes: http://sqlobject.org/News.html StackOverflow: https://stackoverflow.com/questions/tagged/sqlobject Mailing lists: https://sourceforge.net/p/sqlobject/mailman/ Development: http://sqlobject.org/devel/ Developer Guide: http://sqlobject.org/DeveloperGuide.html Example ======= Install:: $ pip install sqlobject 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 rob.cliffe at btinternet.com Sat Nov 11 17:49:51 2023 From: rob.cliffe at btinternet.com (Rob Cliffe) Date: Sat, 11 Nov 2023 22:49:51 +0000 Subject: Beep on WIndows 11 Message-ID: <4f323aee-ea6b-44f3-9f48-e72006a22b1e@btinternet.com> ?Apologies if this is not a Python question. I? recently moved from a WIndows 10 laptop to a Windows 11 one. Although there is nothing wrong with the sound on the new machine (I can listen to podcasts and watch videos), I find that outputting "\a" to the console (aka stdout) no longer beeps (or makes any sound).? This is true whether I print "\a" from a python program, or "type ". I have found via Google workarounds such as ??? os.system("rundll32 user32.dll,MessageBeep") but it is a trifle annoying to have to modify all of my programs that beep. Can anyone shed light on this, and perhaps give a simpler fix? Best wishes Rob Cliffe From mickey_yang9 at msn.com Sat Nov 11 18:44:19 2023 From: mickey_yang9 at msn.com (Y Y) Date: Sat, 11 Nov 2023 23:44:19 +0000 Subject: Beep on WIndows 11 In-Reply-To: <4f323aee-ea6b-44f3-9f48-e72006a22b1e@btinternet.com> References: <4f323aee-ea6b-44f3-9f48-e72006a22b1e@btinternet.com> Message-ID: I am curious and humble to ask: What is the purpose of a BEEP? -----Original Message----- From: Python-list On Behalf Of Rob Cliffe via Python-list Sent: Sunday, November 12, 2023 6:50 AM To: Python Subject: Beep on WIndows 11 ?Apologies if this is not a Python question. I? recently moved from a WIndows 10 laptop to a Windows 11 one. Although there is nothing wrong with the sound on the new machine (I can listen to podcasts and watch videos), I find that outputting "\a" to the console (aka stdout) no longer beeps (or makes any sound).? This is true whether I print "\a" from a python program, or "type ". I have found via Google workarounds such as ??? os.system("rundll32 user32.dll,MessageBeep") but it is a trifle annoying to have to modify all of my programs that beep. Can anyone shed light on this, and perhaps give a simpler fix? Best wishes Rob Cliffe -- https://mail.python.org/mailman/listinfo/python-list From nospam at please.ty Sat Nov 11 20:50:26 2023 From: nospam at please.ty (jak) Date: Sun, 12 Nov 2023 02:50:26 +0100 Subject: Beep on WIndows 11 In-Reply-To: References: <4f323aee-ea6b-44f3-9f48-e72006a22b1e@btinternet.com> Message-ID: Rob Cliffe ha scritto: > ?Apologies if this is not a Python question. > I? recently moved from a WIndows 10 laptop to a Windows 11 one. > Although there is nothing wrong with the sound on the new machine (I can > listen to podcasts and watch videos), I find that outputting "\a" to the > console (aka stdout) no longer beeps (or makes any sound).? This is true > whether I print "\a" from a python program, or "type > ". > I have found via Google workarounds such as > ??? os.system("rundll32 user32.dll,MessageBeep") > but it is a trifle annoying to have to modify all of my programs that beep. > Can anyone shed light on this, and perhaps give a simpler fix? > Best wishes > Rob Cliffe HI, I would first check the properties of the terminal, then the system configuration relating to the system beep. It can be disabled. You can find some tips here: From 2QdxY4RzWzUUiLuE at potatochowder.com Sun Nov 12 05:50:00 2023 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Sun, 12 Nov 2023 05:50:00 -0500 Subject: Beep on WIndows 11 In-Reply-To: References: <4f323aee-ea6b-44f3-9f48-e72006a22b1e@btinternet.com> Message-ID: On 2023-11-11 at 23:44:19 +0000, Y Y via Python-list wrote: > I am curious and humble to ask: What is the purpose of a BEEP? It's a simple way for a terminal-based program to alert (hence '\a') a user or an operator that their attention is requested or required. See also . From rosuav at gmail.com Sun Nov 12 06:16:40 2023 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 12 Nov 2023 22:16:40 +1100 Subject: Beep on WIndows 11 In-Reply-To: References: <4f323aee-ea6b-44f3-9f48-e72006a22b1e@btinternet.com> Message-ID: On Sun, 12 Nov 2023 at 21:27, Y Y via Python-list wrote: > > I am curious and humble to ask: What is the purpose of a BEEP? > There are several purposes. I can't say which of these are relevant to the OP, but some or all of them could easily be. * A very very simple notification that can be triggered by any program * An audio cue that is not routed to your regular audio system (good if you use headphones but are AFK) * An extremely low level signal that requires little-to-no processing power * An emergency signal that does not even require a CPU (probably not in this instance though!) * Imitating a pre-existing audio signal that works by beeping Depending on what's needed, a more complex system might suffice (for example, I cover the first two points by having an entire separate audio subsystem with its own dedicated speakers, which I can invoke using VLC in a specific configuration); but a basic beep is definitely of value. I suspect in this situation that the first point is important here, but it's up to the OP to elaborate. (Note that the "no CPU emergency sound" option usually requires a motherboard-mounted speaker or speaker header, which not all have these days. Sad.) ChrisA From python at mrabarnett.plus.com Sun Nov 12 12:12:17 2023 From: python at mrabarnett.plus.com (MRAB) Date: Sun, 12 Nov 2023 17:12:17 +0000 Subject: Beep on WIndows 11 In-Reply-To: References: <4f323aee-ea6b-44f3-9f48-e72006a22b1e@btinternet.com> Message-ID: <64af3352-955d-4080-9769-4e40c5d7aa72@mrabarnett.plus.com> On 2023-11-12 11:16, Chris Angelico via Python-list wrote: > On Sun, 12 Nov 2023 at 21:27, Y Y via Python-list > wrote: >> >> I am curious and humble to ask: What is the purpose of a BEEP? >> > > There are several purposes. I can't say which of these are relevant to > the OP, but some or all of them could easily be. > > * A very very simple notification that can be triggered by any program > * An audio cue that is not routed to your regular audio system (good > if you use headphones but are AFK) > * An extremely low level signal that requires little-to-no processing power > * An emergency signal that does not even require a CPU (probably not > in this instance though!) > * Imitating a pre-existing audio signal that works by beeping > > Depending on what's needed, a more complex system might suffice (for > example, I cover the first two points by having an entire separate > audio subsystem with its own dedicated speakers, which I can invoke > using VLC in a specific configuration); but a basic beep is definitely > of value. I suspect in this situation that the first point is > important here, but it's up to the OP to elaborate. > > (Note that the "no CPU emergency sound" option usually requires a > motherboard-mounted speaker or speaker header, which not all have > these days. Sad.) > Recently, I wanted a program to beep. In the old days, with a BBC micro, that was simple. It had 3 tone channels and 1 white noise channel, with control over frequency, duration and volume, beeps on different channels could be synchronised to start at the same time, there was a sound queue so that the SOUND command returned immediately, and there was an ENVELOPE command for controlling the attack, decay, sustain and release. All this on an 8-bit machine! My current PC is way more powerful. 64-bit processor, GBs of RAM, etc. Python offers winsound.Beep. 1 tone, no volume control, and it blocks while beeping. From rosuav at gmail.com Sun Nov 12 12:21:19 2023 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 13 Nov 2023 04:21:19 +1100 Subject: Beep on WIndows 11 In-Reply-To: <64af3352-955d-4080-9769-4e40c5d7aa72@mrabarnett.plus.com> References: <4f323aee-ea6b-44f3-9f48-e72006a22b1e@btinternet.com> <64af3352-955d-4080-9769-4e40c5d7aa72@mrabarnett.plus.com> Message-ID: On Mon, 13 Nov 2023 at 04:13, MRAB via Python-list wrote: > In the old days, with a BBC micro, that was simple. It had 3 tone > channels and 1 white noise channel, with control over frequency, > duration and volume, beeps on different channels could be synchronised > to start at the same time, there was a sound queue so that the SOUND > command returned immediately, and there was an ENVELOPE command for > controlling the attack, decay, sustain and release. All this on an 8-bit > machine! > > My current PC is way more powerful. 64-bit processor, GBs of RAM, etc. > Python offers winsound.Beep. 1 tone, no volume control, and it blocks > while beeping. I learned to make a computer beep using the programmable timer chip (8254?). Send it signals on the I/O port saying "timer chip, speaker signal, counter = N" (where N is the fundamental clock divided by the frequency I wanted), and then "speaker, respond to timer chip". Then you wait the right length of time, then send "speaker, stop responding to timer chip". Of course, I had a bug in the "wait the right length of time" part, and my program stopped running. My family was not amused. ChrisA From dom.grigonis at gmail.com Mon Nov 13 03:49:37 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Mon, 13 Nov 2023 10:49:37 +0200 Subject: xor operator Message-ID: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> Hi All, I think it could be useful to have `xor` builtin, which has API similar to the one of `any` and `all`. * Also, it could have optional second argument `n=1`, which indicates how many positives indicates `True` return. * For complete flexibility 3rd argument could indicate if `the number` is equal, greater, less, ... than `n` I find I sometimes need it when dealing with pub-sub filters and multiple predicates in general. What is the current situation that led me to writing this e-mail? Dealing with circular import in low level component space: library builtins depend on validation utilities, while validation utilities want to use xor from library builtins. Not a big issue, but seen there are fairly large threads in stack everyone inventing their own `xor`. And surprisingly there aren?t many good solutions. Almost none of them deal with short-circuiting well. And those that do contain loops that result in very poor performance. Regards, DG From loris.bennett at fu-berlin.de Mon Nov 13 04:20:55 2023 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Mon, 13 Nov 2023 10:20:55 +0100 Subject: SQL rollback of multiple inserts involving constraints References: <877cmqt1dk.fsf@zedat.fu-berlin.de> <9cd27924-cd96-8013-794c-97acbbd4562f@gmail.com> Message-ID: <87sf5aau14.fsf@zedat.fu-berlin.de> Jacob Kruger writes: > Think performing a session/transaction flush after the first two > inserts should offer the workaround before you've committed all > transaction actions to the database finally: > > https://medium.com/@oba2311/sqlalchemy-whats-the-difference-between-a-flush-and-commit-baec6c2410a9 > > > HTH Yes, thank you, it does. I hadn't been aware of 'flush'. > Jacob Kruger > +2782 413 4791 > "Resistance is futile!...Acceptance is versatile..." > > > On 2023/11/10 11:15, Loris Bennett via Python-list wrote: >> Hi, >> >> In my MariaDB database I have a table 'people' with 'uid' as the primary >> key and a table 'groups' with 'gid' as the primary key. I have a third >> table 'memberships' with 'uid' and 'gid' being the primary key and the >> constraint that values for 'uid' and 'gid' exist in the tables 'people' >> and 'groups', respectively. I am using SQLAlchemy and writing a method >> to setup a membership for a new person in a new group. >> >> I had assumed that I should be able to perform all three inserts >> (person, group, membership) with a single transaction and then rollback >> if there is a problem. However, the problem is that if the both the >> insert into 'people' and that into 'groups' are not first committed, the >> constraint on the insertion of the membership fails. >> >> What am I doing wrong? >> >> Apologies if this is actually an SQL question rather than something >> related to SQLAlchemy. >> >> Cheers, >> >> Loris >> > -- Dr. Loris Bennett (Herr/Mr) ZEDAT, Freie Universit?t Berlin From jacob.kruger.work at gmail.com Mon Nov 13 12:18:02 2023 From: jacob.kruger.work at gmail.com (Jacob Kruger) Date: Mon, 13 Nov 2023 19:18:02 +0200 Subject: No current way to just compile flet code into truly native packages for smart phones, etc.? Message-ID: <3a534da3-dfc9-33db-2ffa-ae15092ddb8e@gmail.com> Had a look at the following bit of introduction to using python and flet to build cross-platform flutter-based apps using same python code, and, while it seems to work alright if tell it to run as under GUI here on windows desktop, and, while can get it to fire up PWA version as well, that's not really stand-alone since will still require code to be running in background, and, in terms of, for example, android, it seems like it will need to then be running via the native android flet interpreter for it to work as such? https://flet.dev/docs/ Flet PWA deployment -- Jacob Kruger +2782 413 4791 "Resistance is futile!...Acceptance is versatile..." From barry at barrys-emacs.org Mon Nov 13 12:42:14 2023 From: barry at barrys-emacs.org (Barry) Date: Mon, 13 Nov 2023 17:42:14 +0000 Subject: xor operator In-Reply-To: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> Message-ID: > On 13 Nov 2023, at 15:16, Dom Grigonis via Python-list wrote: > > I think it could be useful to have `xor` builtin, which has API similar to the one of `any` and `all`. I do not understand how xor(iterator) works. I thought xor takes exactly 2 args. I also do not understand how xor can be short circuited. For AND or OR only looking at the first arg works. But that does not work for xor right? Barry From barry at barrys-emacs.org Mon Nov 13 12:47:32 2023 From: barry at barrys-emacs.org (Barry) Date: Mon, 13 Nov 2023 17:47:32 +0000 Subject: No current way to just compile flet code into truly native packages for smart phones, etc.? In-Reply-To: <3a534da3-dfc9-33db-2ffa-ae15092ddb8e@gmail.com> References: <3a534da3-dfc9-33db-2ffa-ae15092ddb8e@gmail.com> Message-ID: > On 13 Nov 2023, at 17:21, Jacob Kruger via Python-list wrote: > > ?Had a look at the following bit of introduction to using python and flet to build cross-platform flutter-based apps using same python code, and, while it seems to work alright if tell it to run as under GUI here on windows desktop, and, while can get it to fire up PWA version as well, that's not really stand-alone since will still require code to be running in background, and, in terms of, for example, android, it seems like it will need to then be running via the native android flet interpreter for it to work as such? > > > https://flet.dev/docs/ > > > Flet PWA deployment flet looks interesting. It seems from the road map there is lots missing today. Also the people that know flet are on discord. You may find someone here. Barry > > -- > > Jacob Kruger > +2782 413 4791 > "Resistance is futile!...Acceptance is versatile..." > > -- > https://mail.python.org/mailman/listinfo/python-list > From dom.grigonis at gmail.com Mon Nov 13 12:47:50 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Mon, 13 Nov 2023 19:47:50 +0200 Subject: xor operator In-Reply-To: References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> Message-ID: <44FBD8A8-E092-40FF-BD56-467E6936AAE9@gmail.com> Well yes, I don?t think naming is very accurate. If iterable has 2 elements, then it is `xor`, otherwise it is something else - it checks the number of truth values in iterable. Short circuiting happens, when: xor([True, True, False, False], n=1) At index 1 it is clear that the answer is false. Regards, DG > On 13 Nov 2023, at 19:42, Barry wrote: > > > >> On 13 Nov 2023, at 15:16, Dom Grigonis via Python-list wrote: >> >> I think it could be useful to have `xor` builtin, which has API similar to the one of `any` and `all`. > > I do not understand how xor(iterator) works. > I thought xor takes exactly 2 args. > > I also do not understand how xor can be short circuited. > For AND or OR only looking at the first arg works. > But that does not work for xor right? > > Barry > > From barry at barrys-emacs.org Mon Nov 13 16:03:12 2023 From: barry at barrys-emacs.org (Barry) Date: Mon, 13 Nov 2023 21:03:12 +0000 Subject: xor operator In-Reply-To: <44FBD8A8-E092-40FF-BD56-467E6936AAE9@gmail.com> References: <44FBD8A8-E092-40FF-BD56-467E6936AAE9@gmail.com> Message-ID: > On 13 Nov 2023, at 17:48, Dom Grigonis wrote: > > Short circuiting happens, when: > xor([True, True, False, False], n=1) > At index 1 it is clear that the answer is false. Can you share an example with 4 values that is true? And explain why it is xor. Barry From knomenet at gmail.com Mon Nov 13 16:20:27 2023 From: knomenet at gmail.com (Michael Speer) Date: Mon, 13 Nov 2023 16:20:27 -0500 Subject: xor operator In-Reply-To: References: <44FBD8A8-E092-40FF-BD56-467E6936AAE9@gmail.com> Message-ID: I don't think an exclusive-or/truthy-entries-count-checker needs to be a builtin by any stretch. >>> def xor( iterable, n = 1 ): ... return sum( map( bool, iterable ) ) == n Or if you insist on short circuiting: >>> def xor_ss( iterable, n = 1 ): ... for intermediate in itertools.accumulate( iterable, (lambda x, y: x + bool(y)), initial = 0 ): ... if intermediate > n: ... return False ... return intermediate == n On Mon, Nov 13, 2023 at 4:05?PM Barry via Python-list < python-list at python.org> wrote: > > > > On 13 Nov 2023, at 17:48, Dom Grigonis wrote: > > > > Short circuiting happens, when: > > xor([True, True, False, False], n=1) > > At index 1 it is clear that the answer is false. > > Can you share an example with 4 values that is true? > And explain why it is xor. > > Barry > > -- > https://mail.python.org/mailman/listinfo/python-list > From python at mrabarnett.plus.com Mon Nov 13 16:25:42 2023 From: python at mrabarnett.plus.com (MRAB) Date: Mon, 13 Nov 2023 21:25:42 +0000 Subject: xor operator In-Reply-To: References: <44FBD8A8-E092-40FF-BD56-467E6936AAE9@gmail.com> Message-ID: On 2023-11-13 21:03, Barry via Python-list wrote: > > >> On 13 Nov 2023, at 17:48, Dom Grigonis wrote: >> >> Short circuiting happens, when: >> xor([True, True, False, False], n=1) >> At index 1 it is clear that the answer is false. > > Can you share an example with 4 values that is true? > And explain why it is xor. > I think what the OP wants is something that stops after finding n true items. It's a more general form of what 'any' and 'all' do - 'any' stops when it finds 1 true item and 'all' stops when it finds 1 false item. In general, you might want to stop when you find n true items or n false items, or whatever. From dom.grigonis at gmail.com Mon Nov 13 16:35:32 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Mon, 13 Nov 2023 23:35:32 +0200 Subject: xor operator In-Reply-To: References: <44FBD8A8-E092-40FF-BD56-467E6936AAE9@gmail.com> Message-ID: xor([True, False, False, False], n=1) xor([False, False, False, True], n=1) Both of the above would evaluate to true. Well, it depends how you interpret it. In binary case it reads: ?exclusively one positive bit or the other, but not both? In this case one could read: ?exclusively one positive set of certain length, but not more than one such set at the same time" But I completely see how one could argue, that ?exclusive? refers to slightly different thing. And multivariate `xor` is a function which defines fixed subsets out of which only one is true, but not the others, but this is theoretical, as in practice each set would need to always have all values switched on or off, which boils down to my proposed `xor` with `n=1`. But the point is if there is a need for such function or I am the only one who happens to use it. DG > On 13 Nov 2023, at 23:03, Barry wrote: > > > >> On 13 Nov 2023, at 17:48, Dom Grigonis wrote: >> >> Short circuiting happens, when: >> xor([True, True, False, False], n=1) >> At index 1 it is clear that the answer is false. > > Can you share an example with 4 values that is true? > And explain why it is xor. > > Barry > From mail at axel-reichert.de Mon Nov 13 16:23:53 2023 From: mail at axel-reichert.de (Axel Reichert) Date: Mon, 13 Nov 2023 22:23:53 +0100 Subject: xor operator References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> Message-ID: <87cywdpct2.fsf@axel-reichert.de> Barry writes: > I do not understand how xor(iterator) works. > I thought xor takes exactly 2 args. See https://mathworld.wolfram.com/XOR.html for some background (I was not aware of any generalizations for more than 2 arguments either). > I also do not understand how xor can be short circuited. Me neither, but that could be related to the meaning of n (which I did not get) in the OP's question. Maybe he can clarify. Best regards Axel From rosuav at gmail.com Mon Nov 13 17:01:15 2023 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 14 Nov 2023 09:01:15 +1100 Subject: xor operator In-Reply-To: <87cywdpct2.fsf@axel-reichert.de> References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> <87cywdpct2.fsf@axel-reichert.de> Message-ID: On Tue, 14 Nov 2023 at 08:57, Axel Reichert via Python-list wrote: > > Barry writes: > > > I do not understand how xor(iterator) works. > > I thought xor takes exactly 2 args. > > See > > https://mathworld.wolfram.com/XOR.html > > for some background (I was not aware of any generalizations for more > than 2 arguments either). > Generalization to more arguments usually means calculating parity - that is, it tells you whether you have an odd or even number of true results. Which means that short-circuiting is nonsensical. ChrisA From dom.grigonis at gmail.com Mon Nov 13 17:11:30 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Tue, 14 Nov 2023 00:11:30 +0200 Subject: xor operator In-Reply-To: References: <44FBD8A8-E092-40FF-BD56-467E6936AAE9@gmail.com> Message-ID: <166AE5F3-3FF0-458D-9DA8-D6A7367122C4@gmail.com> Benchmarks: test1 = [False] * 100 + [True] * 2 test2 = [True] * 100 + [False] * 2 TIMER.repeat([ lambda: xor(test1), # 0.0168 lambda: xor(test2), # 0.0172 lambda: xor_ss(test1), # 0.1392 lambda: xor_ss(test2), # 0.0084 lambda: xor_new(test1), # 0.0116 lambda: xor_new(test2), # 0.0074 lambda: all(test1), # 0.0016 lambda: all(test2) # 0.0046 ]) Your first function is fairly slow. Second one deals with short-circuiting, but is super slow on full search. `xor_new` is the best what I could achieve using python builtins. But builtin `all` has the best performance. DG > On 13 Nov 2023, at 23:20, Michael Speer wrote: > > I don't think an exclusive-or/truthy-entries-count-checker needs to be a builtin by any stretch. > > >>> def xor( iterable, n = 1 ): > ... return sum( map( bool, iterable ) ) == n > > Or if you insist on short circuiting: > > >>> def xor_ss( iterable, n = 1 ): > ... for intermediate in itertools.accumulate( iterable, (lambda x, y: x + bool(y)), initial = 0 ): > ... if intermediate > n: > ... return False > ... return intermediate == n > > > > On Mon, Nov 13, 2023 at 4:05?PM Barry via Python-list > wrote: > > > > On 13 Nov 2023, at 17:48, Dom Grigonis > wrote: > > > > Short circuiting happens, when: > > xor([True, True, False, False], n=1) > > At index 1 it is clear that the answer is false. > > Can you share an example with 4 values that is true? > And explain why it is xor. > > Barry > > -- > https://mail.python.org/mailman/listinfo/python-list From grant.b.edwards at gmail.com Mon Nov 13 17:51:05 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 13 Nov 2023 14:51:05 -0800 (PST) Subject: xor operator References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> Message-ID: <6552a859.020a0220.8cb14.012f@mx.google.com> On 2023-11-13, Dom Grigonis via Python-list wrote: > Hi All, > > I think it could be useful to have `xor` builtin, which has API similar to the one of `any` and `all`. > > * Also, it could have optional second argument `n=1`, which > * indicates how many positives indicates `True` return. For > * complete flexibility 3rd argument could indicate if `the number` > * is equal, greater, less, ... than `n` I would expect "xor" to return true if there are an odd number of trues, and false if there are an even number of trues. It's not clear to me what you're asking for. From dom.grigonis at gmail.com Mon Nov 13 17:58:58 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Tue, 14 Nov 2023 00:58:58 +0200 Subject: xor operator In-Reply-To: <6552a859.020a0220.8cb14.012f@mx.google.com> References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> <6552a859.020a0220.8cb14.012f@mx.google.com> Message-ID: <78B43ECD-2EFC-4CDF-99C4-DC310F0B26DE@gmail.com> I am not asking. Just inquiring if the function that I described could be useful for more people. Which is: a function with API that of `all` and `any` and returns `True` if specified number of elements is True. It is not a generalised `xor` in strict programatic space. I.e. NOT bitwise xor applied to many bits. This is more in line with cases that `any` and `all` builtins are used. > On 14 Nov 2023, at 00:51, Grant Edwards via Python-list wrote: > > On 2023-11-13, Dom Grigonis via Python-list wrote: >> Hi All, >> >> I think it could be useful to have `xor` builtin, which has API similar to the one of `any` and `all`. >> >> * Also, it could have optional second argument `n=1`, which >> * indicates how many positives indicates `True` return. For >> * complete flexibility 3rd argument could indicate if `the number` >> * is equal, greater, less, ... than `n` > > I would expect "xor" to return true if there are an odd number of > trues, and false if there are an even number of trues. It's not clear > to me what you're asking for. > > > > -- > https://mail.python.org/mailman/listinfo/python-list From rosuav at gmail.com Mon Nov 13 18:12:56 2023 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 14 Nov 2023 10:12:56 +1100 Subject: xor operator In-Reply-To: <78B43ECD-2EFC-4CDF-99C4-DC310F0B26DE@gmail.com> References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> <6552a859.020a0220.8cb14.012f@mx.google.com> <78B43ECD-2EFC-4CDF-99C4-DC310F0B26DE@gmail.com> Message-ID: On Tue, 14 Nov 2023 at 10:00, Dom Grigonis via Python-list wrote: > > I am not asking. Just inquiring if the function that I described could be useful for more people. > > Which is: a function with API that of `all` and `any` and returns `True` if specified number of elements is True. > > It is not a generalised `xor` in strict programatic space. I.e. NOT bitwise xor applied to many bits. > This is more in line with cases that `any` and `all` builtins are used. > A generalization of XOR is exactly what Grant and I said, though: a parity check. See for example: https://en.wikipedia.org/wiki/Exclusive_or https://reference.wolfram.com/language/ref/Xor.html It tells you whether you have an odd or even number of true values. Now, if you want something that short-circuits a counting function, that's definitely doable, but it's a sum-and-compare, not xor. Also, it's quite specialized so it's unlikely to end up in the stdlib. ChrisA From dom.grigonis at gmail.com Mon Nov 13 18:24:19 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Tue, 14 Nov 2023 01:24:19 +0200 Subject: xor operator In-Reply-To: References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> <6552a859.020a0220.8cb14.012f@mx.google.com> <78B43ECD-2EFC-4CDF-99C4-DC310F0B26DE@gmail.com> Message-ID: I am not arguing that it is a generalised xor. I don?t want anything, I am just gauging if it is specialised or if there is a need for it. So just thought could suggest it as I have encountered such need several times already. It is fairly clear by now that it is not a common one given it took some time to even convey what I mean. Bad naming didn?t help ofc, but if it was something that is needed I think it would have clicked much faster. Thanks, DG > On 14 Nov 2023, at 01:12, Chris Angelico via Python-list wrote: > > On Tue, 14 Nov 2023 at 10:00, Dom Grigonis via Python-list > wrote: >> >> I am not asking. Just inquiring if the function that I described could be useful for more people. >> >> Which is: a function with API that of `all` and `any` and returns `True` if specified number of elements is True. >> >> It is not a generalised `xor` in strict programatic space. I.e. NOT bitwise xor applied to many bits. >> This is more in line with cases that `any` and `all` builtins are used. >> > > A generalization of XOR is exactly what Grant and I said, though: a > parity check. See for example: > > https://en.wikipedia.org/wiki/Exclusive_or > https://reference.wolfram.com/language/ref/Xor.html > > It tells you whether you have an odd or even number of true values. > > Now, if you want something that short-circuits a counting function, > that's definitely doable, but it's a sum-and-compare, not xor. Also, > it's quite specialized so it's unlikely to end up in the stdlib. > > ChrisA > -- > https://mail.python.org/mailman/listinfo/python-list From grant.b.edwards at gmail.com Mon Nov 13 19:18:18 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 13 Nov 2023 16:18:18 -0800 (PST) Subject: xor operator References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> <6552a859.020a0220.8cb14.012f@mx.google.com> <78B43ECD-2EFC-4CDF-99C4-DC310F0B26DE@gmail.com> Message-ID: <6552bcca.050a0220.216c3.01b1@mx.google.com> On 2023-11-13, Dom Grigonis via Python-list wrote: > I am not asking. Just inquiring if the function that I described > could be useful for more people. > > Which is: a function with API that of `all` and `any` and returns > `True` if specified number of elements is True. I've got no objection to a function that counts True objects returned by an iterator and returns True IFF count == . I've got no objection to a function that counts True objects returned by an iterator and returns True IFF count >= . I've got no objection if that latter function short-circuits by stopping the iteration and returning True when it has seen true objects. I don't recall ever having a need for such a function in the 25 years I've been writing Python code, but I'm not going to claim that nobody else has a need for such a function. I would object to that being called 'xor', and would fight to the death (yes, I'm being hyperbolic) the addition of a builtin with the name 'xor' that does what you describe. > It is not a generalised `xor` in strict programatic space. AFAICT, it's not nothing at all to do with 'xor' in any sense. > I.e. NOT bitwise xor applied to many bits. This is more in line > with cases that `any` and `all` builtins are used. Except the 'any' and 'all' builtins are _exactly_ the same as bitwise or and and applided to many bits. To do something "in line" with that using the 'xor' operator would return True for an odd number of True values and False for an even Number of True values. -- Grant From dom.grigonis at gmail.com Mon Nov 13 19:28:12 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Tue, 14 Nov 2023 02:28:12 +0200 Subject: xor operator In-Reply-To: <6552bcca.050a0220.216c3.01b1@mx.google.com> References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> <6552a859.020a0220.8cb14.012f@mx.google.com> <78B43ECD-2EFC-4CDF-99C4-DC310F0B26DE@gmail.com> <6552bcca.050a0220.216c3.01b1@mx.google.com> Message-ID: > Except the 'any' and 'all' builtins are _exactly_ the same as bitwise > or and and applided to many bits. To do something "in line" with that > using the 'xor' operator would return True for an odd number of True > values and False for an even Number of True values. Fair point. Have you ever encountered the need for xor for many bits (the one that I am NOT referring to)? Would be interested in what sort of case it could be useful. From mats at wichmann.us Mon Nov 13 19:33:06 2023 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 13 Nov 2023 17:33:06 -0700 Subject: xor operator In-Reply-To: References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> <6552a859.020a0220.8cb14.012f@mx.google.com> <78B43ECD-2EFC-4CDF-99C4-DC310F0B26DE@gmail.com> Message-ID: <2f915cf1-c8ca-4db4-87a7-4597d5209b71@wichmann.us> On 11/13/23 16:24, Dom Grigonis via Python-list wrote: > I am not arguing that it is a generalised xor. > > I don?t want anything, I am just gauging if it is specialised or if there is a need for it. So just thought could suggest it as I have encountered such need several times already. > > It is fairly clear by now that it is not a common one given it took some time to even convey what I mean. Bad naming didn?t help ofc, but if it was something that is needed I think it would have clicked much faster. There are things that If You Need Them You Know, and If You Do Not You Do Not Understand - and you seem to have found one. The problem is that forums like this are not a statistically great sampling mechanism - a few dozen people, perhaps, chime in on many topics; there are millions of people using Python. Still, the folks here like to think they're at least somewhat representative :) Hardware and software people may have somewhat different views of xor, so *maybe* the topic title added a bit to the muddle. To me (one of those millions), any/all falsy, any/all truthy have some interest, and Python does provide those. Once you get into How Many True question - whether that's the odd-is-true, even-is-false model, or the bail-after-X-truthy-values model, it's not terribly interesting to me: once it gets more complex than an all/any decision, I need to check for particular combinations specifically. Two-of-six means nothing to me until I know which combination of two it is. From knomenet at gmail.com Mon Nov 13 19:36:09 2023 From: knomenet at gmail.com (Michael Speer) Date: Mon, 13 Nov 2023 19:36:09 -0500 Subject: xor operator In-Reply-To: <6552bcca.050a0220.216c3.01b1@mx.google.com> References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> <6552a859.020a0220.8cb14.012f@mx.google.com> <78B43ECD-2EFC-4CDF-99C4-DC310F0B26DE@gmail.com> <6552bcca.050a0220.216c3.01b1@mx.google.com> Message-ID: >AFAICT, it's not nothing at all to do with 'xor' in any sense. As much as I agree that the function needn't be in the base of python, I can easily follow the OP's logic on the function name. With two items in the iterator, it is a standard binary exclusive or. It is true if one of but not both of the items is true. OP then generalized this to is exclusively one of any number of these options are true, which is different than the repetitious binary operator application, certainly, but is still very much an 'or' that excludes the case of other options being true. OP then generalized this from exclusively one truth in the set of variables to some other specific number of truths that need be. I expect the OP could then generalize this to a range of truthiness for the set with a minimum and maximum allowable truthiness, and probably a key function to extract some facet from the iterable for consideration. I understand why you find it disagreeable, but I cannot find it necessarily illogical, and it is easy, I think, to see what it has to do with xor. A better name for OP's generalization, however, could likely be 'aut', from the Latin exclusive or. On Mon, Nov 13, 2023 at 7:20?PM Grant Edwards via Python-list < python-list at python.org> wrote: > On 2023-11-13, Dom Grigonis via Python-list > wrote: > > > I am not asking. Just inquiring if the function that I described > > could be useful for more people. > > > > Which is: a function with API that of `all` and `any` and returns > > `True` if specified number of elements is True. > > I've got no objection to a function that counts True objects returned > by an iterator and returns True IFF count == . > > I've got no objection to a function that counts True objects returned > by an iterator and returns True IFF count >= . > > I've got no objection if that latter function short-circuits by > stopping the iteration and returning True when it has seen true > objects. > > I don't recall ever having a need for such a function in the 25 years > I've been writing Python code, but I'm not going to claim that nobody > else has a need for such a function. > > I would object to that being called 'xor', and would fight to the > death (yes, I'm being hyperbolic) the addition of a builtin with the > name 'xor' that does what you describe. > > > It is not a generalised `xor` in strict programatic space. > > AFAICT, it's not nothing at all to do with 'xor' in any sense. > > > I.e. NOT bitwise xor applied to many bits. This is more in line > > with cases that `any` and `all` builtins are used. > > Except the 'any' and 'all' builtins are _exactly_ the same as bitwise > or and and applided to many bits. To do something "in line" with that > using the 'xor' operator would return True for an odd number of True > values and False for an even Number of True values. > > -- > Grant > -- > https://mail.python.org/mailman/listinfo/python-list > From rosuav at gmail.com Mon Nov 13 19:40:38 2023 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 14 Nov 2023 11:40:38 +1100 Subject: xor operator In-Reply-To: References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> <6552a859.020a0220.8cb14.012f@mx.google.com> <78B43ECD-2EFC-4CDF-99C4-DC310F0B26DE@gmail.com> <6552bcca.050a0220.216c3.01b1@mx.google.com> Message-ID: On Tue, 14 Nov 2023 at 11:29, Dom Grigonis via Python-list wrote: > > > > Except the 'any' and 'all' builtins are _exactly_ the same as bitwise > > or and and applided to many bits. To do something "in line" with that > > using the 'xor' operator would return True for an odd number of True > > values and False for an even Number of True values. > > Fair point. > > Have you ever encountered the need for xor for many bits (the one that I am NOT referring to)? Would be interested in what sort of case it could be useful. Yes, parity checking. That's why I namedropped that in my prior response - it's an easy thing to search the web for if you want to know more about it. Here's a couple of excellent videos on error correction, and you'll see XOR showing up as a crucial feature: https://www.youtube.com/watch?v=X8jsijhllIA https://www.youtube.com/watch?v=h0jloehRKas ChrisA From dom.grigonis at gmail.com Mon Nov 13 20:00:26 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Tue, 14 Nov 2023 03:00:26 +0200 Subject: xor operator In-Reply-To: <2f915cf1-c8ca-4db4-87a7-4597d5209b71@wichmann.us> References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> <6552a859.020a0220.8cb14.012f@mx.google.com> <78B43ECD-2EFC-4CDF-99C4-DC310F0B26DE@gmail.com> <2f915cf1-c8ca-4db4-87a7-4597d5209b71@wichmann.us> Message-ID: <50B86B3F-4EE9-4570-A650-691554F8E71F@gmail.com> I agree, from perspective of standard `all` and `any` use cases this does not seem very useful. However, in my experience it has its usages. E.g.: * If sum(map(bool, iterable) [> | <] n can be useful. Counting dead processes and similar, optimisation problems where need to re-initialise if less than certain number of nodes reached certain threshold. * If sum(map(bool, iterable) [== | !=] n is an edge case. Can?t even think of an example * Finally, it would be a convenient shorthand for `bool(a) ^ bool(b)` I sometimes think that there is also a case when certain function is not in one?s mind he doesn?t see the usefulness, but sometimes the sheer knowledge of its existence can twist certain situations in a positive manner. What about an alternative, which does seem more useful: def count_compare(iterable, n): return np.sign(sum(map(bool, iterable)) - n) print(count_compare([False, False, False], 1)) As I am here, I will dare to ask if there is no way that `sign` function is going to be added to `math` or `builtins`. `np.sign` does the trick, but it is very slow to be used on a single number. And yes, I know that `copysign` exists, it just doesn?t do the same thing. DG > On 14 Nov 2023, at 02:33, Mats Wichmann via Python-list wrote: > > On 11/13/23 16:24, Dom Grigonis via Python-list wrote: >> I am not arguing that it is a generalised xor. >> I don?t want anything, I am just gauging if it is specialised or if there is a need for it. So just thought could suggest it as I have encountered such need several times already. >> It is fairly clear by now that it is not a common one given it took some time to even convey what I mean. Bad naming didn?t help ofc, but if it was something that is needed I think it would have clicked much faster. > > There are things that If You Need Them You Know, and If You Do Not You Do Not Understand - and you seem to have found one. The problem is that forums like this are not a statistically great sampling mechanism - a few dozen people, perhaps, chime in on many topics; there are millions of people using Python. Still, the folks here like to think they're at least somewhat representative :) > > Hardware and software people may have somewhat different views of xor, so *maybe* the topic title added a bit to the muddle. To me (one of those millions), any/all falsy, any/all truthy have some interest, and Python does provide those. Once you get into How Many True question - whether that's the odd-is-true, even-is-false model, or the bail-after-X-truthy-values model, it's not terribly interesting to me: once it gets more complex than an all/any decision, I need to check for particular combinations specifically. Two-of-six means nothing to me until I know which combination of two it is. > > > -- > https://mail.python.org/mailman/listinfo/python-list From rosuav at gmail.com Mon Nov 13 20:05:02 2023 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 14 Nov 2023 12:05:02 +1100 Subject: xor operator In-Reply-To: <50B86B3F-4EE9-4570-A650-691554F8E71F@gmail.com> References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> <6552a859.020a0220.8cb14.012f@mx.google.com> <78B43ECD-2EFC-4CDF-99C4-DC310F0B26DE@gmail.com> <2f915cf1-c8ca-4db4-87a7-4597d5209b71@wichmann.us> <50B86B3F-4EE9-4570-A650-691554F8E71F@gmail.com> Message-ID: On Tue, 14 Nov 2023 at 12:02, Dom Grigonis via Python-list wrote: > As I am here, I will dare to ask if there is no way that `sign` function is going to be added to `math` or `builtins`. > https://docs.python.org/3/library/math.html#math.copysign ChrisA From learn2program at gmail.com Mon Nov 13 20:08:26 2023 From: learn2program at gmail.com (Alan Gauld) Date: Tue, 14 Nov 2023 01:08:26 +0000 Subject: xor operator In-Reply-To: <2f915cf1-c8ca-4db4-87a7-4597d5209b71@wichmann.us> References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> <6552a859.020a0220.8cb14.012f@mx.google.com> <78B43ECD-2EFC-4CDF-99C4-DC310F0B26DE@gmail.com> <2f915cf1-c8ca-4db4-87a7-4597d5209b71@wichmann.us> Message-ID: <1b048d51-e0e6-1915-3593-b15f3e147f36@yahoo.co.uk> On 14/11/2023 00:33, Mats Wichmann via Python-list wrote: > Hardware and software people may have somewhat different views of xor I've come at it from both sides. I started life as a telecomms technician and we learned about xor in the context of switching and relays and xor was a wiring configuration for scenarios where you wanted any single change of switch state to toggle the entire system (think a stairwell with switches on every landing). Later, I got into software engineering and we studied Boolean algebra and xor was an odd number of Truth values, used in parity tests (and in encryption). But from both perspectives xor is pretty clearly defined in how it operates and not, I suspect, what the OP really wants in this case. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From rosuav at gmail.com Mon Nov 13 20:14:04 2023 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 14 Nov 2023 12:14:04 +1100 Subject: xor operator In-Reply-To: References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> <6552a859.020a0220.8cb14.012f@mx.google.com> <78B43ECD-2EFC-4CDF-99C4-DC310F0B26DE@gmail.com> <6552bcca.050a0220.216c3.01b1@mx.google.com> Message-ID: On Tue, 14 Nov 2023 at 11:40, Chris Angelico wrote: > Here's a couple of excellent videos on error correction, and you'll > see XOR showing up as a crucial feature: > > https://www.youtube.com/watch?v=X8jsijhllIA > https://www.youtube.com/watch?v=h0jloehRKas > I just flipped through that 3blue1brown video again, and as it turns out, the actual part where he talks about multi-argument XOR happens in part two (it's barely touched on at the very end as he's introducing part two). https://www.youtube.com/watch?v=b3NxrZOu_CE Honestly though, the full video is well worth watching. More modern error correction systems are slightly different, but will still be built on many of the same principles. ChrisA From grant.b.edwards at gmail.com Mon Nov 13 20:19:10 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 13 Nov 2023 17:19:10 -0800 (PST) Subject: xor operator References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> <6552a859.020a0220.8cb14.012f@mx.google.com> <78B43ECD-2EFC-4CDF-99C4-DC310F0B26DE@gmail.com> <6552bcca.050a0220.216c3.01b1@mx.google.com> Message-ID: <6552cb0e.020a0220.4a172.0253@mx.google.com> On 2023-11-14, Dom Grigonis via Python-list wrote: > >> Except the 'any' and 'all' builtins are _exactly_ the same as bitwise >> or and and applided to many bits. To do something "in line" with that >> using the 'xor' operator would return True for an odd number of True >> values and False for an even Number of True values. > > Fair point. > > Have you ever encountered the need for xor for many bits (the one > that I am NOT referring to)? Would be interested in what sort of > case it could be useful. Yes, it's used all the time in low-level communications protocols, where it's often implemented in hardware. But, it is also not at all unusual to implement it in software. It's also not that unusual for the "count-ones" part of the function you're asking for to be implemented in hardware by a CPU having an instruction that counts the number of 1 bits in a register. GCC has a low-level builtins called __builtin_popcount() and __builtin-popcountl() that counts the number of 1's in an unsigned (long) int. From avi.e.gross at gmail.com Mon Nov 13 21:27:16 2023 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Mon, 13 Nov 2023 21:27:16 -0500 Subject: xor operator In-Reply-To: <6552cb0e.020a0220.4a172.0253@mx.google.com> References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> <6552a859.020a0220.8cb14.012f@mx.google.com> <78B43ECD-2EFC-4CDF-99C4-DC310F0B26DE@gmail.com> <6552bcca.050a0220.216c3.01b1@mx.google.com> <6552cb0e.020a0220.4a172.0253@mx.google.com> Message-ID: <00f301da16a2$16313e90$4293bbb0$@gmail.com> I was going to ask a dumb question. Has any other language you know of made something available that does what is being asked for and included it in the main program environment rather than an add-on? A secondary mention here has been whether short-circuiting functions like "any" and "all" have been augmented with something like "has_n" that evaluates arguments till it has found n or perhaps n+1 of what it wants then skips the rest. Does any language supply something like that? What would such a function return and does it have an "any" or an "all" side? It sounds like if I asked if a list of integers has at least n prime numbers in "any" mode, it should ignore any that are not primes till it finds n primes or fails and returns true or false. If in "all" mode, I assume it would have to be the first n items without a failure. Fine, but then someone may want to know WHERE you stopped or for you to return the sublist of the ones that made the match, or even return everything that was skipped so you can later process that. Consider a long list of jurors you process to place a dozen that qualify on a jury and then later you want to choose from among the rest for another jury. Human minds can come up with an amazing number of ideas including for "useful" functions or features but I find the vast majority would rarely be used as nobody remembers it is available and some fairly simple method using other functions can easily be cobbled together. -----Original Message----- From: Python-list On Behalf Of Grant Edwards via Python-list Sent: Monday, November 13, 2023 8:19 PM To: python-list at python.org Subject: Re: xor operator On 2023-11-14, Dom Grigonis via Python-list wrote: > >> Except the 'any' and 'all' builtins are _exactly_ the same as bitwise >> or and and applided to many bits. To do something "in line" with that >> using the 'xor' operator would return True for an odd number of True >> values and False for an even Number of True values. > > Fair point. > > Have you ever encountered the need for xor for many bits (the one > that I am NOT referring to)? Would be interested in what sort of > case it could be useful. Yes, it's used all the time in low-level communications protocols, where it's often implemented in hardware. But, it is also not at all unusual to implement it in software. It's also not that unusual for the "count-ones" part of the function you're asking for to be implemented in hardware by a CPU having an instruction that counts the number of 1 bits in a register. GCC has a low-level builtins called __builtin_popcount() and __builtin-popcountl() that counts the number of 1's in an unsigned (long) int. -- https://mail.python.org/mailman/listinfo/python-list From dom.grigonis at gmail.com Mon Nov 13 22:11:52 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Tue, 14 Nov 2023 05:11:52 +0200 Subject: xor operator (DEPRECATED) In-Reply-To: <00f301da16a2$16313e90$4293bbb0$@gmail.com> References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> <6552a859.020a0220.8cb14.012f@mx.google.com> <78B43ECD-2EFC-4CDF-99C4-DC310F0B26DE@gmail.com> <6552bcca.050a0220.216c3.01b1@mx.google.com> <6552cb0e.020a0220.4a172.0253@mx.google.com> <00f301da16a2$16313e90$4293bbb0$@gmail.com> Message-ID: <5F698B60-6387-44FF-83B2-853601F11177@gmail.com> Fair point. However, I gave it a shot for the following reason: I couldn?t find a way to make such performant function. Using python builtin components still ends up several times slower than builtin `all`. Cython or numba or similar is not an option as they do not support `truth` values. Or if they do, it ends up slower than pure python variant. So all what is left is writing a proper extension. Which I would prefer not to do for 1 function. I thought maybe `xor`, as in logical XOR functionality in its vanilla case could be compelling. And after doing a bit of search I see that very very few languages have that and it seems for a good reason. Some that do: R, thats all I could find. Although some (if not many) went through the proposal phase. And yes, none of them have a function that I am proposing. So yes, you are right, not a good proposal. But there still seems to be the need for short-circuiting performant implementations in python space. The issue is that there are many variants of what might be needed while there is no efficient solution to sourcing predicates from python to lower level implementations. Someone mentioned that numpy experimented with such implementations in C, but they did not get anywhere with it. The best I could come up with is cached numba for numpy problems, which does perform very well and more than worth it if function is re-used. It even ends up faster than cython or cffi extensions, however can?t have many of those due to JIT and AOT is currently being deprecated (which wouldn?t solve anything anyway). However, as I mentioned earlier it does not apply to this case. So it?s either: a) Something very clever and flexible implemented that covers most of such needs and doesn?t require predicates. b) I welcome any thoughts on this. DG > On 14 Nov 2023, at 04:27, AVI GROSS via Python-list wrote: > > I was going to ask a dumb question. Has any other language you know of made > something available that does what is being asked for and included it in the > main program environment rather than an add-on? > > A secondary mention here has been whether short-circuiting functions like > "any" and "all" have been augmented with something like "has_n" that > evaluates arguments till it has found n or perhaps n+1 of what it wants then > skips the rest. Does any language supply something like that? What would > such a function return and does it have an "any" or an "all" side? > > It sounds like if I asked if a list of integers has at least n prime numbers > in "any" mode, it should ignore any that are not primes till it finds n > primes or fails and returns true or false. If in "all" mode, I assume it > would have to be the first n items without a failure. > > Fine, but then someone may want to know WHERE you stopped or for you to > return the sublist of the ones that made the match, or even return > everything that was skipped so you can later process that. Consider a long > list of jurors you process to place a dozen that qualify on a jury and then > later you want to choose from among the rest for another jury. > > Human minds can come up with an amazing number of ideas including for > "useful" functions or features but I find the vast majority would rarely be > used as nobody remembers it is available and some fairly simple method using > other functions can easily be cobbled together. > > -----Original Message----- > From: Python-list On > Behalf Of Grant Edwards via Python-list > Sent: Monday, November 13, 2023 8:19 PM > To: python-list at python.org > Subject: Re: xor operator > > On 2023-11-14, Dom Grigonis via Python-list wrote: >> >>> Except the 'any' and 'all' builtins are _exactly_ the same as bitwise >>> or and and applided to many bits. To do something "in line" with that >>> using the 'xor' operator would return True for an odd number of True >>> values and False for an even Number of True values. >> >> Fair point. >> >> Have you ever encountered the need for xor for many bits (the one >> that I am NOT referring to)? Would be interested in what sort of >> case it could be useful. > > Yes, it's used all the time in low-level communications protocols, > where it's often implemented in hardware. But, it is also not at all > unusual to implement it in software. > > It's also not that unusual for the "count-ones" part of the function > you're asking for to be implemented in hardware by a CPU having an > instruction that counts the number of 1 bits in a register. > > GCC has a low-level builtins called __builtin_popcount() and > __builtin-popcountl() that counts the number of 1's in an unsigned > (long) int. > > > -- > https://mail.python.org/mailman/listinfo/python-list > > -- > https://mail.python.org/mailman/listinfo/python-list From avi.e.gross at gmail.com Mon Nov 13 23:44:19 2023 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Mon, 13 Nov 2023 23:44:19 -0500 Subject: xor operator (DEPRECATED) In-Reply-To: <5F698B60-6387-44FF-83B2-853601F11177@gmail.com> References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> <6552a859.020a0220.8cb14.012f@mx.google.com> <78B43ECD-2EFC-4CDF-99C4-DC310F0B26DE@gmail.com> <6552bcca.050a0220.216c3.01b1@mx.google.com> <6552cb0e.020a0220.4a172.0253@mx.google.com> <00f301da16a2$16313e90$4293bbb0$@gmail.com> <5F698B60-6387-44FF-83B2-853601F11177@gmail.com> Message-ID: <010c01da16b5$3b303e40$b190bac0$@gmail.com> Dom, I hear you. As you say, writing your own extension in something like C++ may not appeal to you even if it is faster. I was wondering if using a generator or something similar in R might make sense. I mean what happens if you write a function that includes a "yield" or two and does a part of what you want. It maintains some internal state between invocations. So you can call it once to setup things then call it repeatedly to keep processing the next item. You stop calling it when you get a result you want, such as that it has seen what you want N times. Since the code stays in memory, it may effectively run faster than some other kinds of functions calls. It can keep things in internal storage such as not just how many N you want but how many it has seen. Your outer function can maintain a list of the items you want to XOR or generate a new one dynamically as needed. It can use functional programming techniques to create a new customized version of the iterator, such as with a value of N built in. You would then call the outer function and let it use the inner function till the result is available or until the data in the iterator runs out or perhaps other tweaks involving two way communication of sorts between the functions. I am NOT suggesting this approach is optimal or fast but merely wondering if something along these lines is worth trying that might speed things up even if not very fast. Such approaches can be even more effective if what you are working on need not all be instantiated up front but can be dynamically calculated or incrementally read from files. With care, you can make multiple instantiations that each iterate over their own sets of data without interference. Just a thought. In a sense, this can be a slightly decent substitute for the non-standard evaluation in R where you can arrange for lots of your data to not be interpreted till absolutely needed. -----Original Message----- From: Dom Grigonis Sent: Monday, November 13, 2023 10:12 PM To: avi.e.gross at gmail.com Cc: Grant Edwards ; Python Subject: Re: xor operator (DEPRECATED) Fair point. However, I gave it a shot for the following reason: I couldn?t find a way to make such performant function. Using python builtin components still ends up several times slower than builtin `all`. Cython or numba or similar is not an option as they do not support `truth` values. Or if they do, it ends up slower than pure python variant. So all what is left is writing a proper extension. Which I would prefer not to do for 1 function. I thought maybe `xor`, as in logical XOR functionality in its vanilla case could be compelling. And after doing a bit of search I see that very very few languages have that and it seems for a good reason. Some that do: R, thats all I could find. Although some (if not many) went through the proposal phase. And yes, none of them have a function that I am proposing. So yes, you are right, not a good proposal. But there still seems to be the need for short-circuiting performant implementations in python space. The issue is that there are many variants of what might be needed while there is no efficient solution to sourcing predicates from python to lower level implementations. Someone mentioned that numpy experimented with such implementations in C, but they did not get anywhere with it. The best I could come up with is cached numba for numpy problems, which does perform very well and more than worth it if function is re-used. It even ends up faster than cython or cffi extensions, however can?t have many of those due to JIT and AOT is currently being deprecated (which wouldn?t solve anything anyway). However, as I mentioned earlier it does not apply to this case. So it?s either: a) Something very clever and flexible implemented that covers most of such needs and doesn?t require predicates. b) I welcome any thoughts on this. DG > On 14 Nov 2023, at 04:27, AVI GROSS via Python-list wrote: > > I was going to ask a dumb question. Has any other language you know of made > something available that does what is being asked for and included it in the > main program environment rather than an add-on? > > A secondary mention here has been whether short-circuiting functions like > "any" and "all" have been augmented with something like "has_n" that > evaluates arguments till it has found n or perhaps n+1 of what it wants then > skips the rest. Does any language supply something like that? What would > such a function return and does it have an "any" or an "all" side? > > It sounds like if I asked if a list of integers has at least n prime numbers > in "any" mode, it should ignore any that are not primes till it finds n > primes or fails and returns true or false. If in "all" mode, I assume it > would have to be the first n items without a failure. > > Fine, but then someone may want to know WHERE you stopped or for you to > return the sublist of the ones that made the match, or even return > everything that was skipped so you can later process that. Consider a long > list of jurors you process to place a dozen that qualify on a jury and then > later you want to choose from among the rest for another jury. > > Human minds can come up with an amazing number of ideas including for > "useful" functions or features but I find the vast majority would rarely be > used as nobody remembers it is available and some fairly simple method using > other functions can easily be cobbled together. > > -----Original Message----- > From: Python-list On > Behalf Of Grant Edwards via Python-list > Sent: Monday, November 13, 2023 8:19 PM > To: python-list at python.org > Subject: Re: xor operator > > On 2023-11-14, Dom Grigonis via Python-list wrote: >> >>> Except the 'any' and 'all' builtins are _exactly_ the same as bitwise >>> or and and applided to many bits. To do something "in line" with that >>> using the 'xor' operator would return True for an odd number of True >>> values and False for an even Number of True values. >> >> Fair point. >> >> Have you ever encountered the need for xor for many bits (the one >> that I am NOT referring to)? Would be interested in what sort of >> case it could be useful. > > Yes, it's used all the time in low-level communications protocols, > where it's often implemented in hardware. But, it is also not at all > unusual to implement it in software. > > It's also not that unusual for the "count-ones" part of the function > you're asking for to be implemented in hardware by a CPU having an > instruction that counts the number of 1 bits in a register. > > GCC has a low-level builtins called __builtin_popcount() and > __builtin-popcountl() that counts the number of 1's in an unsigned > (long) int. > > > -- > https://mail.python.org/mailman/listinfo/python-list > > -- > https://mail.python.org/mailman/listinfo/python-list From list1 at tompassin.net Tue Nov 14 00:23:28 2023 From: list1 at tompassin.net (Thomas Passin) Date: Tue, 14 Nov 2023 00:23:28 -0500 Subject: xor operator (DEPRECATED) In-Reply-To: <010c01da16b5$3b303e40$b190bac0$@gmail.com> References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> <6552a859.020a0220.8cb14.012f@mx.google.com> <78B43ECD-2EFC-4CDF-99C4-DC310F0B26DE@gmail.com> <6552bcca.050a0220.216c3.01b1@mx.google.com> <6552cb0e.020a0220.4a172.0253@mx.google.com> <00f301da16a2$16313e90$4293bbb0$@gmail.com> <5F698B60-6387-44FF-83B2-853601F11177@gmail.com> <010c01da16b5$3b303e40$b190bac0$@gmail.com> Message-ID: On 11/13/2023 11:44 PM, AVI GROSS via Python-list wrote: > Dom, > > I hear you. > > As you say, writing your own extension in something like C++ may not appeal to you even if it is faster. > > I was wondering if using a generator or something similar in R might make sense. > > I mean what happens if you write a function that includes a "yield" or two and does a part of what you want. It maintains some internal state between invocations. So you can call it once to setup things then call it repeatedly to keep processing the next item. You stop calling it when you get a result you want, such as that it has seen what you want N times. > > Since the code stays in memory, it may effectively run faster than some other kinds of functions calls. It can keep things in internal storage such as not just how many N you want but how many it has seen. I'm inclined to just turn the iterable into a set to get the values, then iterate through those values calling count() on a listified version of the iterable. If the count >= target, return. It may not be the fastest one could do but it's simple and probably pretty fast for many uses. I suppose that for some iterables it would be better not to turn them into lists, but one could figure out about that after working out more carefully what cases need to be covered. > Your outer function can maintain a list of the items you want to XOR or generate a new one dynamically as needed. It can use functional programming techniques to create a new customized version of the iterator, such as with a value of N built in. You would then call the outer function and let it use the inner function till the result is available or until the data in the iterator runs out or perhaps other tweaks involving two way communication of sorts between the functions. > > I am NOT suggesting this approach is optimal or fast but merely wondering if something along these lines is worth trying that might speed things up even if not very fast. Such approaches can be even more effective if what you are working on need not all be instantiated up front but can be dynamically calculated or incrementally read from files. With care, you can make multiple instantiations that each iterate over their own sets of data without interference. > > Just a thought. In a sense, this can be a slightly decent substitute for the non-standard evaluation in R where you can arrange for lots of your data to not be interpreted till absolutely needed. > > > > -----Original Message----- > From: Dom Grigonis > Sent: Monday, November 13, 2023 10:12 PM > To: avi.e.gross at gmail.com > Cc: Grant Edwards ; Python > Subject: Re: xor operator (DEPRECATED) > > Fair point. However, I gave it a shot for the following reason: > > I couldn?t find a way to make such performant function. Using python builtin components still ends up several times slower than builtin `all`. Cython or numba or similar is not an option as they do not support `truth` values. Or if they do, it ends up slower than pure python variant. > > So all what is left is writing a proper extension. Which I would prefer not to do for 1 function. I thought maybe `xor`, as in logical XOR functionality in its vanilla case could be compelling. And after doing a bit of search I see that very very few languages have that and it seems for a good reason. > > Some that do: R, thats all I could find. Although some (if not many) went through the proposal phase. And yes, none of them have a function that I am proposing. > > So yes, you are right, not a good proposal. > > But there still seems to be the need for short-circuiting performant implementations in python space. The issue is that there are many variants of what might be needed while there is no efficient solution to sourcing predicates from python to lower level implementations. Someone mentioned that numpy experimented with such implementations in C, but they did not get anywhere with it. > > The best I could come up with is cached numba for numpy problems, which does perform very well and more than worth it if function is re-used. It even ends up faster than cython or cffi extensions, however can?t have many of those due to JIT and AOT is currently being deprecated (which wouldn?t solve anything anyway). However, as I mentioned earlier it does not apply to this case. > > So it?s either: > a) Something very clever and flexible implemented that covers most of such needs and doesn?t require predicates. > b) I welcome any thoughts on this. > > DG > >> On 14 Nov 2023, at 04:27, AVI GROSS via Python-list wrote: >> >> I was going to ask a dumb question. Has any other language you know of made >> something available that does what is being asked for and included it in the >> main program environment rather than an add-on? >> >> A secondary mention here has been whether short-circuiting functions like >> "any" and "all" have been augmented with something like "has_n" that >> evaluates arguments till it has found n or perhaps n+1 of what it wants then >> skips the rest. Does any language supply something like that? What would >> such a function return and does it have an "any" or an "all" side? >> >> It sounds like if I asked if a list of integers has at least n prime numbers >> in "any" mode, it should ignore any that are not primes till it finds n >> primes or fails and returns true or false. If in "all" mode, I assume it >> would have to be the first n items without a failure. >> >> Fine, but then someone may want to know WHERE you stopped or for you to >> return the sublist of the ones that made the match, or even return >> everything that was skipped so you can later process that. Consider a long >> list of jurors you process to place a dozen that qualify on a jury and then >> later you want to choose from among the rest for another jury. >> >> Human minds can come up with an amazing number of ideas including for >> "useful" functions or features but I find the vast majority would rarely be >> used as nobody remembers it is available and some fairly simple method using >> other functions can easily be cobbled together. >> >> -----Original Message----- >> From: Python-list On >> Behalf Of Grant Edwards via Python-list >> Sent: Monday, November 13, 2023 8:19 PM >> To: python-list at python.org >> Subject: Re: xor operator >> >> On 2023-11-14, Dom Grigonis via Python-list wrote: >>> >>>> Except the 'any' and 'all' builtins are _exactly_ the same as bitwise >>>> or and and applided to many bits. To do something "in line" with that >>>> using the 'xor' operator would return True for an odd number of True >>>> values and False for an even Number of True values. >>> >>> Fair point. >>> >>> Have you ever encountered the need for xor for many bits (the one >>> that I am NOT referring to)? Would be interested in what sort of >>> case it could be useful. >> >> Yes, it's used all the time in low-level communications protocols, >> where it's often implemented in hardware. But, it is also not at all >> unusual to implement it in software. >> >> It's also not that unusual for the "count-ones" part of the function >> you're asking for to be implemented in hardware by a CPU having an >> instruction that counts the number of 1 bits in a register. >> >> GCC has a low-level builtins called __builtin_popcount() and >> __builtin-popcountl() that counts the number of 1's in an unsigned >> (long) int. >> >> >> -- >> https://mail.python.org/mailman/listinfo/python-list >> >> -- >> https://mail.python.org/mailman/listinfo/python-list > > From dom.grigonis at gmail.com Tue Nov 14 01:19:19 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Tue, 14 Nov 2023 08:19:19 +0200 Subject: xor operator (DEPRECATED) In-Reply-To: References: <2624DD04-097A-48B1-9F05-C6EF30F4C82D@gmail.com> <6552a859.020a0220.8cb14.012f@mx.google.com> <78B43ECD-2EFC-4CDF-99C4-DC310F0B26DE@gmail.com> <6552bcca.050a0220.216c3.01b1@mx.google.com> <6552cb0e.020a0220.4a172.0253@mx.google.com> <00f301da16a2$16313e90$4293bbb0$@gmail.com> <5F698B60-6387-44FF-83B2-853601F11177@gmail.com> <010c01da16b5$3b303e40$b190bac0$@gmail.com> Message-ID: <86188759-8055-41C8-8C26-EE77F2CB79A0@gmail.com> Thank you, I have spent a fair bit of time on these and found optimal solutions (at least I think so), but they are still multiple times slower than python builtin function. I am currently out of ideas, maybe will dig something out in time. > On 14 Nov 2023, at 07:23, Thomas Passin via Python-list wrote: > > On 11/13/2023 11:44 PM, AVI GROSS via Python-list wrote: >> Dom, >> I hear you. >> As you say, writing your own extension in something like C++ may not appeal to you even if it is faster. >> I was wondering if using a generator or something similar in R might make sense. >> I mean what happens if you write a function that includes a "yield" or two and does a part of what you want. It maintains some internal state between invocations. So you can call it once to setup things then call it repeatedly to keep processing the next item. You stop calling it when you get a result you want, such as that it has seen what you want N times. >> Since the code stays in memory, it may effectively run faster than some other kinds of functions calls. It can keep things in internal storage such as not just how many N you want but how many it has seen. > > I'm inclined to just turn the iterable into a set to get the values, then iterate through those values calling count() on a listified version of the iterable. If the count >= target, return. > > It may not be the fastest one could do but it's simple and probably pretty fast for many uses. I suppose that for some iterables it would be better not to turn them into lists, but one could figure out about that after working out more carefully what cases need to be covered. > >> Your outer function can maintain a list of the items you want to XOR or generate a new one dynamically as needed. It can use functional programming techniques to create a new customized version of the iterator, such as with a value of N built in. You would then call the outer function and let it use the inner function till the result is available or until the data in the iterator runs out or perhaps other tweaks involving two way communication of sorts between the functions. >> I am NOT suggesting this approach is optimal or fast but merely wondering if something along these lines is worth trying that might speed things up even if not very fast. Such approaches can be even more effective if what you are working on need not all be instantiated up front but can be dynamically calculated or incrementally read from files. With care, you can make multiple instantiations that each iterate over their own sets of data without interference. >> Just a thought. In a sense, this can be a slightly decent substitute for the non-standard evaluation in R where you can arrange for lots of your data to not be interpreted till absolutely needed. >> -----Original Message----- >> From: Dom Grigonis >> Sent: Monday, November 13, 2023 10:12 PM >> To: avi.e.gross at gmail.com >> Cc: Grant Edwards ; Python >> Subject: Re: xor operator (DEPRECATED) >> Fair point. However, I gave it a shot for the following reason: >> I couldn?t find a way to make such performant function. Using python builtin components still ends up several times slower than builtin `all`. Cython or numba or similar is not an option as they do not support `truth` values. Or if they do, it ends up slower than pure python variant. >> So all what is left is writing a proper extension. Which I would prefer not to do for 1 function. I thought maybe `xor`, as in logical XOR functionality in its vanilla case could be compelling. And after doing a bit of search I see that very very few languages have that and it seems for a good reason. >> Some that do: R, thats all I could find. Although some (if not many) went through the proposal phase. And yes, none of them have a function that I am proposing. >> So yes, you are right, not a good proposal. >> But there still seems to be the need for short-circuiting performant implementations in python space. The issue is that there are many variants of what might be needed while there is no efficient solution to sourcing predicates from python to lower level implementations. Someone mentioned that numpy experimented with such implementations in C, but they did not get anywhere with it. >> The best I could come up with is cached numba for numpy problems, which does perform very well and more than worth it if function is re-used. It even ends up faster than cython or cffi extensions, however can?t have many of those due to JIT and AOT is currently being deprecated (which wouldn?t solve anything anyway). However, as I mentioned earlier it does not apply to this case. >> So it?s either: >> a) Something very clever and flexible implemented that covers most of such needs and doesn?t require predicates. >> b) I welcome any thoughts on this. >> DG >>> On 14 Nov 2023, at 04:27, AVI GROSS via Python-list wrote: >>> >>> I was going to ask a dumb question. Has any other language you know of made >>> something available that does what is being asked for and included it in the >>> main program environment rather than an add-on? >>> >>> A secondary mention here has been whether short-circuiting functions like >>> "any" and "all" have been augmented with something like "has_n" that >>> evaluates arguments till it has found n or perhaps n+1 of what it wants then >>> skips the rest. Does any language supply something like that? What would >>> such a function return and does it have an "any" or an "all" side? >>> >>> It sounds like if I asked if a list of integers has at least n prime numbers >>> in "any" mode, it should ignore any that are not primes till it finds n >>> primes or fails and returns true or false. If in "all" mode, I assume it >>> would have to be the first n items without a failure. >>> >>> Fine, but then someone may want to know WHERE you stopped or for you to >>> return the sublist of the ones that made the match, or even return >>> everything that was skipped so you can later process that. Consider a long >>> list of jurors you process to place a dozen that qualify on a jury and then >>> later you want to choose from among the rest for another jury. >>> >>> Human minds can come up with an amazing number of ideas including for >>> "useful" functions or features but I find the vast majority would rarely be >>> used as nobody remembers it is available and some fairly simple method using >>> other functions can easily be cobbled together. >>> >>> -----Original Message----- >>> From: Python-list On >>> Behalf Of Grant Edwards via Python-list >>> Sent: Monday, November 13, 2023 8:19 PM >>> To: python-list at python.org >>> Subject: Re: xor operator >>> >>> On 2023-11-14, Dom Grigonis via Python-list wrote: >>>> >>>>> Except the 'any' and 'all' builtins are _exactly_ the same as bitwise >>>>> or and and applided to many bits. To do something "in line" with that >>>>> using the 'xor' operator would return True for an odd number of True >>>>> values and False for an even Number of True values. >>>> >>>> Fair point. >>>> >>>> Have you ever encountered the need for xor for many bits (the one >>>> that I am NOT referring to)? Would be interested in what sort of >>>> case it could be useful. >>> >>> Yes, it's used all the time in low-level communications protocols, >>> where it's often implemented in hardware. But, it is also not at all >>> unusual to implement it in software. >>> >>> It's also not that unusual for the "count-ones" part of the function >>> you're asking for to be implemented in hardware by a CPU having an >>> instruction that counts the number of 1 bits in a register. >>> >>> GCC has a low-level builtins called __builtin_popcount() and >>> __builtin-popcountl() that counts the number of 1's in an unsigned >>> (long) int. >>> >>> >>> -- >>> https://mail.python.org/mailman/listinfo/python-list >>> >>> -- >>> https://mail.python.org/mailman/listinfo/python-list > > -- > https://mail.python.org/mailman/listinfo/python-list From jacob.kruger.work at gmail.com Tue Nov 14 03:34:40 2023 From: jacob.kruger.work at gmail.com (Jacob Kruger) Date: Tue, 14 Nov 2023 10:34:40 +0200 Subject: No current way to just compile flet code into truly native packages for smart phones, etc.? In-Reply-To: References: <3a534da3-dfc9-33db-2ffa-ae15092ddb8e@gmail.com> Message-ID: <9d0cb6e4-ee66-8afb-565c-ca5492d3f9ec@gmail.com> Yup. Also checked out beeware - which also offers cross-platform compilation of same code - but, one minor issue there first time tried it out was working with additional/external modules, and, packaging resources. Plus, while it includes it's own form of LBC GUI interface - toga - the one included here in flet seemed 'nicer': https://beeware.org/project/projects/libraries/toga/ But, haven't taken time to really take it much further than just a bit of playing around so far. Jacob Kruger +2782 413 4791 "Resistance is futile!...Acceptance is versatile..." On 2023/11/13 19:47, Barry wrote: > >> On 13 Nov 2023, at 17:21, Jacob Kruger via Python-list wrote: >> >> ?Had a look at the following bit of introduction to using python and flet to build cross-platform flutter-based apps using same python code, and, while it seems to work alright if tell it to run as under GUI here on windows desktop, and, while can get it to fire up PWA version as well, that's not really stand-alone since will still require code to be running in background, and, in terms of, for example, android, it seems like it will need to then be running via the native android flet interpreter for it to work as such? >> >> >> https://flet.dev/docs/ >> >> >> Flet PWA deployment > flet looks interesting. It seems from the road map there is lots missing today. > Also the people that know flet are on discord. You may find someone here. > > Barry > >> -- >> >> Jacob Kruger >> +2782 413 4791 >> "Resistance is futile!...Acceptance is versatile..." >> >> -- >> https://mail.python.org/mailman/listinfo/python-list >> From miked at dewhirst.com.au Tue Nov 14 18:14:10 2023 From: miked at dewhirst.com.au (Mike Dewhirst) Date: Wed, 15 Nov 2023 10:14:10 +1100 Subject: Code improvement question Message-ID: I'd like to improve the code below, which works. It feels clunky to me. I need to clean up user-uploaded files the size of which I don't know in advance. After cleaning they might be as big as 1Mb but that would be super rare. Perhaps only for testing. I'm extracting CAS numbers and here is the pattern xx-xx-x up to xxxxxxx-xx-x eg., 1012300-77-4 def remove_alpha(txt): ??? """? r'[^0-9\- ]': ??? [^...]: Match any character that is not in the specified set. ??? 0-9: Match any digit. ??? \: Escape character. ??? -: Match a hyphen. ??? Space: Match a space. ??? """ ????cleaned_txt = re.sub(r'[^0-9\- ]', '', txt) ??? bits = cleaned_txt.split() ??? pieces = [] ??? for bit in bits: ??????? # minimum size of a CAS number is 7 so drop smaller clumps of digits ??????? pieces.append(bit if len(bit) > 6 else "") ??? return " ".join(pieces) Many thanks for any hints Cheers Mike From python at mrabarnett.plus.com Tue Nov 14 18:25:10 2023 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 14 Nov 2023 23:25:10 +0000 Subject: Code improvement question In-Reply-To: References: Message-ID: <088586a6-79c2-4114-8d62-5e1a1061b841@mrabarnett.plus.com> On 2023-11-14 23:14, Mike Dewhirst via Python-list wrote: > I'd like to improve the code below, which works. It feels clunky to me. > > I need to clean up user-uploaded files the size of which I don't know in > advance. > > After cleaning they might be as big as 1Mb but that would be super rare. > Perhaps only for testing. > > I'm extracting CAS numbers and here is the pattern xx-xx-x up to > xxxxxxx-xx-x eg., 1012300-77-4 > > def remove_alpha(txt): > > ??? """? r'[^0-9\- ]': > > ??? [^...]: Match any character that is not in the specified set. > > ??? 0-9: Match any digit. > > ??? \: Escape character. > > ??? -: Match a hyphen. > > ??? Space: Match a space. > > ??? """ > > ????cleaned_txt = re.sub(r'[^0-9\- ]', '', txt) > > ??? bits = cleaned_txt.split() > > ??? pieces = [] > > ??? for bit in bits: > > ??????? # minimum size of a CAS number is 7 so drop smaller clumps of digits > > ??????? pieces.append(bit if len(bit) > 6 else "") > > ??? return " ".join(pieces) > > > Many thanks for any hints > Why don't you use re.findall? re.findall(r'\b[0-9]{2,7}-[0-9]{2}-[0-9]{2}\b', txt) From hjp-python at hjp.at Tue Nov 14 19:34:15 2023 From: hjp-python at hjp.at (Peter J. Holzer) Date: Wed, 15 Nov 2023 01:34:15 +0100 Subject: xor operator In-Reply-To: <166AE5F3-3FF0-458D-9DA8-D6A7367122C4@gmail.com> References: <44FBD8A8-E092-40FF-BD56-467E6936AAE9@gmail.com> <166AE5F3-3FF0-458D-9DA8-D6A7367122C4@gmail.com> Message-ID: <20231115003415.mtertwoelhjme4aq@hjp.at> On 2023-11-14 00:11:30 +0200, Dom Grigonis via Python-list wrote: > Benchmarks: > test1 = [False] * 100 + [True] * 2 > test2 = [True] * 100 + [False] * 2 > > TIMER.repeat([ > lambda: xor(test1), # 0.0168 > lambda: xor(test2), # 0.0172 > lambda: xor_ss(test1), # 0.1392 > lambda: xor_ss(test2), # 0.0084 > lambda: xor_new(test1), # 0.0116 > lambda: xor_new(test2), # 0.0074 > lambda: all(test1), # 0.0016 > lambda: all(test2) # 0.0046 > ]) > Your first function is fairly slow. > Second one deals with short-circuiting, but is super slow on full search. > > `xor_new` is the best what I could achieve using python builtins. > > But builtin `all` has the best performance. One question worth asking is if a list of bool is the best data structure for the job. This is essentially a bitmap, and a bitmap is equivalent to a set of integers. len(s) == 1 is also a fairly quick operation if s is small. On my system, len(test1s) == 1 (where test1s is {100, 101}) is about as fast as all(test1) and len(test2s) == 1 (where test2s is set(range(100))) is about twice as fast as all(test2). If you are willing to stray from the standard library, you could e.g. use pyroaring instead of sets: This is about as fast as all(test1) whether there are two bits set or a hundred. 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 miked at dewhirst.com.au Tue Nov 14 22:41:20 2023 From: miked at dewhirst.com.au (Mike Dewhirst) Date: Wed, 15 Nov 2023 14:41:20 +1100 Subject: Code improvement question In-Reply-To: <088586a6-79c2-4114-8d62-5e1a1061b841@mrabarnett.plus.com> References: <088586a6-79c2-4114-8d62-5e1a1061b841@mrabarnett.plus.com> Message-ID: <32bbd365-a2fb-471f-b19e-3a3ec4457124@dewhirst.com.au> On 15/11/2023 10:25 am, MRAB via Python-list wrote: > On 2023-11-14 23:14, Mike Dewhirst via Python-list wrote: >> I'd like to improve the code below, which works. It feels clunky to me. >> >> I need to clean up user-uploaded files the size of which I don't know in >> advance. >> >> After cleaning they might be as big as 1Mb but that would be super rare. >> Perhaps only for testing. >> >> I'm extracting CAS numbers and here is the pattern xx-xx-x up to >> xxxxxxx-xx-x eg., 1012300-77-4 >> >> def remove_alpha(txt): >> >> ? ??? """? r'[^0-9\- ]': >> >> ? ??? [^...]: Match any character that is not in the specified set. >> >> ? ??? 0-9: Match any digit. >> >> ? ??? \: Escape character. >> >> ? ??? -: Match a hyphen. >> >> ? ??? Space: Match a space. >> >> ? ??? """ >> >> ? ????cleaned_txt = re.sub(r'[^0-9\- ]', '', txt) >> >> ? ??? bits = cleaned_txt.split() >> >> ? ??? pieces = [] >> >> ? ??? for bit in bits: >> >> ? ??????? # minimum size of a CAS number is 7 so drop smaller clumps >> of digits >> >> ? ??????? pieces.append(bit if len(bit) > 6 else "") >> >> ? ??? return " ".join(pieces) >> >> >> Many thanks for any hints >> > Why don't you use re.findall? > > re.findall(r'\b[0-9]{2,7}-[0-9]{2}-[0-9]{2}\b', txt) I think I can see what you did there but it won't make sense to me - or whoever looks at the code - in future. That answers your specific question. However, I am in awe of people who can just "do" regular expressions and I thank you very much for what would have been a monumental effort had I tried it. That little re.sub() came from ChatGPT and I can understand it without too much effort because it came documented I suppose ChatGPT is the answer to this thread. Or everything. Or will be. Thanks Mike From python at mrabarnett.plus.com Tue Nov 14 23:08:29 2023 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 15 Nov 2023 04:08:29 +0000 Subject: Code improvement question In-Reply-To: <32bbd365-a2fb-471f-b19e-3a3ec4457124@dewhirst.com.au> References: <088586a6-79c2-4114-8d62-5e1a1061b841@mrabarnett.plus.com> <32bbd365-a2fb-471f-b19e-3a3ec4457124@dewhirst.com.au> Message-ID: On 2023-11-15 03:41, Mike Dewhirst via Python-list wrote: > On 15/11/2023 10:25 am, MRAB via Python-list wrote: >> On 2023-11-14 23:14, Mike Dewhirst via Python-list wrote: >>> I'd like to improve the code below, which works. It feels clunky to me. >>> >>> I need to clean up user-uploaded files the size of which I don't know in >>> advance. >>> >>> After cleaning they might be as big as 1Mb but that would be super rare. >>> Perhaps only for testing. >>> >>> I'm extracting CAS numbers and here is the pattern xx-xx-x up to >>> xxxxxxx-xx-x eg., 1012300-77-4 >>> >>> def remove_alpha(txt): >>> >>> ? ??? """? r'[^0-9\- ]': >>> >>> ? ??? [^...]: Match any character that is not in the specified set. >>> >>> ? ??? 0-9: Match any digit. >>> >>> ? ??? \: Escape character. >>> >>> ? ??? -: Match a hyphen. >>> >>> ? ??? Space: Match a space. >>> >>> ? ??? """ >>> >>> ? ????cleaned_txt = re.sub(r'[^0-9\- ]', '', txt) >>> >>> ? ??? bits = cleaned_txt.split() >>> >>> ? ??? pieces = [] >>> >>> ? ??? for bit in bits: >>> >>> ? ??????? # minimum size of a CAS number is 7 so drop smaller clumps >>> of digits >>> >>> ? ??????? pieces.append(bit if len(bit) > 6 else "") >>> >>> ? ??? return " ".join(pieces) >>> >>> >>> Many thanks for any hints >>> >> Why don't you use re.findall? >> >> re.findall(r'\b[0-9]{2,7}-[0-9]{2}-[0-9]{2}\b', txt) > > I think I can see what you did there but it won't make sense to me - or > whoever looks at the code - in future. > > That answers your specific question. However, I am in awe of people who > can just "do" regular expressions and I thank you very much for what > would have been a monumental effort had I tried it. > > That little re.sub() came from ChatGPT and I can understand it without > too much effort because it came documented > > I suppose ChatGPT is the answer to this thread. Or everything. Or will be. > \b Word boundary [0-9]{2,7} 2..7 digits - "-" [0-9]{2} 2 digits - "-" [0-9]{2} 2 digits \b Word boundary The "word boundary" thing is to stop it matching where there are letters or digits right next to the digits. For example, if the text contained, say, "123456789-12-1234", you wouldn't want it to match because there are more than 7 digits at the start and more than 2 digits at the end. From RealGrizzlyAdams at vivaldi.net Wed Nov 15 02:25:36 2023 From: RealGrizzlyAdams at vivaldi.net (Grizzy Adams) Date: Wed, 15 Nov 2023 07:25:36 -0000 Subject: Newline (NuBe Question) Message-ID: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> Hi & thanks for patience with what could be simple to you Have this (from an online "classes" tutorial) --- Start Code Snippit --- students = [] grades = [] for s in geographyClass: students.append(geographyStudent(s)) for s in students: grades.append(s.school) grades.append(s.name) grades.append(s.finalGrade()) if s.finalGrade()>82: grades.append("Pass") else: grades.append("Fail") print(grades) --- End Code Snippit --- I have extended (from tutorial) it a bit, I would really like to have a newline at end of each record, I have searched (and tested) but cant get "\n" to give a newline, I get "Mydata\n" Do I need to replace "append" with "print", or is there a way to get the newline in as I append to list? Thanks again From PythonList at DancesWithMice.info Wed Nov 15 04:19:41 2023 From: PythonList at DancesWithMice.info (dn) Date: Wed, 15 Nov 2023 22:19:41 +1300 Subject: Newline (NuBe Question) In-Reply-To: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> Message-ID: <8cde1523-57f8-4905-9d6e-bd4a0660d56c@DancesWithMice.info> On 15/11/2023 20.25, Grizzy Adams via Python-list wrote: > Hi & thanks for patience with what could be simple to you > > Have this (from an online "classes" tutorial) There are lots of on-line classes! > --- Start Code Snippit --- > > students = [] > grades = [] > for s in geographyClass: > students.append(geographyStudent(s)) > for s in students: > grades.append(s.school) > grades.append(s.name) > grades.append(s.finalGrade()) > if s.finalGrade()>82: > grades.append("Pass") > else: > grades.append("Fail") > print(grades) > > --- End Code Snippit --- > > I have extended (from tutorial) it a bit, I would really like to have a newline > > at end of each record, I have searched (and tested) but cant get "\n" to give a > > newline, I get "Mydata\n" > > Do I need to replace "append" with "print", or is there a way to get the > newline in as I append to list? Don't know how "Mydata..." results - where is it in the code. What do you see when grades is printed? Do you really want data-values all mashed together? Yes, what changed after removal of all the .append()-s, and instead, within the (second) for-loop print( school, name, ... ) was used? Is it easier to go on from there? -- Regards, =dn From learn2program at gmail.com Wed Nov 15 04:50:51 2023 From: learn2program at gmail.com (Alan Gauld) Date: Wed, 15 Nov 2023 09:50:51 +0000 Subject: Newline (NuBe Question) In-Reply-To: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> Message-ID: <947ea994-92fe-3548-5fdb-0e58b74ea40d@yahoo.co.uk> On 15/11/2023 07:25, Grizzy Adams via Python-list wrote: > for s in students: > grades.append(s.school) > grades.append(s.name) > grades.append(s.finalGrade()) > if s.finalGrade()>82: > grades.append("Pass") > else: > grades.append("Fail") > print(grades) > > --- End Code Snippit --- > Do I need to replace "append" with "print", or is there a way to get the > newline in as I append to list? Firstly, it is usually a bad idea to mix formatting features(like newline) with the data. You will need to remove them again if you want to work with the data itself. So, better to print the raw data and add the formatting during printing. There are a couple of options here (well more than a couple actually!) The simplest is to create another for loop and print each field with a newline automatically added by print() Another is to simply join everything in grades together separated by newlines. Python has a method to do that called join(): print('\n'.join(grades)) Unfortunately it seems your data has a mix of strings and numbers so that won't work without some tweaks: print('\n'.join(str(f) for f in grades)) However, I wonder if this really what you want? You have created grades as a long list containing all of the attributes of all of the students plus their Pass/Fail status. But you have no (easy)way to access the Pass/Fail value for each student. Do you really want to store the Pass/Fail in the student? And then print the students? Like so: for s in students if s.finalGrade() > 82: s.result = "Pass" else: s.result = "Fail" print(s.school) print(s.name) ... print(s.result) Just a thought... PS. There are neater ways to do this but you may not have covered those yet so I'll stick to basics. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From cs at cskk.id.au Wed Nov 15 03:50:04 2023 From: cs at cskk.id.au (Cameron Simpson) Date: Wed, 15 Nov 2023 19:50:04 +1100 Subject: Newline (NuBe Question) In-Reply-To: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> Message-ID: On 15Nov2023 07:25, Grizzy Adams wrote: >Have this (from an online "classes" tutorial) Response inline below. >students = [] >grades = [] >for s in geographyClass: > students.append(geographyStudent(s)) >for s in students: > grades.append(s.school) > grades.append(s.name) > grades.append(s.finalGrade()) > if s.finalGrade()>82: > grades.append("Pass") > else: > grades.append("Fail") >print(grades) > >--- End Code Snippit --- > >I have extended (from tutorial) it a bit, I would really like to have a newline >at end of each record, I have searched (and tested) but cant get "\n" >to give a newline, I get "Mydata\n" It would be useful to: - see some of the things you've tried - what their output actually was - what output you actually want to achieve >Do I need to replace "append" with "print", or is there a way to get the >newline in as I append to list? I think you're confusing output (print) with your data (the list of grades). Is the code above genuinely what you're running? I ask because it looks to me that you're: - appending all the individual grade fields (school, name, ...) to one long grades list containing all the data from all the students - you're printing that single enormous list in one go at the end What I'm imagine you want is one line of grade information per student. Remember that indentation is important in Python. You're grades code looks like this: grades = [] for s in students: grades.append(s.school) grades.append(s.name) grades.append(s.finalGrade()) if s.finalGrade()>82: grades.append("Pass") else: grades.append("Fail") print(grades) This: - makes an empty list - gathers up all of the student data - prints the data in one go I think you may want to do the first and last steps on a per student basis, not just once at the start and the end. So you might want to rearrange things: for s in students: grades = [] grades.append(s.school) grades.append(s.name) grades.append(s.finalGrade()) if s.finalGrade()>82: grades.append("Pass") else: grades.append("Fail") print(grades) Cheers, Cameron Simpson From dom.grigonis at gmail.com Wed Nov 15 05:26:32 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Wed, 15 Nov 2023 12:26:32 +0200 Subject: xor operator In-Reply-To: <20231115003415.mtertwoelhjme4aq@hjp.at> References: <44FBD8A8-E092-40FF-BD56-467E6936AAE9@gmail.com> <166AE5F3-3FF0-458D-9DA8-D6A7367122C4@gmail.com> <20231115003415.mtertwoelhjme4aq@hjp.at> Message-ID: <0E0F3061-A807-4471-9F85-1571259D0705@gmail.com> Thank you, test2 = [True] * 100 + [False] * 2 test2i = list(range(100)) %timeit len(set(test2i)) == 1 # 1.6 ?s ? 63.6 ns per loop (mean ? std. dev. of 7 runs, 1,000,000 loops each) %timeit all(test2) # 386 ns ? 9.58 ns per loop (mean ? std. dev. of 7 runs, 1,000,000 loops each) test2s = set(test2i) %timeit len(test2s) == 1 # 46.1 ns ? 1.65 ns per loop (mean ? std. dev. of 7 runs, 10,000,000 loops each) If you pre-convert to set it is obviously faster. However, set operation is most likely going to be part of the procedure. In which case it ends up to be significantly slower. Regards, DG > On 15 Nov 2023, at 02:34, Peter J. Holzer via Python-list wrote: > > On 2023-11-14 00:11:30 +0200, Dom Grigonis via Python-list wrote: >> Benchmarks: >> test1 = [False] * 100 + [True] * 2 >> test2 = [True] * 100 + [False] * 2 >> >> TIMER.repeat([ >> lambda: xor(test1), # 0.0168 >> lambda: xor(test2), # 0.0172 >> lambda: xor_ss(test1), # 0.1392 >> lambda: xor_ss(test2), # 0.0084 >> lambda: xor_new(test1), # 0.0116 >> lambda: xor_new(test2), # 0.0074 >> lambda: all(test1), # 0.0016 >> lambda: all(test2) # 0.0046 >> ]) >> Your first function is fairly slow. >> Second one deals with short-circuiting, but is super slow on full search. >> >> `xor_new` is the best what I could achieve using python builtins. >> >> But builtin `all` has the best performance. > > One question worth asking is if a list of bool is the best data > structure for the job. This is essentially a bitmap, and a bitmap is > equivalent to a set of integers. len(s) == 1 is also a fairly quick > operation if s is small. On my system, len(test1s) == 1 (where test1s is > {100, 101}) is about as fast as all(test1) and len(test2s) == 1 (where > test2s is set(range(100))) is about twice as fast as all(test2). > > If you are willing to stray from the standard library, you could e.g. > use pyroaring instead of sets: This is about as fast as all(test1) > whether there are two bits set or a hundred. > > 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 RealGrizzlyAdams at vivaldi.net Wed Nov 15 07:32:06 2023 From: RealGrizzlyAdams at vivaldi.net (Grizzy Adams) Date: Wed, 15 Nov 2023 12:32:06 -0000 Subject: Newline (NuBe Question) In-Reply-To: <947ea994-92fe-3548-5fdb-0e58b74ea40d@yahoo.co.uk> References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net>, <947ea994-92fe-3548-5fdb-0e58b74ea40d@yahoo.co.uk> Message-ID: <6554BA46.15177.6C857E@RealGrizzlyAdams.vivaldi.net> Wednesday, November 15, 2023 at 9:50, Alan Gauld via Python-list wrote: Re: Newline (NuBe Question) (at least in part) >On 15/11/2023 07:25, Grizzy Adams via Python-list wrote: >> for s in students: >> grades.append(s.school) >> grades.append(s.name) >> grades.append(s.finalGrade()) >> if s.finalGrade()>82: >> grades.append("Pass") >> else: >> grades.append("Fail") >> print(grades) >> >> --- End Code Snippit --- >> Do I need to replace "append" with "print", or is there a way to get the >> newline in as I append to list? >Firstly, it is usually a bad idea to mix formatting features(like >newline) with the data. You will need to remove them again if you want >to work with the data itself. True, I onlt went that way when my (vain) attempts to add a newline any other way, my usual language is VB/VBA, Delphi or C++ at a push, so I'm really a nube here >So, better to print the raw data and add the formatting during printing. >There are a couple of options here (well more than a couple actually!) >The simplest is to create another for loop and print each field with a >newline automatically added by print() >Another is to simply join everything in grades together separated by >newlines. Python has a method to do that called join(): >print('\n'.join(grades)) >Unfortunately it seems your data has a mix of strings and numbers so >that won't work without some tweaks: >print('\n'.join(str(f) for f in grades)) that gets closer (sort of) my old code gave on long (only 5 records so far) list, ['Example High', 'Mary', 89.6, 'Pass', 'Example High', 'Matthew', 76.5, 'Fail', 'Example High', 'Marie', 80.4, 'Fail', 'Example High', 'Manuel', 79.6, 'Fail', 'Example High', 'Malala', 98.9, 'Pass'] your code gives one tall column, Example High Mary 89.6 Pass Example High Matthew 76.5 Fail Example High Marie 80.4 Fail Example High Manuel 79.6 Fail Example High Malala 98.9 Pass my ideal one row for each student (this I have edited manually) Example High, Mary, 89.6, Pass Example High, Matthew, 76.5, Fail Example High, Marie, 80.4, Fail Example High, Manuel, 79.6, Fail Example High, Malala, 98.9, Pass >However, I wonder if this really what you want? You have created grades as a >long list containing all of the attributes of all of the students plus their >Pass/Fail status. But you have no (easy)way to access the Pass/Fail value for >each student. Do you really want to store the Pass/Fail in the student? And >then print the students? Like so: I do want to keep the data in tact, incase it gets reused later in the tutorial(s) >Just a thought... >PS. There are neater ways to do this but you may not have covered >those yet so I'll stick to basics. I already jumped forward a bit (to python Classes) Thanks From list1 at tompassin.net Wed Nov 15 09:45:03 2023 From: list1 at tompassin.net (Thomas Passin) Date: Wed, 15 Nov 2023 09:45:03 -0500 Subject: Newline (NuBe Question) In-Reply-To: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> Message-ID: On 11/15/2023 2:25 AM, Grizzy Adams via Python-list wrote: > Hi & thanks for patience with what could be simple to you > > Have this (from an online "classes" tutorial) > > --- Start Code Snippit --- > > students = [] > grades = [] > for s in geographyClass: > students.append(geographyStudent(s)) > for s in students: > grades.append(s.school) > grades.append(s.name) > grades.append(s.finalGrade()) > if s.finalGrade()>82: > grades.append("Pass") > else: > grades.append("Fail") > print(grades) > > --- End Code Snippit --- > > I have extended (from tutorial) it a bit, I would really like to have a newline > > at end of each record, I have searched (and tested) but cant get "\n" to give a > > newline, I get "Mydata\n" > > Do I need to replace "append" with "print", or is there a way to get the > newline in as I append to list? First of all, if this is an accurate representation of the course material, you need a better course. There's no sense in appending all those values one after another in a single list since later it will be very inconvenient to detect the end of one student's info and the start of the next one's. And if you don't need to know that, but just want to print out the data, you don't need to a list at all, just print it out in the loop. A list that contains lists of each student's data, one per interior list, would make more sense. Second, it is usual to append data to a list without print formatting, and then add your formatting when you go to print the list. That way you can use the list for other things beyond just printing, and the code is clearer and simpler as well. You may see responses that suggest various code alternatives. But you haven't shown us an example of what you want the output to look like, and you haven't said what else you plan to use the list for. So anyone who responds has to fly blind, without knowing key information. Asking for help is like writing code, with an added social element. You have to be clear about the requirements, inputs, and desired outputs, and you have to organize your request in a way that's easy for others to understand and be willing to help. Your original post is partway there already. From RealGrizzlyAdams at vivaldi.net Wed Nov 15 11:51:09 2023 From: RealGrizzlyAdams at vivaldi.net (Grizzy Adams) Date: Wed, 15 Nov 2023 16:51:09 -0000 Subject: Newline (NuBe Question) In-Reply-To: References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net>, Message-ID: <6554F6FD.23324.1B219E@RealGrizzlyAdams.vivaldi.net> Wednesday, November 15, 2023 at 9:45, Thomas Passin via Python-list wrote: Re: Newline (NuBe Question) (at least in part) >On 11/15/2023 2:25 AM, Grizzy Adams via Python-list wrote: >> Hi & thanks for patience with what could be simple to you >You may see responses that suggest various code alternatives. But you >haven't shown us an example of what you want the output to look like, Offered code got closer (sort of) my old code gave on long (only 5 records so far) list, ['Example High', 'Mary', 89.6, 'Pass', 'Example High', 'Matthew', 76.5, 'Fail', 'Example High', 'Marie', 80.4, 'Fail', 'Example High', 'Manuel', 79.6, 'Fail', 'Example High', 'Malala', 98.9, 'Pass'] offered code gave one tall column, Example High Mary 89.6 Pass Example High Matthew 76.5 Fail Example High Marie 80.4 Fail Example High Manuel 79.6 Fail Example High Malala 98.9 Pass my ideal is one row for each student (I had edited manually to show this) Example High, Mary, 89.6, Pass Example High, Matthew, 76.5, Fail Example High, Marie, 80.4, Fail Example High, Manuel, 79.6, Fail Example High, Malala, 98.9, Pass >and you haven't said what else you plan to use the list for. So anyone >who responds has to fly blind, without knowing key information. I'll keep list for a while in case it gets used or reused later, for now it's just a test bed along with a few others, I can work thru as I learn From hjp-python at hjp.at Wed Nov 15 12:16:50 2023 From: hjp-python at hjp.at (Peter J. Holzer) Date: Wed, 15 Nov 2023 18:16:50 +0100 Subject: xor operator In-Reply-To: <0E0F3061-A807-4471-9F85-1571259D0705@gmail.com> References: <44FBD8A8-E092-40FF-BD56-467E6936AAE9@gmail.com> <166AE5F3-3FF0-458D-9DA8-D6A7367122C4@gmail.com> <20231115003415.mtertwoelhjme4aq@hjp.at> <0E0F3061-A807-4471-9F85-1571259D0705@gmail.com> Message-ID: <20231115171650.sgt5daojsun2cxrj@hjp.at> On 2023-11-15 12:26:32 +0200, Dom Grigonis wrote: > > Thank you, > > > test2 = [True] * 100 + [False] * 2 > test2i = list(range(100)) > > %timeit len(set(test2i)) == 1 # 1.6 ?s ? 63.6 ns per loop (mean ? std. dev. of 7 runs, 1,000,000 loops each) > %timeit all(test2) # 386 ns ? 9.58 ns per loop (mean ? std. dev. of 7 runs, 1,000,000 loops each) > > test2s = set(test2i) > %timeit len(test2s) == 1 # 46.1 ns ? 1.65 ns per loop (mean ? std. dev. of 7 runs, 10,000,000 loops each) > > If you pre-convert to set it is obviously faster. However, set > operation is most likely going to be part of the procedure. In which > case it ends up to be significantly slower. Obviously, if you convert a list to a set just to count the elements it's going to be slow. My suggestion was to use the set *instead* of the list. I don't know whether that's possible in your situation, because you haven't told us anything about it. All I'm suggesting is taking a step back and reconsider your choice of data structure. 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 pf at pfortin.com Wed Nov 15 12:19:16 2023 From: pf at pfortin.com (Pierre Fortin) Date: Wed, 15 Nov 2023 12:19:16 -0500 Subject: Newline (NuBe Question) In-Reply-To: <6554F6FD.23324.1B219E@RealGrizzlyAdams.vivaldi.net> References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> <6554F6FD.23324.1B219E@RealGrizzlyAdams.vivaldi.net> Message-ID: <20231115121916.610cbf32@pfortin.com> On Wed, 15 Nov 2023 16:51:09 -0000 Grizzy Adams via Python-list wrote: I don't give solutions; just a nudge... you appear not to fully grok "list"; your list is ONE list with no delineation between students. You want a "list of lists"... >['Example High', 'Mary', 89.6, 'Pass', 'Example High', 'Matthew', 76.5, 'Fail', 'Example High', 'Marie', 80.4, 'Fail', 'Example High', 'Manuel', 79.6, 'Fail', 'Example High', 'Malala', 98.9, 'Pass'] Like this: students = [ ['Example High', 'Mary', 89.6, 'Pass'], ['Example High','Matthew', 76.5, 'Fail'], ['Example High', 'Marie', 80.4, 'Fail'], ['Example High', 'Manuel', 79.6, 'Fail'], ['Example High', 'Malala', 98.9, 'Pass'] ] This may help get you headed in the right direction: for s in students: print( s ) Hint: look forward to learning about f-strings... HTH, Pierre From dom.grigonis at gmail.com Wed Nov 15 13:13:50 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Wed, 15 Nov 2023 20:13:50 +0200 Subject: xor operator In-Reply-To: <20231115171650.sgt5daojsun2cxrj@hjp.at> References: <44FBD8A8-E092-40FF-BD56-467E6936AAE9@gmail.com> <166AE5F3-3FF0-458D-9DA8-D6A7367122C4@gmail.com> <20231115003415.mtertwoelhjme4aq@hjp.at> <0E0F3061-A807-4471-9F85-1571259D0705@gmail.com> <20231115171650.sgt5daojsun2cxrj@hjp.at> Message-ID: <9E5DAA3E-5670-4056-A73C-4CF363217238@gmail.com> The specific situation was related to truth values and following out of that my considerations regarding equivalent of all and any for counting `truths`. So one of the specific examples: class Publisher: def __init__(self): self.subscribers = dict() def subscribe(self, sub, criteria, agg=all): self.subscribers[sub] = (criteria, agg) def publish(self, msg): for sub, criteria in self.subscribers.items(): if criteria(msg): sub.handle(msg) p = Publisher() p.subscribe(sub, lambda x: all(r > 3 for r in x.ratings)) # So what I needed is: p.subscribe(sub, lambda x: set(r > 3 for r in x.ratings) > 50) # Note, that elements might not necessarily be bool. # E.g. at least 51 non-empty pages p.subscribe(sub, lambda x: set(bool(p) for p in x.pages) > 50) # So the function: p.subscribe(sub, lambda x: xor_more_than(x.pages, 50) # would ideally deal with truth values too. The question is: can you construct a function? which: a) performs: lambda x: set(bool(el) for el in iterable) > n b) is in line with performance of python?s `all` Then, as I said the case where one would need `set() == n` is hard to think of, but it seems fairly probable to need `set() > n` and `set() < n`. Regards, DG > On 15 Nov 2023, at 19:16, Peter J. Holzer via Python-list wrote: > > On 2023-11-15 12:26:32 +0200, Dom Grigonis wrote: >> >> Thank you, >> >> >> test2 = [True] * 100 + [False] * 2 >> test2i = list(range(100)) >> >> %timeit len(set(test2i)) == 1 # 1.6 ?s ? 63.6 ns per loop (mean ? std. dev. of 7 runs, 1,000,000 loops each) >> %timeit all(test2) # 386 ns ? 9.58 ns per loop (mean ? std. dev. of 7 runs, 1,000,000 loops each) >> >> test2s = set(test2i) >> %timeit len(test2s) == 1 # 46.1 ns ? 1.65 ns per loop (mean ? std. dev. of 7 runs, 10,000,000 loops each) >> >> If you pre-convert to set it is obviously faster. However, set >> operation is most likely going to be part of the procedure. In which >> case it ends up to be significantly slower. > > Obviously, if you convert a list to a set just to count the elements > it's going to be slow. My suggestion was to use the set *instead* of the > list. I don't know whether that's possible in your situation, because > you haven't told us anything about it. All I'm suggesting is taking a > step back and reconsider your choice of data structure. > > 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 dom.grigonis at gmail.com Wed Nov 15 11:44:11 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Wed, 15 Nov 2023 18:44:11 +0200 Subject: __set_name__ equivalent for instance Message-ID: So there is a method __set_name__ which is called on class creation. The functionality that I am interested in is not retrieving name, but the fact that it also receives `owner` argument. Thus, allowing simulation of bound class method. I was wandering if there is an equivalent functionality of attribute to receive `instance` argument on instance creation. Regards, DG From dom.grigonis at gmail.com Wed Nov 15 14:00:06 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Wed, 15 Nov 2023 21:00:06 +0200 Subject: xor operator In-Reply-To: <9E5DAA3E-5670-4056-A73C-4CF363217238@gmail.com> References: <44FBD8A8-E092-40FF-BD56-467E6936AAE9@gmail.com> <166AE5F3-3FF0-458D-9DA8-D6A7367122C4@gmail.com> <20231115003415.mtertwoelhjme4aq@hjp.at> <0E0F3061-A807-4471-9F85-1571259D0705@gmail.com> <20231115171650.sgt5daojsun2cxrj@hjp.at> <9E5DAA3E-5670-4056-A73C-4CF363217238@gmail.com> Message-ID: <0A185341-8563-4E4E-B098-70772FFA9EFD@gmail.com> In case someone is actually going to execute the code, there is a bug: `set` need to be wrapped in `len` for criteria args. > On 15 Nov 2023, at 20:13, Dom Grigonis wrote: > > > The specific situation was related to truth values and following out of that my considerations regarding equivalent of all and any for counting `truths`. > > So one of the specific examples: > class Publisher: > def __init__(self): > self.subscribers = dict() > > def subscribe(self, sub, criteria, agg=all): > self.subscribers[sub] = (criteria, agg) > > def publish(self, msg): > for sub, criteria in self.subscribers.items(): > if criteria(msg): > sub.handle(msg) > > p = Publisher() > p.subscribe(sub, lambda x: all(r > 3 for r in x.ratings)) > > # So what I needed is: > p.subscribe(sub, lambda x: set(r > 3 for r in x.ratings) > 50) > # Note, that elements might not necessarily be bool. > # E.g. at least 51 non-empty pages > p.subscribe(sub, lambda x: set(bool(p) for p in x.pages) > 50) > # So the function: > p.subscribe(sub, lambda x: xor_more_than(x.pages, 50) > # would ideally deal with truth values too. > The question is: can you construct a function? which: > a) performs: lambda x: set(bool(el) for el in iterable) > n > b) is in line with performance of python?s `all` > > Then, as I said the case where one would need `set() == n` is hard to think of, but it seems fairly probable to need `set() > n` and `set() < n`. > > Regards, > DG > >> On 15 Nov 2023, at 19:16, Peter J. Holzer via Python-list > wrote: >> >> On 2023-11-15 12:26:32 +0200, Dom Grigonis wrote: >>> >>> Thank you, >>> >>> >>> test2 = [True] * 100 + [False] * 2 >>> test2i = list(range(100)) >>> >>> %timeit len(set(test2i)) == 1 # 1.6 ?s ? 63.6 ns per loop (mean ? std. dev. of 7 runs, 1,000,000 loops each) >>> %timeit all(test2) # 386 ns ? 9.58 ns per loop (mean ? std. dev. of 7 runs, 1,000,000 loops each) >>> >>> test2s = set(test2i) >>> %timeit len(test2s) == 1 # 46.1 ns ? 1.65 ns per loop (mean ? std. dev. of 7 runs, 10,000,000 loops each) >>> >>> If you pre-convert to set it is obviously faster. However, set >>> operation is most likely going to be part of the procedure. In which >>> case it ends up to be significantly slower. >> >> Obviously, if you convert a list to a set just to count the elements >> it's going to be slow. My suggestion was to use the set *instead* of the >> list. I don't know whether that's possible in your situation, because >> you haven't told us anything about it. All I'm suggesting is taking a >> step back and reconsider your choice of data structure. >> >> 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 RealGrizzlyAdams at vivaldi.net Wed Nov 15 14:04:37 2023 From: RealGrizzlyAdams at vivaldi.net (Grizzy Adams) Date: Wed, 15 Nov 2023 19:04:37 -0000 Subject: Newline (NuBe Question) In-Reply-To: <20231115121916.610cbf32@pfortin.com> References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net>, <6554F6FD.23324.1B219E@RealGrizzlyAdams.vivaldi.net>, <20231115121916.610cbf32@pfortin.com> Message-ID: <65551645.18452.230A27@RealGrizzlyAdams.vivaldi.net> Wednesday, November 15, 2023 at 12:19, Pierre Fortin wrote: Re: Newline (NuBe Question) (at least in part) >On Wed, 15 Nov 2023 16:51:09 -0000 Grizzy Adams via Python-list wrote: > >I don't give solutions; just a nudge... you appear not to fully grok >"list"; your list is ONE list with no delineation between students. You >want a "list of lists"... >>['Example High', 'Mary', 89.6, 'Pass', 'Example High', 'Matthew', 76.5, 'Fail', 'Example High', 'Marie', 80.4, 'Fail', 'Example High', 'Manuel', 79.6, 'Fail', 'Example High', 'Malala', 98.9, 'Pass'] >Like this: >students = [ > ['Example High', 'Mary', 89.6, 'Pass'], > ['Example High','Matthew', 76.5, 'Fail'], > ['Example High', 'Marie', 80.4, 'Fail'], > ['Example High', 'Manuel', 79.6, 'Fail'], > ['Example High', 'Malala', 98.9, 'Pass'] >] for now I made a copt of code and altered to students = [] grades = [] for s in geographyClass: students.append(geographyStudent(s)) for s in students: if s.finalGrade()>82: Result=("Pass") else: Result=("Fail") print(s.school, s.name, s.finalGrade(),Result) >This may help get you headed in the right direction: >for s in students: > print( s ) >Hint: look forward to learning about f-strings... I will look forward to them, may even go search ahead, From list1 at tompassin.net Wed Nov 15 15:54:45 2023 From: list1 at tompassin.net (Thomas Passin) Date: Wed, 15 Nov 2023 15:54:45 -0500 Subject: Newline (NuBe Question) In-Reply-To: <65551645.18452.230A27@RealGrizzlyAdams.vivaldi.net> References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> <6554F6FD.23324.1B219E@RealGrizzlyAdams.vivaldi.net> <20231115121916.610cbf32@pfortin.com> <65551645.18452.230A27@RealGrizzlyAdams.vivaldi.net> Message-ID: <5129e9a3-025b-411b-96d1-b562df9b2115@tompassin.net> On 11/15/2023 2:04 PM, Grizzy Adams via Python-list wrote: > Wednesday, November 15, 2023 at 12:19, Pierre Fortin wrote: > Re: Newline (NuBe Question) (at least in part) > >> On Wed, 15 Nov 2023 16:51:09 -0000 Grizzy Adams via Python-list wrote: >> >> I don't give solutions; just a nudge... you appear not to fully grok >> "list"; your list is ONE list with no delineation between students. You >> want a "list of lists"... > >>> ['Example High', 'Mary', 89.6, 'Pass', 'Example High', 'Matthew', 76.5, 'Fail', 'Example High', 'Marie', 80.4, 'Fail', 'Example High', 'Manuel', 79.6, 'Fail', 'Example High', 'Malala', 98.9, 'Pass'] > >> Like this: > >> students = [ >> ['Example High', 'Mary', 89.6, 'Pass'], >> ['Example High','Matthew', 76.5, 'Fail'], >> ['Example High', 'Marie', 80.4, 'Fail'], >> ['Example High', 'Manuel', 79.6, 'Fail'], >> ['Example High', 'Malala', 98.9, 'Pass'] >> ] > > for now I made a copt of code and altered to > > students = [] > grades = [] # In this design there is no point in the extra loop. # also, the indentation is wrong. Perhaps you inserted # tabs? Use only spaces in these posts. # Also you don't need the students list > for student in geographyClass: > # students.append(geographyStudent(s)) s = geographyStudent(student) > # for s in students: > if s.finalGrade()>82: Result=("Pass") > else: Result=("Fail") > print(s.school, s.name, s.finalGrade(),Result) > >> This may help get you headed in the right direction: > >> for s in students: >> print( s ) > >> Hint: look forward to learning about f-strings... > > I will look forward to them, may even go search ahead, From RealGrizzlyAdams at vivaldi.net Thu Nov 16 01:19:59 2023 From: RealGrizzlyAdams at vivaldi.net (Grizzy Adams) Date: Thu, 16 Nov 2023 06:19:59 -0000 Subject: Newline (NuBe Question) In-Reply-To: <5129e9a3-025b-411b-96d1-b562df9b2115@tompassin.net> References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net>, <65551645.18452.230A27@RealGrizzlyAdams.vivaldi.net>, <5129e9a3-025b-411b-96d1-b562df9b2115@tompassin.net> Message-ID: <6555B48F.10108.156EC1@RealGrizzlyAdams.vivaldi.net> Wednesday, November 15, 2023 at 15:54, Thomas Passin via Python-list wrote: Re: Newline (NuBe Question) (at least in part) >On 11/15/2023 2:04 PM, Grizzy Adams via Python-list wrote: >> Wednesday, November 15, 2023 at 12:19, Pierre Fortin wrote: >> Re: Newline (NuBe Question) (at least in part) >>> On Wed, 15 Nov 2023 16:51:09 -0000 Grizzy Adams via Python-list wrote: >>> I don't give solutions; just a nudge... you appear not to fully grok >>> "list"; your list is ONE list with no delineation between students. You >>> want a "list of lists"... >>>> ['Example High', 'Mary', 89.6, 'Pass', 'Example High', 'Matthew', 76.5, 'Fail', 'Example High', 'Marie', 80.4, 'Fail', 'Example High', 'Manuel', 79.6, 'Fail', 'Example High', 'Malala', 98.9, 'Pass'] >>> Like this: >>> students = [ >>> ['Example High', 'Mary', 89.6, 'Pass'], >>> ['Example High','Matthew', 76.5, 'Fail'], >>> ['Example High', 'Marie', 80.4, 'Fail'], >>> ['Example High', 'Manuel', 79.6, 'Fail'], >>> ['Example High', 'Malala', 98.9, 'Pass'] >>> ] >> for now I made a copt of code and altered to >> >> students = [] >> grades = [] ># In this design there is no point in the extra loop. ># also, the indentation is wrong. Perhaps you inserted ># tabs? Use only spaces in these posts. I copy-pasted the code direct from IDLE, (to avoid any other typo's) ># Also you don't need the students list >> for student in geographyClass: >> # students.append(geographyStudent(s)) > s = geographyStudent(student) >> > # for s in students: >> if s.finalGrade()>82: Result=("Pass") >> else: Result=("Fail") >> print(s.school, s.name, s.finalGrade(),Result) I'll hive this a try (as a learning point) Thanks From learn2program at gmail.com Thu Nov 16 07:33:57 2023 From: learn2program at gmail.com (Alan Gauld) Date: Thu, 16 Nov 2023 12:33:57 +0000 Subject: Amy known issues with tkinter /ttk on latest MacOS? Message-ID: I have a little app that I wrote ages ago (2015) using tkinter/ttk and it just works. Or it did, up until the latest MacOS version upgrade and now it has become very sporadic in response to mouse clicks. For example I have a drop-down list and I can drop the list but then it won't let me select an item. Or sometimes, the selected item is highlighted but the corresponding action doesn't get fired. It is intermittent which makes debugging it difficult. And it's not just lists it also affects regular buttons as well. Right clicks seem to work ok, it's only the left mouse button. Also, I've just noticed that if I move the mouse slightly while clicking that seems to work. There are no error/warning messages in the Console. I'm just wondered if this is a known issue, or just my setup? Any suggestions welcomed. Python version - 3.10.4 OS version - Sonoma 14.1 M1 Mac Mini, 16GB Ram I could upgrade my Python version but I was planning on waiting for the 3.13 release to finalize first. And I doubt if that's the cause anyway. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From list1 at tompassin.net Thu Nov 16 07:47:21 2023 From: list1 at tompassin.net (Thomas Passin) Date: Thu, 16 Nov 2023 07:47:21 -0500 Subject: Newline (NuBe Question) In-Reply-To: <6555B48F.10108.156EC1@RealGrizzlyAdams.vivaldi.net> References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> <65551645.18452.230A27@RealGrizzlyAdams.vivaldi.net> <5129e9a3-025b-411b-96d1-b562df9b2115@tompassin.net> <6555B48F.10108.156EC1@RealGrizzlyAdams.vivaldi.net> Message-ID: <4626640f-4fe5-49bc-a6f8-d555b7f7b58a@tompassin.net> On 11/16/2023 1:19 AM, Grizzy Adams via Python-list wrote: > Wednesday, November 15, 2023 at 15:54, Thomas Passin via Python-list wrote: > Re: Newline (NuBe Question) (at least in part) > >> On 11/15/2023 2:04 PM, Grizzy Adams via Python-list wrote: >>> Wednesday, November 15, 2023 at 12:19, Pierre Fortin wrote: >>> Re: Newline (NuBe Question) (at least in part) > >>>> On Wed, 15 Nov 2023 16:51:09 -0000 Grizzy Adams via Python-list wrote: > >>>> I don't give solutions; just a nudge... you appear not to fully grok >>>> "list"; your list is ONE list with no delineation between students. You >>>> want a "list of lists"... > >>>>> ['Example High', 'Mary', 89.6, 'Pass', 'Example High', 'Matthew', 76.5, 'Fail', 'Example High', 'Marie', 80.4, 'Fail', 'Example High', 'Manuel', 79.6, 'Fail', 'Example High', 'Malala', 98.9, 'Pass'] > >>>> Like this: > >>>> students = [ >>>> ['Example High', 'Mary', 89.6, 'Pass'], >>>> ['Example High','Matthew', 76.5, 'Fail'], >>>> ['Example High', 'Marie', 80.4, 'Fail'], >>>> ['Example High', 'Manuel', 79.6, 'Fail'], >>>> ['Example High', 'Malala', 98.9, 'Pass'] >>>> ] > >>> for now I made a copt of code and altered to >>> >>> students = [] >>> grades = [] > >> # In this design there is no point in the extra loop. >> # also, the indentation is wrong. Perhaps you inserted >> # tabs? Use only spaces in these posts. > > I copy-pasted the code direct from IDLE, (to avoid any other typo's) > >> # Also you don't need the students list >>> for student in geographyClass: >>> # students.append(geographyStudent(s)) >> s = geographyStudent(student) >>> >> # for s in students: >>> if s.finalGrade()>82: Result=("Pass") >>> else: Result=("Fail") >>> print(s.school, s.name, s.finalGrade(),Result) > > I'll hive this a try (as a learning point) I wrote that you don't need the "students" list, which is correct. But there could be a use for a list. It would let you change the order in which students appear in the printed output. Knowing how to do that is a useful skill. But that should be left for a later lesson, not mixed in here. From RealGrizzlyAdams at vivaldi.net Thu Nov 16 08:40:42 2023 From: RealGrizzlyAdams at vivaldi.net (Grizzy Adams) Date: Thu, 16 Nov 2023 13:40:42 -0000 Subject: Newline (NuBe Question) In-Reply-To: <4626640f-4fe5-49bc-a6f8-d555b7f7b58a@tompassin.net> References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net>, <6555B48F.10108.156EC1@RealGrizzlyAdams.vivaldi.net>, <4626640f-4fe5-49bc-a6f8-d555b7f7b58a@tompassin.net> Message-ID: <65561BDA.14413.9EACE9@RealGrizzlyAdams.vivaldi.net> Thursday, November 16, 2023 at 7:47, Thomas Passin via Python-list wrote: Re: Newline (NuBe Question) (at least in part) >I wrote that you don't need the "students" list, which is correct. But >there could be a use for a list. It would let you change the order in >which students appear in the printed output. Knowing how to do that is >a useful skill. But that should be left for a later lesson, not mixed >in here. I have a vague memory of seeing sorted list somewhere ;->) From dom.grigonis at gmail.com Thu Nov 16 13:12:19 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Thu, 16 Nov 2023 20:12:19 +0200 Subject: __set_name__ equivalent for instance In-Reply-To: <25942.22823.215688.837713@ixdm.fritz.box> References: <25942.22823.215688.837713@ixdm.fritz.box> Message-ID: <1E96390D-219C-4064-9C46-4F7BED89E324@gmail.com> What I am interested in is a callback. Preferably just after methods get bound. So in `object.__new__`. I have done it via metaclass, but it is not ideal as there would be too much overhead. I think what I am looking for is custom method binding. Regards, DG > On 16 Nov 2023, at 20:02, Dieter Maurer wrote: > > Dom Grigonis wrote at 2023-11-15 18:44 +0200: >> So there is a method __set_name__ which is called on class creation. >> >> The functionality that I am interested in is not retrieving name, but the fact that it also receives `owner` argument. >> >> Thus, allowing simulation of bound class method. >> >> I was wandering if there is an equivalent functionality of attribute to receive `instance` argument on instance creation. > > As PEP 487 describes, `__set_name__` essentially targets descriptors. > It is there to inform a descriptor about the name it is used for > in a class (and the class itself). There is no other (easy) way to allow > a descriptor to learn about this name. > > If a descriptor is accessed via an instance, the descriptor (protocol) > methods get the instance as parameter. > Note that descriptors are stored in the class: they must not store > instance specific information in their attributes. > Therefore, a method informing an descriptor about instance creation > would not help: it cannot do anything with it. From dieter at handshake.de Thu Nov 16 13:02:15 2023 From: dieter at handshake.de (Dieter Maurer) Date: Thu, 16 Nov 2023 19:02:15 +0100 Subject: __set_name__ equivalent for instance In-Reply-To: References: Message-ID: <25942.22823.215688.837713@ixdm.fritz.box> Dom Grigonis wrote at 2023-11-15 18:44 +0200: >So there is a method __set_name__ which is called on class creation. > >The functionality that I am interested in is not retrieving name, but the fact that it also receives `owner` argument. > >Thus, allowing simulation of bound class method. > >I was wandering if there is an equivalent functionality of attribute to receive `instance` argument on instance creation. As PEP 487 describes, `__set_name__` essentially targets descriptors. It is there to inform a descriptor about the name it is used for in a class (and the class itself). There is no other (easy) way to allow a descriptor to learn about this name. If a descriptor is accessed via an instance, the descriptor (protocol) methods get the instance as parameter. Note that descriptors are stored in the class: they must not store instance specific information in their attributes. Therefore, a method informing an descriptor about instance creation would not help: it cannot do anything with it. From dieter at handshake.de Thu Nov 16 14:00:46 2023 From: dieter at handshake.de (Dieter Maurer) Date: Thu, 16 Nov 2023 20:00:46 +0100 Subject: __set_name__ equivalent for instance In-Reply-To: <1E96390D-219C-4064-9C46-4F7BED89E324@gmail.com> References: <25942.22823.215688.837713@ixdm.fritz.box> <1E96390D-219C-4064-9C46-4F7BED89E324@gmail.com> Message-ID: <25942.26334.931807.146304@ixdm.fritz.box> Dom Grigonis wrote at 2023-11-16 20:12 +0200: >What I am interested in is a callback. >Preferably just after methods get bound. So in `object.__new__`. >I have done it via metaclass, but it is not ideal as there would be too much overhead. > >I think what I am looking for is custom method binding. Methods are not bound during instance creation, they are bound during access. You can use descriptors to implement "custom method binding". Descriptors are defined on the class (and do not behave as descriptors when defined on instances). Thus, you would need a metaclass or `__inist_subclass__` is you want your "custom method binding" globally. For many methods (but usually not the `__...__` methods), you can take over the binding in `__new__` or `__init__` and populate the instance with prebound methods. From dom.grigonis at gmail.com Thu Nov 16 14:11:18 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Thu, 16 Nov 2023 21:11:18 +0200 Subject: __set_name__ equivalent for instance In-Reply-To: <25942.26334.931807.146304@ixdm.fritz.box> References: <25942.22823.215688.837713@ixdm.fritz.box> <1E96390D-219C-4064-9C46-4F7BED89E324@gmail.com> <25942.26334.931807.146304@ixdm.fritz.box> Message-ID: > On 16 Nov 2023, at 21:00, Dieter Maurer wrote: > > Dom Grigonis wrote at 2023-11-16 20:12 +0200: >> What I am interested in is a callback. >> Preferably just after methods get bound. So in `object.__new__`. > >> I have done it via metaclass, but it is not ideal as there would be too much overhead. >> >> I think what I am looking for is custom method binding. > > Methods are not bound during instance creation, they are bound during > access. Good to know. What is the criteria for binding then? Does it check if its type is `vanilla` function? If yes, is there any way to simulate it for arbitrary object? I have tried inheriting from function type, but not allowed. > You can use descriptors to implement "custom method binding". > > Descriptors are defined on the class (and do not behave as > descriptors when defined on instances). > Thus, you would need a metaclass or `__inist_subclass__` is you > want your "custom method binding" globally. Yes, I have tried that. This works well. But maybe will be useful for another case. Currently, the focus is decorators that can be used on arbitrary methods. Needing to inherit and add metaclasses whenever I want to decorate is not an option. I think I will continue with descriptor approach and am slowly finding route to get where I need to, but still exploring options. Regards, DG From dieter at handshake.de Thu Nov 16 14:30:28 2023 From: dieter at handshake.de (Dieter Maurer) Date: Thu, 16 Nov 2023 20:30:28 +0100 Subject: __set_name__ equivalent for instance In-Reply-To: References: <25942.22823.215688.837713@ixdm.fritz.box> <1E96390D-219C-4064-9C46-4F7BED89E324@gmail.com> <25942.26334.931807.146304@ixdm.fritz.box> Message-ID: <25942.28116.545555.332868@ixdm.fritz.box> Dom Grigonis wrote at 2023-11-16 21:11 +0200: > ... >> On 16 Nov 2023, at 21:00, Dieter Maurer wrote: >> ... >> Methods are not bound during instance creation, they are bound during >> access. > >Good to know. What is the criteria for binding then? Does it check if its type is `vanilla` function? If yes, is there any way to simulate it for arbitrary object? Attribute access (including method binding) is documented in the language reference. Functions and descriptors accessed via an instance but found in a class (i.e. not directly in the instance) are handled specially; functions are bound. Other objects are returned as is. `__getattribute__` can be used to take over control over the attribute access. From dom.grigonis at gmail.com Thu Nov 16 14:35:31 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Thu, 16 Nov 2023 21:35:31 +0200 Subject: __set_name__ equivalent for instance In-Reply-To: <25942.28116.545555.332868@ixdm.fritz.box> References: <25942.22823.215688.837713@ixdm.fritz.box> <1E96390D-219C-4064-9C46-4F7BED89E324@gmail.com> <25942.26334.931807.146304@ixdm.fritz.box> <25942.28116.545555.332868@ixdm.fritz.box> Message-ID: <22F347BF-A58E-4441-9D4C-12773D1ED68B@gmail.com> Thank you. > On 16 Nov 2023, at 21:30, Dieter Maurer wrote: > > Dom Grigonis wrote at 2023-11-16 21:11 +0200: >> ... >>> On 16 Nov 2023, at 21:00, Dieter Maurer wrote: >>> ... >>> Methods are not bound during instance creation, they are bound during >>> access. >> >> Good to know. What is the criteria for binding then? Does it check if its type is `vanilla` function? If yes, is there any way to simulate it for arbitrary object? > > Attribute access (including method binding) is documented in the > language reference. > > Functions and descriptors accessed via an instance but found in a class (i.e. > not directly in the instance) are handled specially; > functions are bound. Other objects are returned as is. > > `__getattribute__` can be used to take over control over the attribute > access. From miked at dewhirst.com.au Thu Nov 16 20:15:43 2023 From: miked at dewhirst.com.au (Mike Dewhirst) Date: Fri, 17 Nov 2023 12:15:43 +1100 Subject: Code improvement question In-Reply-To: References: <088586a6-79c2-4114-8d62-5e1a1061b841@mrabarnett.plus.com> <32bbd365-a2fb-471f-b19e-3a3ec4457124@dewhirst.com.au> Message-ID: <637d04c1-a6bf-4df7-b3bb-05b67d328f68@dewhirst.com.au> On 15/11/2023 3:08 pm, MRAB via Python-list wrote: > On 2023-11-15 03:41, Mike Dewhirst via Python-list wrote: >> On 15/11/2023 10:25 am, MRAB via Python-list wrote: >>> On 2023-11-14 23:14, Mike Dewhirst via Python-list wrote: >>>> I'd like to improve the code below, which works. It feels clunky to >>>> me. >>>> >>>> I need to clean up user-uploaded files the size of which I don't >>>> know in >>>> advance. >>>> >>>> After cleaning they might be as big as 1Mb but that would be super >>>> rare. >>>> Perhaps only for testing. >>>> >>>> I'm extracting CAS numbers and here is the pattern xx-xx-x up to >>>> xxxxxxx-xx-x eg., 1012300-77-4 >>>> >>>> def remove_alpha(txt): >>>> >>>> ? ??? """? r'[^0-9\- ]': >>>> >>>> ? ??? [^...]: Match any character that is not in the specified set. >>>> >>>> ? ??? 0-9: Match any digit. >>>> >>>> ? ??? \: Escape character. >>>> >>>> ? ??? -: Match a hyphen. >>>> >>>> ? ??? Space: Match a space. >>>> >>>> ? ??? """ >>>> >>>> ? ????cleaned_txt = re.sub(r'[^0-9\- ]', '', txt) >>>> >>>> ? ??? bits = cleaned_txt.split() >>>> >>>> ? ??? pieces = [] >>>> >>>> ? ??? for bit in bits: >>>> >>>> ? ??????? # minimum size of a CAS number is 7 so drop smaller >>>> clumps of digits >>>> >>>> ? ??????? pieces.append(bit if len(bit) > 6 else "") >>>> >>>> ? ??? return " ".join(pieces) >>>> >>>> >>>> Many thanks for any hints >>>> >>> Why don't you use re.findall? >>> >>> re.findall(r'\b[0-9]{2,7}-[0-9]{2}-[0-9]{2}\b', txt) >> >> I think I can see what you did there but it won't make sense to me - or >> whoever looks at the code - in future. >> >> That answers your specific question. However, I am in awe of people who >> can just "do" regular expressions and I thank you very much for what >> would have been a monumental effort had I tried it. >> >> That little re.sub() came from ChatGPT and I can understand it without >> too much effort because it came documented >> >> I suppose ChatGPT is the answer to this thread. Or everything. Or >> will be. >> > \b????????? Word boundary > [0-9]{2,7}? 2..7 digits > -?????????? "-" > [0-9]{2}??? 2 digits > -?????????? "-" > [0-9]{2}??? 2 digits > \b????????? Word boundary > > The "word boundary" thing is to stop it matching where there are > letters or digits right next to the digits. > > For example, if the text contained, say, "123456789-12-1234", you > wouldn't want it to match because there are more than 7 digits at the > start and more than 2 digits at the end. > Thanks I know I should invest some brainspace in re. Many years ago at a Perl conferenceI did buy a coffee mug completely covered with a regex cheat sheet. It currently holds pens and pencils on my desk. And spiders now I look closely! Then I took up Python and re is different. Maybe I'll have another look ... Cheers Mike -- Signed email is an absolute defence against phishing. This email has been signed with my private key. If you import my public key you can automatically decrypt my signature and be sure it came from me. Your email software can handle signing. -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature.asc Type: application/pgp-signature Size: 495 bytes Desc: OpenPGP digital signature URL: From python at mrabarnett.plus.com Thu Nov 16 20:22:46 2023 From: python at mrabarnett.plus.com (MRAB) Date: Fri, 17 Nov 2023 01:22:46 +0000 Subject: Code improvement question In-Reply-To: <637d04c1-a6bf-4df7-b3bb-05b67d328f68@dewhirst.com.au> References: <088586a6-79c2-4114-8d62-5e1a1061b841@mrabarnett.plus.com> <32bbd365-a2fb-471f-b19e-3a3ec4457124@dewhirst.com.au> <637d04c1-a6bf-4df7-b3bb-05b67d328f68@dewhirst.com.au> Message-ID: <2cc09743-97e4-4514-b0b6-b94218dc7b30@mrabarnett.plus.com> On 2023-11-17 01:15, Mike Dewhirst via Python-list wrote: > On 15/11/2023 3:08 pm, MRAB via Python-list wrote: >> On 2023-11-15 03:41, Mike Dewhirst via Python-list wrote: >>> On 15/11/2023 10:25 am, MRAB via Python-list wrote: >>>> On 2023-11-14 23:14, Mike Dewhirst via Python-list wrote: >>>>> I'd like to improve the code below, which works. It feels clunky to >>>>> me. >>>>> >>>>> I need to clean up user-uploaded files the size of which I don't >>>>> know in >>>>> advance. >>>>> >>>>> After cleaning they might be as big as 1Mb but that would be super >>>>> rare. >>>>> Perhaps only for testing. >>>>> >>>>> I'm extracting CAS numbers and here is the pattern xx-xx-x up to >>>>> xxxxxxx-xx-x eg., 1012300-77-4 >>>>> >>>>> def remove_alpha(txt): >>>>> >>>>> ? ??? """? r'[^0-9\- ]': >>>>> >>>>> ? ??? [^...]: Match any character that is not in the specified set. >>>>> >>>>> ? ??? 0-9: Match any digit. >>>>> >>>>> ? ??? \: Escape character. >>>>> >>>>> ? ??? -: Match a hyphen. >>>>> >>>>> ? ??? Space: Match a space. >>>>> >>>>> ? ??? """ >>>>> >>>>> ? ????cleaned_txt = re.sub(r'[^0-9\- ]', '', txt) >>>>> >>>>> ? ??? bits = cleaned_txt.split() >>>>> >>>>> ? ??? pieces = [] >>>>> >>>>> ? ??? for bit in bits: >>>>> >>>>> ? ??????? # minimum size of a CAS number is 7 so drop smaller >>>>> clumps of digits >>>>> >>>>> ? ??????? pieces.append(bit if len(bit) > 6 else "") >>>>> >>>>> ? ??? return " ".join(pieces) >>>>> >>>>> >>>>> Many thanks for any hints >>>>> >>>> Why don't you use re.findall? >>>> >>>> re.findall(r'\b[0-9]{2,7}-[0-9]{2}-[0-9]{2}\b', txt) >>> >>> I think I can see what you did there but it won't make sense to me - or >>> whoever looks at the code - in future. >>> >>> That answers your specific question. However, I am in awe of people who >>> can just "do" regular expressions and I thank you very much for what >>> would have been a monumental effort had I tried it. >>> >>> That little re.sub() came from ChatGPT and I can understand it without >>> too much effort because it came documented >>> >>> I suppose ChatGPT is the answer to this thread. Or everything. Or >>> will be. >>> >> \b????????? Word boundary >> [0-9]{2,7}? 2..7 digits >> -?????????? "-" >> [0-9]{2}??? 2 digits >> -?????????? "-" >> [0-9]{2}??? 2 digits >> \b????????? Word boundary >> >> The "word boundary" thing is to stop it matching where there are >> letters or digits right next to the digits. >> >> For example, if the text contained, say, "123456789-12-1234", you >> wouldn't want it to match because there are more than 7 digits at the >> start and more than 2 digits at the end. >> > Thanks > > I know I should invest some brainspace in re. Many years ago at a Perl > conferenceI did buy a coffee mug completely covered with a regex cheat > sheet. It currently holds pens and pencils on my desk. And spiders now I > look closely! > > Then I took up Python and re is different. > > Maybe I'll have another look ... > The patterns themselves aren't that different; Perl's just has more features than the re module's. From rimuatkinson+usenet at gmail.com Wed Nov 15 17:34:16 2023 From: rimuatkinson+usenet at gmail.com (Rimu Atkinson) Date: Thu, 16 Nov 2023 11:34:16 +1300 Subject: Code improvement question In-Reply-To: References: <088586a6-79c2-4114-8d62-5e1a1061b841@mrabarnett.plus.com> <32bbd365-a2fb-471f-b19e-3a3ec4457124@dewhirst.com.au> Message-ID: >>> >> Why don't you use re.findall? >> >> re.findall(r'\b[0-9]{2,7}-[0-9]{2}-[0-9]{2}\b', txt) > > I think I can see what you did there but it won't make sense to me - or > whoever looks at the code - in future. > > That answers your specific question. However, I am in awe of people who > can just "do" regular expressions and I thank you very much for what > would have been a monumental effort had I tried it. I feel the same way about regex. If I can find a way to write something without regex I very much prefer to as regex usually adds complexity and hurts readability. You might find https://regex101.com/ to be useful for testing your regex. You can enter in sample data and see if it matches. If I understood what your regex was trying to do I might be able to suggest some python to do the same thing. Is it just removing numbers from text? The for loop, "for bit in bits" etc, could be written as a list comprehension. pieces = [bit if len(bit) > 6 else "" for bit in bits] For devs familiar with other languages but new to Python this will look like gibberish so arguably the original for loop is clearer, depending on your team. It's worth making the effort to get into list comprehensions though because they're awesome. > > That little re.sub() came from ChatGPT and I can understand it without > too much effort because it came documented > > I suppose ChatGPT is the answer to this thread. Or everything. Or will be. I am doubtful. We'll see! R From miked at dewhirst.com.au Thu Nov 16 23:56:19 2023 From: miked at dewhirst.com.au (Mike Dewhirst) Date: Fri, 17 Nov 2023 15:56:19 +1100 Subject: Code improvement question In-Reply-To: References: <088586a6-79c2-4114-8d62-5e1a1061b841@mrabarnett.plus.com> <32bbd365-a2fb-471f-b19e-3a3ec4457124@dewhirst.com.au> Message-ID: <7591aa86-d484-4fd9-abd4-ae0875170dee@dewhirst.com.au> On 16/11/2023 9:34 am, Rimu Atkinson via Python-list wrote: > >>>> >>> Why don't you use re.findall? >>> >>> re.findall(r'\b[0-9]{2,7}-[0-9]{2}-[0-9]{2}\b', txt) >> >> I think I can see what you did there but it won't make sense to me - >> or whoever looks at the code - in future. >> >> That answers your specific question. However, I am in awe of people >> who can just "do" regular expressions and I thank you very much for >> what would have been a monumental effort had I tried it. > > I feel the same way about regex. If I can find a way to write > something without regex I very much prefer to as regex usually adds > complexity and hurts readability. > > You might find https://regex101.com/ to be useful for testing your > regex. You can enter in sample data and see if it matches. > > If I understood what your regex was trying to do I might be able to > suggest some python to do the same thing. Is it just removing numbers > from text? > > The for loop, "for bit in bits" etc, could be written as a list > comprehension. > > pieces = [bit if len(bit) > 6 else "" for bit in bits] > > For devs familiar with other languages but new to Python this will > look like gibberish so arguably the original for loop is clearer, > depending on your team. > > It's worth making the effort to get into list comprehensions though > because they're awesome. I agree qualitatively 100% but quantitively perhaps I agree 80% where readability is easy. I think that's what you are saying anyway. > > > >> >> That little re.sub() came from ChatGPT and I can understand it >> without too much effort because it came documented >> >> I suppose ChatGPT is the answer to this thread. Or everything. Or >> will be. > > I am doubtful. We'll see! > > R > > -- Signed email is an absolute defence against phishing. This email has been signed with my private key. If you import my public key you can automatically decrypt my signature and be sure it came from me. Your email software can handle signing. -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature.asc Type: application/pgp-signature Size: 495 bytes Desc: OpenPGP digital signature URL: From hjp-python at hjp.at Fri Nov 17 06:17:44 2023 From: hjp-python at hjp.at (Peter J. Holzer) Date: Fri, 17 Nov 2023 12:17:44 +0100 Subject: Code improvement question In-Reply-To: References: <088586a6-79c2-4114-8d62-5e1a1061b841@mrabarnett.plus.com> <32bbd365-a2fb-471f-b19e-3a3ec4457124@dewhirst.com.au> Message-ID: <20231117111744.oocpwdjryvcty5ol@hjp.at> On 2023-11-16 11:34:16 +1300, Rimu Atkinson via Python-list wrote: > > > Why don't you use re.findall? > > > > > > re.findall(r'\b[0-9]{2,7}-[0-9]{2}-[0-9]{2}\b', txt) > > > > I think I can see what you did there but it won't make sense to me - or > > whoever looks at the code - in future. > > > > That answers your specific question. However, I am in awe of people who > > can just "do" regular expressions and I thank you very much for what > > would have been a monumental effort had I tried it. > > I feel the same way about regex. If I can find a way to write something > without regex I very much prefer to as regex usually adds complexity and > hurts readability. I find "straight" regexps very easy to write. There are only a handful of constructs which are all very simple and you just string them together. But then I've used regexps for 30+ years, so of course they feel natural to me. (Reading regexps may be a bit harder, exactly because they are to simple: There is no abstraction, so a complicated pattern results in a long regexp.) There are some extensions to regexps which are conceptually harder, like lookahead and lookbehind or nested contexts in Perl. I may need the manual for those (especially because they are new(ish) and every language uses a different syntax for them) or avoid them altogether. Oh, and Python (just like Perl) allows you to embed whitespace and comments into Regexps, which helps readability a lot if you have to write long regexps. > You might find https://regex101.com/ to be useful for testing your regex. > You can enter in sample data and see if it matches. > > If I understood what your regex was trying to do I might be able to suggest > some python to do the same thing. Is it just removing numbers from text? Not "removing" them (as I understood it), but extracting them (i.e. find and collect them). > > > re.findall(r'\b[0-9]{2,7}-[0-9]{2}-[0-9]{2}\b', txt) \b - a word boundary. [0-9]{2,7} - 2 to 7 digits - - a hyphen-minus [0-9]{2} - exactly 2 digits - - a hyphen-minus [0-9]{2} - exactly 2 digits \b - a word boundary. Seems quite straightforward to me. I'll be impressed if you can write that in Python in a way which is easier to read. 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 list1 at tompassin.net Fri Nov 17 07:48:41 2023 From: list1 at tompassin.net (Thomas Passin) Date: Fri, 17 Nov 2023 07:48:41 -0500 Subject: Code improvement question In-Reply-To: <20231117111744.oocpwdjryvcty5ol@hjp.at> References: <088586a6-79c2-4114-8d62-5e1a1061b841@mrabarnett.plus.com> <32bbd365-a2fb-471f-b19e-3a3ec4457124@dewhirst.com.au> <20231117111744.oocpwdjryvcty5ol@hjp.at> Message-ID: <7072d3e8-317c-4953-9b7e-5a1750d957aa@tompassin.net> On 11/17/2023 6:17 AM, Peter J. Holzer via Python-list wrote: > On 2023-11-16 11:34:16 +1300, Rimu Atkinson via Python-list wrote: >>>> Why don't you use re.findall? >>>> >>>> re.findall(r'\b[0-9]{2,7}-[0-9]{2}-[0-9]{2}\b', txt) >>> >>> I think I can see what you did there but it won't make sense to me - or >>> whoever looks at the code - in future. >>> >>> That answers your specific question. However, I am in awe of people who >>> can just "do" regular expressions and I thank you very much for what >>> would have been a monumental effort had I tried it. >> >> I feel the same way about regex. If I can find a way to write something >> without regex I very much prefer to as regex usually adds complexity and >> hurts readability. > > I find "straight" regexps very easy to write. There are only a handful > of constructs which are all very simple and you just string them > together. But then I've used regexps for 30+ years, so of course they > feel natural to me. > > (Reading regexps may be a bit harder, exactly because they are to > simple: There is no abstraction, so a complicated pattern results in a > long regexp.) > > There are some extensions to regexps which are conceptually harder, like > lookahead and lookbehind or nested contexts in Perl. I may need the > manual for those (especially because they are new(ish) and every > language uses a different syntax for them) or avoid them altogether. > > Oh, and Python (just like Perl) allows you to embed whitespace and > comments into Regexps, which helps readability a lot if you have to > write long regexps. > > >> You might find https://regex101.com/ to be useful for testing your regex. >> You can enter in sample data and see if it matches. >> >> If I understood what your regex was trying to do I might be able to suggest >> some python to do the same thing. Is it just removing numbers from text? > > Not "removing" them (as I understood it), but extracting them (i.e. find > and collect them). > >>>> re.findall(r'\b[0-9]{2,7}-[0-9]{2}-[0-9]{2}\b', txt) > > \b - a word boundary. > [0-9]{2,7} - 2 to 7 digits > - - a hyphen-minus > [0-9]{2} - exactly 2 digits > - - a hyphen-minus > [0-9]{2} - exactly 2 digits > \b - a word boundary. > > Seems quite straightforward to me. I'll be impressed if you can write > that in Python in a way which is easier to read. And the re.VERBOSE (also re.X) flag can always be used so the entire expression can be written line-by-line with comments nearly the same as the example above From hjp-python at hjp.at Fri Nov 17 09:46:06 2023 From: hjp-python at hjp.at (Peter J. Holzer) Date: Fri, 17 Nov 2023 15:46:06 +0100 Subject: Code improvement question In-Reply-To: <7072d3e8-317c-4953-9b7e-5a1750d957aa@tompassin.net> References: <088586a6-79c2-4114-8d62-5e1a1061b841@mrabarnett.plus.com> <32bbd365-a2fb-471f-b19e-3a3ec4457124@dewhirst.com.au> <20231117111744.oocpwdjryvcty5ol@hjp.at> <7072d3e8-317c-4953-9b7e-5a1750d957aa@tompassin.net> Message-ID: <20231117144606.ssezd234lj753bp2@hjp.at> On 2023-11-17 07:48:41 -0500, Thomas Passin via Python-list wrote: > On 11/17/2023 6:17 AM, Peter J. Holzer via Python-list wrote: > > Oh, and Python (just like Perl) allows you to embed whitespace and > > comments into Regexps, which helps readability a lot if you have to > > write long regexps. > > [...] > > > > > re.findall(r'\b[0-9]{2,7}-[0-9]{2}-[0-9]{2}\b', txt) > > > > \b - a word boundary. > > [0-9]{2,7} - 2 to 7 digits > > - - a hyphen-minus > > [0-9]{2} - exactly 2 digits > > - - a hyphen-minus > > [0-9]{2} - exactly 2 digits > > \b - a word boundary. > > > > Seems quite straightforward to me. I'll be impressed if you can write > > that in Python in a way which is easier to read. > > And the re.VERBOSE (also re.X) flag can always be used so the entire > expression can be written line-by-line with comments nearly the same > as the example above Yes. That's what I alluded to above. 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 list1 at tompassin.net Fri Nov 17 10:17:37 2023 From: list1 at tompassin.net (Thomas Passin) Date: Fri, 17 Nov 2023 10:17:37 -0500 Subject: Code improvement question In-Reply-To: <20231117144606.ssezd234lj753bp2@hjp.at> References: <088586a6-79c2-4114-8d62-5e1a1061b841@mrabarnett.plus.com> <32bbd365-a2fb-471f-b19e-3a3ec4457124@dewhirst.com.au> <20231117111744.oocpwdjryvcty5ol@hjp.at> <7072d3e8-317c-4953-9b7e-5a1750d957aa@tompassin.net> <20231117144606.ssezd234lj753bp2@hjp.at> Message-ID: <303c6738-4c51-4dbd-9c3c-1fe659b2ff6e@tompassin.net> On 11/17/2023 9:46 AM, Peter J. Holzer via Python-list wrote: > On 2023-11-17 07:48:41 -0500, Thomas Passin via Python-list wrote: >> On 11/17/2023 6:17 AM, Peter J. Holzer via Python-list wrote: >>> Oh, and Python (just like Perl) allows you to embed whitespace and >>> comments into Regexps, which helps readability a lot if you have to >>> write long regexps. >>> > [...] >>>>>> re.findall(r'\b[0-9]{2,7}-[0-9]{2}-[0-9]{2}\b', txt) >>> >>> \b - a word boundary. >>> [0-9]{2,7} - 2 to 7 digits >>> - - a hyphen-minus >>> [0-9]{2} - exactly 2 digits >>> - - a hyphen-minus >>> [0-9]{2} - exactly 2 digits >>> \b - a word boundary. >>> >>> Seems quite straightforward to me. I'll be impressed if you can write >>> that in Python in a way which is easier to read. >> >> And the re.VERBOSE (also re.X) flag can always be used so the entire >> expression can be written line-by-line with comments nearly the same >> as the example above > > Yes. That's what I alluded to above. I know, and I just wanted to make it explicit for people who didn't know much about Python regexes. From nospam at please.ty Fri Nov 17 04:38:14 2023 From: nospam at please.ty (jak) Date: Fri, 17 Nov 2023 10:38:14 +0100 Subject: Code improvement question In-Reply-To: References: <088586a6-79c2-4114-8d62-5e1a1061b841@mrabarnett.plus.com> <32bbd365-a2fb-471f-b19e-3a3ec4457124@dewhirst.com.au> Message-ID: Mike Dewhirst ha scritto: > On 15/11/2023 10:25 am, MRAB via Python-list wrote: >> On 2023-11-14 23:14, Mike Dewhirst via Python-list wrote: >>> I'd like to improve the code below, which works. It feels clunky to me. >>> >>> I need to clean up user-uploaded files the size of which I don't know in >>> advance. >>> >>> After cleaning they might be as big as 1Mb but that would be super rare. >>> Perhaps only for testing. >>> >>> I'm extracting CAS numbers and here is the pattern xx-xx-x up to >>> xxxxxxx-xx-x eg., 1012300-77-4 >>> >>> def remove_alpha(txt): >>> >>> ? ??? """? r'[^0-9\- ]': >>> >>> ? ??? [^...]: Match any character that is not in the specified set. >>> >>> ? ??? 0-9: Match any digit. >>> >>> ? ??? \: Escape character. >>> >>> ? ??? -: Match a hyphen. >>> >>> ? ??? Space: Match a space. >>> >>> ? ??? """ >>> >>> ? ????cleaned_txt = re.sub(r'[^0-9\- ]', '', txt) >>> >>> ? ??? bits = cleaned_txt.split() >>> >>> ? ??? pieces = [] >>> >>> ? ??? for bit in bits: >>> >>> ? ??????? # minimum size of a CAS number is 7 so drop smaller clumps >>> of digits >>> >>> ? ??????? pieces.append(bit if len(bit) > 6 else "") >>> >>> ? ??? return " ".join(pieces) >>> >>> >>> Many thanks for any hints >>> >> Why don't you use re.findall? >> >> re.findall(r'\b[0-9]{2,7}-[0-9]{2}-[0-9]{2}\b', txt) > > I think I can see what you did there but it won't make sense to me - or > whoever looks at the code - in future. > > That answers your specific question. However, I am in awe of people who > can just "do" regular expressions and I thank you very much for what > would have been a monumental effort had I tried it. > > That little re.sub() came from ChatGPT and I can understand it without > too much effort because it came documented > > I suppose ChatGPT is the answer to this thread. Or everything. Or will be. > > Thanks > > Mike I respect your opinion but from the point of view of many usenet users asking a question to chatgpt to solve your problem is truly an overkill. The computer world overflows with people who know regex. If you had not already had the answer with the use of 're' I would have sent you my suggestion that as you can see it is practically identical. I am quite sure that in this usenet the same solution came to the mind of many people. with open(file) as fp: try: ret = re.findall(r'\b\d{2,7}\-\d{2}\-\d{1}\b', fp.read()) except: ret = [] The only difference is '\d' instead of '[0-9]' but they are equivalent. From python at mrabarnett.plus.com Fri Nov 17 13:56:54 2023 From: python at mrabarnett.plus.com (MRAB) Date: Fri, 17 Nov 2023 18:56:54 +0000 Subject: Code improvement question In-Reply-To: References: <088586a6-79c2-4114-8d62-5e1a1061b841@mrabarnett.plus.com> <32bbd365-a2fb-471f-b19e-3a3ec4457124@dewhirst.com.au> Message-ID: <520925c5-bb86-4473-a27a-9c6aa74d73b9@mrabarnett.plus.com> On 2023-11-17 09:38, jak via Python-list wrote: > Mike Dewhirst ha scritto: >> On 15/11/2023 10:25 am, MRAB via Python-list wrote: >>> On 2023-11-14 23:14, Mike Dewhirst via Python-list wrote: >>>> I'd like to improve the code below, which works. It feels clunky to me. >>>> >>>> I need to clean up user-uploaded files the size of which I don't know in >>>> advance. >>>> >>>> After cleaning they might be as big as 1Mb but that would be super rare. >>>> Perhaps only for testing. >>>> >>>> I'm extracting CAS numbers and here is the pattern xx-xx-x up to >>>> xxxxxxx-xx-x eg., 1012300-77-4 >>>> >>>> def remove_alpha(txt): >>>> >>>> ? ??? """? r'[^0-9\- ]': >>>> >>>> ? ??? [^...]: Match any character that is not in the specified set. >>>> >>>> ? ??? 0-9: Match any digit. >>>> >>>> ? ??? \: Escape character. >>>> >>>> ? ??? -: Match a hyphen. >>>> >>>> ? ??? Space: Match a space. >>>> >>>> ? ??? """ >>>> >>>> ? ????cleaned_txt = re.sub(r'[^0-9\- ]', '', txt) >>>> >>>> ? ??? bits = cleaned_txt.split() >>>> >>>> ? ??? pieces = [] >>>> >>>> ? ??? for bit in bits: >>>> >>>> ? ??????? # minimum size of a CAS number is 7 so drop smaller clumps >>>> of digits >>>> >>>> ? ??????? pieces.append(bit if len(bit) > 6 else "") >>>> >>>> ? ??? return " ".join(pieces) >>>> >>>> >>>> Many thanks for any hints >>>> >>> Why don't you use re.findall? >>> >>> re.findall(r'\b[0-9]{2,7}-[0-9]{2}-[0-9]{2}\b', txt) >> >> I think I can see what you did there but it won't make sense to me - or >> whoever looks at the code - in future. >> >> That answers your specific question. However, I am in awe of people who >> can just "do" regular expressions and I thank you very much for what >> would have been a monumental effort had I tried it. >> >> That little re.sub() came from ChatGPT and I can understand it without >> too much effort because it came documented >> >> I suppose ChatGPT is the answer to this thread. Or everything. Or will be. >> >> Thanks >> >> Mike > > I respect your opinion but from the point of view of many usenet users > asking a question to chatgpt to solve your problem is truly an overkill. > The computer world overflows with people who know regex. If you had not > already had the answer with the use of 're' I would have sent you my > suggestion that as you can see it is practically identical. I am quite > sure that in this usenet the same solution came to the mind of many > people. > > with open(file) as fp: > try: ret = re.findall(r'\b\d{2,7}\-\d{2}\-\d{1}\b', fp.read()) > except: ret = [] > > The only difference is '\d' instead of '[0-9]' but they are equivalent. > Bare excepts are a very bad idea. From nospam at please.ty Fri Nov 17 18:53:21 2023 From: nospam at please.ty (jak) Date: Sat, 18 Nov 2023 00:53:21 +0100 Subject: Code improvement question In-Reply-To: References: <088586a6-79c2-4114-8d62-5e1a1061b841@mrabarnett.plus.com> <32bbd365-a2fb-471f-b19e-3a3ec4457124@dewhirst.com.au> <520925c5-bb86-4473-a27a-9c6aa74d73b9@mrabarnett.plus.com> Message-ID: MRAB ha scritto: > Bare excepts are a very bad idea. I know, you're right but to test the CAS numbers were inside a string (txt) and instead of the 'open(file)' there was 'io.StingIO(txt)' so the risk was almost null. When I copied it here I didn't think about it. Sorry. From avi.e.gross at gmail.com Sat Nov 18 01:55:13 2023 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Sat, 18 Nov 2023 01:55:13 -0500 Subject: Code improvement question In-Reply-To: <20231117111744.oocpwdjryvcty5ol@hjp.at> References: <088586a6-79c2-4114-8d62-5e1a1061b841@mrabarnett.plus.com> <32bbd365-a2fb-471f-b19e-3a3ec4457124@dewhirst.com.au> <20231117111744.oocpwdjryvcty5ol@hjp.at> Message-ID: <002f01da19ec$2e90d1b0$8bb27510$@gmail.com> Many features like regular expressions can be mini languages that are designed to be very powerful while also a tad cryptic to anyone not familiar. But consider an alternative in some languages that may use some complex set of nested function calls that each have names like match_white_space(2, 5) and even if some are set up to be sort of readable, they can be a pain. Quite a few problems can be solved nicely with a single regular expression or several in a row with each one being fairly simple. Sometimes you can do parts using some of the usual text manipulation functions built-in or in a module for either speed or to simplify things so that the RE part is simpler and easier to follow. And, as noted, Python allows ways to include comments in RE or ways to specify extensions such as PERL-style and so on. Adding enough comments above or within the code can help remind people or point to a reference and just explaining in English (or the language of your choice that hopefully others later can understand) can be helpful. You can spell out in whatever level of detail what you expect your data to look like and what you want to match or extract and then the RE may be easier to follow. Of course the endless extensions added due to things like supporting UNICODE have made some RE much harder to create or understand and sometimes the result may not even be what you expected if something strange happens like the symbols ??? The above might match digits and maybe be interpreted at some point as 12 dozen, which may even be appropriate but a bit of a surprise perhaps. -----Original Message----- From: Python-list On Behalf Of Peter J. Holzer via Python-list Sent: Friday, November 17, 2023 6:18 AM To: python-list at python.org Subject: Re: Code improvement question On 2023-11-16 11:34:16 +1300, Rimu Atkinson via Python-list wrote: > > > Why don't you use re.findall? > > > > > > re.findall(r'\b[0-9]{2,7}-[0-9]{2}-[0-9]{2}\b', txt) > > > > I think I can see what you did there but it won't make sense to me - or > > whoever looks at the code - in future. > > > > That answers your specific question. However, I am in awe of people who > > can just "do" regular expressions and I thank you very much for what > > would have been a monumental effort had I tried it. > > I feel the same way about regex. If I can find a way to write something > without regex I very much prefer to as regex usually adds complexity and > hurts readability. I find "straight" regexps very easy to write. There are only a handful of constructs which are all very simple and you just string them together. But then I've used regexps for 30+ years, so of course they feel natural to me. (Reading regexps may be a bit harder, exactly because they are to simple: There is no abstraction, so a complicated pattern results in a long regexp.) There are some extensions to regexps which are conceptually harder, like lookahead and lookbehind or nested contexts in Perl. I may need the manual for those (especially because they are new(ish) and every language uses a different syntax for them) or avoid them altogether. Oh, and Python (just like Perl) allows you to embed whitespace and comments into Regexps, which helps readability a lot if you have to write long regexps. > You might find https://regex101.com/ to be useful for testing your regex. > You can enter in sample data and see if it matches. > > If I understood what your regex was trying to do I might be able to suggest > some python to do the same thing. Is it just removing numbers from text? Not "removing" them (as I understood it), but extracting them (i.e. find and collect them). > > > re.findall(r'\b[0-9]{2,7}-[0-9]{2}-[0-9]{2}\b', txt) \b - a word boundary. [0-9]{2,7} - 2 to 7 digits - - a hyphen-minus [0-9]{2} - exactly 2 digits - - a hyphen-minus [0-9]{2} - exactly 2 digits \b - a word boundary. Seems quite straightforward to me. I'll be impressed if you can write that in Python in a way which is easier to read. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" From learn2program at gmail.com Sun Nov 19 14:33:02 2023 From: learn2program at gmail.com (Alan Gauld) Date: Sun, 19 Nov 2023 19:33:02 +0000 Subject: Amy known issues with tkinter /ttk on latest MacOS? In-Reply-To: <60d413a1-2a95-4429-9df5-1227694a69f9@udel.edu> References: <60d413a1-2a95-4429-9df5-1227694a69f9@udel.edu> Message-ID: <1bcd49d2-4323-420b-a56c-e8015482301d@yahoo.co.uk> On 17/11/2023 03:38, Terry Reedy wrote: > There have been other reports on the cpython issue tracker than Sonoma > broke bits of tk behavior. > https://github.com/python/cpython/issues?q=is%3Aissue+label%3AOS-mac+is%3Aclosed > shows a couple Thanks Terry, I had a browse and it seems I'm not alone. That's a relief. I'll upgrade to 3.13 when it comes out and hopefully it will go away. (Another suggestion was to use the homebrew python but I don't like having any more homebrew stuff than is absolutely necessary!) Meantime I'll just have to continue nudging the mouse as I click! Alan G. From rimuatkinson+usenet at gmail.com Mon Nov 20 15:48:49 2023 From: rimuatkinson+usenet at gmail.com (Rimu Atkinson) Date: Tue, 21 Nov 2023 09:48:49 +1300 Subject: Code improvement question In-Reply-To: References: <088586a6-79c2-4114-8d62-5e1a1061b841@mrabarnett.plus.com> <32bbd365-a2fb-471f-b19e-3a3ec4457124@dewhirst.com.au> <20231117111744.oocpwdjryvcty5ol@hjp.at> Message-ID: > >>>> re.findall(r'\b[0-9]{2,7}-[0-9]{2}-[0-9]{2}\b', txt) > > \b - a word boundary. > [0-9]{2,7} - 2 to 7 digits > - - a hyphen-minus > [0-9]{2} - exactly 2 digits > - - a hyphen-minus > [0-9]{2} - exactly 2 digits > \b - a word boundary. > > Seems quite straightforward to me. I'll be impressed if you can write > that in Python in a way which is easier to read. > Now that I know what {} does, you're right, that IS straightforward! Maybe 2023 will be the year I finally get off my arse and learn regex. Thanks :) From PythonList at DancesWithMice.info Wed Nov 22 16:59:24 2023 From: PythonList at DancesWithMice.info (dn) Date: Thu, 23 Nov 2023 10:59:24 +1300 Subject: NZPUG Mtg: Making Python faster, and "Dependency Inversion" Message-ID: <3929f1a1-9eb0-46a2-be12-efd9855ee426@DancesWithMice.info> Virtual meeting: Wednesday 6 December, 1815 for 1830 NZDT/UTC+13 Book at https://www.meetup.com/nzpug-auckland/events/295433876/ 1 Making Python faster - using type hints Tushar will lead us through: A brief history of type hints Using type checkers to verify your type hints Compiling type checked Python to make it faster Some examples of libraries and the speedups they get from type hints We'll be looking at mypy/mypyc. Audience Level: intermediate, ie understand Python constructs, functions, control flow, etc. Tushar has been a long term Python developer, OSS contributor, author and speaker. He has been working with static analysis and type checkers for the past 3 years, and has contributed to various PSF-projects such as black and mypy. 2 SOLID's Dependency Inversion Principle Olaf will complete the current Software Craftsmanship series on the SOLID Principles with a session on the Dependency Inversion Principle. This one is particularly fascinating, because at first-glance the inversion seems to be asking us to do things backwards. With understanding, we realise that it is an impressive device enabling us to focus on what is needed by the 'layer' of more valuable components, rather than the lower-level, eg UIs and external interfaces (need refresher? see https://www.bmc.com/blogs/solid-design-principles/) Audience Level: advanced, ie understand programming constructs, patterns, principles, etc. Olaf needs no introduction having generously brought us the earlier sessions in his "Software Craftsmanship" series over the last two years. Let's complete this exercise in dogged-persistence and round things off neatly - if you remember, this talk was originally scheduled last month, but technical-gremlins got in the way! Also, please tell us what topics you'd like to cover at this skill-level in future... Please come, and come with a collegial frame-of-mind. Questions and conversation will be the order of the day. If you are more confident in Python, your constructive advice, suggestions, and alternate approaches will be valued ... -- Regards =dn From thomas at python.org Wed Nov 22 19:48:29 2023 From: thomas at python.org (Thomas Wouters) Date: Thu, 23 Nov 2023 01:48:29 +0100 Subject: Python 3.13.0 alpha 2 now available. Message-ID: Well, well, well, it?s time for Python 3.13.0 alpha 2! https://www.python.org/downloads/release/python-3130a2/ *This is an early developer preview of Python 3.13* Major new features of the 3.13 series, compared to 3.12 Python 3.13 is still in development. This release, 3.13.0a2 is the second of seven planned alpha releases. Alpha releases are intended to make it easier to test the current state of new features and bug fixes and to test the release process. During the alpha phase, features may be added up until the start of the beta phase (2024-05-07) and, if necessary, may be modified or deleted up until the release candidate phase (2024-07-30). Please keep in mind that this is a preview release and its use is *not* recommended for production environments. Many new features for Python 3.13 are still being planned and written. The most notable change so far: - PEP 594 (Removing dead batteries from the standard library) scheduled removals of many deprecated modules: aifc, audioop, chunk, cgi, cgitb, crypt, imghdr, mailcap, msilib, nis, nntplib, ossaudiodev, pipes, sndhdr, spwd, sunau, telnetlib, uu, xdrlib, lib2to3. - Many other removals of deprecated classes, functions and methods in various standard library modules. - New deprecations , most of which are scheduled for removal from Python 3.15 or 3.16. - C API removals and deprecations . (Some removals present in alpha 1 have been reverted in alpha 2, as the removals were deemed too disruptive at this time.) (Hey, *fellow core developer,* if a feature you find important is missing from this list, let Thomas know .) The next pre-release of Python 3.13 will be 3.13.0a3, currently scheduled for 2023-12-19. More resources - Online Documentation - PEP 719 , 3.13 Release Schedule - Report bugs at https://github.com/python/cpython/issues . - Help fund Python and its community . Enjoy the new releases Thanks to all of the many volunteers who help make Python Development and these releases possible! Please consider supporting our efforts by volunteering yourself or through organization contributions to the Python Software Foundation. Regards from chilly Amsterdam, Your release team, Thomas Wouters Ned Deily Steve Dower ?ukasz Langa -- Thomas Wouters From mal at egenix.com Thu Nov 23 10:12:27 2023 From: mal at egenix.com (Marc-Andre Lemburg) Date: Thu, 23 Nov 2023 16:12:27 +0100 Subject: FOSDEM 2024: Call for Proposals - Python Devrooom Message-ID: <7a0c1dbc-0f11-4906-8d47-f214b4fcd90d@egenix.com> We are happy to announce that we will be running a Python devroom again at FOSDEM 2024. This year's edition will be exclusively in-person, and take place on the 3rd and 4th of February, with the Python devroom being available on Sunday 4th. If you have not heard about FOSDEM before or are looking for more information, you can visit the official website at https://www.fosdem.org/. As usual, we are looking for multiple Pythonistas to help us shape the devroom schedule. We are now open to receiving your proposals ! With over 8000 participants, FOSDEM is the perfect place to share your story and meet fellow Python enthusiasts. Please head over to https://python-fosdem.org/call-for-proposals/ for the full information about FOSDEM, the CFP and the Devroom. Good luck to everyone applying. We?re looking forward to meeting you all at FOSDEM 2024 ! Cheers, -- Eric Gazoni and Marc-Andre Lemburg From avi.e.gross at gmail.com Fri Nov 24 22:45:54 2023 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Fri, 24 Nov 2023 22:45:54 -0500 Subject: Newline (NuBe Question) In-Reply-To: <65561BDA.14413.9EACE9@RealGrizzlyAdams.vivaldi.net> References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net>, <6555B48F.10108.156EC1@RealGrizzlyAdams.vivaldi.net>, <4626640f-4fe5-49bc-a6f8-d555b7f7b58a@tompassin.net> <65561BDA.14413.9EACE9@RealGrizzlyAdams.vivaldi.net> Message-ID: <016601da1f51$e4e84410$aeb8cc30$@gmail.com> Grizz[l]y, I think the point is not about a sorted list or sorting in general It is about reasons why maintaining a data structure such as a list in a program can be useful beyond printing things once. There are many possible examples such as having a list of lists containing a record where the third item is a GPA for the student and writing a little list comprehension that selects a smaller list containing only students who are Magna Cum Laude or Summa Cum Laude. studs = [ ["Peter", 82, 3.53], ["Paul", 77, 2.83], ["Mary", 103, 3.82] ] magna = [stud for stud in studs if stud[2] >= 3.5 ] summa = [stud for stud in studs if stud[2] >= 3.75 ] print(studs, magna, summa, sep="\n") OUTPUT: >>> print(studs, magna, summa, sep="\n") [['Peter', 82, 3.53], ['Paul', 77, 2.83], ['Mary', 103, 3.82]] [['Peter', 82, 3.53], ['Mary', 103, 3.82]] [['Mary', 103, 3.82]] Of course, for serious work, some might suggest avoiding constructs like a list of lists and switch to using modules and data structures that are often more efficient to represent your data such as some form of matrix or data.frame. And, yes, you can sort something like the above by name or GPA or number of credits taken but the point was responding to why bother making a list just to print it. The answer is that many and even most programs do a bit more than that and a good choice of data structure facilitates ... -----Original Message----- From: Python-list On Behalf Of Grizzy Adams via Python-list Sent: Thursday, November 16, 2023 8:41 AM To: python-list at python.org Subject: Re: Newline (NuBe Question) Thursday, November 16, 2023 at 7:47, Thomas Passin via Python-list wrote: Re: Newline (NuBe Question) (at least in part) >I wrote that you don't need the "students" list, which is correct. But >there could be a use for a list. It would let you change the order in >which students appear in the printed output. Knowing how to do that is >a useful skill. But that should be left for a later lesson, not mixed >in here. I have a vague memory of seeing sorted list somewhere ;->) -- https://mail.python.org/mailman/listinfo/python-list From loris.bennett at fu-berlin.de Fri Nov 24 09:31:20 2023 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Fri, 24 Nov 2023 15:31:20 +0100 Subject: Printing dict value for possibly undefined key Message-ID: <87msv34407.fsf@zedat.fu-berlin.de> Hi, I want to print some records from a database table where one of the fields contains a JSON string which is read into a dict. I am doing something like print(f"{id} {d['foo']} {d['bar']}") However, the dict does not always have the same keys, so d['foo'] or d['bar'] may be undefined. I can obviously do something like if not 'foo' in d: d['foo']="NULL" if not 'bar' in d: d['bar']="NULL" print(f"{id} {d['foo']} {d['bar']}") Is there any more compact way of achieving the same thing? Cheers, Loris -- This signature is currently under constuction. From duncan at invalid.invalid Fri Nov 24 11:35:14 2023 From: duncan at invalid.invalid (duncan smith) Date: Fri, 24 Nov 2023 16:35:14 +0000 Subject: Printing dict value for possibly undefined key In-Reply-To: <87msv34407.fsf@zedat.fu-berlin.de> References: <87msv34407.fsf@zedat.fu-berlin.de> Message-ID: <6h48N.18969$_z86.2637@fx46.iad> On 24/11/2023 14:31, Loris Bennett wrote: > Hi, > > I want to print some records from a database table where one of the > fields contains a JSON string which is read into a dict. I am doing > something like > > print(f"{id} {d['foo']} {d['bar']}") > > However, the dict does not always have the same keys, so d['foo'] or > d['bar'] may be undefined. I can obviously do something like > > if not 'foo' in d: > d['foo']="NULL" > if not 'bar' in d: > d['bar']="NULL" > print(f"{id} {d['foo']} {d['bar']}") > > Is there any more compact way of achieving the same thing? > > Cheers, > > Loris > Yes. e.g. d.get('foo', "NULL") Duncan From duncan at invalid.invalid Fri Nov 24 11:54:53 2023 From: duncan at invalid.invalid (duncan smith) Date: Fri, 24 Nov 2023 16:54:53 +0000 Subject: Printing dict value for possibly undefined key In-Reply-To: <6h48N.18969$_z86.2637@fx46.iad> References: <87msv34407.fsf@zedat.fu-berlin.de> <6h48N.18969$_z86.2637@fx46.iad> Message-ID: On 24/11/2023 16:35, duncan smith wrote: > On 24/11/2023 14:31, Loris Bennett wrote: >> Hi, >> >> I want to print some records from a database table where one of the >> fields contains a JSON string which is read into a dict.? I am doing >> something like >> >> ?? print(f"{id} {d['foo']} {d['bar']}") >> >> However, the dict does not always have the same keys, so d['foo'] or >> d['bar'] may be undefined.? I can obviously do something like >> >> ?? if not 'foo' in d: >> ???? d['foo']="NULL" >> ?? if not 'bar' in d: >> ???? d['bar']="NULL" >> ?? print(f"{id} {d['foo']} {d['bar']}") >> >> Is there any more compact way of achieving the same thing? >> >> Cheers, >> >> Loris >> > > Yes. e.g. > > d.get('foo', "NULL") > > Duncan Or make d a defaultdict. from collections import defaultdict dic = defaultdict(lambda:'NULL') dic['foo'] = 'astring' dic['foo'] 'astring' dic['bar'] 'NULL' Duncan From cl at isbd.net Fri Nov 24 15:49:20 2023 From: cl at isbd.net (Chris Green) Date: Fri, 24 Nov 2023 20:49:20 +0000 Subject: Silly/crazy problem with sqlite Message-ID: This is driving me crazy, I'm running this code:- #!/usr/bin/env python3 # # # Show the electric fence history, default to last 24 hours # import sqlite3 import datetime import sys today = datetime.datetime.now() today = str(today) x = str(today[0:10]) print(x) fdb = sqlite3.connect("/home/chris/.share/newbourne.db") cr = fdb.cursor() sql = "SELECT * FROM fence where datetime LIKE ?" cr.execute(sql, ('%' + "2023-11" + '%')) rv = cr.fetchall() for d in rv: print(d) fdb.commit() fdb.close() Forget about the 'today =' bits, they no longer do anything. When I run the above I get:- chris at esprimo$ fence.py 2023-11-24 Traceback (most recent call last): File "/home/chris/dev/bin/fence.py", line 19, in cr.execute(sql, ('%' + "2023-11" + '%')) sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 9 supplied. chris at esprimo$ It's treating the "2023-11" plus % at each end as separate variables to the binding, this is crazy! I've done similar elsewhere and it works OK, what on earth am I doing wrong here? It has to be something very silly but I can't see it at the moment. -- Chris Green ? From cl at isbd.net Fri Nov 24 16:10:08 2023 From: cl at isbd.net (Chris Green) Date: Fri, 24 Nov 2023 21:10:08 +0000 Subject: Silly/crazy problem with sqlite References: Message-ID: Chris Green wrote: > This is driving me crazy, I'm running this code:- OK, I've found what's wrong:- > cr.execute(sql, ('%' + "2023-11" + '%')) should be:- cr.execute(sql, ('%' + x + '%',) ) I have to say this seems very non-pythonesque to me, the 'obvious' default simply doesn't work right, and I really can't think of a case where the missing comma would make any sense at all. Maybe I've had too much to eat and drink tonight! :-) -- Chris Green ? From rimuatkinson+usenet at gmail.com Fri Nov 24 16:49:06 2023 From: rimuatkinson+usenet at gmail.com (Rimu Atkinson) Date: Sat, 25 Nov 2023 10:49:06 +1300 Subject: Silly/crazy problem with sqlite In-Reply-To: References: Message-ID: > > I really can't think of a case > where the missing comma would make any sense at all. > That is pretty tricky, yes. The comma means it's a tuple. Without the comma, it's just a string with parenthesis around it, which is a string. PyDev console: starting. Python 3.9.15 (main, Oct 28 2022, 17:28:38) [GCC] on linux x = ('%' + "2023-11" + '%') x '%2023-11%' x = ('%' + x + '%',) x ('%%2023-11%%',) x.__class__.__name__ 'tuple' From nulla.epistola at web.de Sat Nov 25 08:34:37 2023 From: nulla.epistola at web.de (Sibylle Koczian) Date: Sat, 25 Nov 2023 14:34:37 +0100 Subject: Silly/crazy problem with sqlite In-Reply-To: References: Message-ID: <102cbeeb-b1cc-4711-886c-cc644d20c707@web.de> Am 24.11.2023 um 22:49 schrieb Rimu Atkinson via Python-list: > >> > >> I really can't think of a case >> where the missing comma would make any sense at all. >> > > That is pretty tricky, yes. > > The comma means it's a tuple. Without the comma, it's just a string with > parenthesis around it, which is a string. > Placeholders for the parameters in an SQL command for sqlite3.execute(..) must always be given as dict or sequence. Even if it's just one parameter. Same thing with other database modules, it's given in PEP 249. HTH Sibylle From mats at wichmann.us Sat Nov 25 14:32:30 2023 From: mats at wichmann.us (Mats Wichmann) Date: Sat, 25 Nov 2023 12:32:30 -0700 Subject: Silly/crazy problem with sqlite In-Reply-To: References: Message-ID: <19639faf-1a73-4548-ac60-04f7a858dd47@wichmann.us> On 11/24/23 14:10, Chris Green via Python-list wrote: > Chris Green wrote: >> This is driving me crazy, I'm running this code:- > > OK, I've found what's wrong:- > >> cr.execute(sql, ('%' + "2023-11" + '%')) > > should be:- > > cr.execute(sql, ('%' + x + '%',) ) > > > I have to say this seems very non-pythonesque to me, the 'obvious' > default simply doesn't work right, and I really can't think of a case > where the missing comma would make any sense at all. as noted, the comma makes it a tuple. this might be a case where rewriting as an f-string makes it just a little more readable, since the syntax will make it look like there's a single string followed by a comma - the addition just makes it look less clear to my eyes: cr.execute(sql, (f'%2023-11%', )) cr.execute(sql, (f'%{x}%', )) From PythonList at DancesWithMice.info Sat Nov 25 14:43:48 2023 From: PythonList at DancesWithMice.info (DL Neil) Date: Sun, 26 Nov 2023 08:43:48 +1300 Subject: Printing dict value for possibly undefined key In-Reply-To: <87msv34407.fsf@zedat.fu-berlin.de> References: <87msv34407.fsf@zedat.fu-berlin.de> Message-ID: <6372e983-0636-4cf3-98d5-164944f65419@DancesWithMice.info> On 11/25/2023 3:31 AM, Loris Bennett via Python-list wrote: > Hi, > > I want to print some records from a database table where one of the > fields contains a JSON string which is read into a dict. I am doing > something like > > print(f"{id} {d['foo']} {d['bar']}") > > However, the dict does not always have the same keys, so d['foo'] or > d['bar'] may be undefined. I can obviously do something like > > if not 'foo' in d: > d['foo']="NULL" > if not 'bar' in d: > d['bar']="NULL" > print(f"{id} {d['foo']} {d['bar']}") > > Is there any more compact way of achieving the same thing? What does "the dict does not always have the same keys" mean? a) there are two (or...) keys, but some records don't include both; b) there may be keys other than 'foo' and 'bar' which not-known in-advance; c) something else. As mentioned, dict.get() solves one of these. Otherwise, there are dict methods which collect/reveal all the keys, all the values, or both - dict.keys(), .values(), .items(), resp. -- Regards =dn From list1 at tompassin.net Sat Nov 25 18:40:58 2023 From: list1 at tompassin.net (Thomas Passin) Date: Sat, 25 Nov 2023 18:40:58 -0500 Subject: Silly/crazy problem with sqlite In-Reply-To: References: Message-ID: On 11/24/2023 4:49 PM, Rimu Atkinson via Python-list wrote: > >> > >> I really can't think of a case >> where the missing comma would make any sense at all. >> > > That is pretty tricky, yes. > > The comma means it's a tuple. Without the comma, it's just a string with > parenthesis around it, which is a string. > > PyDev console: starting. > Python 3.9.15 (main, Oct 28 2022, 17:28:38) [GCC] on linux > x = ('%' + "2023-11" + '%') > x > '%2023-11%' > x = ('%' +? x + '%',) > x > ('%%2023-11%%',) > x.__class__.__name__ > 'tuple' To make it very clear in your code so that you are reminded next time you want to re-use it, you could write param = '%2023-11%' cr.execute(sql, (param,)) Probably the param value will actually use a variable instead of the hard-coded value in the example. So use an f-string, because it's more readable and easier to get right: date = ... # Where ever the actual date value comes from param = f'%{date}%' cr.execute(sql, (param,)) From michael.stemper at gmail.com Sat Nov 25 09:32:24 2023 From: michael.stemper at gmail.com (Michael F. Stemper) Date: Sat, 25 Nov 2023 08:32:24 -0600 Subject: Newline (NuBe Question) In-Reply-To: References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> <6555B48F.10108.156EC1@RealGrizzlyAdams.vivaldi.net> <4626640f-4fe5-49bc-a6f8-d555b7f7b58a@tompassin.net> <65561BDA.14413.9EACE9@RealGrizzlyAdams.vivaldi.net> <016601da1f51$e4e84410$aeb8cc30$@gmail.com> Message-ID: On 24/11/2023 21.45, avi.e.gross at gmail.com wrote: > Grizz[l]y, > > I think the point is not about a sorted list or sorting in general It is > about reasons why maintaining a data structure such as a list in a program > can be useful beyond printing things once. There are many possible examples > such as having a list of lists containing a record where the third item is a > GPA for the student and writing a little list comprehension that selects a > smaller list containing only students who are Magna Cum Laude or Summa Cum > Laude. > > studs = [ > ["Peter", 82, 3.53], > ["Paul", 77, 2.83], > ["Mary", 103, 3.82] > ] I've seen Mary, and she didn't look like a "stud" to me. > Of course, for serious work, some might suggest avoiding constructs like a > list of lists and switch to using modules and data structures [...] Those who would recommend that approach do not appear to include Mr. Rossum, who said: Avoid overengineering data structures. Tuples are better than objects (try namedtuple too though). Prefer simple fields over getter/setter functions... Built-in datatypes are your friends. Use more numbers, strings, tuples, lists, sets, dicts. Also check out the collections library, eps. deque.[1] I was nodding along with the people saying "list of lists" until I reread this quote. A list of tuples seems most appropriate to me. [1] , as quoted by Bill Lubanovic in _Introducing Python_ -- Michael F. Stemper This sentence no verb. From cl at isbd.net Sat Nov 25 10:01:26 2023 From: cl at isbd.net (Chris Green) Date: Sat, 25 Nov 2023 15:01:26 +0000 Subject: Silly/crazy problem with sqlite References: Message-ID: <6re93k-bfu53.ln1@esprimo.zbmc.eu> Stefan Ram wrote: > Chris Green writes: > >I have to say this seems very non-pythonesque to me, the 'obvious' > >default simply doesn't work right, and I really can't think of a case > >where the missing comma would make any sense at all. > > |6.15 Expression lists > ... > |an expression list containing at least one comma yields a tuple. > ... > The Python Language Reference, Release 3.13.0a0; > Guido van Rossum and the Python development team; > October 10, 2023. > I wasn't meaning that it wasn't correct Python, more that doing the obvious doesn't work which, in Python, it usually does in my experience. The error message could be a bit more helpful too, maybe one of those "... did you mean ....?" ones could point one in the right direction. -- Chris Green ? From piergiorgio.sartor.this.should.not.be.used at nexgo.REMOVETHIS.de Sat Nov 25 16:15:58 2023 From: piergiorgio.sartor.this.should.not.be.used at nexgo.REMOVETHIS.de (Piergiorgio Sartor) Date: Sat, 25 Nov 2023 22:15:58 +0100 Subject: Context without manager Message-ID: Hi all, I apologize in advance for the "foggy" question, but I've myself unclear ideas. Anyway... Python has "context manager". For example, the "open()" class can be simply used as follow: with open(...) as fp: fp.do_something() On the other hand, it is also possible to do: fp = open() fp.do_something() fp.close() Now, if we want to use "open()" in a class, it would be possible to apply the second variant, with "self.fp = open()" in "__init__(...)", "self.fp.close()" maybe in "__del__(...)" and having few methods doing this and that with the "self.fp". Apparently, the "with" context manager is not usable in classes, at least not with __init__() & co. It seems there are classes ("gradio.Blocks()", for example) which are *only* usable with context manager. I found more... One way to do the same as in "open()" is: def __init__(...): fp = open(...) fp.__enter__() ... def __del__(...): fp.__exit__() fp.close() This works, but it seems quite ugly. I could not find any other way, in case the class do only support context manager. Question: is there any other way to use a context manager only object within a class, with methods accessing the object? Or any other solution to the same situation? Thanks a lot in advance. P.S.: currently gmail posts are deleted, due to excessive spam, so I'll not see any reply coming from this family of addresses. bye, -- piergiorgio From rosuav at gmail.com Sun Nov 26 06:48:49 2023 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 26 Nov 2023 22:48:49 +1100 Subject: Newline (NuBe Question) In-Reply-To: References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> <6555B48F.10108.156EC1@RealGrizzlyAdams.vivaldi.net> <4626640f-4fe5-49bc-a6f8-d555b7f7b58a@tompassin.net> <65561BDA.14413.9EACE9@RealGrizzlyAdams.vivaldi.net> <016601da1f51$e4e84410$aeb8cc30$@gmail.com> Message-ID: On Sun, 26 Nov 2023 at 21:08, Michael F. Stemper via Python-list wrote: > > On 24/11/2023 21.45, avi.e.gross at gmail.com wrote: > > Grizz[l]y, > > > > I think the point is not about a sorted list or sorting in general It is > > about reasons why maintaining a data structure such as a list in a program > > can be useful beyond printing things once. There are many possible examples > > such as having a list of lists containing a record where the third item is a > > GPA for the student and writing a little list comprehension that selects a > > smaller list containing only students who are Magna Cum Laude or Summa Cum > > Laude. > > > > studs = [ > > ["Peter", 82, 3.53], > > ["Paul", 77, 2.83], > > ["Mary", 103, 3.82] > > ] > > I've seen Mary, and she didn't look like a "stud" to me. > That's what happens when you abbreviate "student" though :) Don't worry, there's far FAR worse around the place, and juvenile brains will always find things to snigger at, usually in mathematical libraries with "cumulative" functions. ChrisA From roel at roelschroeven.net Sun Nov 26 07:08:09 2023 From: roel at roelschroeven.net (Roel Schroeven) Date: Sun, 26 Nov 2023 13:08:09 +0100 Subject: Newline (NuBe Question) In-Reply-To: References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> <6555B48F.10108.156EC1@RealGrizzlyAdams.vivaldi.net> <4626640f-4fe5-49bc-a6f8-d555b7f7b58a@tompassin.net> <65561BDA.14413.9EACE9@RealGrizzlyAdams.vivaldi.net> <016601da1f51$e4e84410$aeb8cc30$@gmail.com> Message-ID: <9971c210-f777-41ea-b3b8-a3a429c65882@roelschroeven.net> Michael F. Stemper via Python-list schreef op 25/11/2023 om 15:32: > On 24/11/2023 21.45,avi.e.gross at gmail.com wrote: > > Grizz[l]y, > > > > I think the point is not about a sorted list or sorting in general It is > > about reasons why maintaining a data structure such as a list in a program > > can be useful beyond printing things once. There are many possible examples > > such as having a list of lists containing a record where the third item is a > > GPA for the student and writing a little list comprehension that selects a > > smaller list containing only students who are Magna Cum Laude or Summa Cum > > Laude. > > > > studs = [ > > ["Peter", 82, 3.53], > > ["Paul", 77, 2.83], > > ["Mary", 103, 3.82] > > ] > > > Of course, for serious work, some might suggest avoiding constructs like a > > list of lists and switch to using modules and data structures [...] > > Those who would recommend that approach do not appear to include Mr. > Rossum, who said: > > Avoid overengineering data structures. Tuples are better than > objects (try namedtuple too though). Prefer simple fields over > getter/setter functions... Built-in datatypes are your friends. > Use more numbers, strings, tuples, lists, sets, dicts. Also > check out the collections library, eps. deque.[1] > > I was nodding along with the people saying "list of lists" until I > reread this quote. A list of tuples seems most appropriate to me. I prefer namedtuples or dataclasses over tuples. They allow you to refer to their fields by name instead of index: student.gpa is much clearer than student[2], and makes it less likely to accidentally refer to the wrong field. -- "Man had always assumed that he was more intelligent than dolphins because he had achieved so much ? the wheel, New York, wars and so on ? whilst all the dolphins had ever done was muck about in the water having a good time. But conversely, the dolphins had always believed that they were far more intelligent than man ? for precisely the same reasons." -- Douglas Adams From dieter at handshake.de Sun Nov 26 12:50:38 2023 From: dieter at handshake.de (Dieter Maurer) Date: Sun, 26 Nov 2023 18:50:38 +0100 Subject: Context without manager In-Reply-To: References: Message-ID: <25955.34158.142219.335334@ixdm.fritz.box> Piergiorgio Sartor wrote at 2023-11-25 22:15 +0100: > ... >Apparently, the "with" context manager is not usable >in classes, at least not with __init__() & co. You can use `with` in classes -- with any context manager. However, you would usually not use `with` with a file you have opened in `__init__`. If a class defines `__enter__` and `__exit__` (i.e. the "cntext manager protocol"), then its instances can be used with the `with` statement. The important use case for a context manager is the situation: set up a context (--> method `__enter__`) perform some operations in this context (--> body of `with` statement) tear down the context (--> method `__exit__`). If you do not have this case (e.g. usually if you open the file in a class's `__init__`), you do not use a context manager. From avi.e.gross at gmail.com Sun Nov 26 14:06:37 2023 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Sun, 26 Nov 2023 14:06:37 -0500 Subject: Newline (NuBe Question) In-Reply-To: References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> <6555B48F.10108.156EC1@RealGrizzlyAdams.vivaldi.net> <4626640f-4fe5-49bc-a6f8-d555b7f7b58a@tompassin.net> <65561BDA.14413.9EACE9@RealGrizzlyAdams.vivaldi.net> <016601da1f51$e4e84410$aeb8cc30$@gmail.com> Message-ID: <003901da209b$aed7d110$0c877330$@gmail.com> That is an entirely different discussion, Michael. I do not know what ideas Guido had ages ago and where he might stand now and I actually seriously disagree with the snippet you quoted below. Python was started long ago as a way to improve in some ways on what was there before. Some of the ideas were nice but also for some purposes, way too slow. If you regard the original versions of LISP, they too simplicity to an extreme and pretty much the main or even only data structure was a list. Functions like CAR and CDR accessed an element but a complex structure resulted in people creating functions with names like CAAAAAR and CADADADR to automate climbing a tree of sorts to get to the parts you want. It was a recipe for complexity and errors. My point was that although a list can do so many things in principle, it is not really optimized to do some things that can be way easier using add-ons or your own data structures like objects and he notes the collection library and deque as an example that he is not as much of a purist as you may think. My point was that if you have a fairly detailed and complex application that will manipulate lots of data, then instead of reading in a CSV with many columns and rows recorded into a list of lists, it may make sense to import numpy and pandas that come with all kinds of functionality built in so you do not need to re-invent everything. Just how easy is it using lists of lists to rearrange the order of columns of data, or add new columns containing calculations built from existing columns and so on? Of course, for many purposes, it is indeed overkill albeit once you learn a method, ... I think part of the design of Python, and this is just my guess, included going away from overly specific things done in earlier compiled languages and making it more abstract and inclusive. Arrays or vectors or other such names would normally require everything to be of the same data type and with a fixed length. The list data structure loosened this up quite a bit and also allowed lists within lists. That is great and for some purposes, not very efficient and especially not when your data actually is all of the same type or of fixed length. You can make matrix-like data structures of any depth using lists and it may be hard to traverse such as when you want to multiply two such 2-D matrices. Place the same data (all say floating point numbers) in a vector-like structure that also has stored info about the dimensions, and a simple mathematical calculation accesses any item such as may_tricks[5,42] in the same amount of time as an offset from the top. I have seen this phenomenon in many languages where a somewhat clean and sparse design gets added to, often by others, until some core features are used less often. An example would be R which does have lists nut they are just one form of vectors which are really more the core data idea. It also contains data.frames in the core which are implemented as a list of vectors and more recently a bit more. It was designed to do statistical tasks as one of the main objectives. Yet the graphics functions have been added to so there are by now quite a few independent ways to make graphics using different paradigms. Python also has something like that. And completely new paradigms such as piping data in a chain were added in packages and it became so popular that a version has been added to the core language. Now although the core language includes lots of the functionality you might see in numpy/pandas and you can do all kinds of things, some others kept creating new ways to do things including different data structures that either dealt with weaknesses found or were ore efficient and so on and an entire growing body of alternate ways to do things with lots more power and often more speed that I prefer. A collection of lots of these alternative packages has been assembled and I and others often simply start programs by including the "tidyverse" and the resulting programs might as well be written in a different language to anyone who only knows base R. But I do not see that as a bad thing albeit someone trying to get a part of a program from an AI-like service may need to specify or they may get code they cannot trivially read and evaluate but that works fine once they have loaded the packages. Guido is like many others who create or invent and do it in the way they are proud of. Why change it? But the reality is that first attempts are often done with lots of room for change and improvement. Now if you are teaching a course on Python basics, it may be a good idea to teach the basics and require students to only use in their homework what has already been taught. But if you get a job where the norm is to use modules like numpy, it makes sense to use the expanded language if it results in faster writing perhaps of faster code with fewer mistakes. -----Original Message----- From: Python-list On Behalf Of Michael F. Stemper via Python-list Sent: Saturday, November 25, 2023 9:32 AM To: python-list at python.org Subject: Re: RE: Newline (NuBe Question) On 24/11/2023 21.45, avi.e.gross at gmail.com wrote: > Grizz[l]y, > > I think the point is not about a sorted list or sorting in general It is > about reasons why maintaining a data structure such as a list in a program > can be useful beyond printing things once. There are many possible examples > such as having a list of lists containing a record where the third item is a > GPA for the student and writing a little list comprehension that selects a > smaller list containing only students who are Magna Cum Laude or Summa Cum > Laude. > > studs = [ > ["Peter", 82, 3.53], > ["Paul", 77, 2.83], > ["Mary", 103, 3.82] > ] I've seen Mary, and she didn't look like a "stud" to me. > Of course, for serious work, some might suggest avoiding constructs like a > list of lists and switch to using modules and data structures [...] Those who would recommend that approach do not appear to include Mr. Rossum, who said: Avoid overengineering data structures. Tuples are better than objects (try namedtuple too though). Prefer simple fields over getter/setter functions... Built-in datatypes are your friends. Use more numbers, strings, tuples, lists, sets, dicts. Also check out the collections library, eps. deque.[1] I was nodding along with the people saying "list of lists" until I reread this quote. A list of tuples seems most appropriate to me. [1] , as quoted by Bill Lubanovic in _Introducing Python_ -- Michael F. Stemper This sentence no verb. -- https://mail.python.org/mailman/listinfo/python-list From avi.e.gross at gmail.com Sun Nov 26 14:15:13 2023 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Sun, 26 Nov 2023 14:15:13 -0500 Subject: Newline (NuBe Question) In-Reply-To: References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> <6555B48F.10108.156EC1@RealGrizzlyAdams.vivaldi.net> <4626640f-4fe5-49bc-a6f8-d555b7f7b58a@tompassin.net> <65561BDA.14413.9EACE9@RealGrizzlyAdams.vivaldi.net> <016601da1f51$e4e84410$aeb8cc30$@gmail.com> Message-ID: <005201da209c$e1bb0c90$a53125b0$@gmail.com> Just FYI, I deliberately chose that abbreviation for a sort of irony as for some people college is about almost anything except learning and some people think they are studs and just party and ... And I am very tired of gender discussions. Lots of words now include two or even more genders. Women are often now "actors", not actresses. I see no reason women cannot be studs! But I learn from criticism. If I ever write a program like that and do not feel like typing, will this do? dents = [ ...] Or will that not include students who happen to be edentulous? -----Original Message----- From: Python-list On Behalf Of Chris Angelico via Python-list Sent: Sunday, November 26, 2023 6:49 AM To: python-list at python.org Subject: Re: RE: Newline (NuBe Question) On Sun, 26 Nov 2023 at 21:08, Michael F. Stemper via Python-list wrote: > > On 24/11/2023 21.45, avi.e.gross at gmail.com wrote: > > Grizz[l]y, > > > > I think the point is not about a sorted list or sorting in general It is > > about reasons why maintaining a data structure such as a list in a program > > can be useful beyond printing things once. There are many possible examples > > such as having a list of lists containing a record where the third item is a > > GPA for the student and writing a little list comprehension that selects a > > smaller list containing only students who are Magna Cum Laude or Summa Cum > > Laude. > > > > studs = [ > > ["Peter", 82, 3.53], > > ["Paul", 77, 2.83], > > ["Mary", 103, 3.82] > > ] > > I've seen Mary, and she didn't look like a "stud" to me. > That's what happens when you abbreviate "student" though :) Don't worry, there's far FAR worse around the place, and juvenile brains will always find things to snigger at, usually in mathematical libraries with "cumulative" functions. ChrisA -- https://mail.python.org/mailman/listinfo/python-list From hjp-python at hjp.at Sun Nov 26 16:04:09 2023 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sun, 26 Nov 2023 22:04:09 +0100 Subject: Newline (NuBe Question) In-Reply-To: References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> <6555B48F.10108.156EC1@RealGrizzlyAdams.vivaldi.net> <4626640f-4fe5-49bc-a6f8-d555b7f7b58a@tompassin.net> <65561BDA.14413.9EACE9@RealGrizzlyAdams.vivaldi.net> <016601da1f51$e4e84410$aeb8cc30$@gmail.com> Message-ID: <20231126210409.wbcdjkuxmwh7l23q@hjp.at> On 2023-11-25 08:32:24 -0600, Michael F. Stemper via Python-list wrote: > On 24/11/2023 21.45, avi.e.gross at gmail.com wrote: > > Of course, for serious work, some might suggest avoiding constructs like a > > list of lists and switch to using modules and data structures [...] > > Those who would recommend that approach do not appear to include Mr. > Rossum, who said: > Avoid overengineering data structures. ^^^^^^^^^^^^^^^ The key point here is *over*engineering. Don't make things more complicated than they need to be. But also don't make them simpler than necessary. > Tuples are better than objects (try namedtuple too though). If Guido thought that tuples would always be better than objects, then Python wouldn't have objects. Why would he add such a complicated feature to the language if he thought it was useless? The (unspoken?) context here is "if tuples are sufficient, then ..." 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 PythonList at danceswithmice.info Sun Nov 26 16:58:08 2023 From: PythonList at danceswithmice.info (DL Neil) Date: Mon, 27 Nov 2023 10:58:08 +1300 Subject: Newline (NuBe Question) In-Reply-To: References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> <6555B48F.10108.156EC1@RealGrizzlyAdams.vivaldi.net> <4626640f-4fe5-49bc-a6f8-d555b7f7b58a@tompassin.net> <65561BDA.14413.9EACE9@RealGrizzlyAdams.vivaldi.net> <016601da1f51$e4e84410$aeb8cc30$@gmail.com> Message-ID: <765911b5-b673-4d3b-b7e4-3bd0ea94bf3d@danceswithmice.info> On 11/27/2023 12:48 AM, Chris Angelico via Python-list wrote: > On Sun, 26 Nov 2023 at 21:08, Michael F. Stemper via Python-list > wrote: >> >> On 24/11/2023 21.45, avi.e.gross at gmail.com wrote: >>> Grizz[l]y, >>> >>> I think the point is not about a sorted list or sorting in general It is >>> about reasons why maintaining a data structure such as a list in a program >>> can be useful beyond printing things once. There are many possible examples >>> such as having a list of lists containing a record where the third item is a >>> GPA for the student and writing a little list comprehension that selects a >>> smaller list containing only students who are Magna Cum Laude or Summa Cum >>> Laude. >>> >>> studs = [ >>> ["Peter", 82, 3.53], >>> ["Paul", 77, 2.83], >>> ["Mary", 103, 3.82] >>> ] >> >> I've seen Mary, and she didn't look like a "stud" to me. >> > > That's what happens when you abbreviate "student" though :) Don't > worry, there's far FAR worse around the place, and juvenile brains > will always find things to snigger at, usually in mathematical > libraries with "cumulative" functions. The OP used an abbreviation: "studs". Why? Too lazy to type the full word? Abbreviation has full-meaning in the (narrow) domain? Was wanting something funny, or to snigger over? Was the respondent sniggering? Perhaps he, like the OP, was also saving typing-time by making a joke, hoping that the OP would see the implicit-error in expecting others to understand that "studs" meant "students"? Actually, Peter, Paul, and Mary were a band (https://www.peterpaulandmary.com/), so "studs" is even less expressive when the data also tells a story... Working with "trainees", I avoid the word "student" even though some might see them as synonyms. In my mind, the abbreviation did not readily expand to the full word (mea culpa). Accordingly, would not pass Code Review! For the want of a few characters... (https://en.wikipedia.org/wiki/For_Want_of_a_Nail) -- Regards =dn From rosuav at gmail.com Sun Nov 26 16:58:21 2023 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 27 Nov 2023 08:58:21 +1100 Subject: Newline (NuBe Question) In-Reply-To: <005201da209c$e1bb0c90$a53125b0$@gmail.com> References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> <6555B48F.10108.156EC1@RealGrizzlyAdams.vivaldi.net> <4626640f-4fe5-49bc-a6f8-d555b7f7b58a@tompassin.net> <65561BDA.14413.9EACE9@RealGrizzlyAdams.vivaldi.net> <016601da1f51$e4e84410$aeb8cc30$@gmail.com> <005201da209c$e1bb0c90$a53125b0$@gmail.com> Message-ID: On Mon, 27 Nov 2023 at 06:15, wrote: > But I learn from criticism. If I ever write a program like that and do not > feel like typing, will this do? > > dents = [ ...] > > Or will that not include students who happen to be edentulous? > If they're learning to drive, this variable name would make complete sense. ChrisA From PythonList at danceswithmice.info Sun Nov 26 17:01:51 2023 From: PythonList at danceswithmice.info (DL Neil) Date: Mon, 27 Nov 2023 11:01:51 +1300 Subject: Newline (NuBe Question) In-Reply-To: <9971c210-f777-41ea-b3b8-a3a429c65882@roelschroeven.net> References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> <6555B48F.10108.156EC1@RealGrizzlyAdams.vivaldi.net> <4626640f-4fe5-49bc-a6f8-d555b7f7b58a@tompassin.net> <65561BDA.14413.9EACE9@RealGrizzlyAdams.vivaldi.net> <016601da1f51$e4e84410$aeb8cc30$@gmail.com> <9971c210-f777-41ea-b3b8-a3a429c65882@roelschroeven.net> Message-ID: On 11/27/2023 1:08 AM, Roel Schroeven via Python-list wrote: > I prefer namedtuples or dataclasses over tuples. They allow you to refer > to their fields by name instead of index: student.gpa is much clearer > than student[2], and makes it less likely to accidentally refer to the > wrong field. +1 readability/comprehension! -- Regards =dn From PythonList at danceswithmice.info Sun Nov 26 17:19:28 2023 From: PythonList at danceswithmice.info (DL Neil) Date: Mon, 27 Nov 2023 11:19:28 +1300 Subject: Newline (NuBe Question) In-Reply-To: <20231126210409.wbcdjkuxmwh7l23q@hjp.at> References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> <6555B48F.10108.156EC1@RealGrizzlyAdams.vivaldi.net> <4626640f-4fe5-49bc-a6f8-d555b7f7b58a@tompassin.net> <65561BDA.14413.9EACE9@RealGrizzlyAdams.vivaldi.net> <016601da1f51$e4e84410$aeb8cc30$@gmail.com> <20231126210409.wbcdjkuxmwh7l23q@hjp.at> Message-ID: <91044403-9584-4161-a490-7cac3d8310a7@danceswithmice.info> On 11/27/2023 10:04 AM, Peter J. Holzer via Python-list wrote: > On 2023-11-25 08:32:24 -0600, Michael F. Stemper via Python-list wrote: >> On 24/11/2023 21.45, avi.e.gross at gmail.com wrote: >>> Of course, for serious work, some might suggest avoiding constructs like a >>> list of lists and switch to using modules and data structures [...] >> >> Those who would recommend that approach do not appear to include Mr. >> Rossum, who said: >> Avoid overengineering data structures. > ^^^^^^^^^^^^^^^ > > The key point here is *over*engineering. Don't make things more > complicated than they need to be. But also don't make them simpler than > necessary. > >> Tuples are better than objects (try namedtuple too though). > > If Guido thought that tuples would always be better than objects, then > Python wouldn't have objects. Why would he add such a complicated > feature to the language if he thought it was useless? > > The (unspoken?) context here is "if tuples are sufficient, then ..." At recent PUG-meetings I've listened to a colleague asking questions and conducting research on Python data-structures*, eg lists-of-lists cf lists-of-tuples, etc, etc. The "etc, etc" goes on for some time! Respecting the effort, even as it becomes boringly-detailed, am encouraging him to publish his findings. * sadly, he is resistant to OOP and included only a cursory look at custom-objects, and early in the process. His 'new thinking' has been to look at in-core databases and the speed-ups SQL (or other) might offer... However, his motivation came from a particular application, and to create a naming-system so that he could distinguish a list-of-lists structure from some other tabular abstraction. The latter enables the code to change data-format to speed the next process, without the coder losing-track of the data-type/format. The trouble is, whereas the research reveals which is faster (in-isolation, and (only) on his 'platform'), my suspicion is that he loses all gains by reformatting the data between 'the most efficient' structure for each step. A problem of only looking at the 'micro', whilst ignoring wider/macro concerns. Accordingly, as to the word "engineering" (above), a reminder that we work in two domains: code and data. The short 'toy examples' in training courses discourage us from a design-stage for the former - until we enter 'the real world' and meet a problem/solution too large to fit in a single human-brain. Sadly, too many of us are pre-disposed to be math/algorithmically-oriented, and thus data-design is rarely-considered (in the macro!). Yet, here we are... -- Regards =dn From avi.e.gross at gmail.com Sun Nov 26 21:50:54 2023 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Sun, 26 Nov 2023 21:50:54 -0500 Subject: Newline (NuBe Question) In-Reply-To: <765911b5-b673-4d3b-b7e4-3bd0ea94bf3d@danceswithmice.info> References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> <6555B48F.10108.156EC1@RealGrizzlyAdams.vivaldi.net> <4626640f-4fe5-49bc-a6f8-d555b7f7b58a@tompassin.net> <65561BDA.14413.9EACE9@RealGrizzlyAdams.vivaldi.net> <016601da1f51$e4e84410$aeb8cc30$@gmail.com> <765911b5-b673-4d3b-b7e4-3bd0ea94bf3d@danceswithmice.info> Message-ID: <008701da20dc$8a869260$9f93b720$@gmail.com> Isn't it fascinating that a meaningless piece of code used to illustrate something can be analyzed as if it was full of malicious content? Yes, my choice of names was as expected. The numbers chosen had no special meaning other than choosing one number in each of three equivalence classes. But, if you want me to add subtle meaning for generations to examine as it it were a literary work, I offer this: Peter and Paul were studs who got Mary'd. Can we now go back to our regularly scheduled talking about aspects of a computer language? P.S. And just for history, Paul was really Noel Paul Stookey but Peter, Paul & Mary sounded more like new testament characters and I think Noel signifies a birth to Peter and Mary, sort of, which might have fit too unless it was a computer program where a name with an umlaut was once not common. Another interpretation is that Noel came from the Latin word for news. Be that as it may, and I have no interest in this topic, in the future I may use the ever popular names of Primus, Secundus and Tertius and get blamed for using Latin. -----Original Message----- From: Python-list On Behalf Of DL Neil via Python-list Sent: Sunday, November 26, 2023 4:58 PM To: python-list at python.org Subject: Re: Newline (NuBe Question) On 11/27/2023 12:48 AM, Chris Angelico via Python-list wrote: > On Sun, 26 Nov 2023 at 21:08, Michael F. Stemper via Python-list > wrote: >> >> On 24/11/2023 21.45, avi.e.gross at gmail.com wrote: >>> Grizz[l]y, >>> >>> I think the point is not about a sorted list or sorting in general It is >>> about reasons why maintaining a data structure such as a list in a program >>> can be useful beyond printing things once. There are many possible examples >>> such as having a list of lists containing a record where the third item is a >>> GPA for the student and writing a little list comprehension that selects a >>> smaller list containing only students who are Magna Cum Laude or Summa Cum >>> Laude. >>> >>> studs = [ >>> ["Peter", 82, 3.53], >>> ["Paul", 77, 2.83], >>> ["Mary", 103, 3.82] >>> ] >> >> I've seen Mary, and she didn't look like a "stud" to me. >> > > That's what happens when you abbreviate "student" though :) Don't > worry, there's far FAR worse around the place, and juvenile brains > will always find things to snigger at, usually in mathematical > libraries with "cumulative" functions. The OP used an abbreviation: "studs". Why? Too lazy to type the full word? Abbreviation has full-meaning in the (narrow) domain? Was wanting something funny, or to snigger over? Was the respondent sniggering? Perhaps he, like the OP, was also saving typing-time by making a joke, hoping that the OP would see the implicit-error in expecting others to understand that "studs" meant "students"? Actually, Peter, Paul, and Mary were a band (https://www.peterpaulandmary.com/), so "studs" is even less expressive when the data also tells a story... Working with "trainees", I avoid the word "student" even though some might see them as synonyms. In my mind, the abbreviation did not readily expand to the full word (mea culpa). Accordingly, would not pass Code Review! For the want of a few characters... (https://en.wikipedia.org/wiki/For_Want_of_a_Nail) -- Regards =dn -- https://mail.python.org/mailman/listinfo/python-list From rosuav at gmail.com Sun Nov 26 22:01:17 2023 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 27 Nov 2023 14:01:17 +1100 Subject: Newline (NuBe Question) In-Reply-To: <008701da20dc$8a869260$9f93b720$@gmail.com> References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> <6555B48F.10108.156EC1@RealGrizzlyAdams.vivaldi.net> <4626640f-4fe5-49bc-a6f8-d555b7f7b58a@tompassin.net> <65561BDA.14413.9EACE9@RealGrizzlyAdams.vivaldi.net> <016601da1f51$e4e84410$aeb8cc30$@gmail.com> <765911b5-b673-4d3b-b7e4-3bd0ea94bf3d@danceswithmice.info> <008701da20dc$8a869260$9f93b720$@gmail.com> Message-ID: On Mon, 27 Nov 2023 at 13:52, AVI GROSS via Python-list wrote: > Be that as it > may, and I have no interest in this topic, in the future I may use the ever > popular names of Primus, Secundus and Tertius and get blamed for using > Latin. > Imperious Prima flashes forth her edict to "begin it". In gentler tone Secunda hopes there will be nonsense in it. While Tertia interrupts the tale not more than once a minute. ChrisA From avi.e.gross at gmail.com Sun Nov 26 22:15:35 2023 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Sun, 26 Nov 2023 22:15:35 -0500 Subject: Newline (NuBe Question) In-Reply-To: <91044403-9584-4161-a490-7cac3d8310a7@danceswithmice.info> References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> <6555B48F.10108.156EC1@RealGrizzlyAdams.vivaldi.net> <4626640f-4fe5-49bc-a6f8-d555b7f7b58a@tompassin.net> <65561BDA.14413.9EACE9@RealGrizzlyAdams.vivaldi.net> <016601da1f51$e4e84410$aeb8cc30$@gmail.com> <20231126210409.wbcdjkuxmwh7l23q@hjp.at> <91044403-9584-4161-a490-7cac3d8310a7@danceswithmice.info> Message-ID: <008d01da20df$fd06fb60$f714f220$@gmail.com> Dave, Back on a hopefully more serious note, I want to make a bit of an analogy with what happens when you save data in a format like a .CSV file. Often you have a choice of including a header line giving names to the resulting columns, or not. If you read in the data to some structure, often to some variation I would loosely call a data.frame or perhaps something like a matrix, then without headers you have to specify what you want positionally or create your own names for columns to use. If names are already there, your program can manipulate things by using the names and if they are well chosen, with no studs among them, the resulting code can be quite readable. More importantly, if the data being read changes and includes additional columns or in a different order, your original program may run fine as long as the names of the columns you care about remain the same. Positional programs can be positioned to fail in quite subtle ways if the positions no longer apply. As I see it, many situations where some aspects are variable are not ideal for naming. A dictionary is an example that is useful when you have no idea how many items with unknown keys may be present. You can iterate over the names that are there, or use techniques that detect and deal with keys from your list that are not present. Not using names/keys here might involve a longer list with lots of empty slots to designate missing items, This clearly is not great when the data present is sparse or when the number of items is not known in advance or cannot be maintained in the right order. There are many other situations with assorted tradeoffs and to insist on using lists/tuples exclusively would be silly but at the same time, if you are using a list to hold the real and imaginary parts of a complex number, or the X/Y[/Z] coordinates of a point where the order is almost universally accepted, then maybe it is not worth using a data structure more complex or derived as the use may be obvious. I do recall odd methods sometimes used way back when I programmed in C/C++ or similar languages when some method was used to declare small constants like: #define FIRSTNAME 1 #define LASTNAME 2 Or concepts like "const GPA = 3" And so on, so code asking for student_record[LASTNAME] would be a tad more readable and if the order of entries somehow were different, just redefine the constant. In some sense, some of the data structures we are discussing, under the hood, actually may do something very similar as they remap the name to a small integer offset. Others may do much more or be slower but often add value in other ways. A full-blown class may not just encapsulate the names of components of an object but verify the validity of the contents or do logging or any number of other things. Using a list or tuple does nothing else. So if you need nothing else, they are often suitable and sometimes even preferable. -----Original Message----- From: Python-list On Behalf Of DL Neil via Python-list Sent: Sunday, November 26, 2023 5:19 PM To: python-list at python.org Subject: Re: Newline (NuBe Question) On 11/27/2023 10:04 AM, Peter J. Holzer via Python-list wrote: > On 2023-11-25 08:32:24 -0600, Michael F. Stemper via Python-list wrote: >> On 24/11/2023 21.45, avi.e.gross at gmail.com wrote: >>> Of course, for serious work, some might suggest avoiding constructs like a >>> list of lists and switch to using modules and data structures [...] >> >> Those who would recommend that approach do not appear to include Mr. >> Rossum, who said: >> Avoid overengineering data structures. > ^^^^^^^^^^^^^^^ > > The key point here is *over*engineering. Don't make things more > complicated than they need to be. But also don't make them simpler than > necessary. > >> Tuples are better than objects (try namedtuple too though). > > If Guido thought that tuples would always be better than objects, then > Python wouldn't have objects. Why would he add such a complicated > feature to the language if he thought it was useless? > > The (unspoken?) context here is "if tuples are sufficient, then ..." At recent PUG-meetings I've listened to a colleague asking questions and conducting research on Python data-structures*, eg lists-of-lists cf lists-of-tuples, etc, etc. The "etc, etc" goes on for some time! Respecting the effort, even as it becomes boringly-detailed, am encouraging him to publish his findings. * sadly, he is resistant to OOP and included only a cursory look at custom-objects, and early in the process. His 'new thinking' has been to look at in-core databases and the speed-ups SQL (or other) might offer... However, his motivation came from a particular application, and to create a naming-system so that he could distinguish a list-of-lists structure from some other tabular abstraction. The latter enables the code to change data-format to speed the next process, without the coder losing-track of the data-type/format. The trouble is, whereas the research reveals which is faster (in-isolation, and (only) on his 'platform'), my suspicion is that he loses all gains by reformatting the data between 'the most efficient' structure for each step. A problem of only looking at the 'micro', whilst ignoring wider/macro concerns. Accordingly, as to the word "engineering" (above), a reminder that we work in two domains: code and data. The short 'toy examples' in training courses discourage us from a design-stage for the former - until we enter 'the real world' and meet a problem/solution too large to fit in a single human-brain. Sadly, too many of us are pre-disposed to be math/algorithmically-oriented, and thus data-design is rarely-considered (in the macro!). Yet, here we are... -- Regards =dn -- https://mail.python.org/mailman/listinfo/python-list From grant.b.edwards at gmail.com Sun Nov 26 22:43:53 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Sun, 26 Nov 2023 19:43:53 -0800 (PST) Subject: Context without manager References: <25955.34158.142219.335334@ixdm.fritz.box> Message-ID: <65641079.050a0220.5914b.9566@mx.google.com> On 2023-11-26, Dieter Maurer via Python-list wrote: > If you do not have this case (e.g. usually if you open the file > in a class's `__init__`), you do not use a context manager. He knows that. The OP wrote that he wants to use that can _only_ be used by a context manager, but he wants that usage to be spread over various methods of a class he's writing. So he's asking how to fool that into working when he's not using a context manager. -- Grnat From grant.b.edwards at gmail.com Sun Nov 26 23:03:20 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Sun, 26 Nov 2023 20:03:20 -0800 (PST) Subject: Context without manager References: <25955.34158.142219.335334@ixdm.fritz.box> <65641079.050a0220.5914b.9566@mx.google.com> Message-ID: <65641508.050a0220.15ec4.9beb@mx.google.com> On 2023-11-27, Grant Edwards via Python-list wrote: > On 2023-11-26, Dieter Maurer via Python-list wrote: > >> If you do not have this case (e.g. usually if you open the file >> in a class's `__init__`), you do not use a context manager. > > He knows that. The OP wrote that he wants to use that can > _only_ be used by a context manager, but he wants that usage to be > spread over various methods of a class he's writing. So he's asking > how to fool that into working when he's not using a > context manager. I should probably have written "how to fool that into working when he's not using a 'with' statement" -- Grant From greg.ewing at canterbury.ac.nz Mon Nov 27 01:34:04 2023 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Mon, 27 Nov 2023 19:34:04 +1300 Subject: Context without manager In-Reply-To: References: <25955.34158.142219.335334@ixdm.fritz.box> Message-ID: On 27/11/23 9:03 am, Stefan Ram wrote: > Above, "have" is followed by another verb in "have been", > so it should be eligible for a contraction there! Yes, "been" is the past participle of 'to be", so "I've been" is fine. -- Greg From greg.ewing at canterbury.ac.nz Mon Nov 27 01:43:14 2023 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Mon, 27 Nov 2023 19:43:14 +1300 Subject: Context without manager In-Reply-To: References: <25955.34158.142219.335334@ixdm.fritz.box> <65641079.050a0220.5914b.9566@mx.google.com> <65641508.050a0220.15ec4.9beb@mx.google.com> Message-ID: On 27/11/23 5:03 pm, Grant Edwards wrote: > I should probably have written "how to fool that into > working when he's not using a 'with' statement" It should be possible to run the context protocol yourself. Something like (warning, untested): class MyDeviceWrapper: def __init__(self): self.cm = device_open() self.device = self.cm.__enter__() # Other methods here for doing things with # self.device def close(self): self.cm.__exit__(None, None, None) -- Greg From PythonList at danceswithmice.info Mon Nov 27 02:49:07 2023 From: PythonList at danceswithmice.info ('DL Neil') Date: Mon, 27 Nov 2023 20:49:07 +1300 Subject: Newline (NuBe Question) In-Reply-To: <008d01da20df$fd06fb60$f714f220$@gmail.com> References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> <6555B48F.10108.156EC1@RealGrizzlyAdams.vivaldi.net> <4626640f-4fe5-49bc-a6f8-d555b7f7b58a@tompassin.net> <65561BDA.14413.9EACE9@RealGrizzlyAdams.vivaldi.net> <016601da1f51$e4e84410$aeb8cc30$@gmail.com> <20231126210409.wbcdjkuxmwh7l23q@hjp.at> <91044403-9584-4161-a490-7cac3d8310a7@danceswithmice.info> <008d01da20df$fd06fb60$f714f220$@gmail.com> Message-ID: Avi, On 11/27/2023 4:15 PM, avi.e.gross at gmail.com wrote: > Dave, > > Back on a hopefully more serious note, I want to make a bit of an analogy > with what happens when you save data in a format like a .CSV file. > > Often you have a choice of including a header line giving names to the > resulting columns, or not. > > If you read in the data to some structure, often to some variation I would > loosely call a data.frame or perhaps something like a matrix, then without > headers you have to specify what you want positionally or create your own > names for columns to use. If names are already there, your program can > manipulate things by using the names and if they are well chosen, with no > studs among them, the resulting code can be quite readable. More > importantly, if the data being read changes and includes additional columns > or in a different order, your original program may run fine as long as the > names of the columns you care about remain the same. > > Positional programs can be positioned to fail in quite subtle ways if the > positions no longer apply. Must admit to avoiding .csv files, if possible, and working directly with the .xls? original (cf expecting the user to export the .csv - and NOT change the worksheet thereafter). However, have recently been using the .csv format (as described) as a placeholder or introduction to formatting data for an RDBMS. In a tabular structure, the expectation is that every field (column/row intersection) will contain a value. In the RDBMS-world, if the value is not-known then it will be recorded as NULL (equivalent of Python's None). Accordingly, two points: 1 the special case of missing/unavailable data can be handled with ease, 2 most 'connector' interfaces will give the choice of retrieving data into a tuple or a dictionary (where the keys are the column-names). The latter easing data-identification issues (as described) both in terms of improving over relational-positioning and name-continuity (or column changes/expansions). The point about data 'appearing' without headings should be considered carefully. The phrase "create your own names for columns" only vaguely accesses the problem. If someone else has created/provided the data, then we need to know the exact design (schema = rules). What is the characteristic of each component? Not only column-names, but also what is the metric (eg the infamous confusion between feet and meters)... > As I see it, many situations where some aspects are variable are not ideal > for naming. A dictionary is an example that is useful when you have no idea > how many items with unknown keys may be present. You can iterate over the > names that are there, or use techniques that detect and deal with keys from > your list that are not present. Not using names/keys here might involve a > longer list with lots of empty slots to designate missing items, This > clearly is not great when the data present is sparse or when the number of > items is not known in advance or cannot be maintained in the right order. Agreed, and this is the draw-back incurred by folk who wish to take advantage of the schema-less (possibility) NoSQL DBs. The DB enjoys flexibility, but the downstream-coder has to contort and flex to cope. In this case, JSON files are an easy place-holder/intro for NoSQL DBs - in fact, Python dicts and MongoDB go hand-in-glove. The next issue raised is sparseness. In a table, the assumption is that all fields, or at least most of them, will be filled with values. However, a sparse matrix would make such very 'expensive' in terms of storage-space (efficacy). Accordingly, there are other ways of doing things. All of these involve labeling each data-item (thus, the data expressed as a table needs to be at least 50% empty to justify the structural change). In this case, one might consider a tree-type of structure - and if we have to continue the pattern, we might look at a Network Database methodology (as distinct from a DB on a network!) > There are many other situations with assorted tradeoffs and to insist on > using lists/tuples exclusively would be silly but at the same time, if you > are using a list to hold the real and imaginary parts of a complex number, > or the X/Y[/Z] coordinates of a point where the order is almost universally > accepted, then maybe it is not worth using a data structure more complex or > derived as the use may be obvious. No argument (in case anyone thought I might...) See @Peter's earlier advice. Much of the consideration (apart from mutable/immutable) is likely to be ease of coding. Getting down 'into the weeds' is probably pointless unless questions are being asked about (execution-time) performance... Isn't the word "obvious" where this discussion started? Whereas "studs" might be an "obvious" abbreviation for "students" to some, it is not to others (quite aside from the abbreviation being unnecessary in this day-and-age). Curiously, whereas I DO happen to think a point as ( x, y, ) or ( x, y, z, ) and thus quite happily interpret ( 1, 2, 3, ) as a location in 3D space, I had a trainee bring a 'problem' on this exact assumption:- He had two positions ( x1, y1, ) and ( x2, y2, ) and was computing the vector between them ( x2 - x1, y2 - y1 ), accordingly: def compute_distance( x1, x2, y1, y2, ): # with return calculated as above Trouble is, the function-call was: result = compute_distance( x1, y1, x2, y2, ) In other words, the function's signature was consistent with the calculation. Whereas, the function-call was consistent with the way the data had 'arrived'. Oops! As soon as a (data)class Point( x, y, ) was created, the function's signature became: def compute_distance( starting_point:Point, ending_point:Point, ): # with amended return calculation and the function-call became congruent, naturally. (in fact, the function was moved into the dataclass to become a method which simplified the signature and call(s) ) Thus, what was "obvious" to the same guy's brain when he was writing the function, and what seemed "obvious" when the function was being used, were materially (and catastrophically) different! So, even though we (two) might think in terms of "universally", we are/were wrong! Thus, a DESIGNED data-type helps to avoid errors, and even when the data-usage seems "obvious", offers advantage! Once again, am tempted to suggest that the saving of: point = ( 1, 2, ) over: @dataclass class Point(): x:float y:float is about as easily justified as preferring "studs" over the complete word "students". YMMV! (excepting Code Review expectations) * will an AI-Assistant code this for us, and thus remove any 'amount of typing' complaint? > I do recall odd methods sometimes used way back when I programmed in C/C++ > or similar languages when some method was used to declare small constants > like: > > #define FIRSTNAME 1 > #define LASTNAME 2 > > Or concepts like "const GPA = 3" > > And so on, so code asking for student_record[LASTNAME] would be a tad more > readable and if the order of entries somehow were different, just redefine > the constant. I've been known to do this in Python too! This example is congruent with what was mentioned (elsewhere/earlier): that LASTNAME is considerably more meaningful than 2. Programming principles includes advice that all 'magic constants' should be hoisted to the top of the code (along with import-statements). Aren't those positional indices 'magic constants'? > In some sense, some of the data structures we are discussing, under the > hood, actually may do something very similar as they remap the name to a > small integer offset. Others may do much more or be slower but often add > value in other ways. A full-blown class may not just encapsulate the names > of components of an object but verify the validity of the contents or do > logging or any number of other things. Using a list or tuple does nothing > else. Not in Python: database keys must be hashable values - for that reason. Argh! The docs (https://docs.python.org/3/tutorial/datastructures.html) don't say that - or don't say it any more. Did it change when key-order became guaranteed, or do I mis-remember? Those docs say "immutable" - but whilst "hashable" and "immutable" have related meanings, they are not exactly the same in effect. Alternately, the wiki (https://wiki.python.org/moin/DictionaryKeys) does say "hashable"! > So if you need nothing else, they are often suitable and sometimes even > preferable. Yes, (make a conscious choice to) use the best tool for the job - but don't let bias cloud your judgement, don't take the ideas of the MD's nephew as 'Gospel', and DO design the way forward... -- Regards =dn From dom.grigonis at gmail.com Mon Nov 27 06:29:01 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Mon, 27 Nov 2023 13:29:01 +0200 Subject: argparse argument post-processing Message-ID: <929736D0-579D-48A1-983F-7271A53BC398@gmail.com> Hi all, I have a situation, maybe someone can give some insight. Say I want to have input which is comma separated array (e.g. paths='path1,path2,path3') and convert it to the desired output - list: import argparse parser = argparse.ArgumentParser() parser.add_argument('paths', type=lambda x: list(filter(str.strip, x.split(',')))) So far so good. But this is just an example of what sort of solution I am after. --------- Now the second case. I want input to be space separated array - bash array. And I want space-separated string returned. My current approach is: import argparse parser = argparse.ArgumentParser() parser.add_argument('paths', nargs='+') args = parser.parse_args() paths = ' '.join(args.paths) But what I am looking for is a way to do this, which is intrinsic to `argparse` module. Reason being I have a fair amount of such cases and I don?t want to do post-processing, where post-post-processing happens (after `parser.parse_args()`). I have tried overloading `parse_args` with post-processor arguments, and that seemed fine, but it stopped working when I had sub-parsers, which are defined in different modules and do not call `parse_args` themselves. Any ideas appreciated, Regards, DG From rosuav at gmail.com Mon Nov 27 07:59:10 2023 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 27 Nov 2023 23:59:10 +1100 Subject: argparse argument post-processing In-Reply-To: <929736D0-579D-48A1-983F-7271A53BC398@gmail.com> References: <929736D0-579D-48A1-983F-7271A53BC398@gmail.com> Message-ID: On Mon, 27 Nov 2023 at 22:31, Dom Grigonis via Python-list wrote: > > Hi all, > > I have a situation, maybe someone can give some insight. > > Say I want to have input which is comma separated array (e.g. paths='path1,path2,path3') and convert it to the desired output - list: This is a single argument. > Now the second case. I want input to be space separated array - bash array. And I want space-separated string returned. My current approach is: > import argparse > parser = argparse.ArgumentParser() > parser.add_argument('paths', nargs='+') > args = parser.parse_args() > paths = ' '.join(args.paths) > But what I am looking for is a way to do this, which is intrinsic to `argparse` module. Reason being I have a fair amount of such cases and I don?t want to do post-processing, where post-post-processing happens (after `parser.parse_args()`). > This is parsing multiple arguments. If you want it space-separated, you can do that, just as a single argument. Otherwise, what you're doing is taking multiple arguments and joining them. I'm not sure what you expect to see, but your examples here pretty clearly show that you are taking multiple arguments, and joining them with spaces. ChrisA From avi.e.gross at gmail.com Mon Nov 27 10:01:32 2023 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Mon, 27 Nov 2023 10:01:32 -0500 Subject: Newline (NuBe Question) In-Reply-To: References: <65547270.3139.338043@RealGrizzlyAdams.vivaldi.net> <6555B48F.10108.156EC1@RealGrizzlyAdams.vivaldi.net> <4626640f-4fe5-49bc-a6f8-d555b7f7b58a@tompassin.net> <65561BDA.14413.9EACE9@RealGrizzlyAdams.vivaldi.net> <016601da1f51$e4e84410$aeb8cc30$@gmail.com> <20231126210409.wbcdjkuxmwh7l23q@hjp.at> <91044403-9584-4161-a490-7cac3d8310a7@danceswithmice.info> <008d01da20df$fd06fb60$f714f220$@gmail.com> Message-ID: <001a01da2142$9c4e5b70$d4eb1250$@gmail.com> Dave, I gave an example, again, and make no deep claims so your comments may be valid, without any argument. I mentioned CSV and a related family such as TSV as they were a common and simple data format that has long been used. There are oodles of others and yes, these days many people can read directly from formats like some from EXCEL. But for data that can be shared to almost anyone using anything, something like Comma Separated Values is often used. And some programs that generate such data simply keep appending a line at a time to a file and do not have any header line. There are even some programs that may not tolerate a file with a header line, or comments or other optional things, and some where header lines you can create would cause problems such as using an extended character set or escaped characters. I have worked with these files in many languages and environments and my thought process here focused on recent work in R, albeit much applies everywhere. My point was really not about CSV but the convenience and advantages of data structures you can access by name when you want and sometimes also by position when you want. Too many errors can happen when humans doing programming are not able to concentrate. It is similar to arguments about file names. In the old UNIX days, and the same for other systems like VMS, a filename tended to have a format where relatively few characters were allowed and it might have two parts with the latter being an extension of up to 3 characters, or whatever. So file names like A321G12.dat were common and also next to it similar unpronounceable other file names. It was easy to confuse them and even people who worked with them regularly would forget what it might mean or use the wrong one. Well, if I load in a CSV in a language like R and there is no header line, as with some other data structures, it may make up a placeholder set of names like V1, V2 and so on. Yes, there are ways to specify the names as they are read in or afterward and they can be changed. But I have seen lots of CSV files offered with way too many columns and no names as well as documentation suggesting what names can be added if you wish. This may be a bit off topic, but I want to add a bit in this context about additional concepts regarding name. As mentioned, there is a whole set of add-ons people sometimes use and in R, I like the tidyverse family and it allows some fairly sophisticated things to be done using names. There are ways to specify you want a subset of a data.frame (sometimes a version called a tibble) and you can ask for say all columns starting with "xyz" or containing it or ending with it. That can be very helpful if say we wave columns containing the height and weight and other metrics of say people in three clinics and your column names embed the name of the clinic, or other such examples, and you want to select one grouping for processing. You cannot easily do that without external info is it is just positional. An extension of this is how compactly you can do fairly complex things such as asking to create lots of new columns using calculations. You can specify, as above, which sets of columns to do this too and that you want the results for each XYY in XYZ.mean and XYZ.std and so on. You can skip oodles of carefully crafted and nested loops because of the ability to manipulate using column names at a high and often abstract level. And, just FYI, many other structures such as lists in R also support names for components. It can be very useful. But the overall paradigm compared to Python has major differences and I see strengths and weaknesses and tradeoffs. Your dictionary example is one of them as numpy/pandas often make good use of them as part of dealing with similar data.frame type structures that are often simpler or easier to code with. There is lots of AI discussion these days and some of what you say is applicable in that additional info besides names might be useful in the storage format to make processing it more useful. That is available in formats related to XML where fairly arbitrary markup can be made available. Have to head out as this is already long enough. -----Original Message----- From: 'DL Neil' Sent: Monday, November 27, 2023 2:49 AM To: avi.e.gross at gmail.com; python-list at python.org Subject: Re: Newline (NuBe Question) Avi, On 11/27/2023 4:15 PM, avi.e.gross at gmail.com wrote: > Dave, > > Back on a hopefully more serious note, I want to make a bit of an analogy > with what happens when you save data in a format like a .CSV file. > > Often you have a choice of including a header line giving names to the > resulting columns, or not. > > If you read in the data to some structure, often to some variation I would > loosely call a data.frame or perhaps something like a matrix, then without > headers you have to specify what you want positionally or create your own > names for columns to use. If names are already there, your program can > manipulate things by using the names and if they are well chosen, with no > studs among them, the resulting code can be quite readable. More > importantly, if the data being read changes and includes additional columns > or in a different order, your original program may run fine as long as the > names of the columns you care about remain the same. > > Positional programs can be positioned to fail in quite subtle ways if the > positions no longer apply. Must admit to avoiding .csv files, if possible, and working directly with the .xls? original (cf expecting the user to export the .csv - and NOT change the worksheet thereafter). However, have recently been using the .csv format (as described) as a placeholder or introduction to formatting data for an RDBMS. In a tabular structure, the expectation is that every field (column/row intersection) will contain a value. In the RDBMS-world, if the value is not-known then it will be recorded as NULL (equivalent of Python's None). Accordingly, two points: 1 the special case of missing/unavailable data can be handled with ease, 2 most 'connector' interfaces will give the choice of retrieving data into a tuple or a dictionary (where the keys are the column-names). The latter easing data-identification issues (as described) both in terms of improving over relational-positioning and name-continuity (or column changes/expansions). The point about data 'appearing' without headings should be considered carefully. The phrase "create your own names for columns" only vaguely accesses the problem. If someone else has created/provided the data, then we need to know the exact design (schema = rules). What is the characteristic of each component? Not only column-names, but also what is the metric (eg the infamous confusion between feet and meters)... > As I see it, many situations where some aspects are variable are not ideal > for naming. A dictionary is an example that is useful when you have no idea > how many items with unknown keys may be present. You can iterate over the > names that are there, or use techniques that detect and deal with keys from > your list that are not present. Not using names/keys here might involve a > longer list with lots of empty slots to designate missing items, This > clearly is not great when the data present is sparse or when the number of > items is not known in advance or cannot be maintained in the right order. Agreed, and this is the draw-back incurred by folk who wish to take advantage of the schema-less (possibility) NoSQL DBs. The DB enjoys flexibility, but the downstream-coder has to contort and flex to cope. In this case, JSON files are an easy place-holder/intro for NoSQL DBs - in fact, Python dicts and MongoDB go hand-in-glove. The next issue raised is sparseness. In a table, the assumption is that all fields, or at least most of them, will be filled with values. However, a sparse matrix would make such very 'expensive' in terms of storage-space (efficacy). Accordingly, there are other ways of doing things. All of these involve labeling each data-item (thus, the data expressed as a table needs to be at least 50% empty to justify the structural change). In this case, one might consider a tree-type of structure - and if we have to continue the pattern, we might look at a Network Database methodology (as distinct from a DB on a network!) > There are many other situations with assorted tradeoffs and to insist on > using lists/tuples exclusively would be silly but at the same time, if you > are using a list to hold the real and imaginary parts of a complex number, > or the X/Y[/Z] coordinates of a point where the order is almost universally > accepted, then maybe it is not worth using a data structure more complex or > derived as the use may be obvious. No argument (in case anyone thought I might...) See @Peter's earlier advice. Much of the consideration (apart from mutable/immutable) is likely to be ease of coding. Getting down 'into the weeds' is probably pointless unless questions are being asked about (execution-time) performance... Isn't the word "obvious" where this discussion started? Whereas "studs" might be an "obvious" abbreviation for "students" to some, it is not to others (quite aside from the abbreviation being unnecessary in this day-and-age). Curiously, whereas I DO happen to think a point as ( x, y, ) or ( x, y, z, ) and thus quite happily interpret ( 1, 2, 3, ) as a location in 3D space, I had a trainee bring a 'problem' on this exact assumption:- He had two positions ( x1, y1, ) and ( x2, y2, ) and was computing the vector between them ( x2 - x1, y2 - y1 ), accordingly: def compute_distance( x1, x2, y1, y2, ): # with return calculated as above Trouble is, the function-call was: result = compute_distance( x1, y1, x2, y2, ) In other words, the function's signature was consistent with the calculation. Whereas, the function-call was consistent with the way the data had 'arrived'. Oops! As soon as a (data)class Point( x, y, ) was created, the function's signature became: def compute_distance( starting_point:Point, ending_point:Point, ): # with amended return calculation and the function-call became congruent, naturally. (in fact, the function was moved into the dataclass to become a method which simplified the signature and call(s) ) Thus, what was "obvious" to the same guy's brain when he was writing the function, and what seemed "obvious" when the function was being used, were materially (and catastrophically) different! So, even though we (two) might think in terms of "universally", we are/were wrong! Thus, a DESIGNED data-type helps to avoid errors, and even when the data-usage seems "obvious", offers advantage! Once again, am tempted to suggest that the saving of: point = ( 1, 2, ) over: @dataclass class Point(): x:float y:float is about as easily justified as preferring "studs" over the complete word "students". YMMV! (excepting Code Review expectations) * will an AI-Assistant code this for us, and thus remove any 'amount of typing' complaint? > I do recall odd methods sometimes used way back when I programmed in C/C++ > or similar languages when some method was used to declare small constants > like: > > #define FIRSTNAME 1 > #define LASTNAME 2 > > Or concepts like "const GPA = 3" > > And so on, so code asking for student_record[LASTNAME] would be a tad more > readable and if the order of entries somehow were different, just redefine > the constant. I've been known to do this in Python too! This example is congruent with what was mentioned (elsewhere/earlier): that LASTNAME is considerably more meaningful than 2. Programming principles includes advice that all 'magic constants' should be hoisted to the top of the code (along with import-statements). Aren't those positional indices 'magic constants'? > In some sense, some of the data structures we are discussing, under the > hood, actually may do something very similar as they remap the name to a > small integer offset. Others may do much more or be slower but often add > value in other ways. A full-blown class may not just encapsulate the names > of components of an object but verify the validity of the contents or do > logging or any number of other things. Using a list or tuple does nothing > else. Not in Python: database keys must be hashable values - for that reason. Argh! The docs (https://docs.python.org/3/tutorial/datastructures.html) don't say that - or don't say it any more. Did it change when key-order became guaranteed, or do I mis-remember? Those docs say "immutable" - but whilst "hashable" and "immutable" have related meanings, they are not exactly the same in effect. Alternately, the wiki (https://wiki.python.org/moin/DictionaryKeys) does say "hashable"! > So if you need nothing else, they are often suitable and sometimes even > preferable. Yes, (make a conscious choice to) use the best tool for the job - but don't let bias cloud your judgement, don't take the ideas of the MD's nephew as 'Gospel', and DO design the way forward... -- Regards =dn From just.kashishhn at gmail.com Sun Nov 26 07:18:45 2023 From: just.kashishhn at gmail.com (Kashish Naqvi) Date: Sun, 26 Nov 2023 04:18:45 -0800 (PST) Subject: how to connect linux aws ec2 instance to windows local machine at my home using paramiko Message-ID: <60050671-39ff-4d68-a1d0-5a3363ff9f3bn@googlegroups.com> I have a north viriginia ec2 linux instance and a windows machine at my home, how do I connec tthem? import paramiko import time def run_scripts(): # Set your local machine's SSH details local_machine_ip = ' ' username = 'justk' private_key_path = 'C:/Users/justk/.ssh/kashish' print("Connected 1", private_key_path) # Create an SSH client ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) print("Connected 2.2") try: # Connect to the local machine ssh.connect(local_machine_ip, username=username, key_filename=private_key_path,password='abc') print("Connected 2") # Stop the first script: check_messages.py stop_check_messages_command = 'pkill -f python C:/Project/pipeline-deployment/check_messages.py' ssh.exec_command(stop_check_messages_command) print("Connected 3") # Stop the second script: manage.py runserver stop_runserver_command = 'pkill -f "python C:/Project/pipeline-deployment/manage.py runserver' ssh.exec_command(stop_runserver_command) print("Waiting for 5 seconds before starting scripts...") time.sleep(60) # Run the first script: check_messages.py check_messages_command = 'python C:/Project/pipeline-deployment/check_messages.py' stdin, stdout, stderr = ssh.exec_command(check_messages_command) print(f"Output of check_messages.py:\n{stdout.read().decode('utf-8')}") # Run the second script: manage.py runserver runserver_command = 'python C:/Project/pipeline-deployment/manage.py runserver' stdin, stdout, stderr = ssh.exec_command(runserver_command) print(f"Output of manage.py runserver:\n{stdout.read().decode('utf-8')}") # Wait for 60 seconds print("Waiting for 60 seconds...") time.sleep(60) # Run the third script: restart.py restart_command = 'python C:/Project/pipeline-deployment/restartworkersbutton.py' stdin, stdout, stderr = ssh.exec_command(restart_command) print(f"Output of restart.py:\n{stdout.read().decode('utf-8')}") except Exception as e: print(f"Error: {e}") finally: # Close the SSH connection ssh.close() if __name__ == "__main__": run_scripts() i used this but i am unable to know what ip address to use? From piergiorgio.sartor.this.should.not.be.used at nexgo.REMOVETHIS.de Sun Nov 26 13:58:58 2023 From: piergiorgio.sartor.this.should.not.be.used at nexgo.REMOVETHIS.de (Piergiorgio Sartor) Date: Sun, 26 Nov 2023 19:58:58 +0100 Subject: Context without manager In-Reply-To: References: <25955.34158.142219.335334@ixdm.fritz.box> Message-ID: On 26/11/2023 18.50, Dieter Maurer wrote: > Piergiorgio Sartor wrote at 2023-11-25 22:15 +0100: >> ... >> Apparently, the "with" context manager is not usable >> in classes, at least not with __init__() & co. > > You can use `with` in classes -- with any context manager. > However, you would usually not use `with` with a file you have opened > in `__init__`. > > If a class defines `__enter__` and `__exit__` (i.e. > the "cntext manager protocol"), then its instances > can be used with the `with` statement. > > The important use case for a context manager is the > situation: > set up a context (--> method `__enter__`) > perform some operations in this context (--> body of `with` statement) > tear down the context (--> method `__exit__`). > If you do not have this case (e.g. usually if you open the file > in a class's `__init__`), you do not use a context manager. Very clear, but what if the class is *not* "open()", but something else _requiring_ using "with"? How to do this in a "__init__()" of a class? In other words, what if "open()" could *only* be used with "with" and not just by assigning "fp = open()"? The problem is I've some SDK of some device which provides context manager *only* classes. I *cannot* do: device = device_open(...) device.do_something() device.close() I *must* do: with device_open() as device: device.do_something() Nevertheless, I _need_ to have a class where the device is opened in the __init__() and used in some methods. Any ideas? bye, -- piergiorgio From richard at damon-family.org Mon Nov 27 12:50:42 2023 From: richard at damon-family.org (Richard Damon) Date: Mon, 27 Nov 2023 12:50:42 -0500 Subject: Context without manager Message-ID: ?Read the Fine context manager documentation. What ?with with_expression as var? does is effectively: ob = with_expression var = ob.__enter__() And then at the end of the with, does a ob.__exit__() (With some parameters to __exit__, that could just be None, None, None for the simplest case). Note, YOUR program must now make sure that the __exit__ function is called, and handle any exceptions that got thrown, and that ob and var are put somewhere you can access them at that later time. > On Nov 27, 2023, at 12:24?PM, Piergiorgio Sartor via Python-list wrote: > > ?On 26/11/2023 18.50, Dieter Maurer wrote: >> Piergiorgio Sartor wrote at 2023-11-25 22:15 +0100: >>> ... >>> Apparently, the "with" context manager is not usable >>> in classes, at least not with __init__() & co. >> You can use `with` in classes -- with any context manager. >> However, you would usually not use `with` with a file you have opened >> in `__init__`. >> If a class defines `__enter__` and `__exit__` (i.e. >> the "cntext manager protocol"), then its instances >> can be used with the `with` statement. >> The important use case for a context manager is the >> situation: >> set up a context (--> method `__enter__`) >> perform some operations in this context (--> body of `with` statement) >> tear down the context (--> method `__exit__`). >> If you do not have this case (e.g. usually if you open the file >> in a class's `__init__`), you do not use a context manager. > > Very clear, but what if the class is *not* "open()", > but something else _requiring_ using "with"? > How to do this in a "__init__()" of a class? > > In other words, what if "open()" could *only* be used > with "with" and not just by assigning "fp = open()"? > > The problem is I've some SDK of some device which > provides context manager *only* classes. > > I *cannot* do: > > device = device_open(...) > device.do_something() > device.close() > > I *must* do: > > with device_open() as device: > device.do_something() > > Nevertheless, I _need_ to have a class > where the device is opened in the __init__() > and used in some methods. > > Any ideas? > > bye, > > -- > > piergiorgio > > -- > https://mail.python.org/mailman/listinfo/python-list From richard at damon-family.org Mon Nov 27 12:51:27 2023 From: richard at damon-family.org (Richard Damon) Date: Mon, 27 Nov 2023 12:51:27 -0500 Subject: Context without manager Message-ID: <44962B50-9A04-4BFF-952C-AED45AD96252@damon-family.org> ?Read the Fine context manager documentation. What ?with with_expression as var? does is effectively: ob = with_expression var = ob.__enter__() And then at the end of the with, does a ob.__exit__() (With some parameters to __exit__, that could just be None, None, None for the simplest case). Note, YOUR program must now make sure that the __exit__ function is called, and handle any exceptions that got thrown, and that ob and var are put somewhere you can access them at that later time. > On Nov 27, 2023, at 12:24?PM, Piergiorgio Sartor via Python-list wrote: > > ?On 26/11/2023 18.50, Dieter Maurer wrote: >> Piergiorgio Sartor wrote at 2023-11-25 22:15 +0100: >>> ... >>> Apparently, the "with" context manager is not usable >>> in classes, at least not with __init__() & co. >> You can use `with` in classes -- with any context manager. >> However, you would usually not use `with` with a file you have opened >> in `__init__`. >> If a class defines `__enter__` and `__exit__` (i.e. >> the "cntext manager protocol"), then its instances >> can be used with the `with` statement. >> The important use case for a context manager is the >> situation: >> set up a context (--> method `__enter__`) >> perform some operations in this context (--> body of `with` statement) >> tear down the context (--> method `__exit__`). >> If you do not have this case (e.g. usually if you open the file >> in a class's `__init__`), you do not use a context manager. > > Very clear, but what if the class is *not* "open()", > but something else _requiring_ using "with"? > How to do this in a "__init__()" of a class? > > In other words, what if "open()" could *only* be used > with "with" and not just by assigning "fp = open()"? > > The problem is I've some SDK of some device which > provides context manager *only* classes. > > I *cannot* do: > > device = device_open(...) > device.do_something() > device.close() > > I *must* do: > > with device_open() as device: > device.do_something() > > Nevertheless, I _need_ to have a class > where the device is opened in the __init__() > and used in some methods. > > Any ideas? > > bye, > > -- > > piergiorgio > > -- > https://mail.python.org/mailman/listinfo/python-list From David.Raymond at tomtom.com Mon Nov 27 12:58:40 2023 From: David.Raymond at tomtom.com (David Raymond) Date: Mon, 27 Nov 2023 17:58:40 +0000 Subject: Context without manager In-Reply-To: References: <25955.34158.142219.335334@ixdm.fritz.box> Message-ID: > I *must* do: > > with device_open() as device: > device.do_something() > > Nevertheless, I _need_ to have a class > where the device is opened in the __init__() > and used in some methods. > > Any ideas? Perhaps take a look at contextlib.ExitStack and see if you can do something with it. (Below is not tested) import contextlib class myClass: def __init__(self): self._exitStack = contextlib.ExitStack() device = self._exitStack.enter_context(device_open(...)) def __del__(self): self._exitStack.close() From mats at wichmann.us Mon Nov 27 14:55:35 2023 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 27 Nov 2023 12:55:35 -0700 Subject: argparse argument post-processing In-Reply-To: <929736D0-579D-48A1-983F-7271A53BC398@gmail.com> References: <929736D0-579D-48A1-983F-7271A53BC398@gmail.com> Message-ID: <67aa7ccc-c90f-4251-94f1-befba04f14b4@wichmann.us> On 11/27/23 04:29, Dom Grigonis via Python-list wrote: > Hi all, > > I have a situation, maybe someone can give some insight. > > Say I want to have input which is comma separated array (e.g. paths='path1,path2,path3') and convert it to the desired output - list: > import argparse > parser = argparse.ArgumentParser() > parser.add_argument('paths', type=lambda x: list(filter(str.strip, x.split(',')))) > So far so good. But this is just an example of what sort of solution I am after. Maybe use "action" rather than "type" here? the conversion of a csv argument into words seems more like an action. > Now the second case. I want input to be space separated array - bash array. And I want space-separated string returned. My current approach is: > import argparse > parser = argparse.ArgumentParser() > parser.add_argument('paths', nargs='+') > args = parser.parse_args() > paths = ' '.join(args.paths) > But what I am looking for is a way to do this, which is intrinsic to `argparse` module. Reason being I have a fair amount of such cases and I don?t want to do post-processing, where post-post-processing happens (after `parser.parse_args()`). > > I have tried overloading `parse_args` with post-processor arguments, and that seemed fine, but it stopped working when I had sub-parsers, which are defined in different modules and do not call `parse_args` themselves. Depending on what *else* you need to handle it may or not may work here to just collect these from the remainders, and then use an action to join them, like: import argparse class JoinAction(argparse.Action): def __call__(self, parser, namespace, values, option_string=None): setattr(namespace, self.dest, ' '.join(values)) parser = argparse.ArgumentParser() parser.add_argument('paths', nargs=argparse.REMAINDER, action=JoinAction) args = parser.parse_args() print(f"{args.paths!r}") From dom.grigonis at gmail.com Mon Nov 27 15:21:14 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Mon, 27 Nov 2023 22:21:14 +0200 Subject: argparse argument post-processing In-Reply-To: <67aa7ccc-c90f-4251-94f1-befba04f14b4@wichmann.us> References: <929736D0-579D-48A1-983F-7271A53BC398@gmail.com> <67aa7ccc-c90f-4251-94f1-befba04f14b4@wichmann.us> Message-ID: <48FAB5B6-948C-46A3-9949-529958E9116B@gmail.com> Thank you, exactly what I was looking for! One more question following this. Is there a way to have a customisable action? I.e. What if I want to join with space in one case and with coma in another. Is there a way to reuse the same action class? Regards, DG > On 27 Nov 2023, at 21:55, Mats Wichmann via Python-list wrote: > > On 11/27/23 04:29, Dom Grigonis via Python-list wrote: >> Hi all, >> I have a situation, maybe someone can give some insight. >> Say I want to have input which is comma separated array (e.g. paths='path1,path2,path3') and convert it to the desired output - list: >> import argparse >> parser = argparse.ArgumentParser() >> parser.add_argument('paths', type=lambda x: list(filter(str.strip, x.split(',')))) >> So far so good. But this is just an example of what sort of solution I am after. > > Maybe use "action" rather than "type" here? the conversion of a csv argument into words seems more like an action. > >> Now the second case. I want input to be space separated array - bash array. And I want space-separated string returned. My current approach is: >> import argparse >> parser = argparse.ArgumentParser() >> parser.add_argument('paths', nargs='+') >> args = parser.parse_args() >> paths = ' '.join(args.paths) >> But what I am looking for is a way to do this, which is intrinsic to `argparse` module. Reason being I have a fair amount of such cases and I don?t want to do post-processing, where post-post-processing happens (after `parser.parse_args()`). >> I have tried overloading `parse_args` with post-processor arguments, and that seemed fine, but it stopped working when I had sub-parsers, which are defined in different modules and do not call `parse_args` themselves. > > Depending on what *else* you need to handle it may or not may work here to just collect these from the remainders, and then use an action to join them, like: > > import argparse > > class JoinAction(argparse.Action): > def __call__(self, parser, namespace, values, option_string=None): > setattr(namespace, self.dest, ' '.join(values)) > > parser = argparse.ArgumentParser() > parser.add_argument('paths', nargs=argparse.REMAINDER, action=JoinAction) > args = parser.parse_args() > > print(f"{args.paths!r}") > > > > > > > -- > https://mail.python.org/mailman/listinfo/python-list From mats at wichmann.us Mon Nov 27 15:36:05 2023 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 27 Nov 2023 13:36:05 -0700 Subject: argparse argument post-processing In-Reply-To: <48FAB5B6-948C-46A3-9949-529958E9116B@gmail.com> References: <929736D0-579D-48A1-983F-7271A53BC398@gmail.com> <67aa7ccc-c90f-4251-94f1-befba04f14b4@wichmann.us> <48FAB5B6-948C-46A3-9949-529958E9116B@gmail.com> Message-ID: <811103f0-57ab-47bd-b6f5-f1a059ffd7f6@wichmann.us> On 11/27/23 13:21, Dom Grigonis wrote: > Thank you, exactly what I was looking for! > > One more question following this. Is there a way to have a customisable action? I.e. What if I want to join with space in one case and with coma in another. Is there a way to reuse the same action class? I've worked more with optparse (the project I work on that uses it has reasons why it's not feasible to convert to argparse); in optparse you use a callback function, rather than an action class, and the change to a callable class is somewhat significant :-; so I'm not really an expert. The question is how you determine which you want to do - then there's no problem for the action class's call method to implement it. I presume you can write an initializer class that takes an extra argument, collect that and stuff it into an instance variable, then use super to call the base Action class's initializer with the rest of the args super().__init__(option_strings=option_strings, *args, **kwargs) Hopefully someone else has done this kind of thing because now I'm just guessing! From dom.grigonis at gmail.com Mon Nov 27 15:42:29 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Mon, 27 Nov 2023 22:42:29 +0200 Subject: argparse argument post-processing In-Reply-To: <811103f0-57ab-47bd-b6f5-f1a059ffd7f6@wichmann.us> References: <929736D0-579D-48A1-983F-7271A53BC398@gmail.com> <67aa7ccc-c90f-4251-94f1-befba04f14b4@wichmann.us> <48FAB5B6-948C-46A3-9949-529958E9116B@gmail.com> <811103f0-57ab-47bd-b6f5-f1a059ffd7f6@wichmann.us> Message-ID: Yeah, I have been hearing that people are having troubles converting, but I have only used argparse - got lucky there I guess. I am thinking just making the function which spits the class out. Maybe not very optimised solution, but simple. Argument parsing in my case is very far from being a bottleneck. > On 27 Nov 2023, at 22:36, Mats Wichmann wrote: > > On 11/27/23 13:21, Dom Grigonis wrote: >> Thank you, exactly what I was looking for! >> One more question following this. Is there a way to have a customisable action? I.e. What if I want to join with space in one case and with coma in another. Is there a way to reuse the same action class? > > I've worked more with optparse (the project I work on that uses it has reasons why it's not feasible to convert to argparse); in optparse you use a callback function, rather than an action class, and the change to a callable class is somewhat significant :-; so I'm not really an expert. > > The question is how you determine which you want to do - then there's no problem for the action class's call method to implement it. I presume you can write an initializer class that takes an extra argument, collect that and stuff it into an instance variable, then use super to call the base Action class's initializer with the rest of the args > > super().__init__(option_strings=option_strings, *args, **kwargs) > > Hopefully someone else has done this kind of thing because now I'm just guessing! > > From loris.bennett at fu-berlin.de Tue Nov 28 08:58:26 2023 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Tue, 28 Nov 2023 14:58:26 +0100 Subject: Printing dict value for possibly undefined key References: <87msv34407.fsf@zedat.fu-berlin.de> <6h48N.18969$_z86.2637@fx46.iad> Message-ID: <87bkbej7y5.fsf@zedat.fu-berlin.de> duncan smith writes: > On 24/11/2023 16:35, duncan smith wrote: >> On 24/11/2023 14:31, Loris Bennett wrote: >>> Hi, >>> >>> I want to print some records from a database table where one of the >>> fields contains a JSON string which is read into a dict.? I am doing >>> something like >>> >>> ?? print(f"{id} {d['foo']} {d['bar']}") >>> >>> However, the dict does not always have the same keys, so d['foo'] or >>> d['bar'] may be undefined.? I can obviously do something like >>> >>> ?? if not 'foo' in d: >>> ???? d['foo']="NULL" >>> ?? if not 'bar' in d: >>> ???? d['bar']="NULL" >>> ?? print(f"{id} {d['foo']} {d['bar']}") >>> >>> Is there any more compact way of achieving the same thing? >>> >>> Cheers, >>> >>> Loris >>> >> Yes. e.g. >> d.get('foo', "NULL") >> Duncan > > Or make d a defaultdict. > > from collections import defaultdict > > dic = defaultdict(lambda:'NULL') > dic['foo'] = 'astring' > dic['foo'] > 'astring' > dic['bar'] > 'NULL' > > Duncan > I have gone with the 'd.get' solution, as I am just need to print the dict to the terminal. The dict is actually from a list of dicts which is generated by querying a database, so I don't think the defaultdict approach would be so appropriate, but it's good to know about it. Thanks, Loris -- This signature is currently under constuction. From loris.bennett at fu-berlin.de Tue Nov 28 09:06:11 2023 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Tue, 28 Nov 2023 15:06:11 +0100 Subject: Printing dict value for possibly undefined key References: <87msv34407.fsf@zedat.fu-berlin.de> <6372e983-0636-4cf3-98d5-164944f65419@DancesWithMice.info> Message-ID: <877cm2j7l8.fsf@zedat.fu-berlin.de> DL Neil writes: > On 11/25/2023 3:31 AM, Loris Bennett via Python-list wrote: >> Hi, >> I want to print some records from a database table where one of the >> fields contains a JSON string which is read into a dict. I am doing >> something like >> print(f"{id} {d['foo']} {d['bar']}") >> However, the dict does not always have the same keys, so d['foo'] or >> d['bar'] may be undefined. I can obviously do something like >> if not 'foo' in d: >> d['foo']="NULL" >> if not 'bar' in d: >> d['bar']="NULL" >> print(f"{id} {d['foo']} {d['bar']}") >> Is there any more compact way of achieving the same thing? > > > What does "the dict does not always have the same keys" mean? > > a) there are two (or...) keys, but some records don't include both; > > b) there may be keys other than 'foo' and 'bar' which not-known in-advance; > > c) something else. Sorry for being unclear. There is either 'foo' or 'bar' or both, plus some other keys which are always present. > As mentioned, dict.get() solves one of these. > > Otherwise, there are dict methods which collect/reveal all the keys, > all the values, or both - dict.keys(), .values(), .items(), resp. That is a also a good point. I had forgotten about dict.keys() and dict.values(), and hadn't been aware of dict.items(). Cheers, Loris -- This signature is currently under constuction. From loris.bennett at fu-berlin.de Tue Nov 28 10:56:33 2023 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Tue, 28 Nov 2023 16:56:33 +0100 Subject: Accessing configuration across multiple modules Message-ID: <87msuxzxam.fsf@zedat.fu-berlin.de> Hi, I am using Typer to create a command-line program with multiple levels of subcommands, so a typical call might look like mytool --config-file=~/test/mytool.conf serviceXYZ list people In the top-level mytool.main, I evaluate the option '--config-file' and read the config file to initialize the logging. This works fine. However, in the module which lists people, namely mytool.serviceXYZ.cli_people I need to set up a connection to an LDAP server in order to actually read the data. If the LDAP connection details are also in the config file, what is the best way of making them accessible at the point where the object wrapping the LDAP server is initialized? I found this a suggestion here which involves creating a separate module for the configuration and then importing it https://codereview.stackexchange.com/questions/269550/python-share-global-variables-across-modules-from-user-defined-config-file I think I could probably get that to work, but are there any better alternatives? Cheers, Loris -- This signature is currently under constuction. From jshem at yaxenu.org Wed Nov 29 19:44:01 2023 From: jshem at yaxenu.org (Julieta Shem) Date: Wed, 29 Nov 2023 21:44:01 -0300 Subject: on writing a number as 2^s * q, where q is odd Message-ID: <87sf4oysry.fsf@yaxenu.org> How would you write this procedure? --8<---------------cut here---------------start------------->8--- def powers_of_2_in(n): s = 0 while "I still find factors of 2 in n...": q, r = divmod(n, 2) if r == 0: s = s + 1 n = n // 2 else: return s, n --8<---------------cut here---------------end--------------->8--- From dom.grigonis at gmail.com Wed Nov 29 21:06:24 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Thu, 30 Nov 2023 04:06:24 +0200 Subject: on writing a number as 2^s * q, where q is odd In-Reply-To: <87sf4oysry.fsf@yaxenu.org> References: <87sf4oysry.fsf@yaxenu.org> Message-ID: <0C8F1949-D992-4A8D-A8EB-8384C6A208A9@gmail.com> def powers_of_2_in(n): s = 0 while n % 2 == 0: s += 1 n = n // 2 return s, n > On 30 Nov 2023, at 02:44, Julieta Shem via Python-list wrote: > > How would you write this procedure? > > --8<---------------cut here---------------start------------->8--- > def powers_of_2_in(n): > s = 0 > while "I still find factors of 2 in n...": > q, r = divmod(n, 2) > if r == 0: > s = s + 1 > n = n // 2 > else: > return s, n > --8<---------------cut here---------------end--------------->8--- > -- > https://mail.python.org/mailman/listinfo/python-list From 2QdxY4RzWzUUiLuE at potatochowder.com Wed Nov 29 21:10:26 2023 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Wed, 29 Nov 2023 21:10:26 -0500 Subject: on writing a number as 2^s * q, where q is odd In-Reply-To: <87sf4oysry.fsf@yaxenu.org> References: <87sf4oysry.fsf@yaxenu.org> Message-ID: On 2023-11-29 at 21:44:01 -0300, Julieta Shem via Python-list wrote: > How would you write this procedure? > > --8<---------------cut here---------------start------------->8--- > def powers_of_2_in(n): > s = 0 > while "I still find factors of 2 in n...": > q, r = divmod(n, 2) > if r == 0: > s = s + 1 > n = n // 2 > else: > return s, n > --8<---------------cut here---------------end--------------->8--- What's wrong with what you have? From alan at csail.mit.edu Wed Nov 29 21:34:58 2023 From: alan at csail.mit.edu (Alan Bawden) Date: Wed, 29 Nov 2023 21:34:58 -0500 Subject: on writing a number as 2^s * q, where q is odd References: <87sf4oysry.fsf@yaxenu.org> Message-ID: <86leagt1d9.fsf@williamsburg.bawden.org> Julieta Shem writes: How would you write this procedure? def powers_of_2_in(n): ... def powers_of_2_in(n): return (n ^ (n - 1)).bit_count() - 1 From nospam at please.ty Wed Nov 29 23:58:34 2023 From: nospam at please.ty (jak) Date: Thu, 30 Nov 2023 05:58:34 +0100 Subject: on writing a number as 2^s * q, where q is odd In-Reply-To: References: <87sf4oysry.fsf@yaxenu.org> <0C8F1949-D992-4A8D-A8EB-8384C6A208A9@gmail.com> Message-ID: Dom Grigonis ha scritto: > def powers_of_2_in(n): > s = 0 > while n % 2 == 0: > s += 1 > n = n // 2 > return s, n > Good solution, unfortunately if the input data is zero, the function never ends. >> On 30 Nov 2023, at 02:44, Julieta Shem via Python-list wrote: >> >> How would you write this procedure? >> >> --8<---------------cut here---------------start------------->8--- >> def powers_of_2_in(n): >> s = 0 >> while "I still find factors of 2 in n...": >> q, r = divmod(n, 2) >> if r == 0: >> s = s + 1 >> n = n // 2 >> else: >> return s, n >> --8<---------------cut here---------------end--------------->8--- >> -- >> https://mail.python.org/mailman/listinfo/python-list > From nospam at please.ty Thu Nov 30 00:07:00 2023 From: nospam at please.ty (jak) Date: Thu, 30 Nov 2023 06:07:00 +0100 Subject: on writing a number as 2^s * q, where q is odd In-Reply-To: <86leagt1d9.fsf@williamsburg.bawden.org> References: <87sf4oysry.fsf@yaxenu.org> <86leagt1d9.fsf@williamsburg.bawden.org> Message-ID: Alan Bawden ha scritto: > Julieta Shem writes: > > How would you write this procedure? > def powers_of_2_in(n): > ... > > def powers_of_2_in(n): > return (n ^ (n - 1)).bit_count() - 1 > Great solution, unfortunately the return value is not a tuple as in the OP version. Maybe in this way? def powers_of_2_inB(n): bc = (n ^ (n - 1)).bit_count() - 1 return bc, int(n / (1 << bc)) From alan at csail.mit.edu Thu Nov 30 01:27:57 2023 From: alan at csail.mit.edu (Alan Bawden) Date: Thu, 30 Nov 2023 01:27:57 -0500 Subject: on writing a number as 2^s * q, where q is odd References: <87sf4oysry.fsf@yaxenu.org> <86leagt1d9.fsf@williamsburg.bawden.org> Message-ID: <86h6l3u55e.fsf@williamsburg.bawden.org> jak writes: Alan Bawden ha scritto: > Julieta Shem writes: > > How would you write this procedure? > def powers_of_2_in(n): > ... > > def powers_of_2_in(n): > return (n ^ (n - 1)).bit_count() - 1 > Great solution, unfortunately the return value is not a tuple as in the OP version. Maybe in this way? def powers_of_2_inB(n): bc = (n ^ (n - 1)).bit_count() - 1 return bc, int(n / (1 << bc)) Good point. I overlooked that. I should have written: def powers_of_2_in(n): bc = (n ^ (n - 1)).bit_count() - 1 return bc, n >> bc