From PythonList at DancesWithMice.info Sat Feb 1 00:15:47 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Sat, 1 Feb 2020 18:15:47 +1300 Subject: Suggestions on mechanism or existing code - maintain persistence of file download history In-Reply-To: References: <9d1c662e-c63e-3400-b068-d1834e7f169c@DancesWithMice.info> Message-ID: <929c8cba-5f5a-8bb9-9396-73124d1acbfc@DancesWithMice.info> On 31/01/20 9:53 PM, R.Wieser wrote: >> Using ctrl+c is a VERY BAD idea. > > To have it just exit the program ? Yes, indeed. > > Though you /could/ keep track of what needs to be finished and have the > ctrl-c handler do that for you (barf). > > Another posibility is to capture the ctrl-c and set a flag, which than > instructs the program to terminate loops wherever possible - and thus have > the program finish as if there was no more to do. > >> (see also 'sledgehammer to crack a nut') > > While I agree with you there, I've been searching for other ways to detect a > keypress (in a console-based script) and have found none. IOW, you do not > (seem to) have another option. Color me disappointed! I was hoping to be enlightened as to how one might code exactly that. (so I went looking...) My first thought was a try...except looking for a keyboard error, but wouldn't that only work if there was an input() loop? The idea of putting, effectively the entire code-base, into a try...except block seemed crude and likely to cause side-effects. https://stackoverflow.com/questions/1112343/how-do-i-capture-sigint-in-python put me on a good path. So, I opened a door in my memory, shut my ears to the intense screeching noise, and used a yard-broom to sweep away all the rust that flaked off the hinges... PSL's signal ? Set handlers for asynchronous events (https://docs.python.org/3/library/signal.html) appears to handle keyboard interrupts, *at least in MS-Windows*. Rusty? I think, years ago, I used signal(s) to establish time-limits on systems that had a possibility of 'run-away' or over-refining a solution which would only ever be asymptotic. I've not used the library in this manner. That said, I'm using one of Python's asynchronous features, and Internet activity is riddled with delay-periods which make such retrievals ripe for async (code) solutions... >> Why do you need to abandon the process mid-way? > > Take your pick. Mostly because of "I need to leave *now*". Or perhaps > because of an "you have X seconds before the device shuts down because of > the battery being low" situation. I (personally) cannot make use of the above. However, even if my portable's battery threatens complete disaster, the system "hibernates", and thus averts major disaster, eg file system (or RDBMS) corruption. This seems enough for 99% of 'average uses'. Of course it is regarded as trivially-unacceptable in the non-stop world, eg banking. Would our OP classify this project as anything other than the first of those categories? Thus: >> What is the OP's definition of "unlikely" or "acceptable risk"? > > Good question, but one I had no wish for to try to ascertain. I just gave > some "worst case" secenario based replies (aka, the "did you think of > situation" kind). Understood. However, your understanding of RDBMS interrupt 'security' appears either aged, or biased to a particular implementation (which (in my imagination) wouldn't match the high-standards I expect you hold). Have already admitted that I (personally) may 'over use' RDBMS because it is 'easy' for me. When we do feel the justification to examine the details of "worst case scenarios"/"did you think of this?" RDBMS stand-out as a 'solution' simply because of the incredible amounts of time and depths of thought, highly-specialised minds (far superior to any input I could offer) have invested in providing highly refined services/servers. (which I dare-say informed @Chris' comments) Neither MSFT nor the relevant GNU/Linux projects assure common file systems to such a degree (and particularly not in the mentioned circumstances). That's why there are FS 'rescue' procedures (Linux runs fsck automatically when 'trouble' is noted during system-start and every so-many reboots, regardless). I'm sufficiently intrigued to wonder if anyone will dispute/correct such - but not sufficiently motivated to research any position other than the one currently held - so call me "Curious", but not "George" then... >> There are so many reasons why such won't work first-time, when they should >> every time; that it may be quite difficult to detect 'corruption' > > :-) That was not even considered. Just the "what do I still need to > download" datafile. Yes, we left the OP's (actual) spec, way-back somewhere! >> Accordingly, there is no non-atomic transaction in the proposal > > The problem there is that you are second-guessing to what the OP will be > writing, and that it will be good. I didn't and I don't assume that. I've > seen too much "it works, so its good" noobie code. :-) Absolutely! One of the 'joys' of working text-only is that even when one knows (much) more about the background to a posted-question, it is still so easy to 'answer-wrong'. Even in my courses, where the Discussion Lists (are supposedly) related to each week/chapter of a course, you'd think we'd have adequate 'hints' as to the level of the trainee and where his/her question is 'coming-from'. Not true! The secret is probably somewhere in the understanding of *that* potential problem and going from there... Sigh, if I had a dollar for every time someone looked at a simple solution (MS-Excel I'm looking at you!) and uttered 'suggestions' such as "we could run the entire company off one of these spreadsheet things" or "if we captured all the company's transactions, couldn't we run it off one Python pgm?"... The world has moved-on though. Forty years ago it was common for someone writing his/her first program(me) to come 'crying' "the computer made a mistake" because it performed some simple arithmetic/statistical calculation without yielding the expected answer! That said, it continues to astonish me that computing-professionals still can't apply the 'attention to detail' coding requires to their typing - regardless of whether the input is code or a Discussion List post. What is that mind-set??? (this comment NOT aimed at you, or any other participant on this list, personally!) >> Do I want to deal with the complexities of managing files and corruptions, >> in that arena? > ... >> Do you? > > :-) Its was-and-is not my choice to make. I gave the OP some stuff to > think about, and left making the choice upto him. All three of the > presented options are viable. Good stuff! Yet at the same time, that very lack of clarity is good reason to allow that 'another' solution might be 'right' - even if it is not 'better'. (for any definitions of "right" or "better", or ...) As sent to the OP. I appreciate these discussions, in the expectation of learning something-new. (and with rust-removal paints at the ready!) >> Be aware that formation rules for URLs are not congruent with OS FS rules! > > Yup. Though I seldom see that happen. Though I guess I should have > mentioned that ... :-| I'd show you the marks where that came back to bite me once - but fortunately for you, the list doesn't allow graphic attachments (nor should distressed (and distressing) images of such parts of one's anatomy EVER be seen, even by qualified medical professionals...) -- Regards =dn From PythonList at DancesWithMice.info Sat Feb 1 00:48:41 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Sat, 1 Feb 2020 18:48:41 +1300 Subject: Please answer fast..... In-Reply-To: References: Message-ID: On 1/02/20 1:05 AM, Souvik Dutta wrote: > Hi, > This is problem from pyqt5. Actually I want to have about 40 labels added > into a window when a button is clicked. The text are not the same so the > label is not the same. I cannot just add 40 labels before hand and then > change its text to something from a qlineedit. Please say me something that > is more efficient and less idiot like. Thank you. Hi, you have certainly become part of the Python community. It's probably too late to say "welcome". Perhaps you are unfamiliar with this sort of discussion list, so please allow me try helping you to fit-in... Are you aware that the people who might ask your question are paid as much for that, as you were when asking it? ie ZERO! Is the message title respectfully asking for someone to give-up his/her free time to help you? The key word is "community" (as distinct from HelpDesk or (salaried) Support Department). Has this question been asked before? Such could only be ascertained by reviewing the list's archives (which we should all do before posting). Let's assume (with some confidence) that you are 'the first' to ask about Qt5 labels and buttons, how might someone else with a similar question, sometime in the future, be able to find 'the answer'? Would the message title "Please answer fast..." do it for you/for them? So, thoughtful selection of question subject-lines, just as for Python object names, is how you would be helping us all! (at the same time as asking ('everyone') for help) Sometimes people come to the list asking for 'work' to be done for them - either to avoid $paying a professional, or perhaps to avoid doing their homework - which rather defeats their learning objectives, but...! (that's a question/reference you will have seen on-list during the last few days) If you show (code) what you have done (and err.msgs showing where it went-wrong), might other people be more motivated to help you? Similarly, (see this sort of response in other posts) if you are challenged coping with something 'new', would it help a respondent if you mentioned your (level of) existing knowledge, eg even "it worked in Qt4" informs. If "forms" is a new topic to you, or you are a beginner at learning Python, mentioning the tutorial/book/course you are following would also help 'set the scene' and assist/motivate us to help you with something "more efficient and less idiot like". (More/less than what?) Lastly, (and with apologies because I don't know the answer to either your posted-question, or this one) is this the best place for Qt questions, or are there alternative venues? Which is not to say that there won't be someone, who is also using Qt5 from Python, who will be able to help... Apologies if it feels as if I am rebuking you. The intent is actually to help you, and to hope that as you ask questions and learn for yourself, we might also learn (from you)! (the bulk of the membership read far more posts than they ever post/contribute answers) Here's hoping someone smarter than I (and five times cuter - hah, "Qt5"!) will be able to help... -- Regards =dn From khishorks at gmail.com Sat Feb 1 01:19:56 2020 From: khishorks at gmail.com (khishorks at gmail.com) Date: Fri, 31 Jan 2020 22:19:56 -0800 (PST) Subject: data sequencing Message-ID: <3b2b69b8-aa45-448d-9518-add43f8d86bb@googlegroups.com> I have a data sequence of around 300000 sets. I need to batch the sequence into an input-output format. for example data= [1,2,3,4,5,6,7,8,9,10,......,100] X1= [1,2,3,4,5,6,7,8,9,10] y1 = [11,12] X2= [3,4,5,6,7,8,9,....11,12] y2 = [13,14] and it continues till 100. here X is input and y is output. How to sequence the data in steps of 2? From rosuav at gmail.com Sat Feb 1 03:27:49 2020 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 1 Feb 2020 19:27:49 +1100 Subject: Suggestions on mechanism or existing code - maintain persistence of file download history In-Reply-To: <929c8cba-5f5a-8bb9-9396-73124d1acbfc@DancesWithMice.info> References: <9d1c662e-c63e-3400-b068-d1834e7f169c@DancesWithMice.info> <929c8cba-5f5a-8bb9-9396-73124d1acbfc@DancesWithMice.info> Message-ID: On Sat, Feb 1, 2020 at 4:17 PM DL Neil via Python-list wrote: > > On 31/01/20 9:53 PM, R.Wieser wrote: > >> Using ctrl+c is a VERY BAD idea. > > > > To have it just exit the program ? Yes, indeed. > > > > Though you /could/ keep track of what needs to be finished and have the > > ctrl-c handler do that for you (barf). > > > > Another posibility is to capture the ctrl-c and set a flag, which than > > instructs the program to terminate loops wherever possible - and thus have > > the program finish as if there was no more to do. > > > >> (see also 'sledgehammer to crack a nut') > > > > While I agree with you there, I've been searching for other ways to detect a > > keypress (in a console-based script) and have found none. IOW, you do not > > (seem to) have another option. > > Color me disappointed! I was hoping to be enlightened as to how one > might code exactly that. (so I went looking...) > > My first thought was a try...except looking for a keyboard error, but > wouldn't that only work if there was an input() loop? The idea of > putting, effectively the entire code-base, into a try...except block > seemed crude and likely to cause side-effects. No, it should be fine - you'll get KeyboardInterrupt even without input(). At least, you will on Unix systems; can someone confirm that this is also the case on Windows? Having a try/except around your main function that catches one specific exception is usually fine. I often do this in the main of something that's designed to run a server - for development, I'll invoke the script directly and then Ctrl-C to stop it, for deployment, it'll be run through some service manager. > Sigh, if I had a dollar for every time someone looked at a simple > solution (MS-Excel I'm looking at you!) and uttered 'suggestions' such > as "we could run the entire company off one of these spreadsheet things" > or "if we captured all the company's transactions, couldn't we run it > off one Python pgm?"... ... ugh, I feel your pain... yep, heard that sort of thing way too many times. ChrisA From PythonList at DancesWithMice.info Sat Feb 1 03:40:51 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Sat, 1 Feb 2020 21:40:51 +1300 Subject: data sequencing In-Reply-To: <3b2b69b8-aa45-448d-9518-add43f8d86bb@googlegroups.com> References: <3b2b69b8-aa45-448d-9518-add43f8d86bb@googlegroups.com> Message-ID: <5f516607-67a7-3491-5a65-8a628fe34466@DancesWithMice.info> On 1/02/20 7:19 PM, khishorks at gmail.com wrote: > I have a data sequence of around 300000 sets. I need to batch the sequence into an input-output format. for example > > data= [1,2,3,4,5,6,7,8,9,10,......,100] > > X1= [1,2,3,4,5,6,7,8,9,10] y1 = [11,12] > X2= [3,4,5,6,7,8,9,....11,12] y2 = [13,14] > and it continues till 100. > > here X is input and y is output. How to sequence the data in steps of 2? Hi, welcome to the list! What is the application - or is this ComSc 'homework'? Have you considered for-loops? What code have you written have so-far, and what does it output? -- Regards =dn From hjp-python at hjp.at Sat Feb 1 06:58:15 2020 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sat, 1 Feb 2020 12:58:15 +0100 Subject: Suggestions on mechanism or existing code - maintain persistence of file download history In-Reply-To: References: Message-ID: <20200201115815.GA3731@hjp.at> On 2020-01-30 07:56:30 +1100, Chris Angelico wrote: > On Thu, Jan 30, 2020 at 7:49 AM MRAB wrote: > > On 2020-01-29 20:00, jkn wrote: > > > I could have a file with all the URLs listed and work through each line in turn. > > > But then I would have to rewrite the file (say, with the previously-successful > > > lines commented out) as I go. > > > > > Why comment out the lines yourself when the download manager could do it > > for you? > > > > Load the list from disk. > > > > For each uncommented line: > > > > Download the file. > > > > Comment out the line. > > > > Write the list back to disk. > > Isn't that exactly what the OP was talking about? It involves > rewriting the file at every step, with the consequent risks of > trampling on other changes, corruption on error, etc, etc, etc. If you do it right, the risk is small: 1) read file, 2) do the download 3) write temporary file with changes 4) rename temporary file to file. Remaining risks: Someone might start the download manager twice. This can be prevented with a lock file. The computer might crash between 3 and 4 (or shortly after 4). In this case you might lose the contents of file. This can be prevented with proper use of fsync, but at this point it gets complicated and filesystem dependent (there were a number of papers and talks about this topic over the last few years), so personally I would live with the risk or use a database. Subrisk: Your disk might lie to your computer about having stored the data. In this case there is nothing you can do except buying a better disk. 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 address at not.available Sat Feb 1 07:00:18 2020 From: address at not.available (R.Wieser) Date: Sat, 1 Feb 2020 13:00:18 +0100 Subject: Suggestions on mechanism or existing code - maintain persistence of file download history References: <9d1c662e-c63e-3400-b068-d1834e7f169c@DancesWithMice.info> <929c8cba-5f5a-8bb9-9396-73124d1acbfc@DancesWithMice.info> Message-ID: DL, >> While I agree with you there, I've been searching for other ways to >> detect a >> keypress (in a console-based script) and have found none. .... > > Color me disappointed! I was disapponted too, but realized that being able to just capture any keypress (how does the 'puter know the script has focus, as there is nothing to give it to) is an easy way to userland keylogging ... > but wouldn't that only work if there was an input() loop? Just being able to check for such a keypress at the end of a "do the next download" (in the OPs case) loop would be enough for me. > Understood. However, your understanding of RDBMS interrupt 'security' > appears either aged, or biased to a particular implementation (which (in > my imagination) wouldn't match the high-standards I expect you hold). :-) You might well be correct there. Mea culpa. As for the high standards ? While I am quite sure that currently any self-respecting DB system will be crammed full with methods to forgo corruption, it always sticks in my mind that its possible. In other words, its possible I'm simply a bit too cautious. Than again, switching an unresponsive 'puter off by pressing the powerbutton for a couple of seconds is a wide/well-known practice ... :-( > Good stuff! Yet at the same time, that very lack of clarity is good reason > to allow that 'another' solution might be 'right' - even if it is not > 'better'. > (for any definitions of "right" or "better", or ...) "The very lack of clarity" ? But yes, keeping the possibility open that some other method (than the ones presented) could be even more apropriate is part of why I leave the choice with the asker. Its all too easy to (unwittingly) automatically think in a certain direction, and than overlook other solutions ("for someone with a hammer" and all that). > As sent to the OP. I appreciate these discussions, in the expectation of > learning something-new. (and with rust-removal paints at the ready!) Indeed. Even if its just a different POV which makes you rethink the reasons of your own one. Regards, Rudy Wieser From souvik.viksou at gmail.com Sat Feb 1 07:06:12 2020 From: souvik.viksou at gmail.com (Souvik Dutta) Date: Sat, 1 Feb 2020 17:36:12 +0530 Subject: Pyqt5 help In-Reply-To: References: Message-ID: I was making a pyqt5 project and I ran into a problem. I want a button in one window to add a label in another window when clicked upon. But that is not happening. Now the no. Of labels depend upon something, so I decided to use a for loop which is not working. Attaching the code below. Can you help? -------------- next part -------------- from PyQt5 import QtWidgets, QtCore, QtGui from datetime import * from PyQt5.QtWidgets import QApplication, QMainWindow, QLineEdit import sys class mywindow(QMainWindow): def __init__(self): super(mywindow, self).__init__() self.setGeometry(100, 100, 700, 600) self.setWindowTitle("The HBT App") self.initUi() def initUi(self): self.img_label1 = QtWidgets.QLabel(self) self.img_label1.setGeometry(QtCore.QRect(235, 0, 470, 270)) self.img_label1.setPixmap(QtGui.QPixmap("birthday cake.jpg")) self.img_label1.setScaledContents(True) self.img_label1 = QtWidgets.QLabel(self) self.img_label1.setGeometry(QtCore.QRect(0, 0, 240, 270)) self.img_label1.setPixmap(QtGui.QPixmap("whitewash.jpg")) self.img_label1.setScaledContents(True) self.img_label2 = QtWidgets.QLabel(self) self.img_label2.setPixmap(QtGui.QPixmap("blackline.jpg")) self.img_label2.setGeometry(QtCore.QRect(100, 298, 605, 3)) self.Label = QtWidgets.QLabel(self) self.Label.setText("Upcoming") self.Label.setFont(QtGui.QFont("Arial", 14)) self.Label.setGeometry(QtCore.QRect(10, 280, 101, 31)) self.button = QtWidgets.QPushButton(self) self.button.setText("Add..") self.button.setGeometry(QtCore.QRect(590, 510, 80, 60)) self.button.clicked.connect(self.clicked) self.button.setFont(QtGui.QFont("Arial", 18)) self.n = {} def clicked(self): self.NewWindow = QtWidgets.QMainWindow() self.NewWindow.setGeometry(100, 100, 500, 500) self.NewWindow.setWindowTitle("Add friends") self.FriendLabel = QtWidgets.QLabel(self.NewWindow) self.FriendLabel.setText("Add Friends") self.FriendLabel.setFont(QtGui.QFont("Comic Sans MS", 18)) self.FriendLabel.setGeometry(180, 40, 400, 100) self.Namelabel = QtWidgets.QLabel(self.NewWindow) self.Namelabel.setText("Name : ") self.Namelabel.setGeometry(QtCore.QRect(80, 170, 90, 75)) self.Namelabel.setFont(QtGui.QFont("Comic Sans MS", 14)) self.Namefield = QLineEdit(self.NewWindow) self.Namefield.setGeometry(QtCore.QRect(160, 190, 250, 35)) self.Datelabel = QtWidgets.QLabel(self.NewWindow) self.Datelabel.setText("Birthday: ") self.Datelabel.setGeometry(QtCore.QRect(62, 240, 90, 75)) self.Datelabel.setFont(QtGui.QFont("Comic Sans MS", 14)) self.Datefield = QLineEdit(self.NewWindow) self.Datefield.setGeometry(QtCore.QRect(160, 260, 250, 35)) self.Save = QtWidgets.QPushButton(self.NewWindow) self.Save.setText("Save") self.Save.setFont(QtGui.QFont("Comic Sans MS", 14)) self.Save.setGeometry(QtCore.QRect(70, 360, 90, 50)) self.Save.clicked.connect(self.save) self.Cancel = QtWidgets.QPushButton(self.NewWindow) self.Cancel.setText("Cancel") self.Cancel.setFont(QtGui.QFont("Comic Sans MS", 14)) self.Cancel.setGeometry(QtCore.QRect(360, 360, 90, 50)) self.Cancel.clicked.connect(self.cancel) self.NewWindow.show() def save(self): self.friend_name = self.Namefield.text() self.friend_date = self.Datefield.text() self.Namefield.clear() self.Datefield.clear() self.n[self.friend_name] = self.friend_date print(self.n) for a in self.n: NewLabel = QtWidgets.QLabel(self) NewLabel.setText(self.friend_name + "has birthday on " + self.friend_date) NewLabel.setGeometry(QtCore.QRect(30, 250, 100, 100)) self.check_date() def check_date(self): today = datetime.now() only_date = today.day strdate = datetime.strptime(self.friend_date, "%d/%m").date() onlydate = strdate.day only_month = today.month onlymonth = strdate.month if only_month == onlymonth and onlydate == only_date: print("Today is ", self.friend_name, "'s birthday.") def cancel(self): self.Namefield.clear() self.Datefield.clear() def window(): app = QApplication(sys.argv) win = mywindow() win.show() sys.exit(app.exec_()) window() From barry at barrys-emacs.org Sat Feb 1 11:41:22 2020 From: barry at barrys-emacs.org (Barry Scott) Date: Sat, 1 Feb 2020 16:41:22 +0000 Subject: Pyqt5 help In-Reply-To: References: Message-ID: <88A532D5-3E34-4C55-A46E-AC29EEBB5832@barrys-emacs.org> > On 1 Feb 2020, at 12:06, Souvik Dutta wrote: > > I was making a pyqt5 project and I ran into a problem. I want a button in > one window to add a label in another window when clicked upon. But that is > not happening. Now the no. Of labels depend upon something, so I decided to > use a for loop which is not working. Attaching the code below. Can you help? > -- > https://mail.python.org/mailman/listinfo/python-list I just read the code, did not run it. The file should have .py as the extension not .txt. In python3 its super().__init__ no need for the args. I cannot see you calling setCentralWidget() so nothing will be drawn. If you expect to show more then 1 Widget you will have to use layout widgets. Here is the ref to the Qt docs on layouts. https://doc.qt.io/qt-5/examples-layouts.html A blank line before each def would make the code easier to read. Barry From marek.mosiewicz at jotel.com.pl Sat Feb 1 12:13:51 2020 From: marek.mosiewicz at jotel.com.pl (Marek Mosiewicz) Date: Sat, 01 Feb 2020 18:13:51 +0100 Subject: Calculator In-Reply-To: <5e1f4758$0$21588$426a74cc@news.free.fr> References: <055c4593-5542-4ac5-b603-6b6104855a90@googlegroups.com> <49bf3a3b-8840-47c9-ba4c-e96cc8e5c40e@googlegroups.com> <5e1f4758$0$21588$426a74cc@news.free.fr> Message-ID: Considering just basic calculator with eval it could be possible search eval string if it only contains digits, parenthensis and operators. Assuring no letter (maybe except e for expotential) and special characters this calculator should be quite safe. But I give no any warranty for such security. Cheers, Marek Mosiewicz W dniu ?ro, 15.01.2020 o godzinie 18?09?+0100, u?ytkownik Python napisa?: > Le 15/01/2020 ? 16:34, andershe02 at gmail.com a ?crit : > > Thanks! > > Do not try it, though, with a expression such as > import os; os.system('rm -rf ~/*'). > > > From PythonList at DancesWithMice.info Sat Feb 1 17:03:23 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Sun, 2 Feb 2020 11:03:23 +1300 Subject: Suggestions on mechanism or existing code - maintain persistence of file download history In-Reply-To: References: <9d1c662e-c63e-3400-b068-d1834e7f169c@DancesWithMice.info> <929c8cba-5f5a-8bb9-9396-73124d1acbfc@DancesWithMice.info> Message-ID: On 2/02/20 1:00 AM, R.Wieser wrote: >> As sent to the OP. I appreciate these discussions, in the expectation of >> learning something-new. (and with rust-removal paints at the ready!) > > Indeed. Even if its just a different POV which makes you rethink the > reasons of your own one. +1 -- Regards =dn From jon+usenet at unequivocal.eu Sun Feb 2 09:46:07 2020 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Sun, 2 Feb 2020 14:46:07 -0000 (UTC) Subject: JavaScript's void operator in Python? References: Message-ID: On 2020-02-02, Stefan Ram wrote: > JavaScript has a void operator that maps everything to > undefined. E.g., > > JavaScript console > >|< void( console.log( 2 ) ) >| 2 >|> undefined > > I can easily write a corresponding function in Python. > > main.py > > def void( x ): > pass > > void( ( print( 2 ), print( 3 ))) > > transcript > > 2 > 3 > > . But is an operator or a function like that already > defined in Python or its standard library? I'm not sure why you'd want to - but "None and foo" is an expression that will return None regardless of the value of "foo". From souvik.viksou at gmail.com Sun Feb 2 10:55:21 2020 From: souvik.viksou at gmail.com (Souvik Dutta) Date: Sun, 2 Feb 2020 21:25:21 +0530 Subject: App made with pyinstaller is not running on another computer. Message-ID: Hi, I made an executable file with pyinstaller on my pc which had python 3.7. It ran well in my pc but when I tried to run it on my friend computer having a 32 bit windows 10 os it didn't run it is just saying that "this app cannot be run on your pc". My pc has a 64 bit version of windows 10 and also my friend does not has any version of python installed. Can you help me solve this problem? Thank you for your precious time. From souvik.viksou at gmail.com Sun Feb 2 10:59:01 2020 From: souvik.viksou at gmail.com (Souvik Dutta) Date: Sun, 2 Feb 2020 21:29:01 +0530 Subject: PyQt5 help on buttons and grid layout Message-ID: Hi, I want to add about 40 buttons based upon a dictionary. I want them to be added to a grid layout. How can I do it easily. Please write the code and thank you for your trouble. From rosuav at gmail.com Sun Feb 2 11:03:03 2020 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 3 Feb 2020 03:03:03 +1100 Subject: App made with pyinstaller is not running on another computer. In-Reply-To: References: Message-ID: On Mon, Feb 3, 2020 at 2:57 AM Souvik Dutta wrote: > > Hi, > I made an executable file with pyinstaller on my pc which had python 3.7. > It ran well in my pc but when I tried to run it on my friend computer > having a 32 bit windows 10 os it didn't run it is just saying that "this > app cannot be run on your pc". My pc has a 64 bit version of windows 10 and > also my friend does not has any version of python installed. Can you help > me solve this problem? Thank you for your precious time. Easy fix: Have your friend install Python, and then just give him/her the .py file instead of using pyinstaller. Way WAY easier and more reliable. ChrisA From arj.python at gmail.com Sun Feb 2 12:08:09 2020 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Sun, 2 Feb 2020 21:08:09 +0400 Subject: App made with pyinstaller is not running on another computer. In-Reply-To: References: Message-ID: recompile with the latest dev versio of pyinstaller, fixed my issue. On Sun, 2 Feb 2020, 19:55 Souvik Dutta, wrote: > Hi, > I made an executable file with pyinstaller on my pc which had python 3.7. > It ran well in my pc but when I tried to run it on my friend computer > having a 32 bit windows 10 os it didn't run it is just saying that "this > app cannot be run on your pc". My pc has a 64 bit version of windows 10 and > also my friend does not has any version of python installed. Can you help > me solve this problem? Thank you for your precious time. > -- > https://mail.python.org/mailman/listinfo/python-list > From arj.python at gmail.com Sun Feb 2 12:09:33 2020 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Sun, 2 Feb 2020 21:09:33 +0400 Subject: PyQt5 help on buttons and grid layout In-Reply-To: References: Message-ID: d = {} layout = ... for key in d: layout.addWidget(QButton(...)) On Sun, 2 Feb 2020, 19:59 Souvik Dutta, wrote: > Hi, > I want to add about 40 buttons based upon a dictionary. I want them to be > added to a grid layout. How can I do it easily. Please write the code and > thank you for your trouble. > -- > https://mail.python.org/mailman/listinfo/python-list > From python at invalid Sun Feb 2 13:53:44 2020 From: python at invalid (Python) Date: Sun, 2 Feb 2020 19:53:44 +0100 Subject: JavaScript's void operator in Python? In-Reply-To: References: Message-ID: <5e371abc$0$10392$426a74cc@news.free.fr> Stefan Ram wrote: > Jon Ribbens writes: >> On 2020-02-02, Stefan Ram wrote: >>> void( ( print( 2 ), print( 3 ))) >>> 2 >>> 3 >> I'm not sure why you'd want to - but "None and foo" is an expression >> that will return None regardless of the value of "foo". > > Yes, but it also does not evaluate the second operand. I.e., > > None and( print( 2 ), print( 3 )) > > prints nothing at all. > > I was looking for something that still evaluates and then > maps the value obtained to None. ( (print(2), print(3)), None)[1] I wonder why one would need such a thing, though... From kent.tong.mo at gmail.com Sun Feb 2 04:43:47 2020 From: kent.tong.mo at gmail.com (Kent Tong) Date: Sun, 2 Feb 2020 01:43:47 -0800 (PST) Subject: My Python programming book for kids is free for 48 hours Message-ID: Hi, If you're interested, please get it for free at: https://www.amazon.com/Yes-Kids-can-learn-Python-ebook/dp/B084CY2L43/ref=sr_1_3 This is a set of training materials I used to successfully teach Python to kids as little as 10 years old. The online learning environment are freely available at https://p4kweb.appspot.com and the first four chapters are available at https://www.istudycenter.org/yes-kids-can-learn-python. Lesson 1: Call a function & use variables Lesson 2: Expressions and text strings Lesson 3: Perform various calculations based values input by the user Lesson 4: Use the tank to draw shapes with its bombs Lesson 5: Show an input box and use "if" in Python Lesson 6: Prompt for multiple values and display information in a message box Lesson 7: increase the value of a variable and call a function that gives back information Lesson 8: Use "if" without "else" Lesson 9: Use "if" to guard against an operation that might fail Lesson 10: 2D coordinate system for positioning objects Lesson 11: Respond to mouse clicks and kick start a continuous process Lesson 12: Use random numbers Lesson 13: Use 'and' or embedded 'if's Lesson 14: Respond to key presses Lesson 15: Respond to key presses (2) Lesson 16: Boolean values and stop a continuous process Lesson 17: stop a continuous process (2) Lesson 18: Steer a continuous process From alan.gauld at yahoo.co.uk Sun Feb 2 09:52:25 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 2 Feb 2020 14:52:25 +0000 Subject: Pyqt5 help In-Reply-To: References: Message-ID: On 01/02/2020 12:06, Souvik Dutta wrote: > I was making a pyqt5 project and I ran into a problem. I want a button in > one window to add a label in another window when clicked upon. But that is > not happening. What is happening? Don't expect us to run your buggy code! > Now the no. Of labels depend upon something, so I decided to > use a for loop which is not working. Looking at the code I see: for a in self.n: NewLabel = QtWidgets.QLabel(self) NewLabel.setText(self.friend_name + "has birthday on " + self.friend_date) NewLabel.setGeometry(QtCore.QRect(30, 250, 100, 100)) I'm no Qt expert but it seems that you are overwriting the same widget (or widget location?) with all of the labels? And all of the labels are identical since you use the same data to create them? I would expect something more like (pseudo code!): for a in self.n: newLabel = QtWidgets.QLabel(self) NewLabel.setText(self.friends[a].friend_name + "has birthday on " + self.friends[a]._date) NewLabel.setGeometry(QtCore.QRect(self.calculateGeometry(a)) self.friendLabels.append(newLabel) # if you need a reference -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at yahoo.co.uk Sun Feb 2 10:09:42 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 2 Feb 2020 15:09:42 +0000 Subject: Pyqt5 help In-Reply-To: References: Message-ID: On 01/02/2020 12:06, Souvik Dutta wrote: > not happening. Now the no. Of labels depend upon something, so I decided to > use a for loop which is not working. Attaching the code below. Can you help? I just spotted something else odd in your code: def initUi(self): ... self.n = {} self.n is a dictionary.... maybe self.friends would be a better name? def save(self): self.friend_name = self.Namefield.text() self.friend_date = self.Datefield.text() self.n[self.friend_name] = self.friend_date And here you add a new value from your UI fields for a in self.n: Now you iterate over the dictionary creating a label for each entry in the dict but... NewLabel = QtWidgets.QLabel(self) NewLabel.setText(self.friend_name + "has birthday on " + self.friend_date) NewLabel.setGeometry(QtCore.QRect(30, 250, 100, 100)) The labels all have the name of the most recent friend? And they all have the same geometry, so presumably sit on top of each other? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From arj.python at gmail.com Sun Feb 2 12:12:23 2020 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Sun, 2 Feb 2020 21:12:23 +0400 Subject: Please answer fast..... In-Reply-To: References: Message-ID: I'm 100% ready to answer your question, just add some more details like why you need 40 labels. From arj.python at gmail.com Sun Feb 2 13:05:25 2020 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Sun, 2 Feb 2020 22:05:25 +0400 Subject: Please answer fast..... In-Reply-To: References: Message-ID: Ah ok. suggest you put names, birthday in csv the load csv for each row: layout.addWidget(QLabel) On Sun, 2 Feb 2020, 21:21 Souvik Dutta, wrote: > Because i want to show the name and date of 40 persons and their birthdays. > > On Sun, Feb 2, 2020, 10:42 PM Abdur-Rahmaan Janhangeer < > arj.python at gmail.com> wrote: > >> I'm 100% ready to answer your question, just add some more details like >> why you need 40 labels. >> > From PythonList at DancesWithMice.info Sun Feb 2 16:05:31 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Mon, 3 Feb 2020 10:05:31 +1300 Subject: Please answer fast..... In-Reply-To: References: Message-ID: <96baf6aa-b1a4-b596-5ac1-916c9801eee7@DancesWithMice.info> On 3/02/20 7:05 AM, Abdur-Rahmaan Janhangeer wrote: ... > suggest you put names, birthday in csv > > the load csv > > for each row: > layout.addWidget(QLabel) > > On Sun, 2 Feb 2020, 21:21 Souvik Dutta, wrote: > >> Because i want to show the name and date of 40 persons and their birthdays. Why csv? Why prefer that over native-Python constructs, eg two 40-element lists, a list of (pairs) lists, or indeed a dict with name as 'key' and date as 'value'? -- Regards =dn From greg.ewing at canterbury.ac.nz Sun Feb 2 17:41:28 2020 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Mon, 3 Feb 2020 11:41:28 +1300 Subject: JavaScript's void operator in Python? In-Reply-To: References: Message-ID: On 3/02/20 3:38 am, Stefan Ram wrote: > void( ( print( 2 ), print( 3 ))) If the functions you're calling all return None, you can do this: >>> print(2); print(3) 2 3 -- Greg From jon+usenet at unequivocal.eu Sun Feb 2 18:06:50 2020 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Sun, 2 Feb 2020 23:06:50 -0000 (UTC) Subject: JavaScript's void operator in Python? References: Message-ID: On 2020-02-02, Stefan Ram wrote: > Greg Ewing writes: >>If the functions you're calling all return None, you can >>do this: >> >>> print(2); print(3) > > ?print(2); print(3)? is not an expression anymore but an stmt_list. > It cannot be used in all places where an expression is allowed. Why does it matter if the return value is None? "print(2), print(3)" is an expression that will evaluate all of its sub-expressions. If the sub-expressions return None then I guess you could do "(x, y, z)[0]" too. From jon+usenet at unequivocal.eu Sun Feb 2 18:29:47 2020 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Sun, 2 Feb 2020 23:29:47 -0000 (UTC) Subject: JavaScript's void operator in Python? References: Message-ID: On 2020-02-02, Stefan Ram wrote: > Jon Ribbens writes: >>Why does it matter if the return value is None? > > In a lambda, a return value of None sometimes would be > convenient as by convention it indicates that the return > value does not carry any information and the function is > intended to be used just for its effect. A value of None > will not be printed in the console, so it does not add > distracting noise there. If it's a lambda then the arguments will be evaluated before the lambda is called anyway, so: >>> f = lambda *x: None >>> f(print(2), print(3)) 2 3 Or if you're writing it inline then: >>> (None, print(2), print(3))[0] 2 3 From arj.python at gmail.com Sun Feb 2 19:41:28 2020 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Mon, 3 Feb 2020 04:41:28 +0400 Subject: Please answer fast..... In-Reply-To: <96baf6aa-b1a4-b596-5ac1-916c9801eee7@DancesWithMice.info> References: <96baf6aa-b1a4-b596-5ac1-916c9801eee7@DancesWithMice.info> Message-ID: CSV as data entry with " " is a pain. > > From PythonList at DancesWithMice.info Sun Feb 2 21:15:04 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Mon, 3 Feb 2020 15:15:04 +1300 Subject: The source of the PSL* Message-ID: <933cbd11-6a70-1dd1-b863-5c413450a41c@etelligence.info> Is there a set location for PSL project repos? (it used to be GitHub, and before that, Google) I'd like to review some serious PyTest/Unittest examples, eg as are applied to familiar (Python source) library members... * should be easier to find than was the source of the Nile (by Europeans) -- Regards, =dn From frank at chagford.com Mon Feb 3 01:56:50 2020 From: frank at chagford.com (Frank Millman) Date: Mon, 3 Feb 2020 08:56:50 +0200 Subject: lxml - minor problem appending new element Message-ID: Hi all I usually send lxml queries to the lxml mailing list, but it appears to be not working, so I thought I would try here. This is a minor issue, and I have found an ugly workaround, but I thought I would mention it. In Python I can iterate through a list, and on a certain condition append a new item to the list, which is then included in the iteration. >>> x = ['a', 'b', 'c'] >>> for y in x: ... print(y) ... if y == 'b': ... x.append('d') ... a b c d >>> x ['a', 'b', 'c', 'd'] >>> The same thing works in lxml - >>> lmx = '' >>> xml = etree.fromstring(lmx) >>> for y in xml: ... print(etree.tostring(y)) ... if y.get('z') == 'b': ... xml.append(etree.Element('y', attrib={'z': 'd'})) ... b'' b'' b'' b'' >>> etree.tostring(xml) b'' However, if it happens that the condition is met on the last item in the list, Python still works, but lxml does not include the appended item in the iteration. In the following, the only change is checking for 'c' instead of 'b'. >>> x = ['a', 'b', 'c'] >>> for y in x: ... print(y) ... if y == 'c': ... x.append('d') ... a b c d >>> x ['a', 'b', 'c', 'd'] >>> >>> lmx = '' >>> xml = etree.fromstring(lmx) >>> for y in xml: ... print(etree.tostring(y)) ... if y.get('z') == 'c': ... xml.append(etree.Element('y', attrib={'z': 'd'})) ... b'' b'' b'' >>> etree.tostring(xml) b'' As you can see, the last element is correctly appended, but is not included in the iteration. Is there any chance that this can be looked at, or is it just the way it works? BTW, I see that ElementTree in the standard library does not have this problem. Thanks Frank Millman From __peter__ at web.de Mon Feb 3 03:39:10 2020 From: __peter__ at web.de (Peter Otten) Date: Mon, 03 Feb 2020 09:39:10 +0100 Subject: lxml - minor problem appending new element References: Message-ID: Frank Millman wrote: > Hi all > > I usually send lxml queries to the lxml mailing list, but it appears to > be not working, so I thought I would try here. > > This is a minor issue, and I have found an ugly workaround, but I > thought I would mention it. Like this? children = list(xml) for y in children: print(etree.tostring(y)) if y.get('z') == 'c': child = etree.Element('y', attrib={'z': 'd'}) xml.append(child) children.append(child) It doesn't look /that/ ugly to me. > In Python I can iterate through a list, and on a certain condition > append a new item to the list, which is then included in the iteration. Personally I follow the rule "never mutate a list you are iterating over", even for appends, where the likelihood of problems is small: items = ["a"] for item in items: if item == "a": items.append("a") > >>> x = ['a', 'b', 'c'] > >>> for y in x: > ... print(y) > ... if y == 'b': > ... x.append('d') > ... > a > b > c > d > >>> x > ['a', 'b', 'c', 'd'] > >>> > > The same thing works in lxml - > > >>> lmx = '' > >>> xml = etree.fromstring(lmx) > >>> for y in xml: > ... print(etree.tostring(y)) > ... if y.get('z') == 'b': > ... xml.append(etree.Element('y', attrib={'z': 'd'})) > ... > b'' > b'' > b'' > b'' > >>> etree.tostring(xml) > b'' > > However, if it happens that the condition is met on the last item in the > list, Python still works, but lxml does not include the appended item in > the iteration. In the following, the only change is checking for 'c' > instead of 'b'. > > >>> x = ['a', 'b', 'c'] > >>> for y in x: > ... print(y) > ... if y == 'c': > ... x.append('d') > ... > a > b > c > d > >>> x > ['a', 'b', 'c', 'd'] > >>> > > >>> lmx = '' > >>> xml = etree.fromstring(lmx) > >>> for y in xml: > ... print(etree.tostring(y)) > ... if y.get('z') == 'c': > ... xml.append(etree.Element('y', attrib={'z': 'd'})) > ... > b'' > b'' > b'' > >>> etree.tostring(xml) > b'' > > As you can see, the last element is correctly appended, but is not > included in the iteration. > > Is there any chance that this can be looked at, or is it just the way it > works? File a bug report and see if the author is willing to emulate the list behaviour. > BTW, I see that ElementTree in the standard library does not have this > problem. Maybe uses a list under the hood. From frank at chagford.com Mon Feb 3 04:43:25 2020 From: frank at chagford.com (Frank Millman) Date: Mon, 3 Feb 2020 11:43:25 +0200 Subject: lxml - minor problem appending new element In-Reply-To: References: Message-ID: <1baa0763-8211-d810-d79a-5ee80d1cc846@chagford.com> On 2020-02-03 10:39 AM, Peter Otten wrote: > Frank Millman wrote: > >> This is a minor issue, and I have found an ugly workaround, but I >> thought I would mention it. > > Like this? > > children = list(xml) > for y in children: > print(etree.tostring(y)) > if y.get('z') == 'c': > child = etree.Element('y', attrib={'z': 'd'}) > xml.append(child) > children.append(child) > > It doesn't look /that/ ugly to me. > That is not bad. My actual solution was to revert to the non-pythonic method of iterating over a list - pos = 0 while pos < len(xml): y = xml[pos] print(etree.tostring(y)) if y.get('z') == 'c': xml.append(etree.Element('y', attrib={'z': 'd'})) pos += 1 That way, if I append to xml, I automatically pick up the appended element. >> In Python I can iterate through a list, and on a certain condition >> append a new item to the list, which is then included in the iteration. > > Personally I follow the rule "never mutate a list you are iterating over", > even for appends, where the likelihood of problems is small: > > items = ["a"] > for item in items: > if item == "a": items.append("a") > I did feel a bit uneasy doing it, but once I had got it working it did not feel too bad. I did not test for appending from the last item, so that bug has just bitten me now, but I will run with my workaround unless/until lxml is fixed. >> >> Is there any chance that this can be looked at, or is it just the way it >> works? > > File a bug report and see if the author is willing to emulate the list > behaviour. > Will do. >> BTW, I see that ElementTree in the standard library does not have this >> problem. > > Maybe uses a list under the hood. > Thanks for the advice. Frank From frank at chagford.com Mon Feb 3 04:43:25 2020 From: frank at chagford.com (Frank Millman) Date: Mon, 3 Feb 2020 11:43:25 +0200 Subject: lxml - minor problem appending new element In-Reply-To: References: Message-ID: <1baa0763-8211-d810-d79a-5ee80d1cc846@chagford.com> On 2020-02-03 10:39 AM, Peter Otten wrote: > Frank Millman wrote: > >> This is a minor issue, and I have found an ugly workaround, but I >> thought I would mention it. > > Like this? > > children = list(xml) > for y in children: > print(etree.tostring(y)) > if y.get('z') == 'c': > child = etree.Element('y', attrib={'z': 'd'}) > xml.append(child) > children.append(child) > > It doesn't look /that/ ugly to me. > That is not bad. My actual solution was to revert to the non-pythonic method of iterating over a list - pos = 0 while pos < len(xml): y = xml[pos] print(etree.tostring(y)) if y.get('z') == 'c': xml.append(etree.Element('y', attrib={'z': 'd'})) pos += 1 That way, if I append to xml, I automatically pick up the appended element. >> In Python I can iterate through a list, and on a certain condition >> append a new item to the list, which is then included in the iteration. > > Personally I follow the rule "never mutate a list you are iterating over", > even for appends, where the likelihood of problems is small: > > items = ["a"] > for item in items: > if item == "a": items.append("a") > I did feel a bit uneasy doing it, but once I had got it working it did not feel too bad. I did not test for appending from the last item, so that bug has just bitten me now, but I will run with my workaround unless/until lxml is fixed. >> >> Is there any chance that this can be looked at, or is it just the way it >> works? > > File a bug report and see if the author is willing to emulate the list > behaviour. > Will do. >> BTW, I see that ElementTree in the standard library does not have this >> problem. > > Maybe uses a list under the hood. > Thanks for the advice. Frank From shipan76 at mail.ustc.edu.cn Mon Feb 3 03:04:33 2020 From: shipan76 at mail.ustc.edu.cn (=?utf-8?Q?=E7=9F=B3=E7=9B=BC?=) Date: Mon, 3 Feb 2020 16:04:33 +0800 Subject: when uses time.clock,there are always mistakes Message-ID: <5E37D412.153213.28531@ustc.edu.cn> Hello ! ?The problem like this: ? ================================ RESTART: Shell ================================ ??>>> import time ??>>> t = time.clock() ??Traceback (most recent call last): ? File "", line 1, in ? t = time.clock() ??AttributeError: module 'time' has no attribute 'clock' ??>>> ??Thanks! ??Best wishes! From mbharathi1112 at gmail.com Mon Feb 3 06:14:04 2020 From: mbharathi1112 at gmail.com (the python app i had downloaded is not opening!) Date: Mon, 3 Feb 2020 16:44:04 +0530 Subject: no explanation towards not installing my application// Message-ID: <5e380074.1c69fb81.1150c.acff@mx.google.com> Sent from Mail for Windows 10 From bgailer at gmail.com Mon Feb 3 08:37:52 2020 From: bgailer at gmail.com (Bob Gailer) Date: Mon, 3 Feb 2020 08:37:52 -0500 Subject: no explanation towards not installing my application// In-Reply-To: <5e380074.1c69fb81.1150c.acff@mx.google.com> References: <5e380074.1c69fb81.1150c.acff@mx.google.com> Message-ID: On Feb 3, 2020 8:18 AM, "the python app i had downloaded is not opening!" < mbharathi1112 at gmail.com> wrote: I'm assuming you're using Windows 10. Correct? You're telling us you downloaded the program installer. Did you run the installer? Where did it tell you it was putting the program? Exactly what did you do to try to open python? Exactly what results did you get? Bob Gailer From rhodri at kynesim.co.uk Mon Feb 3 08:54:10 2020 From: rhodri at kynesim.co.uk (Rhodri James) Date: Mon, 3 Feb 2020 13:54:10 +0000 Subject: when uses time.clock,there are always mistakes In-Reply-To: <5E37D412.153213.28531@ustc.edu.cn> References: <5E37D412.153213.28531@ustc.edu.cn> Message-ID: <9ac47ebb-9b71-257a-3f3c-c7e76fd91d62@kynesim.co.uk> On 03/02/2020 08:04, ?? wrote: > Hello ! > ?The problem like this: > ? ================================ RESTART: Shell ================================ > ??>>> import time > ??>>> t = time.clock() > ??Traceback (most recent call last): > ? File "", line 1, in > ? t = time.clock() > ??AttributeError: module 'time' has no attribute 'clock' It is correct, there is no time.clock() function. The documentation is here: https://docs.python.org/3/library/time.html -- Rhodri James *-* Kynesim Ltd From __peter__ at web.de Mon Feb 3 09:59:43 2020 From: __peter__ at web.de (Peter Otten) Date: Mon, 03 Feb 2020 15:59:43 +0100 Subject: when uses time.clock,there are always mistakes References: <5E37D412.153213.28531@ustc.edu.cn> Message-ID: ?? wrote: > The problem like this: > t = time.clock() > AttributeError: module 'time' has no attribute 'clock' Quoting https://docs.python.org/3/whatsnew/3.8.html#api-and-feature-removals """ The function time.clock() has been removed, after having been deprecated since Python 3.3: use time.perf_counter() or time.process_time() instead, depending on your requirements, to have well-defined behavior. (Contributed by Matthias Bussonnier in bpo-36895.) """ From chapardar.parisa at gmail.com Mon Feb 3 11:55:39 2020 From: chapardar.parisa at gmail.com (Parisa Ch) Date: Mon, 3 Feb 2020 08:55:39 -0800 (PST) Subject: braket an matrix in python Message-ID: <45c82e87-1e6e-4bc3-92c4-75318187e64a@googlegroups.com> x=np.linspace(0,2*math.pi,n) n=len(x) r=int(math.ceil(f*n)) h=[np.sort(np.abs(x-x[i]))[r] for i in range(n)] this is part of a python code. the last line is confusing? x is a matrix and x[i] is a number. how calculate x-x[i] for each i? why the put r in [] ? From __peter__ at web.de Mon Feb 3 13:16:20 2020 From: __peter__ at web.de (Peter Otten) Date: Mon, 03 Feb 2020 19:16:20 +0100 Subject: braket an matrix in python References: <45c82e87-1e6e-4bc3-92c4-75318187e64a@googlegroups.com> Message-ID: Parisa Ch wrote: > x=np.linspace(0,2*math.pi,n) > n=len(x) > r=int(math.ceil(f*n)) > h=[np.sort(np.abs(x-x[i]))[r] for i in range(n)] > > this is part of a python code. the last line is confusing? x is a matrix > and x[i] is a number. how calculate x-x[i] for each i? > why the put r in [] ? Brake it appart: y = x - x[i] # the numpy feature that makes that possible is called # "broadcasting" subtracts the value x[i] from every entry in the vector x z = np.abs(y) calculates the absolute value of every entry in y. t = np.sort(z) sorts the values in z and finally, assuming r is an integer, u = t[r] looks up a single scalar in the vector. The enclosing "list comprehension" [expr for item in iterable] builds a list of n values calculated as sketched above. From laiba.zubair96 at gmail.com Tue Feb 4 09:49:30 2020 From: laiba.zubair96 at gmail.com (laiba.zubair96 at gmail.com) Date: Tue, 4 Feb 2020 06:49:30 -0800 (PST) Subject: ERROR in loading data Message-ID: #load the training and testing data, then scale it into the # range [0, 1] print("[INFO] loading ADNI data...") ((trainX, trainY), (testX, testY)) = '/content/gdrive/My Drive/3_Classes/'.loads_data() trainX = trainX.astype("float") / 255.0 testX = testX.astype("float") / 255.0 # initialize the label names for the ADNI dataset labelNames = ["outAD", "outCN", "outMCI"] When i try to run this code I got the following error. [INFO] loading ADNI data... --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) in () 1 print("[INFO] loading ADNI data...") ----> 2 ((trainX, trainY), (testX, testY)) = '/content/gdrive/My Drive/3_Classes/'.loads_data() 3 trainX = trainX.astype("float") / 255.0 4 testX = testX.astype("float") / 255.0 5 From rhodri at kynesim.co.uk Tue Feb 4 10:04:26 2020 From: rhodri at kynesim.co.uk (Rhodri James) Date: Tue, 4 Feb 2020 15:04:26 +0000 Subject: ERROR in loading data In-Reply-To: References: Message-ID: On 04/02/2020 14:49, laiba.zubair96 at gmail.com wrote: > #load the training and testing data, then scale it into the > # range [0, 1] > print("[INFO] loading ADNI data...") > ((trainX, trainY), (testX, testY)) = '/content/gdrive/My Drive/3_Classes/'.loads_data() > trainX = trainX.astype("float") / 255.0 > testX = testX.astype("float") / 255.0 > > # initialize the label names for the ADNI dataset > labelNames = ["outAD", "outCN", "outMCI"] > When i try to run this code I got the following error. > > [INFO] loading ADNI data... > --------------------------------------------------------------------------- > AttributeError Traceback (most recent call last) > in () > 1 print("[INFO] loading ADNI data...") > ----> 2 ((trainX, trainY), (testX, testY)) = '/content/gdrive/My Drive/3_Classes/'.loads_data() > 3 trainX = trainX.astype("float") / 255.0 > 4 testX = testX.astype("float") / 255.0 > 5 So that error is saying that something on line 2 is trying to use an attribute incorrectly, probably one that doesn't exist (there really should be more explanatory information in the error, by the way). The only thing on line 2 that tries to access an attribute is the string '/content/gdrive/My Drive/3_Classes/', which tries to run the method loads_data(). Fair enough. A quick test on the interactive command line or a look in the documents will tell you that strings indeed do not have a loads_data() method. I don't know what library you are intending to use, but you need to open your file with that first. -- Rhodri James *-* Kynesim Ltd From joel.goldstick at gmail.com Tue Feb 4 11:47:40 2020 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Tue, 4 Feb 2020 11:47:40 -0500 Subject: ERROR in loading data In-Reply-To: References: Message-ID: On Tue, Feb 4, 2020 at 9:51 AM wrote: > > #load the training and testing data, then scale it into the > # range [0, 1] > print("[INFO] loading ADNI data...") > ((trainX, trainY), (testX, testY)) = '/content/gdrive/My Drive/3_Classes/'.loads_data() What is the class of the .loads)data() method? I don't think it is a string representing a file path. Look in the docs for .loads_data() to see what you are doing wrong. That looks like it might be a numpy > trainX = trainX.astype("float") / 255.0 > testX = testX.astype("float") / 255.0 > > # initialize the label names for the ADNI dataset > labelNames = ["outAD", "outCN", "outMCI"] > When i try to run this code I got the following error. > > [INFO] loading ADNI data... > --------------------------------------------------------------------------- > AttributeError Traceback (most recent call last) > in () > 1 print("[INFO] loading ADNI data...") > ----> 2 ((trainX, trainY), (testX, testY)) = '/content/gdrive/My Drive/3_Classes/'.loads_data() > 3 trainX = trainX.astype("float") / 255.0 > 4 testX = testX.astype("float") / 255.0 > 5 > -- > https://mail.python.org/mailman/listinfo/python-list -- Joel Goldstick http://joelgoldstick.com/blog http://cc-baseballstats.info/stats/birthdays From dcwhatthe at gmail.com Tue Feb 4 12:34:47 2020 From: dcwhatthe at gmail.com (dcwhatthe at gmail.com) Date: Tue, 4 Feb 2020 09:34:47 -0800 (PST) Subject: How to instlal pyodbc, without pip Message-ID: <54f829b7-3227-4b11-a8b6-2a43ea134323@googlegroups.com> Hi, Pip won't work on my desktop, because of the firewalls we have set up. I have the version from github. Assuming my Python 3.8.1 Home Directory is C:\Python, How can I install pyodbc pyodbc-master.zip? Which folders should I unzip it into? Regards, From PythonList at DancesWithMice.info Tue Feb 4 16:37:52 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Wed, 5 Feb 2020 10:37:52 +1300 Subject: How to instlal pyodbc, without pip In-Reply-To: <54f829b7-3227-4b11-a8b6-2a43ea134323@googlegroups.com> References: <54f829b7-3227-4b11-a8b6-2a43ea134323@googlegroups.com> Message-ID: On 5/02/20 6:34 AM, dcwhatthe at gmail.com wrote: > Pip won't work on my desktop, because of the firewalls we have set up. > > I have the version from github. Assuming my Python 3.8.1 Home Directory is C:\Python, How can I install pyodbc pyodbc-master.zip? Which folders should I unzip it into? I don't use MS-Win. My personal library directory is /home/dn/.local/lib/python3.7/site-packages. There is an equivalent of such, for you. Pip is a convenience. Manual installation is perfectly reasonable. For wider understanding and to take advantage of Python's flexibility to include the limitations of your situation, the following might help: Python Setup and Usage https://docs.python.org/3/using/index.html Installing Python Modules https://docs.python.org/3/installing/index.html Installing Packages https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site -- Regards =dn From tjreedy at udel.edu Tue Feb 4 16:12:09 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Tue, 4 Feb 2020 16:12:09 -0500 Subject: How to instlal pyodbc, without pip In-Reply-To: <54f829b7-3227-4b11-a8b6-2a43ea134323@googlegroups.com> References: <54f829b7-3227-4b11-a8b6-2a43ea134323@googlegroups.com> Message-ID: On 2/4/2020 12:34 PM, dcwhatthe at gmail.com wrote: > Pip won't work on my desktop, because of the firewalls we have set up. > > I have the version from github. Assuming my Python 3.8.1 Home Directory is C:\Python, How can I install pyodbc pyodbc-master.zip? If you have dependencies installed, you should be able to pip install with a command line arg telling it to use that file. Can you run pip -h? > Which folders should I unzip it into? The pyodbc package must end up in .../Lib/site-packages. Unzipping there might work, or maybe not. The zipped manifest.ini and setup.py and maybe other files have the installation details, which pip reads and interprets. -- Terry Jan Reedy From souvik.viksou at gmail.com Tue Feb 4 20:52:33 2020 From: souvik.viksou at gmail.com (Souvik Dutta) Date: Wed, 5 Feb 2020 07:22:33 +0530 Subject: How to instlal pyodbc, without pip In-Reply-To: <54f829b7-3227-4b11-a8b6-2a43ea134323@googlegroups.com> References: <54f829b7-3227-4b11-a8b6-2a43ea134323@googlegroups.com> Message-ID: You might use chocolatey if you like. On Tue, 4 Feb, 2020, 11:05 pm , wrote: > Hi, > > Pip won't work on my desktop, because of the firewalls we have set up. > > I have the version from github. Assuming my Python 3.8.1 Home Directory > is C:\Python, How can I install pyodbc pyodbc-master.zip? Which folders > should I unzip it into? > > > > Regards, > > > > > -- > https://mail.python.org/mailman/listinfo/python-list > From souvik.viksou at gmail.com Tue Feb 4 22:30:45 2020 From: souvik.viksou at gmail.com (Souvik Dutta) Date: Wed, 5 Feb 2020 09:00:45 +0530 Subject: How to make a cross platform python app with pyinstaller?? Message-ID: Hi, I made a python gui with pyqt5 and packed it with pyinstaller. It is running well in my computer but when I gave it to a friend who doesn't have any python version installed and it didn't run. The message was "This app cannot be run on your pc.". How can I solve this??? From rosuav at gmail.com Tue Feb 4 22:33:22 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 5 Feb 2020 14:33:22 +1100 Subject: How to make a cross platform python app with pyinstaller?? In-Reply-To: References: Message-ID: On Wed, Feb 5, 2020 at 2:32 PM Souvik Dutta wrote: > > Hi, > I made a python gui with pyqt5 and packed it with pyinstaller. It is > running well in my computer but when I gave it to a friend who doesn't have > any python version installed and it didn't run. The message was "This app > cannot be run on your pc.". How can I solve this??? Distribute the .py file instead. It can then run on any computer with Python installed. ChrisA From torriem at gmail.com Tue Feb 4 23:27:59 2020 From: torriem at gmail.com (Michael Torrie) Date: Tue, 4 Feb 2020 21:27:59 -0700 Subject: How to make a cross platform python app with pyinstaller?? In-Reply-To: References: Message-ID: <2bc87ae4-b7a3-0329-2517-48ea850aa2a5@gmail.com> On 2/4/20 8:33 PM, Chris Angelico wrote: > On Wed, Feb 5, 2020 at 2:32 PM Souvik Dutta wrote: >> >> Hi, >> I made a python gui with pyqt5 and packed it with pyinstaller. It is >> running well in my computer but when I gave it to a friend who doesn't have >> any python version installed and it didn't run. The message was "This app >> cannot be run on your pc.". How can I solve this??? > > Distribute the .py file instead. It can then run on any computer with > Python installed. And PyQt5 installed of course. And Qt5. None of which is likely to be a commonly installed software package. Asking someone to install Python separately to run your app is a tall order, to say nothing of PyQt5. So while this answer is technically correct, the larger issue of distributing Python programs remains. Furthering Chris's answer a bit, there really is no way to simply distribute a Python app and all its dependencies in any simple, portable way. If the dependencies already exist on the target system, then Chris is absolutely right. You just give him the py file and he double-clicks on it and it runs. That may work some of the time. The reality is that this is often insufficient. Your best bet may be to build an installer that either installs everything you need into a Program Files directory, or also runs the Python, and PyQt5 installers to install them system-wide before installing your app and your bundled shortcuts and program launcher. Building installers isn't too awful using a number of free tools, but it's an entire programming domain in and of itself. From cs at cskk.id.au Wed Feb 5 00:48:56 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Wed, 5 Feb 2020 16:48:56 +1100 Subject: How to make a cross platform python app with pyinstaller?? In-Reply-To: <2bc87ae4-b7a3-0329-2517-48ea850aa2a5@gmail.com> References: <2bc87ae4-b7a3-0329-2517-48ea850aa2a5@gmail.com> Message-ID: <20200205054856.GA46453@cskk.homeip.net> On 04Feb2020 21:27, Michael Torrie wrote: >On 2/4/20 8:33 PM, Chris Angelico wrote: >> On Wed, Feb 5, 2020 at 2:32 PM Souvik Dutta wrote: >>> I made a python gui with pyqt5 and packed it with pyinstaller. It is >>> running well in my computer but when I gave it to a friend who doesn't have >>> any python version installed and it didn't run. The message was "This app >>> cannot be run on your pc.". How can I solve this??? >> >> Distribute the .py file instead. It can then run on any computer with >> Python installed. > >And PyQt5 installed of course. And Qt5. None of which is likely to be >a commonly installed software package. Asking someone to install Python >separately to run your app is a tall order, to say nothing of PyQt5. So >while this answer is technically correct, the larger issue of >distributing Python programs remains. [...] The purpose of tools like py2installer is to build an app containing all the required dependencies. I've been using py2app for this myself, and confess to being rather ignorant about the internals. However, it has problems; the Python executable itself is part of the problem. MacOS apps at least have some funky library linking stuff which lets you derive the library locations from the app location, etc. However, I've had plenty of pain with this myself. I'm contemplating not just including a virtualenv in the app but a whole python install. Cheers, Cameron Simpson From arj.python at gmail.com Wed Feb 5 01:48:56 2020 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Wed, 5 Feb 2020 10:48:56 +0400 Subject: Mauritius UG (pymug) 2019 End of Year Report Message-ID: Greetings list, Today our User Group published it's first ever end-of-year report: https://www.pymug.com/assets/pymug_2019_report.pdf Feel free to ask me anything! Yours, Abdur-Rahmaan Janhangeer pythonmembers.club | github Mauritius From arj.python at gmail.com Wed Feb 5 02:09:57 2020 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Wed, 5 Feb 2020 11:09:57 +0400 Subject: How to make a cross platform python app with pyinstaller?? In-Reply-To: References: Message-ID: Use the Dev version of pyinstaller. pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip Yours, Abdur-Rahmaan Janhangeer pythonmembers.club | github Mauritius On Wed, Feb 5, 2020 at 7:31 AM Souvik Dutta wrote: > Hi, > I made a python gui with pyqt5 and packed it with pyinstaller. It is > running well in my computer but when I gave it to a friend who doesn't have > any python version installed and it didn't run. The message was "This app > cannot be run on your pc.". How can I solve this??? > -- > https://mail.python.org/mailman/listinfo/python-list > From klauck2 at gmail.com Wed Feb 5 08:57:10 2020 From: klauck2 at gmail.com (Stefan Halfpap) Date: Wed, 5 Feb 2020 14:57:10 +0100 Subject: Documentation of __hash__ Message-ID: Hi, I do not understand the following statement from the python (2 and 3) documentation regarding __hash__ and __eq__ methods: "If a class does not define an __eq__() method it should not define a __hash__() operation either;? (see https://docs.python.org/3/reference/datamodel.html#object.__hash__ ) I thought it relates to the second part (?if it defines __eq__() but not __hash__() , its instances will not be usable as items in hashable collections?), which is totally clear to me. But then the implication should be the other way around. But what is the reason (meaning) for the statement as it is? Best regards, Stefan From dcwhatthe at gmail.com Wed Feb 5 10:54:25 2020 From: dcwhatthe at gmail.com (dcwhatthe at gmail.com) Date: Wed, 5 Feb 2020 07:54:25 -0800 (PST) Subject: How to instlal pyodbc, without pip In-Reply-To: References: <54f829b7-3227-4b11-a8b6-2a43ea134323@googlegroups.com> Message-ID: On Tuesday, February 4, 2020 at 8:53:10 PM UTC-5, Souvik Dutta wrote: > You might use chocolatey if you like. > > On Tue, 4 Feb, 2020, 11:05 pm , dcwhatthe wrote: > > > Hi, > > > > Pip won't work on my desktop, because of the firewalls we have set up. > > > > I have the version from github. Assuming my Python 3.8.1 Home Directory > > is C:\Python, How can I install pyodbc pyodbc-master.zip? Which folders > > should I unzip it into? > > > > > > > > Regards, > > > > > > > > > > -- > > https://mail.python.org/mailman/listinfo/python-list > > Thanks DL Neil, Terry, and Souvik, I was able to install them manually, by going to the ..\libregrtest\ folder, copying the .zip there, and running it against the package, thus: pip install --trusted-host pyodbc-master.zip From dieter at handshake.de Wed Feb 5 12:25:42 2020 From: dieter at handshake.de (Dieter Maurer) Date: Wed, 5 Feb 2020 18:25:42 +0100 Subject: Documentation of __hash__ In-Reply-To: References: Message-ID: <24122.64150.717391.820747@localhost.localdomain> Stefan Halfpap wrote at 2020-2-5 14:57 +0100: >I do not understand the following statement from the python (2 and 3) documentation regarding __hash__ and __eq__ methods: >"If a class does not define an __eq__() method it should not define a __hash__() operation either;? >(see https://docs.python.org/3/reference/datamodel.html#object.__hash__ ) > >I thought it relates to the second part (?if it defines __eq__() but not __hash__() , its instances will not be usable as items in hashable collections?), which is totally clear to me. >But then the implication should be the other way around. "if not A then not B" is equivalent to "if B then A". In your case: "__eq__ not defined, then __hash__ not defined" is equivalent to "__hash__ definied requires __eq__ defined". From klauck2 at gmail.com Wed Feb 5 14:55:24 2020 From: klauck2 at gmail.com (klauck2 at gmail.com) Date: Wed, 5 Feb 2020 11:55:24 -0800 (PST) Subject: Documentation of __hash__ In-Reply-To: References: <24122.64150.717391.820747@localhost.localdomain> Message-ID: <4f5b9e9d-9e22-4c25-ad07-73c9022693d6@googlegroups.com> On Wednesday, February 5, 2020 at 7:41:13 PM UTC+1, Dieter Maurer wrote: > Stefan Halfpap wrote at 2020-2-5 14:57 +0100: > >I do not understand the following statement from the python (2 and 3) documentation regarding __hash__ and __eq__ methods: > >"If a class does not define an __eq__() method it should not define a __hash__() operation either;? > >(see https://docs.python.org/3/reference/datamodel.html#object.__hash__ ) > > > >I thought it relates to the second part (?if it defines __eq__() but not __hash__() , its instances will not be usable as items in hashable collections?), which is totally clear to me. > >But then the implication should be the other way around. > > "if not A then not B" is equivalent to "if B then A". > > In your case: "__eq__ not defined, then __hash__ not defined" > is equivalent to "__hash__ definied requires __eq__ defined". You are right. This is what the (first part of the) documentation says, but I do not know why. I thought it should be: "if __hash__ is not defined, then __eq__ should not be defined" which is equivalent to "__eq__ defined then __hash__ should be defined" (the second part, which is clear to me) If not, why should a class not define __hash__, if it does not define __eq__? From auriocus at gmx.de Wed Feb 5 16:19:53 2020 From: auriocus at gmx.de (Christian Gollwitzer) Date: Wed, 5 Feb 2020 22:19:53 +0100 Subject: Documentation of __hash__ In-Reply-To: <4f5b9e9d-9e22-4c25-ad07-73c9022693d6@googlegroups.com> References: <24122.64150.717391.820747@localhost.localdomain> <4f5b9e9d-9e22-4c25-ad07-73c9022693d6@googlegroups.com> Message-ID: Am 05.02.20 um 20:55 schrieb klauck2 at gmail.com: > If not, why should a class not define __hash__, if it does not define __eq__? Hashes are not unique. When you insert or look up something in a hashtable, the hash is computed and used as the index into the table. Because the hash is not necessarily unique, if hash(a)=hash(b), it can still be that a=/= b. Therefore, in a second step, a is compared to b if the hashes match. Therefore, you need a comparison operator which is compatible with the hash function, i.e. if a==b, then hash(a) must be equal to hash(b). Christian From ijbrewster at alaska.edu Wed Feb 5 19:48:54 2020 From: ijbrewster at alaska.edu (Israel Brewster) Date: Wed, 5 Feb 2020 15:48:54 -0900 Subject: Multiprocessing, join(), and crashed processes Message-ID: <5B16C4A5-92CD-41D7-B8A7-17475849CA37@alaska.edu> In a number of places I have constructs where I launch several processes using the multiprocessing library, then loop through said processes calling join() on each one to wait until they are all complete. In general, this works well, with the *apparent* exception of if something causes one of the child processes to crash (not throw an exception, actually crash). In that event, it appears that the call to join() hangs indefinitely. How can I best handle this? Should I put a timeout on the join, and put it in a loop, such that every 5 seconds or so it breaks, checks to see if the process is still actually running, and if so goes back and calls join again? Or is there a better option to say ?wait until this process is done, however long that may be, unless it crashes?? --- Israel Brewster Software Engineer Alaska Volcano Observatory Geophysical Institute - UAF 2156 Koyukuk Drive Fairbanks AK 99775-7320 Work: 907-474-5172 cell: 907-328-9145 From cs at cskk.id.au Thu Feb 6 00:53:23 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 6 Feb 2020 16:53:23 +1100 Subject: Multiprocessing, join(), and crashed processes In-Reply-To: <5B16C4A5-92CD-41D7-B8A7-17475849CA37@alaska.edu> References: <5B16C4A5-92CD-41D7-B8A7-17475849CA37@alaska.edu> Message-ID: <20200206055323.GA50448@cskk.homeip.net> On 05Feb2020 15:48, Israel Brewster wrote: >In a number of places I have constructs where I launch several >processes using the multiprocessing library, then loop through said >processes calling join() on each one to wait until they are all >complete. In general, this works well, with the *apparent* exception of >if something causes one of the child processes to crash (not throw an >exception, actually crash). In that event, it appears that the call to >join() hangs indefinitely. How can I best handle this? Should I put a >timeout on the join, and put it in a loop, such that every 5 seconds or >so it breaks, checks to see if the process is still actually running, >and if so goes back and calls join again? Or is there a better option >to say ?wait until this process is done, however long that may be, >unless it crashes?? What's your platform/OS? And what does "crash" mean, precisely? If a subprocess exits, join() should terminate. If the subprocess _hangs_, then join will not see it exit, because it hasn't. And join will hang. You'll need to define what happens when your subprocesses crash. Cheers, Cameron Simpson From frank at chagford.com Thu Feb 6 07:58:34 2020 From: frank at chagford.com (Frank Millman) Date: Thu, 6 Feb 2020 14:58:34 +0200 Subject: Change in behaviour Python 3.7 > 3.8 Message-ID: Hi all I have noticed a change in behaviour in Python 3.8 compared with previous versions of Python going back to at least 2.7. I am pretty sure that it is not a problem, and is caused by my relying on a certain sequence of events at shutdown, which of course is not guaranteed. However, any change in behaviour is worth reporting, just in case it was unintended, so I thought I would mention it here. I have a module (A) containing common objects shared by other modules. I have a module (B) which imports one of these common objects - a set(). Module B defines a Class, and creates a global instance of this class when the module is created. This instance is never explicitly deleted, so I assume it gets implicitly deleted at shutdown. It has a __del__() method (only for temporary debugging purposes, so will be removed for production) and the __del__ method uses the set() object imported from Module A. This has worked for years, but now when the __del__ method is called, the common object, which was a set(), has become None. My assumption is that Module A gets cleaned up before Module B, and when Module B tries to access the common set() object it no longer exists. I have a workaround, so I am just reporting this for the record. Frank Millman From barry at barrys-emacs.org Thu Feb 6 09:43:54 2020 From: barry at barrys-emacs.org (Barry) Date: Thu, 6 Feb 2020 14:43:54 +0000 Subject: Change in behaviour Python 3.7 > 3.8 In-Reply-To: References: Message-ID: <50CA7E4F-1C23-4B67-BF05-A9CD8283C73D@barrys-emacs.org> > On 6 Feb 2020, at 13:01, Frank Millman wrote: > > ?Hi all > > I have noticed a change in behaviour in Python 3.8 compared with previous versions of Python going back to at least 2.7. I am pretty sure that it is not a problem, and is caused by my relying on a certain sequence of events at shutdown, which of course is not guaranteed. However, any change in behaviour is worth reporting, just in case it was unintended, so I thought I would mention it here. > > I have a module (A) containing common objects shared by other modules. I have a module (B) which imports one of these common objects - a set(). > > Module B defines a Class, and creates a global instance of this class when the module is created. This instance is never explicitly deleted, so I assume it gets implicitly deleted at shutdown. It has a __del__() method (only for temporary debugging purposes, so will be removed for production) and the __del__ method uses the set() object imported from Module A. > > This has worked for years, but now when the __del__ method is called, the common object, which was a set(), has become None. > > My assumption is that Module A gets cleaned up before Module B, and when Module B tries to access the common set() object it no longer exists. > > I have a workaround, so I am just reporting this for the record. I recall reading that shutdown had changed in 3.8, but cannot find the email/webpage that I read. These days I assume that __del__ will almost never be useful and use exploit calls to tell an object I am finished with it and it can do its resource clean up. Barry > > Frank Millman > > -- > https://mail.python.org/mailman/listinfo/python-list > From souvik.viksou at gmail.com Thu Feb 6 10:48:29 2020 From: souvik.viksou at gmail.com (Souvik Dutta) Date: Thu, 6 Feb 2020 21:18:29 +0530 Subject: Change in behaviour Python 3.7 > 3.8 In-Reply-To: References: Message-ID: You might find this helpful. https://docs.python.org/3/reference/datamodel.html Thank you ?? On Thu, Feb 6, 2020, 6:29 PM Frank Millman wrote: > Hi all > > I have noticed a change in behaviour in Python 3.8 compared with > previous versions of Python going back to at least 2.7. I am pretty sure > that it is not a problem, and is caused by my relying on a certain > sequence of events at shutdown, which of course is not guaranteed. > However, any change in behaviour is worth reporting, just in case it was > unintended, so I thought I would mention it here. > > I have a module (A) containing common objects shared by other modules. I > have a module (B) which imports one of these common objects - a set(). > > Module B defines a Class, and creates a global instance of this class > when the module is created. This instance is never explicitly deleted, > so I assume it gets implicitly deleted at shutdown. It has a __del__() > method (only for temporary debugging purposes, so will be removed for > production) and the __del__ method uses the set() object imported from > Module A. > > This has worked for years, but now when the __del__ method is called, > the common object, which was a set(), has become None. > > My assumption is that Module A gets cleaned up before Module B, and when > Module B tries to access the common set() object it no longer exists. > > I have a workaround, so I am just reporting this for the record. > > Frank Millman > > -- > https://mail.python.org/mailman/listinfo/python-list > From storchaka at gmail.com Thu Feb 6 13:12:36 2020 From: storchaka at gmail.com (Serhiy Storchaka) Date: Thu, 6 Feb 2020 20:12:36 +0200 Subject: Change in behaviour Python 3.7 > 3.8 In-Reply-To: References: Message-ID: 06.02.20 14:58, Frank Millman ????: > I have noticed a change in behaviour in Python 3.8 compared with > previous versions of Python going back to at least 2.7. I am pretty sure > that it is not a problem, and is caused by my relying on a certain > sequence of events at shutdown, which of course is not guaranteed. > However, any change in behaviour is worth reporting, just in case it was > unintended, so I thought I would mention it here. > > I have a module (A) containing common objects shared by other modules. I > have a module (B) which imports one of these common objects - a set(). > > Module B defines a Class, and creates a global instance of this class > when the module is created. This instance is never explicitly deleted, > so I assume it gets implicitly deleted at shutdown. It has a __del__() > method (only for temporary debugging purposes, so will be removed for > production) and the __del__ method uses the set() object imported from > Module A. > > This has worked for years, but now when the __del__ method is called, > the common object, which was a set(), has become None. > > My assumption is that Module A gets cleaned up before Module B, and when > Module B tries to access the common set() object it no longer exists. Do you import a common object *from* a module or import a module and access a common object as its attribute? If the latter, the change may be related to https://bugs.python.org/issue33331 . Modules are now cleaned up in the reversed order of importing. In any case, the order of cleaning up modules is not specified/ From klauck2 at gmail.com Thu Feb 6 14:13:45 2020 From: klauck2 at gmail.com (klauck2 at gmail.com) Date: Thu, 6 Feb 2020 11:13:45 -0800 (PST) Subject: Documentation of __hash__ In-Reply-To: References: <24122.64150.717391.820747@localhost.localdomain> <4f5b9e9d-9e22-4c25-ad07-73c9022693d6@googlegroups.com> Message-ID: <78ee3d73-82c6-4483-b6c1-ffa3c0d9ae1d@googlegroups.com> The default __eq__ method (object identity) is compatible with all (reasonable) self-defined __hash__ method. Stefan From frank at chagford.com Fri Feb 7 00:27:21 2020 From: frank at chagford.com (Frank Millman) Date: Fri, 7 Feb 2020 07:27:21 +0200 Subject: Change in behaviour Python 3.7 > 3.8 In-Reply-To: References: Message-ID: <453d72be-a1f3-6f0d-211a-31a6d1a008b7@chagford.com> On 2020-02-06 2:58 PM, Frank Millman wrote: [...] > > I have a module (A) containing common objects shared by other modules. I > have a module (B) which imports one of these common objects - a set(). > [...] > > This has worked for years, but now when the __del__ method is called, > the common object, which was a set(), has become None. > > My assumption is that Module A gets cleaned up before Module B, and when > Module B tries to access the common set() object it no longer exists. > > I have a workaround, so I am just reporting this for the record. Thanks to all for the replies. @Serhiy I import the common object *from* Module A. @Dennis Thanks for the references. I knew that __del__() should not be relied on, but I have not seen the reasons spelled out so clearly before. @Barry I agree that __del__() is rarely useful, but I have not come up with an alternative to achieve what I want to do. My app is a long-running server, and creates many objects on-the-fly depending on user input. They should be short-lived, and be removed when they go out of scope, but I can concerned that I may leave a dangling reference somewhere that keeps one of them alive, resulting in a memory leak over time. Creating a _del__() method and displaying a message to say 'I am being deleted' has proved effective, and has in fact highlighted a few cases where there was a real problem. My solution to this particular issue is to explicitly delete the global instance at program end, so I do not rely on the interpreter to clean it up. It works. Thanks again Frank From frank at chagford.com Fri Feb 7 00:27:21 2020 From: frank at chagford.com (Frank Millman) Date: Fri, 7 Feb 2020 07:27:21 +0200 Subject: Change in behaviour Python 3.7 > 3.8 In-Reply-To: References: Message-ID: <453d72be-a1f3-6f0d-211a-31a6d1a008b7@chagford.com> On 2020-02-06 2:58 PM, Frank Millman wrote: [...] > > I have a module (A) containing common objects shared by other modules. I > have a module (B) which imports one of these common objects - a set(). > [...] > > This has worked for years, but now when the __del__ method is called, > the common object, which was a set(), has become None. > > My assumption is that Module A gets cleaned up before Module B, and when > Module B tries to access the common set() object it no longer exists. > > I have a workaround, so I am just reporting this for the record. Thanks to all for the replies. @Serhiy I import the common object *from* Module A. @Dennis Thanks for the references. I knew that __del__() should not be relied on, but I have not seen the reasons spelled out so clearly before. @Barry I agree that __del__() is rarely useful, but I have not come up with an alternative to achieve what I want to do. My app is a long-running server, and creates many objects on-the-fly depending on user input. They should be short-lived, and be removed when they go out of scope, but I can concerned that I may leave a dangling reference somewhere that keeps one of them alive, resulting in a memory leak over time. Creating a _del__() method and displaying a message to say 'I am being deleted' has proved effective, and has in fact highlighted a few cases where there was a real problem. My solution to this particular issue is to explicitly delete the global instance at program end, so I do not rely on the interpreter to clean it up. It works. Thanks again Frank From barry at barrys-emacs.org Fri Feb 7 06:06:10 2020 From: barry at barrys-emacs.org (Barry Scott) Date: Fri, 7 Feb 2020 11:06:10 +0000 Subject: Change in behaviour Python 3.7 > 3.8 In-Reply-To: <453d72be-a1f3-6f0d-211a-31a6d1a008b7@chagford.com> References: <453d72be-a1f3-6f0d-211a-31a6d1a008b7@chagford.com> Message-ID: <18750057-5220-42D4-8C35-21BA3B37FAFD@barrys-emacs.org> > On 7 Feb 2020, at 05:27, Frank Millman wrote: > > @Barry > I agree that __del__() is rarely useful, but I have not come up with an alternative to achieve what I want to do. My app is a long-running server, and creates many objects on-the-fly depending on user input. They should be short-lived, and be removed when they go out of scope, but I can concerned that I may leave a dangling reference somewhere that keeps one of them alive, resulting in a memory leak over time. Creating a _del__() method and displaying a message to say 'I am being deleted' has proved effective, and has in fact highlighted a few cases where there was a real problem. > > My solution to this particular issue is to explicitly delete the global instance at program end, so I do not rely on the interpreter to clean it up. It works. I have faced the same problem with leaking of objects. What I did was use the python gc to find all the objects. First I call gc.collect() to clean up all the objects what can be deleted. Then I call gc.get_objects() to get a list of all the objects the gc is tracking. I process that list into a collections.Counter() with counts of each type of object that I call a snapshot. By creating the snapshots at interesting times in the services life I can diff the snapshots and see how the object usage changes over time. The software I work on has an admin HTTP interface used internally that I use to request snapshots white the service is running. Barry From frank at chagford.com Fri Feb 7 08:49:02 2020 From: frank at chagford.com (Frank Millman) Date: Fri, 7 Feb 2020 15:49:02 +0200 Subject: Change in behaviour Python 3.7 > 3.8 In-Reply-To: <18750057-5220-42D4-8C35-21BA3B37FAFD@barrys-emacs.org> References: <453d72be-a1f3-6f0d-211a-31a6d1a008b7@chagford.com> <18750057-5220-42D4-8C35-21BA3B37FAFD@barrys-emacs.org> Message-ID: <4a185493-e73b-4e5d-d228-8135dfe89ef5@chagford.com> On 2020-02-07 1:06 PM, Barry Scott wrote: > > >> On 7 Feb 2020, at 05:27, Frank Millman wrote: >> >> @Barry >> I agree that __del__() is rarely useful, but I have not come up with an alternative to achieve what I want to do. My app is a long-running server, and creates many objects on-the-fly depending on user input. They should be short-lived, and be removed when they go out of scope, but I can concerned that I may leave a dangling reference somewhere that keeps one of them alive, resulting in a memory leak over time. Creating a _del__() method and displaying a message to say 'I am being deleted' has proved effective, and has in fact highlighted a few cases where there was a real problem. > > I have faced the same problem with leaking of objects. > > What I did was use the python gc to find all the objects. > > First I call gc.collect() to clean up all the objects what can be deleted. > Then I call gc.get_objects() to get a list of all the objects the gc is tracking. > I process that list into a collections.Counter() with counts of each type of object > that I call a snapshot. > > By creating the snapshots at interesting times in the services life I can diff the > snapshots and see how the object usage changes over time. > > The software I work on has an admin HTTP interface used internally that I use to request > snapshots white the service is running. > This is really useful. I will experiment with this and try to incorporate it into my project. Thanks very much. Frank From frank at chagford.com Fri Feb 7 08:49:02 2020 From: frank at chagford.com (Frank Millman) Date: Fri, 7 Feb 2020 15:49:02 +0200 Subject: Change in behaviour Python 3.7 > 3.8 In-Reply-To: <18750057-5220-42D4-8C35-21BA3B37FAFD@barrys-emacs.org> References: <453d72be-a1f3-6f0d-211a-31a6d1a008b7@chagford.com> <18750057-5220-42D4-8C35-21BA3B37FAFD@barrys-emacs.org> Message-ID: <4a185493-e73b-4e5d-d228-8135dfe89ef5@chagford.com> On 2020-02-07 1:06 PM, Barry Scott wrote: > > >> On 7 Feb 2020, at 05:27, Frank Millman wrote: >> >> @Barry >> I agree that __del__() is rarely useful, but I have not come up with an alternative to achieve what I want to do. My app is a long-running server, and creates many objects on-the-fly depending on user input. They should be short-lived, and be removed when they go out of scope, but I can concerned that I may leave a dangling reference somewhere that keeps one of them alive, resulting in a memory leak over time. Creating a _del__() method and displaying a message to say 'I am being deleted' has proved effective, and has in fact highlighted a few cases where there was a real problem. > > I have faced the same problem with leaking of objects. > > What I did was use the python gc to find all the objects. > > First I call gc.collect() to clean up all the objects what can be deleted. > Then I call gc.get_objects() to get a list of all the objects the gc is tracking. > I process that list into a collections.Counter() with counts of each type of object > that I call a snapshot. > > By creating the snapshots at interesting times in the services life I can diff the > snapshots and see how the object usage changes over time. > > The software I work on has an admin HTTP interface used internally that I use to request > snapshots white the service is running. > This is really useful. I will experiment with this and try to incorporate it into my project. Thanks very much. Frank From Richard at Damon-Family.org Fri Feb 7 10:14:58 2020 From: Richard at Damon-Family.org (Richard Damon) Date: Fri, 7 Feb 2020 10:14:58 -0500 Subject: Documentation of __hash__ In-Reply-To: <78ee3d73-82c6-4483-b6c1-ffa3c0d9ae1d@googlegroups.com> References: <24122.64150.717391.820747@localhost.localdomain> <4f5b9e9d-9e22-4c25-ad07-73c9022693d6@googlegroups.com> <78ee3d73-82c6-4483-b6c1-ffa3c0d9ae1d@googlegroups.com> Message-ID: On 2/6/20 2:13 PM, klauck2 at gmail.com wrote: > The default __eq__ method (object identity) is compatible with all (reasonable) self-defined __hash__ method. > > Stefan If __eq__ compares just the id, then the only hash you need is the default that is also the id. If you define a separate hash function, which uses some of the 'value' of the object, then presumably you intend for objects where that 'value' matches to be equal, which won't happen with the default __eq__. -- Richard Damon From storchaka at gmail.com Fri Feb 7 03:44:56 2020 From: storchaka at gmail.com (Serhiy Storchaka) Date: Fri, 7 Feb 2020 10:44:56 +0200 Subject: Change in behaviour Python 3.7 > 3.8 In-Reply-To: <453d72be-a1f3-6f0d-211a-31a6d1a008b7@chagford.com> References: <453d72be-a1f3-6f0d-211a-31a6d1a008b7@chagford.com> Message-ID: 07.02.20 07:27, Frank Millman ????: > @Serhiy > I import the common object *from* Module A. Sorry, I incorrectly described the change made in issue33331. Even if you import it from module A, you can see that it was set to None at the time of executing __del__. But you could see this even before issue33331. It was just your luck that you did not fail before. The robust way of solving such issues is to keep a reference to all objects used in __del__: def __del__(self, common_object=common_object): ... From random832 at fastmail.com Fri Feb 7 10:29:00 2020 From: random832 at fastmail.com (Random832) Date: Fri, 07 Feb 2020 10:29:00 -0500 Subject: Documentation of __hash__ In-Reply-To: References: <24122.64150.717391.820747@localhost.localdomain> <4f5b9e9d-9e22-4c25-ad07-73c9022693d6@googlegroups.com> <78ee3d73-82c6-4483-b6c1-ffa3c0d9ae1d@googlegroups.com> Message-ID: On Fri, Feb 7, 2020, at 10:14, Richard Damon wrote: > On 2/6/20 2:13 PM, klauck2 at gmail.com wrote: > > The default __eq__ method (object identity) is compatible with all (reasonable) self-defined __hash__ method. > > > > Stefan > > If __eq__ compares just the id, then the only hash you need is the > default that is also the id. If you define a separate hash function, > which uses some of the 'value' of the object, then presumably you intend > for objects where that 'value' matches to be equal, which won't happen > with the default __eq__. I think Stefan's point is that, no matter how questionable the intent may sound, any deterministic __hash__ doesn't technically violate the hash/eq relationship with the default __eq__, because hash(x) will still be equal to hash(x). Only defining __eq__ can create the problem where x == y but hash(x) != hash(y). The purpose of this rule is to save you from having to override the default __hash__ with something that will only raise an exception when you do not intend your class to be hashable. From bill.orinski at gmail.com Fri Feb 7 12:13:38 2020 From: bill.orinski at gmail.com (bill.orinski at gmail.com) Date: Fri, 7 Feb 2020 10:13:38 -0700 Subject: Change in behaviour Python 3.7 > 3.8 In-Reply-To: References: Message-ID: <000e01d5ddd9$f0899d90$d19cd8b0$@gmail.com> Does anyone know of a service where I can send my STL files and have them converted to .x3g file, so I can simply upload the file to my SD card and run the parts in my Printer (Creator Pro Flashforge). I have had no success in doing this and converting to the G-code required for my machine... Thanks, Bill O. -----Original Message----- From: Python-list On Behalf Of Souvik Dutta Sent: Thursday, February 6, 2020 8:48 AM To: Frank Millman Cc: python-list at python.org Subject: Re: Change in behaviour Python 3.7 > 3.8 You might find this helpful. https://docs.python.org/3/reference/datamodel.html Thank you ?? On Thu, Feb 6, 2020, 6:29 PM Frank Millman wrote: > Hi all > > I have noticed a change in behaviour in Python 3.8 compared with > previous versions of Python going back to at least 2.7. I am pretty > sure that it is not a problem, and is caused by my relying on a > certain sequence of events at shutdown, which of course is not guaranteed. > However, any change in behaviour is worth reporting, just in case it > was unintended, so I thought I would mention it here. > > I have a module (A) containing common objects shared by other modules. > I have a module (B) which imports one of these common objects - a set(). > > Module B defines a Class, and creates a global instance of this class > when the module is created. This instance is never explicitly deleted, > so I assume it gets implicitly deleted at shutdown. It has a __del__() > method (only for temporary debugging purposes, so will be removed for > production) and the __del__ method uses the set() object imported from > Module A. > > This has worked for years, but now when the __del__ method is called, > the common object, which was a set(), has become None. > > My assumption is that Module A gets cleaned up before Module B, and > when Module B tries to access the common set() object it no longer exists. > > I have a workaround, so I am just reporting this for the record. > > Frank Millman > > -- > https://mail.python.org/mailman/listinfo/python-list > -- https://mail.python.org/mailman/listinfo/python-list From ethan at stoneleaf.us Fri Feb 7 14:04:27 2020 From: ethan at stoneleaf.us (Ethan Furman) Date: Fri, 7 Feb 2020 11:04:27 -0800 Subject: Change in behaviour Python 3.7 > 3.8 In-Reply-To: <000e01d5ddd9$f0899d90$d19cd8b0$@gmail.com> References: <000e01d5ddd9$f0899d90$d19cd8b0$@gmail.com> Message-ID: <5717f61e-2140-29ff-e37a-7d5713b1a056@stoneleaf.us> On 02/07/2020 09:13 AM, bill.orinski at gmail.com wrote: > Does anyone know of a service where I can send my STL files and have them converted to .x3g file, so I can simply upload the file to my SD card and run the parts in my Printer (Creator Pro Flashforge). > I have had no success in doing this and converting to the G-code required for my machine... Hopefully you sent this email to the wrong place. python-list at python.org is for discussion of things related to the Python Programming Language. Also, please start a new thread instead of piggy-backing on an existing thread. -- ~Ethan~ From jayrod84 at gmail.com Sun Feb 9 10:46:01 2020 From: jayrod84 at gmail.com (J A) Date: Sun, 9 Feb 2020 10:46:01 -0500 Subject: Pkg iter_module for different versions of python Message-ID: as a sysadmin I've written several small tools as python command line apps that get installed with python setup.py install. I would now like to create another tool that would quickly list out all of my custom tools that may be installed on the system. so that others can get a quick menu of what commands are available. I believe I have a working app that uses the iter_modules function to list out all of the names and then I just filter based on names that I know to be mine. My problem.. This works if everyone of my tools is only written in python 3 or 2, but not both. Are there any tricks to getting iter_modules to return both python 3 and 2 installed modules? J From PythonList at DancesWithMice.info Sun Feb 9 17:05:03 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Mon, 10 Feb 2020 11:05:03 +1300 Subject: Pkg iter_module for different versions of python In-Reply-To: References: Message-ID: <8789680d-e7a5-73b8-590b-1c5e7980cc8d@DancesWithMice.info> On 10/02/20 4:46 AM, J A wrote: > as a sysadmin I've written several small tools as python command line apps > that get installed with python setup.py install. I would now like to create > another tool that would quickly list out all of my custom tools that may be > installed on the system. so that others can get a quick menu of what > commands are available. I believe I have a working app that uses the > iter_modules function to list out all of the names and then I just filter > based on names that I know to be mine. > > My problem.. This works if everyone of my tools is only written in python 3 > or 2, but not both. Are there any tricks to getting iter_modules to return > both python 3 and 2 installed modules? Is the issue with iter_modules? Remember that different Python versions are installed with separate libraries/paths. Accordingly, this lap-top's /usr/lib64 has both python2.7/ and python3.7/ sub-directories. When an application is running under one* or the other, the sys.path changes accordingly (assuming the pkgutil.iter_modules(path=None) option). (in case needed) Remember also that different installation methods may install packages in different directories anyway, eg personal installation or system-wide. So, even 'this' sys.path may not reveal what is present on 'this system'. Might it be worth reversing the strategy and starting from a list of your modules, search likely portions of the directory-structure for 'your stuff'? (from a perspective of complete ignorance of the problem domain) * requisite notice about not using deprecated Python2.n these days! ("Do as I say, but not as I do"? I suspect/hope that this system's 2.7 is 'legacy' and no longer used for anything, including the OpSys) -- Regards =dn From jayrod84 at gmail.com Sun Feb 9 18:10:07 2020 From: jayrod84 at gmail.com (J A) Date: Sun, 9 Feb 2020 18:10:07 -0500 Subject: Fwd: Pkg iter_module for different versions of python In-Reply-To: References: <8789680d-e7a5-73b8-590b-1c5e7980cc8d@DancesWithMice.info> Message-ID: Might anyone know of a root place where python modules get saved to for both python2 and 3. I assume I'm looking for all of the places where "site-packages" can be written to. J ---------- Forwarded message --------- From: J A Date: Sun, 9 Feb 2020 at 17:56 Subject: Re: Pkg iter_module for different versions of python To: DL Neil Ya.. perhaps it would make more sense to start with "dirty" knowledge. I.e. a list of package/module names and then make sure they have the required entry points, therefore "validating" that they belong to me. Is there a valid directory structure to start from that is universal? perhaps from there I could parse through site-packages/**/MODULE_name.whl or something? and yes no more python 2 however a few of my commands are/were wrapping third party tool api's that are python 2 :/ J On Sun, 9 Feb 2020 at 17:05, DL Neil via Python-list wrote: > On 10/02/20 4:46 AM, J A wrote: > > as a sysadmin I've written several small tools as python command line > apps > > that get installed with python setup.py install. I would now like to > create > > another tool that would quickly list out all of my custom tools that may > be > > installed on the system. so that others can get a quick menu of what > > commands are available. I believe I have a working app that uses the > > iter_modules function to list out all of the names and then I just filter > > based on names that I know to be mine. > > > > My problem.. This works if everyone of my tools is only written in > python 3 > > or 2, but not both. Are there any tricks to getting iter_modules to > return > > both python 3 and 2 installed modules? > > > Is the issue with iter_modules? > > Remember that different Python versions are installed with separate > libraries/paths. Accordingly, this lap-top's /usr/lib64 has both > python2.7/ and python3.7/ sub-directories. > > When an application is running under one* or the other, the sys.path > changes accordingly (assuming the pkgutil.iter_modules(path=None) option). > > (in case needed) Remember also that different installation methods may > install packages in different directories anyway, eg personal > installation or system-wide. So, even 'this' sys.path may not reveal > what is present on 'this system'. > > Might it be worth reversing the strategy and starting from a list of > your modules, search likely portions of the directory-structure for > 'your stuff'? > (from a perspective of complete ignorance of the problem domain) > > * requisite notice about not using deprecated Python2.n these days! > ("Do as I say, but not as I do"? I suspect/hope that this system's 2.7 > is 'legacy' and no longer used for anything, including the OpSys) > -- > Regards =dn > -- > https://mail.python.org/mailman/listinfo/python-list > From tushita-2000 at outlook.com Mon Feb 10 06:00:25 2020 From: tushita-2000 at outlook.com (Tushita Parashar) Date: Mon, 10 Feb 2020 11:00:25 +0000 Subject: Software not working Message-ID: Even after installing the software on my system the software isn?t running. Sent from Windows Mail From python at bladeshadow.org Mon Feb 10 18:01:22 2020 From: python at bladeshadow.org (Python) Date: Mon, 10 Feb 2020 17:01:22 -0600 Subject: datetime seems to be broken WRT timezones (even when you add them) Message-ID: <20200210230122.GA32713@bladeshadow.org> As best I can tell, Python has no means to make use of the system's timezone info. In order to make datetime "timezone aware", you need to manually create a subclass of datetime.tzinfo, whose methods return the correct values for the timezone you care about. In the general case, this is hard, but since the timezone my dates are in is always GMT, it's no problem: class GMT(datetime.tzinfo): def utcoffset(self, dt): return datetime.timedelta(hours=0) def dst(self, dt): return datetime.timedelta(minutes=0) def tzname(self, dt): return "GMT" Now, you can instantiate a datetime.datetime object with the times you want, and pass an instance of this class as the tzinfo argument to the constructor. Also no problem: >>> dt = datetime.datetime(2020, 1, 31, 1, 30, 45, 987654, GMT()) >>> dt datetime.datetime(2020, 1, 31, 1, 30, 45, 987654, tzinfo=<__main__.GMT object at 0x7f9084e2add0>) >>> print dt 2020-01-31 01:30:45.987654+00:00 Note the tzinfo object, and the +00:00 indicating this is indeed in GMT. If you create a "naive" datetime object, you don't get that: >>> xy = datetime.datetime(2020, 1, 31, 1, 30, 45, 987654) >>> xy datetime.datetime(2020, 1, 31, 1, 30, 45, 987654) >>> print xy 2020-01-31 01:30:45.987654 So far, so good. However, when you go to use this object, the time it represents is in fact wrong. For example: >>> print dt.strftime("%s") 1580452245 Using the date command, we can easily see that it is incorrect: # Ask for UTC, gives the wrong time $ date -u -d "@1580452245" Fri Jan 31 06:30:45 UTC 2020 # Ask for local time, gives the time I specified... which should have # been in GMT, but is in my local timezone $ date -d "@1580452245" Fri Jan 31 01:30:45 EST 2020 And the correct value should have been: $ date -d "2020-01-31 1:30:45 GMT" +%s 1580434245 Same results under Python2.7 or Python3. :( :( :( I suspect this is because the underlying implementation uses strftime() which takes struct tm, which has no field to contain the timezone info, and does not do the necessary conversion before handing it off. I'm not sure what the date command is doing differently, but it clearly is able to get the correct answer. Does Python have an alternative way to do the above, with correct results? Thanks From skip.montanaro at gmail.com Mon Feb 10 18:52:59 2020 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Mon, 10 Feb 2020 17:52:59 -0600 Subject: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: <20200210230122.GA32713@bladeshadow.org> References: <20200210230122.GA32713@bladeshadow.org> Message-ID: > As best I can tell, Python has no means to make use of the system's > timezone info. In order to make datetime "timezone aware", you need > to manually create a subclass of datetime.tzinfo, whose methods return > the correct values for the timezone you care about. > ... > Does Python have an alternative way to do the above, with correct > results? > The datetime module's manipulation of timezones is pretty low-level. Maybe try arrow? https://arrow.readthedocs.io/en/latest/ Skip > From PythonList at DancesWithMice.info Mon Feb 10 18:59:08 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Tue, 11 Feb 2020 12:59:08 +1300 Subject: Software not working In-Reply-To: References: Message-ID: <850e7c7a-76bc-c239-3d32-d3b504799428@DancesWithMice.info> On 11/02/20 12:00 AM, Tushita Parashar wrote: > Even after installing the software on my system the software isn?t running. Today, an (apparently) identical question, already asked and answered. Please see the Python-Tutor list: "Python Beginner" msg. -- Regards =dn From python at bladeshadow.org Mon Feb 10 19:02:14 2020 From: python at bladeshadow.org (Python) Date: Mon, 10 Feb 2020 18:02:14 -0600 Subject: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: References: <20200210230122.GA32713@bladeshadow.org> Message-ID: <20200211000201.GB32713@bladeshadow.org> On Mon, Feb 10, 2020 at 05:52:59PM -0600, Skip Montanaro wrote: > > As best I can tell, Python has no means to make use of the system's > > timezone info. In order to make datetime "timezone aware", you need > > to manually create a subclass of datetime.tzinfo, whose methods return > > the correct values for the timezone you care about. > > > ... > > > Does Python have an alternative way to do the above, with correct > > results? > > > > The datetime module's manipulation of timezones is pretty low-level. Maybe > try arrow? > > https://arrow.readthedocs.io/en/latest/ Yeah, this looks like exacly what I'm looking for, but I need something that's part of the standard Python distribution, due to constraints I have no control over. [This is perhaps not strictly true, but for all intents and purposes...] FWIW, manipulating dates on POSIX systems is pretty much a nightmare, so it's hard to blame Python entirely for the state of things. Thanks though. From rosuav at gmail.com Mon Feb 10 19:04:28 2020 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 11 Feb 2020 11:04:28 +1100 Subject: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: <20200210230122.GA32713@bladeshadow.org> References: <20200210230122.GA32713@bladeshadow.org> Message-ID: On Tue, Feb 11, 2020 at 10:42 AM Python wrote: > > As best I can tell, Python has no means to make use of the system's > timezone info. In order to make datetime "timezone aware", you need > to manually create a subclass of datetime.tzinfo, whose methods return > the correct values for the timezone you care about. In the general > case, this is hard, but since the timezone my dates are in is always > GMT, it's no problem: > > class GMT(datetime.tzinfo): > def utcoffset(self, dt): > return datetime.timedelta(hours=0) > def dst(self, dt): > return datetime.timedelta(minutes=0) > def tzname(self, dt): > return "GMT" > > Now, you can instantiate a datetime.datetime object with the times you > want, and pass an instance of this class as the tzinfo argument to the > constructor. Also no problem: Rather than try to create your own GMT() object, have you considered using datetime.timezone.utc ? I tested it in your examples and it works just fine. ChrisA From python at bladeshadow.org Mon Feb 10 19:16:00 2020 From: python at bladeshadow.org (Python) Date: Mon, 10 Feb 2020 18:16:00 -0600 Subject: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: References: <20200210230122.GA32713@bladeshadow.org> Message-ID: <20200211001600.GC32713@bladeshadow.org> On Tue, Feb 11, 2020 at 11:04:28AM +1100, Chris Angelico wrote: > On Tue, Feb 11, 2020 at 10:42 AM Python wrote: > > Now, you can instantiate a datetime.datetime object with the times you > > want, and pass an instance of this class as the tzinfo argument to the > > constructor. Also no problem: > > Rather than try to create your own GMT() object, have you considered > using datetime.timezone.utc ? I tested it in your examples and it > works just fine. Not here it doesn't: >>> import datetime >>> dt = datetime.datetime(2020, 1, 31, 1, 30, 45, 987654, datetime.timezone.utc) >>> print(dt) 2020-01-31 01:30:45.987654+00:00 >>> print(dt.strftime("%s")) 1580452245 That's the same erroneous result from my example. The correct value is again 1580434245. Unless you've done something subtlely different... Also it's only available on Python3, which may not be the end of the world, but the tool I'm working on is--for the moment at least--expected to work on both python2.7 and 3. But it's irrelevant if it doesn't give the correct result, which seems to still be the case. From rosuav at gmail.com Mon Feb 10 19:33:54 2020 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 11 Feb 2020 11:33:54 +1100 Subject: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: <20200211001600.GC32713@bladeshadow.org> References: <20200210230122.GA32713@bladeshadow.org> <20200211001600.GC32713@bladeshadow.org> Message-ID: On Tue, Feb 11, 2020 at 11:17 AM Python wrote: > > On Tue, Feb 11, 2020 at 11:04:28AM +1100, Chris Angelico wrote: > > On Tue, Feb 11, 2020 at 10:42 AM Python wrote: > > > Now, you can instantiate a datetime.datetime object with the times you > > > want, and pass an instance of this class as the tzinfo argument to the > > > constructor. Also no problem: > > > > Rather than try to create your own GMT() object, have you considered > > using datetime.timezone.utc ? I tested it in your examples and it > > works just fine. > > Not here it doesn't: > > >>> import datetime > >>> dt = datetime.datetime(2020, 1, 31, 1, 30, 45, 987654, datetime.timezone.utc) > >>> print(dt) > 2020-01-31 01:30:45.987654+00:00 > >>> print(dt.strftime("%s")) > 1580452245 > > That's the same erroneous result from my example. The correct value > is again 1580434245. Unless you've done something subtlely > different... I haven't verified the arithmetic or that the date command is actually giving the result you want/expect here, but in my testing, I got what looked like correct results. However, instead of using the undocumented and unsupported strftime %s format code, I've been using the timestamp() method: https://docs.python.org/3/library/datetime.html#datetime.datetime.timestamp rosuav at sikorsky:~$ cat utctest.py import datetime dt = datetime.datetime(2020, 1, 31, 1, 30, 45, 987654, datetime.timezone.utc) print(dt) print(dt.timestamp()) rosuav at sikorsky:~$ python3.9 utctest.py 2020-01-31 01:30:45.987654+00:00 1580434245.987654 rosuav at sikorsky:~$ python3.8 utctest.py 2020-01-31 01:30:45.987654+00:00 1580434245.987654 rosuav at sikorsky:~$ python3.7 utctest.py 2020-01-31 01:30:45.987654+00:00 1580434245.987654 rosuav at sikorsky:~$ python3.6 utctest.py 2020-01-31 01:30:45.987654+00:00 1580434245.987654 rosuav at sikorsky:~$ python3.5 utctest.py 2020-01-31 01:30:45.987654+00:00 1580434245.987654 rosuav at sikorsky:~$ python3.4 utctest.py 2020-01-31 01:30:45.987654+00:00 1580434245.987654 My interpretation is that, on your platform, strftime("%s") is broken in the presence of tzinfo. > Also it's only available on Python3, which may not be the end of the > world, but the tool I'm working on is--for the moment at > least--expected to work on both python2.7 and 3. But it's irrelevant > if it doesn't give the correct result, which seems to still be the > case. > That may be your problem, but it's not mine, and I'm not going to attempt to answer for Python 2. ChrisA From jon+usenet at unequivocal.eu Mon Feb 10 19:59:04 2020 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Tue, 11 Feb 2020 00:59:04 -0000 (UTC) Subject: datetime seems to be broken WRT timezones (even when you add them) References: <20200210230122.GA32713@bladeshadow.org> Message-ID: On 2020-02-10, Python wrote: > So far, so good. However, when you go to use this object, the time it > represents is in fact wrong. Unsurprisingly for a language feature that's been around for nearly 17 years, no it isn't. > For example: > >>>> print dt.strftime("%s") > 1580452245 That's asking your libc's strftime to process the time through the "%s" format code, which has no defined behaviour under either Python or POSIX. If you're using GNU libc however then it uses the time information given and the timezone from the 'TZ' environment variable and returns seconds since the Unix epoch: >>> dt.strftime('%s') '1580452245' >>> import os >>> os.environ['TZ'] = 'UTC' >>> dt.strftime('%s') '1580434245' If you need to know the seconds since the epoch then in Python 3.3+ you can do that with dt.timestamp(). In Python 2.7 you can use the UTC class you created: (dt - datetime(1970, 1, 1, 0, 0, 0, 0, GMT())).total_seconds() From python at bladeshadow.org Mon Feb 10 20:29:02 2020 From: python at bladeshadow.org (Python) Date: Mon, 10 Feb 2020 19:29:02 -0600 Subject: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: Message-ID: <20200211012902.GD32713@bladeshadow.org> On Tue, Feb 11, 2020 at 11:33:54AM +1100, Chris Angelico wrote: > [...] instead of using the undocumented and unsupported strftime %s > format code I'm not sure this characterization is accurate... the docs (for both Python 2 and 3) say: The full set of format codes supported varies across platforms, because Python calls the platform C library?s strftime() function, and platform variations are common. To see the full set of format codes supported on your platform, consult the strftime(3) documentation. And %s is surely there... so it is both documented and supported by virtue of Python's docs saying that whatever your OS supports is supported. But this is largely beside the point. > I've been using the timestamp() method: That's the key piece of info. This does appear to work, though still not on python2. That, as you say, is my problem. But thankfully Jon Ribbens has the save: On Tue, Feb 11, 2020 at 12:59:04AM -0000, Jon Ribbens via Python-list wrote: > On 2020-02-10, Python wrote: > > So far, so good. However, when you go to use this object, the time it > > represents is in fact wrong. > > Unsurprisingly for a language feature that's been around for nearly > 17 years, no it isn't. Well, fine, but it is at best not documented as clearly as it could be (in the man pages of my system, which is not Python's fault). But you've given me what I need to solve my problem: > >>>> print dt.strftime("%s") > > 1580452245 > > That's asking your libc's strftime to process the time through the > "%s" format code [...] If you're using GNU libc however then it uses the time > information given and the timezone from the 'TZ' environment variable > and returns seconds since the Unix epoch: And knowing this, I can get what I need, on Python2 and python3, by doing what I was already doing, but setting os.environ["TZ"] = "GMT" in the code itself. Sure it's a bit hacky, but it won't matter here, and it gets the right answer, which does matter. Thanks From rosuav at gmail.com Mon Feb 10 20:42:26 2020 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 11 Feb 2020 12:42:26 +1100 Subject: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: <20200211012902.GD32713@bladeshadow.org> References: <20200211012902.GD32713@bladeshadow.org> Message-ID: On Tue, Feb 11, 2020 at 12:31 PM Python wrote: > > On Tue, Feb 11, 2020 at 11:33:54AM +1100, Chris Angelico wrote: > > [...] instead of using the undocumented and unsupported strftime %s > > format code > > I'm not sure this characterization is accurate... the docs (for both > Python 2 and 3) say: > > The full set of format codes supported varies across platforms, > because Python calls the platform C library?s strftime() function, > and platform variations are common. To see the full set of format > codes supported on your platform, consult the strftime(3) > documentation. > > And %s is surely there... so it is both documented and supported by > virtue of Python's docs saying that whatever your OS supports is > supported. But this is largely beside the point. https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes The C standard mandates a particular set of format codes, quoted in that page, and %s is not one of them. Also, Python has its own test suite and it ensures certain behaviours of datetime.strftime, and %s is not tested there. So from Python's point of view, I stand by the description of %s as being undocumented and unsupported. It might happen to work, but if you link Python against a different C standard library, it could change that behaviour even on the same computer. > > I've been using the timestamp() method: > > That's the key piece of info. This does appear to work, though still > not on python2. That, as you say, is my problem. But thankfully Jon > Ribbens has the save: Isn't it time to stop going to great effort to support Python 2? > On Tue, Feb 11, 2020 at 12:59:04AM -0000, Jon Ribbens via Python-list wrote: > > On 2020-02-10, Python wrote: > > > So far, so good. However, when you go to use this object, the time it > > > represents is in fact wrong. > > > > Unsurprisingly for a language feature that's been around for nearly > > 17 years, no it isn't. > > Well, fine, but it is at best not documented as clearly as it could be > (in the man pages of my system, which is not Python's fault). But > you've given me what I need to solve my problem: > > > >>>> print dt.strftime("%s") > > > 1580452245 > > > > That's asking your libc's strftime to process the time through the > > "%s" format code [...] If you're using GNU libc however then it uses the time > > information given and the timezone from the 'TZ' environment variable > > and returns seconds since the Unix epoch: > > And knowing this, I can get what I need, on Python2 and python3, by > doing what I was already doing, but setting os.environ["TZ"] = "GMT" > in the code itself. Sure it's a bit hacky, but it won't matter here, > and it gets the right answer, which does matter. > Yes, it's very hacky. The sort of hack that deserves a comment with a TODO in it. :) ChrisA From klauck2 at gmail.com Tue Feb 11 05:23:45 2020 From: klauck2 at gmail.com (klauck2 at gmail.com) Date: Tue, 11 Feb 2020 02:23:45 -0800 (PST) Subject: Documentation of __hash__ In-Reply-To: References: <24122.64150.717391.820747@localhost.localdomain> <4f5b9e9d-9e22-4c25-ad07-73c9022693d6@googlegroups.com> <78ee3d73-82c6-4483-b6c1-ffa3c0d9ae1d@googlegroups.com> Message-ID: <3a0e4141-ed51-4720-8ccd-ae985c7f3bf6@googlegroups.com> On Friday, February 7, 2020 at 4:30:23 PM UTC+1, Random832 wrote: > On Fri, Feb 7, 2020, at 10:14, Richard Damon wrote: > > On 2/6/20 2:13 PM, klauck2 at gmail.com wrote: > > > The default __eq__ method (object identity) is compatible with all (reasonable) self-defined __hash__ method. > > > > > > Stefan > > > > If __eq__ compares just the id, then the only hash you need is the > > default that is also the id. If you define a separate hash function, > > which uses some of the 'value' of the object, then presumably you intend > > for objects where that 'value' matches to be equal, which won't happen > > with the default __eq__. > > I think Stefan's point is that, no matter how questionable the intent may sound, any deterministic __hash__ doesn't technically violate the hash/eq relationship with the default __eq__, because hash(x) will still be equal to hash(x). Only defining __eq__ can create the problem where x == y but hash(x) != hash(y). Yes, this is my question. > > The purpose of this rule is to save you from having to override the default __hash__ with something that will only raise an exception when you do not intend your class to be hashable. If I do not intend my class to be hashable, I will set __hash__ to None (according to the documentation). From jon+usenet at unequivocal.eu Tue Feb 11 05:56:36 2020 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Tue, 11 Feb 2020 10:56:36 -0000 (UTC) Subject: datetime seems to be broken WRT timezones (even when you add them) References: <20200211012902.GD32713@bladeshadow.org> Message-ID: On 2020-02-11, Chris Angelico wrote: >> That's the key piece of info. This does appear to work, though still >> not on python2. That, as you say, is my problem. But thankfully Jon >> Ribbens has the save: > > Isn't it time to stop going to great effort to support Python 2? That depends on what existing systems people need to support. The main project I work on pre-dates the existence of Python's 'datetime' module, let alone Python 3. It still generally uses 1 and 0 for True and False because True and False didn't exist when we started. This project will never move to Python 3. It was a happy and momentous day, fairly recently, when we were able to move to Python 2.7 - albeit we're basically stuck on Python 2.7.5 (plus random patches from RedHat making it not-really-2.7.5). So while it's been about 6 years since anyone should have been starting any new projects using Python 2, there are plenty of projects that are older than that and still need supporting, and often it'd take some pretty huge unavoidable requirement to motivate a port to Python 3. From rosuav at gmail.com Tue Feb 11 06:05:15 2020 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 11 Feb 2020 22:05:15 +1100 Subject: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: References: <20200211012902.GD32713@bladeshadow.org> Message-ID: On Tue, Feb 11, 2020 at 10:01 PM Jon Ribbens via Python-list wrote: > > On 2020-02-11, Chris Angelico wrote: > >> That's the key piece of info. This does appear to work, though still > >> not on python2. That, as you say, is my problem. But thankfully Jon > >> Ribbens has the save: > > > > Isn't it time to stop going to great effort to support Python 2? > > That depends on what existing systems people need to support. The main > project I work on pre-dates the existence of Python's 'datetime' > module, let alone Python 3. It still generally uses 1 and 0 for True > and False because True and False didn't exist when we started. > > This project will never move to Python 3. It was a happy and momentous > day, fairly recently, when we were able to move to Python 2.7 - albeit > we're basically stuck on Python 2.7.5 (plus random patches from RedHat > making it not-really-2.7.5). > > So while it's been about 6 years since anyone should have been > starting any new projects using Python 2, there are plenty of > projects that are older than that and still need supporting, > and often it'd take some pretty huge unavoidable requirement > to motivate a port to Python 3. Or just the recognition that, eventually, technical debt has to be paid. I didn't say that everything has to stop supporting Py2 instantly now that it's 2020, but that it's time to stop going to great lengths for it. Py2 is a legacy system and has been for a long time now, and if it takes a lot of effort to keep maintaining it, then it's time to consider porting to Py3. Just how much work are you going to do, to avoid the work of porting? ChrisA From chapardar.parisa at gmail.com Tue Feb 11 06:13:32 2020 From: chapardar.parisa at gmail.com (Parisa Ch) Date: Tue, 11 Feb 2020 03:13:32 -0800 (PST) Subject: braket an matrix in python In-Reply-To: References: <45c82e87-1e6e-4bc3-92c4-75318187e64a@googlegroups.com> Message-ID: <81de0e63-6ffd-45b0-a78e-b099b4898735@googlegroups.com> On Monday, February 3, 2020 at 9:46:43 PM UTC+3:30, Peter Otten wrote: > Parisa Ch wrote: > > > x=np.linspace(0,2*math.pi,n) > > n=len(x) > > r=int(math.ceil(f*n)) > > h=[np.sort(np.abs(x-x[i]))[r] for i in range(n)] > > > > this is part of a python code. the last line is confusing? x is a matrix > > and x[i] is a number. how calculate x-x[i] for each i? > > why the put r in [] ? > thank you so much > Brake it appart: > > y = x - x[i] # the numpy feature that makes that possible is called > # "broadcasting" > > subtracts the value x[i] from every entry in the vector x > > z = np.abs(y) > > calculates the absolute value of every entry in y. > > t = np.sort(z) > > sorts the values in z and finally, assuming r is an integer, > > u = t[r] > > looks up a single scalar in the vector. > > The enclosing "list comprehension" [expr for item in iterable] builds a list > of n values calculated as sketched above. From jon+usenet at unequivocal.eu Tue Feb 11 06:13:54 2020 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Tue, 11 Feb 2020 11:13:54 -0000 (UTC) Subject: datetime seems to be broken WRT timezones (even when you add them) References: <20200211012902.GD32713@bladeshadow.org> Message-ID: On 2020-02-11, Chris Angelico wrote: > On Tue, Feb 11, 2020 at 10:01 PM Jon Ribbens via Python-list > wrote: >> So while it's been about 6 years since anyone should have been >> starting any new projects using Python 2, there are plenty of >> projects that are older than that and still need supporting, >> and often it'd take some pretty huge unavoidable requirement >> to motivate a port to Python 3. > > Or just the recognition that, eventually, technical debt has to be > paid. I didn't say that everything has to stop supporting Py2 > instantly now that it's 2020, but that it's time to stop going to > great lengths for it. Py2 is a legacy system and has been for a long > time now, and if it takes a lot of effort to keep maintaining it, then > it's time to consider porting to Py3. Just how much work are you going > to do, to avoid the work of porting? Not doing something generally doesn't involve any work. Occasionally there's a very small amount of work when something that would have been trivial in Python 3 is slightly harder in Python 2 - this thread for example, where it appears to involve one extra line of code. From lukasz at langa.pl Tue Feb 11 08:05:03 2020 From: lukasz at langa.pl (=?utf-8?Q?=C5=81ukasz_Langa?=) Date: Tue, 11 Feb 2020 14:05:03 +0100 Subject: [RELEASE] Python 3.8.2rc1 is now available for testing Message-ID: Python 3.8.2rc1 is the release candidate of the second maintenance release of Python 3.8. Go get it here: https://www.python.org/downloads/release/python-382rc1/ Assuming no critical problems are found prior to 2020-02-17, the scheduled release date for 3.8.2 (as well as 3.9.0 alpha 4!), no code changes are planned between this release candidate and the final release. That being said, please keep in mind that this is a pre-release of 3.8.2 and as such its main purpose is testing. Maintenance releases for the 3.8 series will continue at regular bi-monthly intervals, with 3.8.3 planned for April 2020 (during sprints at PyCon US). What?s new? The Python 3.8 series is the newest feature release of the Python language, and it contains many new features and optimizations. See the ?What?s New in Python 3.8 ? document for more information about features included in the 3.8 series. Detailed information about all changes made in version 3.8.2 specifically can be found in its change log . We hope you enjoy Python 3.8! Thanks to all of the many volunteers who help make Python Development and these releases possible! Please consider supporting our efforts by volunteering yourself or through organization contributions to the Python Software Foundation. https://www.python.org/psf/ - ? From python at bladeshadow.org Tue Feb 11 11:54:38 2020 From: python at bladeshadow.org (Python) Date: Tue, 11 Feb 2020 10:54:38 -0600 Subject: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: References: <20200211012902.GD32713@bladeshadow.org> Message-ID: <20200211165438.GE32713@bladeshadow.org> On Tue, Feb 11, 2020 at 12:42:26PM +1100, Chris Angelico wrote: > > > I've been using the timestamp() method: > > > > That's the key piece of info. This does appear to work, though still > > not on python2. That, as you say, is my problem. But thankfully Jon > > Ribbens has the save: > > Isn't it time to stop going to great effort to support Python If you live in a world where you get to decide that, sure. Not everyone does. From ethan at stoneleaf.us Tue Feb 11 12:31:14 2020 From: ethan at stoneleaf.us (Ethan Furman) Date: Tue, 11 Feb 2020 09:31:14 -0800 Subject: Documentation of __hash__ In-Reply-To: <3a0e4141-ed51-4720-8ccd-ae985c7f3bf6@googlegroups.com> References: <24122.64150.717391.820747@localhost.localdomain> <4f5b9e9d-9e22-4c25-ad07-73c9022693d6@googlegroups.com> <78ee3d73-82c6-4483-b6c1-ffa3c0d9ae1d@googlegroups.com> <3a0e4141-ed51-4720-8ccd-ae985c7f3bf6@googlegroups.com> Message-ID: <26a558c5-5135-1918-a7cf-dee47cf1d017@stoneleaf.us> On 02/11/2020 02:23 AM, klauck2 at gmail.com wrote: > On Friday, February 7, 2020 at 4:30:23 PM UTC+1, Random832 wrote: >> The purpose of this rule is to save you from having to override the default __hash__ with something that will only raise an exception when you do not intend your class to be hashable. > > If I do not intend my class to be hashable, I will set __hash__ to None (according to the documentation). If you define your own __eq__ method, __hash__ is automatically set to None. -- ~Ethan~ From rosuav at gmail.com Tue Feb 11 13:38:38 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 12 Feb 2020 05:38:38 +1100 Subject: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: <20200211165438.GE32713@bladeshadow.org> References: <20200211012902.GD32713@bladeshadow.org> <20200211165438.GE32713@bladeshadow.org> Message-ID: On Wed, Feb 12, 2020 at 3:57 AM Python wrote: > > On Tue, Feb 11, 2020 at 12:42:26PM +1100, Chris Angelico wrote: > > > > I've been using the timestamp() method: > > > > > > That's the key piece of info. This does appear to work, though still > > > not on python2. That, as you say, is my problem. But thankfully Jon > > > Ribbens has the save: > > > > Isn't it time to stop going to great effort to support Python > > If you live in a world where you get to decide that, sure. Not > everyone does. > Everyone gets to decide how much time and effort they put into supporting an old and unsupported system. Are you telling me that someone is enslaving you and forcing you to continue supporting Python 2, or are you actually saying that it's less effort to keep maintaining old code than to port to Py3? As I said in the previous email, I did NOT say that it's time to instantly drop Py2 like a hot potato. (And if you do nothing, a hot potato just becomes a cold potato. Thank you, Bernard.) ChrisA From python at bladeshadow.org Tue Feb 11 14:43:09 2020 From: python at bladeshadow.org (Python) Date: Tue, 11 Feb 2020 13:43:09 -0600 Subject: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: References: <20200211012902.GD32713@bladeshadow.org> <20200211165438.GE32713@bladeshadow.org> Message-ID: <20200211194309.GF32713@bladeshadow.org> On Wed, Feb 12, 2020 at 05:38:38AM +1100, Chris Angelico wrote: > > > Isn't it time to stop going to great effort to support Python > > > > If you live in a world where you get to decide that, sure. Not > > everyone does. > > > > Everyone gets to decide how much time and effort they put into > supporting an old and unsupported system. Mostly not... In the real world you typically are beholden to customers (be they internal or external), and you are beholden to your bosses (be they the same or different people from the first group). What you say is true only if you have no customers or bosses to whom you have obligations, or have sufficient financial freedom or influence to ignore them and are willing to accept the consequences. From torriem at gmail.com Tue Feb 11 15:01:56 2020 From: torriem at gmail.com (Michael Torrie) Date: Tue, 11 Feb 2020 13:01:56 -0700 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: References: <20200211012902.GD32713@bladeshadow.org> Message-ID: <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> On 2/11/20 4:05 AM, Chris Angelico wrote: > Or just the recognition that, eventually, technical debt has to be > paid. Speaking about technical debt is certainly fashionable these days. As if we've somehow discovered a brand new way of looking at things. But it doesn't matter what you do, there's always real cost, and therefore always technical debt. Moving to Python 3 incurs technical debt. Staying with Python 2 incurs technical debt. Thus I wonder if the term is actually that useful. I know what you mean, though. The cost of staying with Python2 is increasing rapidly compared to the cost of porting to Python3. Unlike the nebulous term, "technical debt," the cost of staying with Python2 vs porting to Python3 can be quantified in real dollar amounts. I've no doubt that the calculus is in favor of Python2 a while longer for many people. From rosuav at gmail.com Tue Feb 11 15:04:50 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 12 Feb 2020 07:04:50 +1100 Subject: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: <20200211194309.GF32713@bladeshadow.org> References: <20200211012902.GD32713@bladeshadow.org> <20200211165438.GE32713@bladeshadow.org> <20200211194309.GF32713@bladeshadow.org> Message-ID: On Wed, Feb 12, 2020 at 6:45 AM Python wrote: > > On Wed, Feb 12, 2020 at 05:38:38AM +1100, Chris Angelico wrote: > > > > Isn't it time to stop going to great effort to support Python > > > > > > If you live in a world where you get to decide that, sure. Not > > > everyone does. > > > > > > > Everyone gets to decide how much time and effort they put into > > supporting an old and unsupported system. > > Mostly not... In the real world you typically are beholden to > customers (be they internal or external), and you are beholden to your > bosses (be they the same or different people from the first group). > What you say is true only if you have no customers or bosses to whom > you have obligations, or have sufficient financial freedom or > influence to ignore them and are willing to accept the consequences. > Is your boss/client smart enough to understand the concept of putting in effort now to pay off significant dividends later? Does your boss/client recognize that using software that isn't getting security patches means you're vulnerable? Actually, does your boss/client even care what your chosen language is? Certainly in the case of clients or customers, it's extremely common for them to have expectations in terms of "make it work", not "keep it running on Python 2". So long as it's fairly easy to keep it going on Py2, sure, keep it going on Py2. But if it's going to be a lot of effort - and, increasingly, it will - then you need to be willing to take the non-lazy option and do the migration, rather than perpetually putting it off and incurring more and more technical debt in the process. ChrisA From rosuav at gmail.com Tue Feb 11 15:09:12 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 12 Feb 2020 07:09:12 +1100 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> Message-ID: On Wed, Feb 12, 2020 at 7:03 AM Michael Torrie wrote: > > On 2/11/20 4:05 AM, Chris Angelico wrote: > > Or just the recognition that, eventually, technical debt has to be > > paid. > > Speaking about technical debt is certainly fashionable these days. As > if we've somehow discovered a brand new way of looking at things. But > it doesn't matter what you do, there's always real cost, and therefore > always technical debt. Moving to Python 3 incurs technical debt. > Staying with Python 2 incurs technical debt. Thus I wonder if the term > is actually that useful. > > I know what you mean, though. The cost of staying with Python2 is > increasing rapidly compared to the cost of porting to Python3. Unlike > the nebulous term, "technical debt," the cost of staying with Python2 vs > porting to Python3 can be quantified in real dollar amounts. I've no > doubt that the calculus is in favor of Python2 a while longer for many > people. What you're talking about is costs in general, but "debt" is a very specific term. You accrue technical debt whenever you "borrow" time from the future - doing something that's less effort now at the expense of being worse in the future. You pay off that debt when you sink time into something in order to make it easier to work on in the future. The most common form of technical debt is legacy code, where you often end up paying interest on the debt every time you dip your toes into the code to make a small change, avoiding the work of actually refactoring things and fixing the problems. Porting to Python 3 should *improve* your codebase, so it should be a way of shedding technical debt. (Unless you do it by running 2to3 on your code and hoping for the best. But that's a bad idea for many other reasons.) ChrisA From barry at barrys-emacs.org Tue Feb 11 16:17:44 2020 From: barry at barrys-emacs.org (Barry Scott) Date: Tue, 11 Feb 2020 21:17:44 +0000 Subject: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: <20200210230122.GA32713@bladeshadow.org> References: <20200210230122.GA32713@bladeshadow.org> Message-ID: > On 10 Feb 2020, at 23:01, Python wrote: > > As best I can tell, Python has no means to make use of the system's > timezone info. In order to make datetime "timezone aware", you need > to manually create a subclass of datetime.tzinfo, whose methods return > the correct values for the timezone you care about. In the general > case, this is hard, but since the timezone my dates are in is always > GMT, it's no problem: > > class GMT(datetime.tzinfo): > def utcoffset(self, dt): > return datetime.timedelta(hours=0) > def dst(self, dt): > return datetime.timedelta(minutes=0) > def tzname(self, dt): > return "GMT" > > Now, you can instantiate a datetime.datetime object with the times you > want, and pass an instance of this class as the tzinfo argument to the > constructor. Also no problem: >>>> dt = datetime.datetime(2020, 1, 31, 1, 30, 45, 987654, GMT()) >>>> dt > datetime.datetime(2020, 1, 31, 1, 30, 45, 987654, tzinfo=<__main__.GMT object at 0x7f9084e2add0>) >>>> print dt > 2020-01-31 01:30:45.987654+00:00 > > Note the tzinfo object, and the +00:00 indicating this is indeed in > GMT. If you create a "naive" datetime object, you don't get that: > >>>> xy = datetime.datetime(2020, 1, 31, 1, 30, 45, 987654) >>>> xy > datetime.datetime(2020, 1, 31, 1, 30, 45, 987654) >>>> print xy > 2020-01-31 01:30:45.987654 > > > So far, so good. However, when you go to use this object, the time it > represents is in fact wrong. For example: > >>>> print dt.strftime("%s") > 1580452245 > > Using the date command, we can easily see that it is incorrect: > > # Ask for UTC, gives the wrong time > $ date -u -d "@1580452245" > Fri Jan 31 06:30:45 UTC 2020 > > # Ask for local time, gives the time I specified... which should have > # been in GMT, but is in my local timezone > $ date -d "@1580452245" > Fri Jan 31 01:30:45 EST 2020 > > And the correct value should have been: > $ date -d "2020-01-31 1:30:45 GMT" +%s > 1580434245 > > Same results under Python2.7 or Python3. > > :( :( :( > > I suspect this is because the underlying implementation uses > strftime() which takes struct tm, which has no field to contain the > timezone info, and does not do the necessary conversion before handing > it off. I'm not sure what the date command is doing differently, but > it clearly is able to get the correct answer. > > Does Python have an alternative way to do the above, with correct > results? I found that there are two useful PyPi packages to help with time zones. pytz and tzlocal. Here is a piece of code that I use to be timezone aware for UTC and the local time zone. It works for Windows, macOS and unix thanks. import datetime import pytz import tzlocal def utcDatetime( timestamp ): return pytz.utc.localize( datetime.datetime.utcfromtimestamp( timestamp ) ) def localDatetime( datetime_or_timestamp ): if type(datetime_or_timestamp) in (int, float): dt = utcDatetime( datetime_or_timestamp ) else: dt = datetime_or_timestamp local_timezone = tzlocal.get_localzone() local_dt = dt.astimezone( local_timezone ) return local_dt Barry > > Thanks > > -- > https://mail.python.org/mailman/listinfo/python-list > From barry at barrys-emacs.org Tue Feb 11 16:25:35 2020 From: barry at barrys-emacs.org (Barry Scott) Date: Tue, 11 Feb 2020 21:25:35 +0000 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> Message-ID: > On 11 Feb 2020, at 20:01, Michael Torrie wrote: > > On 2/11/20 4:05 AM, Chris Angelico wrote: >> Or just the recognition that, eventually, technical debt has to be >> paid. > > Speaking about technical debt is certainly fashionable these days. As > if we've somehow discovered a brand new way of looking at things. But > it doesn't matter what you do, there's always real cost, and therefore > always technical debt. Moving to Python 3 incurs technical debt. > Staying with Python 2 incurs technical debt. Thus I wonder if the term > is actually that useful. At Chris said moving to python3 will *reduce* your technical debt. You are paying off the debt. > > I know what you mean, though. The cost of staying with Python2 is > increasing rapidly compared to the cost of porting to Python3. Unlike > the nebulous term, "technical debt," the cost of staying with Python2 vs > porting to Python3 can be quantified in real dollar amounts. I've no > doubt that the calculus is in favor of Python2 a while longer for many > people. Not to mention that its harder to hire people to work on tech-debt legacy code. Given the choice between a legacy python2 job and a modern python3 job what would you choose? Barry > -- > https://mail.python.org/mailman/listinfo/python-list > From torriem at gmail.com Tue Feb 11 19:31:24 2020 From: torriem at gmail.com (Michael Torrie) Date: Tue, 11 Feb 2020 17:31:24 -0700 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> Message-ID: On 2/11/20 2:25 PM, Barry Scott wrote: > At Chris said moving to python3 will *reduce* your technical debt. > You are paying off the debt. While at the same time incurring new debt. > Not to mention that its harder to hire people to work on tech-debt legacy code. > > Given the choice between a legacy python2 job and a modern python3 job > what would you choose? If this was an income job, it would entirely depend on what it paid. In this day and age of the so-called "gig economy" it really doesn't matter. I likely wouldn't be around long enough to have to personally deal with the long-term consequences (pay the debt as you say). From rosuav at gmail.com Tue Feb 11 19:37:25 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 12 Feb 2020 11:37:25 +1100 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> Message-ID: On Wed, Feb 12, 2020 at 11:32 AM Michael Torrie wrote: > > On 2/11/20 2:25 PM, Barry Scott wrote: > > At Chris said moving to python3 will *reduce* your technical debt. > > You are paying off the debt. > > While at the same time incurring new debt. That's not an intrinsic part of the rewrite, and will only happen if you do the job sloppily. Perhaps you're completely misunderstanding the meaning of the term? https://en.wikipedia.org/wiki/Technical_debt https://thedailywtf.com/articles/technical-debt ChrisA From torriem at gmail.com Tue Feb 11 19:38:22 2020 From: torriem at gmail.com (Michael Torrie) Date: Tue, 11 Feb 2020 17:38:22 -0700 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> Message-ID: <5a977c94-4cbd-b546-fb32-bf1830645049@gmail.com> On 2/11/20 1:09 PM, Chris Angelico wrote: > What you're talking about is costs in general, but "debt" is a very > specific term. You accrue technical debt whenever you "borrow" time > from the future - doing something that's less effort now at the > expense of being worse in the future. You pay off that debt when you > sink time into something in order to make it easier to work on in the > future. The most common form of technical debt is legacy code, where > you often end up paying interest on the debt every time you dip your > toes into the code to make a small change, avoiding the work of > actually refactoring things and fixing the problems. It's all just different ways of accounting for the same things. In the olden days before the term "technical debt" was invented, we called this "total cost of ownership." This not only included the up front cost, but the on-going (and potentially increasing) cost of maintenance, and often even the future cost of migrating to a new solution. So in the end it's all the same: cost. And it's never paid off. Ever. That's why I've recently come to question the usefulness of the term "technical debt." > Porting to Python 3 should *improve* your codebase, so it should be a > way of shedding technical debt. (Unless you do it by running 2to3 on > your code and hoping for the best. But that's a bad idea for many > other reasons.) But see, this is the thing. There's brand new technical debt accrued with the move to Python 3. The cost of the debt is lower, but it's still there. Because maintenance is still going to cost. Versions still bump and require hopefully minor tweaks. Eventually the bigger jumps come. New ideas come along also. New frameworks, new paradigms. I think it's a fallacy to think we can pay down technical debt. I'm sure we probably disagree. From rosuav at gmail.com Tue Feb 11 19:42:42 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 12 Feb 2020 11:42:42 +1100 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: <5a977c94-4cbd-b546-fb32-bf1830645049@gmail.com> References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> <5a977c94-4cbd-b546-fb32-bf1830645049@gmail.com> Message-ID: On Wed, Feb 12, 2020 at 11:39 AM Michael Torrie wrote: > > On 2/11/20 1:09 PM, Chris Angelico wrote: > > What you're talking about is costs in general, but "debt" is a very > > specific term. You accrue technical debt whenever you "borrow" time > > from the future - doing something that's less effort now at the > > expense of being worse in the future. You pay off that debt when you > > sink time into something in order to make it easier to work on in the > > future. The most common form of technical debt is legacy code, where > > you often end up paying interest on the debt every time you dip your > > toes into the code to make a small change, avoiding the work of > > actually refactoring things and fixing the problems. > > It's all just different ways of accounting for the same things. In the > olden days before the term "technical debt" was invented, we called this > "total cost of ownership." This not only included the up front cost, but > the on-going (and potentially increasing) cost of maintenance, and often > even the future cost of migrating to a new solution. So in the end it's > all the same: cost. And it's never paid off. Ever. That's why I've > recently come to question the usefulness of the term "technical debt." Yes, if you consider the term to be synonymous with TCO, then naturally you'll see it as useless. But it isn't. Technical debt is a very specific thing and it CAN be paid off. ChrisA From torriem at gmail.com Tue Feb 11 19:45:08 2020 From: torriem at gmail.com (Michael Torrie) Date: Tue, 11 Feb 2020 17:45:08 -0700 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> Message-ID: On 2/11/20 5:37 PM, Chris Angelico wrote: > On Wed, Feb 12, 2020 at 11:32 AM Michael Torrie wrote: >> >> On 2/11/20 2:25 PM, Barry Scott wrote: >>> At Chris said moving to python3 will *reduce* your technical debt. >>> You are paying off the debt. >> >> While at the same time incurring new debt. > > That's not an intrinsic part of the rewrite, and will only happen if > you do the job sloppily. > > Perhaps you're completely misunderstanding the meaning of the term? > > https://en.wikipedia.org/wiki/Technical_debt > https://thedailywtf.com/articles/technical-debt Yes I understand the meaning. Getting code out the door now, at the expense of maintenance later. But really all code is technical debt. That's my main point. No one writes good enough code to be completely free of this technical debt. From python at bladeshadow.org Tue Feb 11 19:53:13 2020 From: python at bladeshadow.org (Python) Date: Tue, 11 Feb 2020 18:53:13 -0600 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> Message-ID: <20200212005313.GG32713@bladeshadow.org> On Wed, Feb 12, 2020 at 07:09:12AM +1100, Chris Angelico wrote: > On Wed, Feb 12, 2020 at 7:03 AM Michael Torrie wrote: > > Speaking about technical debt is certainly fashionable these days. As > > if we've somehow discovered a brand new way of looking at things. But > > it doesn't matter what you do, there's always real cost, and therefore > > always technical debt. Moving to Python 3 incurs technical debt. > > Staying with Python 2 incurs technical debt. Thus I wonder if the term > > is actually that useful. [...] > What you're talking about is costs in general, but "debt" is a very > specific term. You accrue technical debt whenever you "borrow" time > from the future - doing something that's less effort now at the > expense of being worse in the future. In pretty much every job I've ever worked at, funding work (e.g. with humans to do it) with exactly and precisely the resources required is basically impossible, and management prefers to underfund the work than to overfund it, for cost-savings reasons. This basically means that any non-trivial work you do inevitably will become technical debt IMMEDIATELY, because you will not be given the time to do the job completely in the first place, there will inevitably be bugs which are minor enough to ignore indefinitely, and most likely, in order to meet arbitrary-but-nevertheless-real time constraints you will find yourself obliged to take shortcuts. So conceptually "costs" may be different from "debt" but in practice, you never have one without the other, and "debt" is really just "costs" you haven't paid yet. If your hypothetical project was implemented perfectly from the beginning, in Python2.x, it may never need updating, and therefore there may well never be any reason to port it to python3. So doing so would be neither "debt" nor "cost" but rather "waste." From torriem at gmail.com Tue Feb 11 19:55:06 2020 From: torriem at gmail.com (Michael Torrie) Date: Tue, 11 Feb 2020 17:55:06 -0700 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> <5a977c94-4cbd-b546-fb32-bf1830645049@gmail.com> Message-ID: <530ac1ea-556f-ed24-baa7-d73161d72f92@gmail.com> On 2/11/20 5:42 PM, Chris Angelico wrote: > Yes, if you consider the term to be synonymous with TCO, then > naturally you'll see it as useless. But it isn't. Technical debt is a > very specific thing and it CAN be paid off. We'll agree to disagree on the last bit. And I'm not the only one that believes technical debt can never be paid off. Microsoft got fabulously wealthy incurring vast amounts of technical debt. We can argue that Windows is the result (it is), but what's killing Windows isn't the technical debt. It's the cloud and the web. From rosuav at gmail.com Tue Feb 11 19:55:33 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 12 Feb 2020 11:55:33 +1100 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> Message-ID: On Wed, Feb 12, 2020 at 11:48 AM Michael Torrie wrote: > > On 2/11/20 5:37 PM, Chris Angelico wrote: > > On Wed, Feb 12, 2020 at 11:32 AM Michael Torrie wrote: > >> > >> On 2/11/20 2:25 PM, Barry Scott wrote: > >>> At Chris said moving to python3 will *reduce* your technical debt. > >>> You are paying off the debt. > >> > >> While at the same time incurring new debt. > > > > That's not an intrinsic part of the rewrite, and will only happen if > > you do the job sloppily. > > > > Perhaps you're completely misunderstanding the meaning of the term? > > > > https://en.wikipedia.org/wiki/Technical_debt > > https://thedailywtf.com/articles/technical-debt > > Yes I understand the meaning. Getting code out the door now, at the > expense of maintenance later. But really all code is technical debt. > That's my main point. No one writes good enough code to be completely > free of this technical debt. But you CAN rewrite code such that it reduces technical debt. You can refactor code to make it more logical. You can update things to use idioms that better express the concepts you're trying to represent (maybe because those idioms require syntactic features that didn't exist, or simply because you didn't know about them when you first wrote the code). Maybe you'll still have SOME debt, but that doesn't mean it's never reduced. Debt is not a binary state. ChrisA From rosuav at gmail.com Tue Feb 11 20:03:15 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 12 Feb 2020 12:03:15 +1100 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: <530ac1ea-556f-ed24-baa7-d73161d72f92@gmail.com> References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> <5a977c94-4cbd-b546-fb32-bf1830645049@gmail.com> <530ac1ea-556f-ed24-baa7-d73161d72f92@gmail.com> Message-ID: On Wed, Feb 12, 2020 at 12:00 PM Michael Torrie wrote: > > On 2/11/20 5:42 PM, Chris Angelico wrote: > > Yes, if you consider the term to be synonymous with TCO, then > > naturally you'll see it as useless. But it isn't. Technical debt is a > > very specific thing and it CAN be paid off. > > We'll agree to disagree on the last bit. And I'm not the only one that > believes technical debt can never be paid off. Microsoft got fabulously > wealthy incurring vast amounts of technical debt. We can argue that > Windows is the result (it is), but what's killing Windows isn't the > technical debt. It's the cloud and the web. So what you're showing is that, sometimes, technical debt isn't paid off. It's a bit of a logical leap to go from there to "technical debt CAN'T be paid off", don't you think? ChrisA From tjreedy at udel.edu Tue Feb 11 19:36:03 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Tue, 11 Feb 2020 19:36:03 -0500 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> Message-ID: On 2/11/2020 3:09 PM, Chris Angelico wrote: > What you're talking about is costs in general, but "debt" is a very > specific term. You accrue technical debt whenever you "borrow" time > from the future - doing something that's less effort now at the > expense of being worse in the future. A prime example is sending code to production without automated tests. > You pay off that debt when you > sink time into something in order to make it easier to work on in the > future. In May 2013, idlelib had no test suite, no test/test_idle.py, and a few non-unittest unit tests. Coverage is now somewhere around 50% and tested modules are much easier to work with. > The most common form of technical debt is legacy code, where > you often end up paying interest on the debt every time you dip your > toes into the code to make a small change, avoiding the work of > actually refactoring things and fixing the problems. Without automated tests, every little change required manual testing and carried a non-zero chance of a regression. -- Terry Jan Reedy From torriem at gmail.com Tue Feb 11 20:11:53 2020 From: torriem at gmail.com (Michael Torrie) Date: Tue, 11 Feb 2020 18:11:53 -0700 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> Message-ID: <399c495d-741c-5081-4950-ced98b6c179f@gmail.com> On 2/11/20 5:55 PM, Chris Angelico wrote: > But you CAN rewrite code such that it reduces technical debt. You can > refactor code to make it more logical. You can update things to use > idioms that better express the concepts you're trying to represent > (maybe because those idioms require syntactic features that didn't > exist, or simply because you didn't know about them when you first > wrote the code). Maybe you'll still have SOME debt, but that doesn't > mean it's never reduced. > > Debt is not a binary state. I agree with that. But your reply to my other comment didn't say that. it said "it CAN be paid off" which is a binary thing. Debt is paid off (no longer existing) or it's not. Debt can be paid down and reduced of course. From torriem at gmail.com Tue Feb 11 20:13:52 2020 From: torriem at gmail.com (Michael Torrie) Date: Tue, 11 Feb 2020 18:13:52 -0700 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: <20200212005313.GG32713@bladeshadow.org> References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> <20200212005313.GG32713@bladeshadow.org> Message-ID: On 2/11/20 5:53 PM, Python wrote: > If your hypothetical project was implemented perfectly from the > beginning, in Python2.x, it may never need updating, and therefore > there may well never be any reason to port it to python3. So doing so > would be neither "debt" nor "cost" but rather "waste." I would agree generally, except eventually Python2 will be unavailable in your distro and may no longer be build-able on current OS's. However if the program is working as well as you state, then the cost of converting to the current version of Python (whatever that will be) is not going to increase significantly. Whatever the case, technical debt belongs to the entity that owns the code. I know some folks still running an MS-DOS system for billing. Thanks to things like DosBox, this system will live on for a long time yet. It works, and they don't have any real need for anything beyond it. It's never needed much updating or maintenance beyond maintenance they would do anyway like backups. Insane amounts of technical debt? Maybe. Or maybe just the cost of buying a new off-the-shelf system, which would be the same cost (or more likely a lot more with upgrades and service plans) had they done this years ago. From rosuav at gmail.com Tue Feb 11 20:15:47 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 12 Feb 2020 12:15:47 +1100 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: <399c495d-741c-5081-4950-ced98b6c179f@gmail.com> References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> <399c495d-741c-5081-4950-ced98b6c179f@gmail.com> Message-ID: On Wed, Feb 12, 2020 at 12:13 PM Michael Torrie wrote: > > On 2/11/20 5:55 PM, Chris Angelico wrote: > > But you CAN rewrite code such that it reduces technical debt. You can > > refactor code to make it more logical. You can update things to use > > idioms that better express the concepts you're trying to represent > > (maybe because those idioms require syntactic features that didn't > > exist, or simply because you didn't know about them when you first > > wrote the code). Maybe you'll still have SOME debt, but that doesn't > > mean it's never reduced. > > > > Debt is not a binary state. > > I agree with that. But your reply to my other comment didn't say that. > it said "it CAN be paid off" which is a binary thing. Debt is paid off > (no longer existing) or it's not. Debt can be paid down and reduced of > course. Ahh, that might be a regional difference then, because around here, it's possible to pay off some of a debt. That would be why we were talking past each other. ChrisA From torriem at gmail.com Tue Feb 11 20:30:33 2020 From: torriem at gmail.com (Michael Torrie) Date: Tue, 11 Feb 2020 18:30:33 -0700 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> <399c495d-741c-5081-4950-ced98b6c179f@gmail.com> Message-ID: On 2/11/20 6:15 PM, Chris Angelico wrote: > On Wed, Feb 12, 2020 at 12:13 PM Michael Torrie wrote: >> >> On 2/11/20 5:55 PM, Chris Angelico wrote: >>> But you CAN rewrite code such that it reduces technical debt. You can >>> refactor code to make it more logical. You can update things to use >>> idioms that better express the concepts you're trying to represent >>> (maybe because those idioms require syntactic features that didn't >>> exist, or simply because you didn't know about them when you first >>> wrote the code). Maybe you'll still have SOME debt, but that doesn't >>> mean it's never reduced. >>> >>> Debt is not a binary state. >> >> I agree with that. But your reply to my other comment didn't say that. >> it said "it CAN be paid off" which is a binary thing. Debt is paid off >> (no longer existing) or it's not. Debt can be paid down and reduced of >> course. > > Ahh, that might be a regional difference then, because around here, > it's possible to pay off some of a debt. That would be why we were > talking past each other. Yup I just came to that conclusion while typing a reply to your other post! My apologies. From rosuav at gmail.com Tue Feb 11 20:36:09 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 12 Feb 2020 12:36:09 +1100 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> <399c495d-741c-5081-4950-ced98b6c179f@gmail.com> Message-ID: On Wed, Feb 12, 2020 at 12:32 PM Michael Torrie wrote: > > On 2/11/20 6:15 PM, Chris Angelico wrote: > > On Wed, Feb 12, 2020 at 12:13 PM Michael Torrie wrote: > >> > >> On 2/11/20 5:55 PM, Chris Angelico wrote: > >>> But you CAN rewrite code such that it reduces technical debt. You can > >>> refactor code to make it more logical. You can update things to use > >>> idioms that better express the concepts you're trying to represent > >>> (maybe because those idioms require syntactic features that didn't > >>> exist, or simply because you didn't know about them when you first > >>> wrote the code). Maybe you'll still have SOME debt, but that doesn't > >>> mean it's never reduced. > >>> > >>> Debt is not a binary state. > >> > >> I agree with that. But your reply to my other comment didn't say that. > >> it said "it CAN be paid off" which is a binary thing. Debt is paid off > >> (no longer existing) or it's not. Debt can be paid down and reduced of > >> course. > > > > Ahh, that might be a regional difference then, because around here, > > it's possible to pay off some of a debt. That would be why we were > > talking past each other. > > Yup I just came to that conclusion while typing a reply to your other > post! My apologies. > My apologies also :) It was one of those weird situations where I was all "oh come on, he doesn't SERIOUSLY think that you never get rid of any tech debt?" and you were all "oh come on, he doesn't SERIOUSLY think that you can get rid of all of it", and we just both had no idea :) ChrisA From .. at use.net Wed Feb 12 02:02:27 2020 From: .. at use.net (..) Date: Wed, 12 Feb 2020 07:02:27 +0000 Subject: python3 embedded in LibreOffice documents Message-ID: Both Open- and LibreOffice use APSO.oxt to support py3 in Office .odt documents, such as HTML files et cetera. So one can make a web page with python and BASIC code essentially and save it as a document, possibly throw in some EMOTET as well. after import NNTPlib one can make a lil usenet client even! From jon+usenet at unequivocal.eu Wed Feb 12 07:15:09 2020 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Wed, 12 Feb 2020 12:15:09 -0000 (UTC) Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> Message-ID: On 2020-02-12, Chris Angelico wrote: > But you CAN rewrite code such that it reduces technical debt. You can > refactor code to make it more logical. ... but if doing so costs more than the debt, you shouldn't do it. From ekopalypse at gmail.com Wed Feb 12 07:41:04 2020 From: ekopalypse at gmail.com (Eko palypse) Date: Wed, 12 Feb 2020 04:41:04 -0800 (PST) Subject: Load python from different plugin dlls Message-ID: Assuming there is an CppApp which allows extending its functionality by adding plugins. Now let's assume there are plugin developer which use cython to create such a plugins. How can one check if there has been already a plugin loaded which itself loaded a python interpreter? And if this is possible, what needs to be done that a second plugin can be used with the python interpreter loaded from the first plugin? To summarize: CppApp loads pluign1 (which loads python3.dll) ok CppApp loads pluign2 (which needs also access to python3.dll but cannot load it itself as it has been already loaded by plugin1) Is such a scenario actually possible? Thank you Eren From rhodri at kynesim.co.uk Wed Feb 12 08:16:03 2020 From: rhodri at kynesim.co.uk (Rhodri James) Date: Wed, 12 Feb 2020 13:16:03 +0000 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: <20200212005313.GG32713@bladeshadow.org> References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> <20200212005313.GG32713@bladeshadow.org> Message-ID: <4fe21f44-e03d-158c-07b6-0446146ecff9@kynesim.co.uk> On 12/02/2020 00:53, Python wrote: > In pretty much every job I've ever worked at, funding work (e.g. with > humans to do it) with exactly and precisely the resources required is > basically impossible, and management prefers to underfund the work > than to overfund it, for cost-savings reasons. This basically means > that any non-trivial work you do inevitably will become technical debt s/become/accrue/. The work itself isn't the debt, but its sub-optimality creates debt (or future headaches, if you prefer to think of it that way). > IMMEDIATELY, because you will not be given the time to do the job > completely in the first place, there will inevitably be bugs which are > minor enough to ignore indefinitely, and most likely, in order to meet > arbitrary-but-nevertheless-real time constraints you will find > yourself obliged to take shortcuts. So conceptually "costs" may be > different from "debt" but in practice, you never have one without the > other, and "debt" is really just "costs" you haven't paid yet. It's that last bit, "you haven't paid yet", that's the important part. Project managers and accountants alike are very much in favour of putting off paying for things if they can. Sometimes they can be persuaded that the interest on the debt (the extra cost that the code structure imposes on fixing bugs) is too much, and then you get the opportunity to refactor and reduce the overall debt (at a cost, obviously) and the interest you will pay in the future. Sometimes, and this is the bit that bean counters really like, you can get away without paying the debt by ditching the project entirely before the debt is paid off. If you don't want to piss your customers off you need to pay the cost of a replacement project, which will accrue its own technical debt... -- Rhodri James *-* Kynesim Ltd From legaulph at gmail.com Wed Feb 12 06:46:18 2020 From: legaulph at gmail.com (legaulph at gmail.com) Date: Wed, 12 Feb 2020 06:46:18 -0500 Subject: ghostscripts in python with watchdog Message-ID: <00b201d5e19a$0a224950$1e66dbf0$@gmail.com> I'm trying to use ghostscripts with python watchdog. I want to duplicate the last page of a pdf to another directory using the same name as the source pdf + page number. So watchdog will monitor the directory for the pdf and ghostscript will copy the last page to another directory. I have this, and not able to figure out how to change the output name and location. import sys import os import time import logging from watchdog.observers import Observer from watchdog.events import LoggingEventHandler from watchdog.events import PatternMatchingEventHandler if __name__ == "__main__": patterns = "*" ignore_patterns = "" ignore_directories = False case_sensitive = True my_event_handler = PatternMatchingEventHandler(patterns, ignore_patterns, ignore_directories, case_sensitive) def on_created(event): number_of_pages = 4 input_pdf = event.src_path for i in range(4, number_of_pages +1): os.system("gswin64c -q -dBATCH -dNOPAUSE -sOutputFile=page{page:04d}.pdf" " -dFirstPage={page} -dLastPage={page}" " -sDEVICE=pdfwrite {input_pdf}" .format(page=i, input_pdf=input_pdf)) my_event_handler.on_created = on_created path = "." go_recursively = True my_observer = Observer() my_observer.schedule(my_event_handler, path, recursive=go_recursively) my_observer.start() try: while True: time.sleep(1) except KeyboardInterrupt: my_observer.stop() my_observer.join() From ethan at stoneleaf.us Wed Feb 12 09:44:22 2020 From: ethan at stoneleaf.us (Ethan Furman) Date: Wed, 12 Feb 2020 06:44:22 -0800 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: <5a977c94-4cbd-b546-fb32-bf1830645049@gmail.com> References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> <5a977c94-4cbd-b546-fb32-bf1830645049@gmail.com> Message-ID: <64f0f28d-d29e-78e4-1208-d4d16876fb70@stoneleaf.us> On 02/11/2020 04:38 PM, Michael Torrie wrote: > It's all just different ways of accounting for the same things. In the > olden days before the term "technical debt" was invented, we called this > "total cost of ownership." TCO is not a fixed number. For example, if a loan is taken to help fund a project, then the "interest debt" will be a portion of the TCO, but its amount will vary depending on the interest rate: 15% will be more interest debt than 4%. Likewise, the technical debt for a project will be higher or lower depending on the quality of the code written. I think an oft overlooked aspect of technical debt is the affect on the programmers dealing with it: frustration, burn-out, and job-seeking. -- ~Ethan~ From avigross at verizon.net Wed Feb 12 11:55:20 2020 From: avigross at verizon.net (Avi Gross) Date: Wed, 12 Feb 2020 11:55:20 -0500 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: <4fe21f44-e03d-158c-07b6-0446146ecff9@kynesim.co.uk> References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> <20200212005313.GG32713@bladeshadow.org> <4fe21f44-e03d-158c-07b6-0446146ecff9@kynesim.co.uk> Message-ID: <00a401d5e1c5$35e56290$a1b027b0$@verizon.net> I have to wonder if this is a bit like what happens when something like Windows offers you an upgrade if you pay for it. Some people have noticed how after such things come out, a series of rapid bug fixes come along. So, they wait. Some wait long enough until another entire version has come along or even several such cycles. They then try to jump from say version 2.1 to version 5.0 and skip paying for all the in-betweens. Others may wait till something forces them to change like receiving documents their version of EXCEL cannot handle properly or at all. And, when that happens, they may simply jump to a different product entirely, like leaving Lotus for EXCEL. And, as noted, some simply move on. All kinds of calendar programs and contact list managers can become obsolete when it is all bundled into something like Microsoft office Outlook. At some point, you toss the old or use some tool to migrate your data, or start over. With your own software a migration can be hairy and especially when the original staff are long gone or promoted and the manager has no clue and no budget for this. There seems to be substantial risk versus just leaving it alone and hoping it works long enough for you to get your bonus or move on. It is worse if the people maintaining it sort of made their own kludge variations like reinventing new features on their own in ways not compatible with the new. Do you port the kludge or switch over to the new way even if it means restructuring other parts of the code. A serious question. What has happened in other aspects of the field where a big enough change bifurcates the community? I am wondering what happened when PERL made incompatible changes. Are people still using both versions? What about largely discontinued languages that stopped being developed in any way and do not even have a compiler for newer machines? I know Microsoft periodically declares no further support for much earlier versions of Windows. I bet people who have old machines keep running without an upgrade, especially when their machine does not support the new version because it does not have enough memory or whatever. Why keep the old? I am sure they have their reasons that boil down to it runs programs they know well and that do what they need and do not add many bells and whistles that they don't think they need or that force them to change their ways. For some touch typists, the earlier word processors that do not know about a mouse and run in one big window, may be just right. But try sending one to others without using some conversion method first. But anyone teaching Python today who still uses version 2 exclusively may have some explaining to do unless the goal is to maintain and migrate those using it to version 3. Are there any serious new projects being built NOW using version 2? -----Original Message----- From: Python-list On Behalf Of Rhodri James Sent: Wednesday, February 12, 2020 8:16 AM To: python-list at python.org Subject: Re: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) On 12/02/2020 00:53, Python wrote: > In pretty much every job I've ever worked at, funding work (e.g. with > humans to do it) with exactly and precisely the resources required is > basically impossible, and management prefers to underfund the work > than to overfund it, for cost-savings reasons. This basically means > that any non-trivial work you do inevitably will become technical debt s/become/accrue/. The work itself isn't the debt, but its sub-optimality creates debt (or future headaches, if you prefer to think of it that way). > IMMEDIATELY, because you will not be given the time to do the job > completely in the first place, there will inevitably be bugs which are > minor enough to ignore indefinitely, and most likely, in order to meet > arbitrary-but-nevertheless-real time constraints you will find > yourself obliged to take shortcuts. So conceptually "costs" may be > different from "debt" but in practice, you never have one without the > other, and "debt" is really just "costs" you haven't paid yet. It's that last bit, "you haven't paid yet", that's the important part. Project managers and accountants alike are very much in favour of putting off paying for things if they can. Sometimes they can be persuaded that the interest on the debt (the extra cost that the code structure imposes on fixing bugs) is too much, and then you get the opportunity to refactor and reduce the overall debt (at a cost, obviously) and the interest you will pay in the future. Sometimes, and this is the bit that bean counters really like, you can get away without paying the debt by ditching the project entirely before the debt is paid off. If you don't want to piss your customers off you need to pay the cost of a replacement project, which will accrue its own technical debt... -- Rhodri James *-* Kynesim Ltd -- https://mail.python.org/mailman/listinfo/python-list From python at bladeshadow.org Wed Feb 12 12:46:13 2020 From: python at bladeshadow.org (Python) Date: Wed, 12 Feb 2020 11:46:13 -0600 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: <4fe21f44-e03d-158c-07b6-0446146ecff9@kynesim.co.uk> References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> <20200212005313.GG32713@bladeshadow.org> <4fe21f44-e03d-158c-07b6-0446146ecff9@kynesim.co.uk> Message-ID: <20200212174613.GH32713@bladeshadow.org> On Wed, Feb 12, 2020 at 01:16:03PM +0000, Rhodri James wrote: > On 12/02/2020 00:53, Python wrote: > > In pretty much every job I've ever worked at, funding work (e.g. with > > humans to do it) with exactly and precisely the resources required is > > basically impossible, and management prefers to underfund the work > > than to overfund it, for cost-savings reasons. This basically means > > that any non-trivial work you do inevitably will become technical debt > > s/become/accrue/. The work itself isn't the debt, but its sub-optimality > creates debt (or future headaches, if you prefer to think of it that way). I think it's a purely semantic distinction without a practical difference...which was the point I was trying to make. The work is the direct cause of the debt, and at the time it is performed the debt is realized. Without the work, that particular debt is not incurred. You may have eliminated some old debt when the work is done, but your new debt replaces your old debt. Depending on the resources you can devote, that debt may or MAY NOT be less than the other, and sometimes the truth of this can not be discovered until you're already knee deep in it. > > So conceptually "costs" may be different from "debt" but in > > practice, you never have one without the other, and "debt" is > > really just "costs" you haven't paid yet. > > It's that last bit, "you haven't paid yet", that's the important part. > Project managers and accountants alike are very much in favour of putting > off paying for things if they can. Sometimes they can be persuaded that the > interest on the debt (the extra cost that the code structure imposes on > fixing bugs) is too much, and then you get the opportunity to refactor and > reduce the overall debt (at a cost, obviously) and the interest you will pay > in the future. Right. Or... not. More often than not, in my experience. And sometimes you can convince them you need to, but other priorities continually surface that block it from ever happening anyway. > Sometimes, and this is the bit that bean counters really like, you can get > away without paying the debt by ditching the project entirely before the > debt is paid off. If you don't want to piss your customers off you need to > pay the cost of a replacement project, which will accrue its own technical > debt... Or it may become obsolete due to changing circumstances. Or (as in many cases) it is sufficient to tell your customers, "don't do that," perhaps with admittedly annoying but not particularly costly consequences if they don't listen. :) [It's not always feasible, but often if they complain, you can say something like, "...but we're working on this other magic thingy that will really help you, and spending time on fixing this thing you're complaining about now will significantly delay the delivery of that." It may or may not be true, but in the interim the customer learns to stop doing that thing, and forgets they ever cared.] Technical debt is just about inevitable, for most non-trivial software (again, unless you've got a special case of a full solution for some problem whose circumstances never change), and isn't necessarily a bad thing. It just depends entirely on the details of your situation. And while I'm not particularly a fan of Agile in practice, the philosophy behind it addresses this reasonably well... But then again, you don't *need* Agile to do that, either. You just have to pay attention to the problem. Like everything else. From rhodri at kynesim.co.uk Wed Feb 12 13:54:52 2020 From: rhodri at kynesim.co.uk (Rhodri James) Date: Wed, 12 Feb 2020 18:54:52 +0000 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: <20200212174613.GH32713@bladeshadow.org> References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> <20200212005313.GG32713@bladeshadow.org> <4fe21f44-e03d-158c-07b6-0446146ecff9@kynesim.co.uk> <20200212174613.GH32713@bladeshadow.org> Message-ID: On 12/02/2020 17:46, Python wrote: > On Wed, Feb 12, 2020 at 01:16:03PM +0000, Rhodri James wrote: >> On 12/02/2020 00:53, Python wrote: >>> In pretty much every job I've ever worked at, funding work (e.g. with >>> humans to do it) with exactly and precisely the resources required is >>> basically impossible, and management prefers to underfund the work >>> than to overfund it, for cost-savings reasons. This basically means >>> that any non-trivial work you do inevitably will become technical debt >> s/become/accrue/. The work itself isn't the debt, but its sub-optimality >> creates debt (or future headaches, if you prefer to think of it that way). > I think it's a purely semantic distinction without a practical > difference...which was the point I was trying to make. The work is > the direct cause of the debt, and at the time it is performed the debt > is realized. Without the work, that particular debt is not incurred. > You may have eliminated some old debt when the work is done, but your > new debt replaces your old debt. Depending on the resources you can > devote, that debt may or MAY NOT be less than the other, and sometimes > the truth of this can not be discovered until you're already knee deep > in it. Here's where the "purely semantic" distinction matters. You are equating the work with the debt, but ignoring the benefit the work presumably brings (otherwise you wouldn't have done it at all). Either you should be rolling it all together or separate both, surely. -- Rhodri James *-* Kynesim Ltd From torriem at gmail.com Wed Feb 12 15:17:44 2020 From: torriem at gmail.com (Michael Torrie) Date: Wed, 12 Feb 2020 13:17:44 -0700 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: <64f0f28d-d29e-78e4-1208-d4d16876fb70@stoneleaf.us> References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> <5a977c94-4cbd-b546-fb32-bf1830645049@gmail.com> <64f0f28d-d29e-78e4-1208-d4d16876fb70@stoneleaf.us> Message-ID: On 2/12/20 7:44 AM, Ethan Furman wrote: > On 02/11/2020 04:38 PM, Michael Torrie wrote: > >> It's all just different ways of accounting for the same things. In >> the olden days before the term "technical debt" was invented, we >> called this "total cost of ownership." > > TCO is not a fixed number. For example, if a loan is taken to help > fund a project, then the "interest debt" will be a portion of the > TCO, but its amount will vary depending on the interest rate: 15% > will be more interest debt than 4%. Likewise, the technical debt for > a project will be higher or lower depending on the quality of the > code written. True. Costs can be calculated and planned for. But Technical debt is often impossible to quantify in a real, meaningful, business sense, other than the that we "know" it's going to cost big time in the future. In some senses, it's theoretical future cost. That's what I was having a hard time with, and still do to a large degree. > I think an oft overlooked aspect of technical debt is the affect on > the programmers dealing with it: frustration, burn-out, and > job-seeking. Yeah for sure. A programmer may not love dealing with technical debt, and certainly he may want to chase greener fields. But there are lots of things about lots of jobs that are less pleasant than other things. Personally I tend to get way caught up trying to get a perfect design that avoids technical debt, but often get not much done (on my personal projects). Whereas another guy just cranks out code that isn't always the best but serves his needs at the time. Guess who is more productive overall? Not me. More on topic, I feel like the technical debt issue might be over used to push folks to upgrade from Python 2, or to do promote certain technologies. Without knowing the details of how and why they used it, it's impossible for me to say that it will cost them a lot in the future. It very well could cost nothing. Or it might be expensive enough to sink an enterprise. In the case of the original poster, it could well be that the maintenance he's doing to the code is minor and of no real cost, nor any maintenance burden in the future. He might not need security patches or any other on-going development of the Python 2 interpreter. His app might have no attack surface. The script does its internal job and that's that. As long as a Python2 interpreter runs he's golden. I suspect a lot of Python 2 use falls into that sort of category. Sort of like the company I know that still uses an MS-DOS billing system. From PythonList at DancesWithMice.info Wed Feb 12 18:22:42 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Thu, 13 Feb 2020 12:22:42 +1300 Subject: Technical debt - was Re: datetime seems to be broken WRT timezones (even when you add them) In-Reply-To: References: <20200211012902.GD32713@bladeshadow.org> <751a2c82-c07f-0cda-a19a-b0c9832e911c@gmail.com> <5a977c94-4cbd-b546-fb32-bf1830645049@gmail.com> <64f0f28d-d29e-78e4-1208-d4d16876fb70@stoneleaf.us> Message-ID: <35fde9bc-d63c-a110-a97b-9e0936017dc2@DancesWithMice.info> On 13/02/20 9:17 AM, Michael Torrie wrote: > On 2/12/20 7:44 AM, Ethan Furman wrote: >> On 02/11/2020 04:38 PM, Michael Torrie wrote: ... > True. Costs can be calculated and planned for. But Technical debt is > often impossible to quantify in a real, meaningful, business sense, > other than the that we "know" it's going to cost big time in the future. > In some senses, it's theoretical future cost. That's what I was having > a hard time with, and still do to a large degree. > >> I think an oft overlooked aspect of technical debt is the affect on >> the programmers dealing with it: frustration, burn-out, and >> job-seeking. > > Yeah for sure. A programmer may not love dealing with technical debt, > and certainly he may want to chase greener fields. But there are lots > of things about lots of jobs that are less pleasant than other things. > Personally I tend to get way caught up trying to get a perfect design > that avoids technical debt, but often get not much done (on my personal > projects). Whereas another guy just cranks out code that isn't always > the best but serves his needs at the time. Guess who is more productive > overall? Not me. Applauding your professional attitude, but haven't you (only) defined "productive" as purely getting 'this job' out the door? cf any definition of "Total" cost? I had an IT Manager moaning at me precisely because of one of those 'other guys'. The job had been 'done'. The contract had mere 'words' to cover 'quality'. Accordingly, difficult to argue that 'the guy' hadn't done what was asked (my 'specialist' $advice on the matter). However, the code was 'ramshackle' and had obviously been 'dashed off' in the shortest amount of time possible. Maintenance costs were expected to be high; motivation of in-house staff to do so, expected to be v.low! So, we're re-negotiating the contract-wording... More importantly, improving their acceptance testing, and adding more detail to their specs/requirements, etc. (the mistake there, was thinking that reqmts to external staff would be 'the same' as such to in-house employees) However, the interesting question was to ask whether he (the manager) was 'taking advantage' of the "gig economy". (yes, that's what it's there for!) Thus, what relationship did he (or even, 'they' of the IT dept) have with the contractor? The home truth: 'using' the cheapest people creates a 'race to the bottom', and must, by definition, lead to 'the cheapest job' being done. Why the surprise? (He doesn't hire me as a programmer - and we're not even talking 'Python', apologies!) I asked him if he wanted a 'professional' to do the job, ie in a 'professional manner'. Yes! So, why are you looking for the guy(?) who'll do it at the lowest-possible price/rate or imposing the delivery date on a short time-line? Ahh... The above concerns contractors, but I managed to slide-in a few questions/comments that relationships with in-house staff require similar consideration and attention! OK, so turning it around to people more like 'us': Professionalism? As a programmer/coder, would you rather work on decent code? So, is that what you turn-out? Alternatively, vice-versa. That is a slightly unfair, or biased, question. I am in the fortunate position of being able to tell certain people that I won't undertake their work, that where they want me to work will push the price UP, that their tool-set is sub-standard, or that the existing platform is imbued with uncomfortably high 'risk'. I quite understand that someone who 'needs the job' will see that as a 'luxury'. (apologies as necessary) That said, would you build a team with a mixture of 'clock-watchers' and 'professionals' or would/do you enjoy working within such a team? Both 'sides' need to understand that there are two view-points to every relationship. One thought that occurred to me lurking/reading this thread, is the likelihood that many of the differing views arise between those working in an 'Agile' environment, and those not (or a pseudo-/'we call it'-Agile environment)? One of the (social) contracts in Scrum (for example) is that the professionals estimate the time needed to do the job, cf some (likely ignorant) 'manager' imposing a deadline. In my experience (YMMV) an established, professional 'Agile' team tends to follow practices which attempt to avoid adding to Technical Debt, and factor-in any need to correct sub-standard or sans-tests old-code. There is no doubt in my mind, that the participation of 'users' helps to create an understanding that (like anything else) software takes time (read also $), and that over-loading (?abusing) development staff is itself a 'Technical Debt' ("Marginal Cost") for the organisation! (absences, turn-over, ... you've been-there, seen-that...). There again, would user-members of the team notice if 'we'd' padded our estimates so as to have plenty of time for 'other things'? It's by no means a cut-and-dried situation. What 'works' in one case may not even get-of-the-ground in another! Thanks for provoking the grey-matter to ponder... -- Regards =dn From address at not.available Thu Feb 13 01:21:39 2020 From: address at not.available (R.Wieser) Date: Thu, 13 Feb 2020 07:21:39 +0100 Subject: Load python from different plugin dlls References: Message-ID: Eko, > which needs also access to python3.dll but cannot load it itself as it has > been already loaded by plugin1 > > Is such a scenario actually possible? Yes. Normally a DLL can be loaded in as many processes (and threads thereof) as you like. However, it is possible that the DLLs initialisation contains code to check if something it needs is available*, and if not directly exit. *like if it can access certain I/O - if the first DLL instance "takes posession" the second DLL instance wil fail. Than again, this can also happen when using two totally different plugin DLLs. tl;dr: Yes, but not likely. From ekopalypse at gmail.com Thu Feb 13 06:51:44 2020 From: ekopalypse at gmail.com (Eko palypse) Date: Thu, 13 Feb 2020 12:51:44 +0100 Subject: Load python from different plugin dlls In-Reply-To: References: Message-ID: Thanks for the information. My test looks like this right now. I have two plugins which, when loaded separately, work. But when both are loaded, I get AccessVioletion messages from python37.dll. The init code for both dlls is this: cpp_init_code = f'''#include #include "PluginInterface.h" PyMODINIT_FUNC PyInit_{PLUGIN_NAME}(void); BOOL APIENTRY DllMain( HANDLE hModule, DWORD reasonForCall, LPVOID /* lpReserved */ ) {{ switch ( reasonForCall ) {{ case DLL_PROCESS_ATTACH: PyImport_AppendInittab("{PLUGIN_NAME}", &PyInit_{PLUGIN_NAME}); Py_InitializeEx(Py_IsInitialized() ? 0 : 1); PyImport_ImportModule("{PLUGIN_NAME}"); break; case DLL_PROCESS_DETACH: Py_Finalize(); break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; }} return TRUE; }}''' This is written to a plugininit.cpp file and then built via setup.py with distutil, cython and VS2017. According to the docs PyImport_AppendInittab should be called before Py_Initialize but I can't call Py_Initialize the second time as it would remove what was initialized by the first dll. And using PyImport_ImportModule on the second dll only does not work either. So that is were I'm trapped. Thank you Eren Am Do., 13. Feb. 2020 um 07:26 Uhr schrieb R.Wieser
: > Eko, > > > which needs also access to python3.dll but cannot load it itself as it > has > > been already loaded by plugin1 > > > > Is such a scenario actually possible? > > Yes. > > Normally a DLL can be loaded in as many processes (and threads thereof) as > you like. > > However, it is possible that the DLLs initialisation contains code to > check > if something it needs is available*, and if not directly exit. > > *like if it can access certain I/O - if the first DLL instance "takes > posession" the second DLL instance wil fail. Than again, this can also > happen when using two totally different plugin DLLs. > > tl;dr: > Yes, but not likely. > > > -- > https://mail.python.org/mailman/listinfo/python-list > From address at not.available Thu Feb 13 07:28:55 2020 From: address at not.available (R.Wieser) Date: Thu, 13 Feb 2020 13:28:55 +0100 Subject: Load python from different plugin dlls References: Message-ID: Eko, > My test looks like this right now. And there you have a probem, as I have no experience with what those functions do. The below is therefore just a bit of educated guessing, so caveat emperor. > According to the docs PyImport_AppendInittab should be called > before Py_Initialize And should probably be done only once - adding the same module to the same list will likely fail, though the above function will than just return a -1 (minus one) result. > Py_InitializeEx(Py_IsInitialized() ? 0 : 1); Initializing when already being initialized might well be the cause of your AccessViolation - the first plugin looses its objects, but still tries to use them. Suggestion: Do a Py_IsInitialized() and if so skip the the Py_InitializeEx() (and maybe change that one to the simpler Py_Initialize() ). Hope that helps. Regards, Rudy Wieser From Mkonopko at csbs.net Thu Feb 13 23:38:53 2020 From: Mkonopko at csbs.net (Marty Konopko) Date: Thu, 13 Feb 2020 21:38:53 -0700 Subject: first time python learner Message-ID: Win 10 Anti Virus off [image: image.png] Any idea? -- Martin Konopko From cs at cskk.id.au Fri Feb 14 00:50:28 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Fri, 14 Feb 2020 16:50:28 +1100 Subject: first time python learner In-Reply-To: References: Message-ID: <20200214055028.GA26443@cskk.homeip.net> On 13Feb2020 21:38, Marty Konopko wrote: >Win 10 >Anti Virus off >[image: image.png] > >Any idea? Alas, this is a text only list; your screenshot has been discarded. Please reply with your complete error message cut/paste into the text. And a description of what you were trying to do. Thanks, Cameron Simpson From me at bheesham.com Fri Feb 14 01:26:13 2020 From: me at bheesham.com (Bheesham Persaud) Date: Fri, 14 Feb 2020 01:26:13 -0500 Subject: ghostscripts in python with watchdog In-Reply-To: References: <00b201d5e19a$0a224950$1e66dbf0$@gmail.com> Message-ID: Hey! If you change the "-sOutputFile` parameter you pass into gswin64c. For example, something like: output_directory = os.path.join(os.path.dirname(input_src), "out") And then you should be able to modify the call to `os.system` to something like: os.system( "gswin64c -q -dBATCH -dNOPAUSE" "-sOutputFile={output_directory}/page{page:04d}.pdf" " -dFirstPage={page} -dLastPage={page}" " -sDEVICE=pdfwrite {input_pdf}" .format( page=i, input_pdf=input_pdf, output_directory=output_directory ) ) From legaulph at gmail.com Fri Feb 14 07:54:40 2020 From: legaulph at gmail.com (legaulph at gmail.com) Date: Fri, 14 Feb 2020 07:54:40 -0500 Subject: ghostscripts in python with watchdog In-Reply-To: References: <00b201d5e19a$0a224950$1e66dbf0$@gmail.com> Message-ID: <002c01d5e335$ec1f1710$c45d4530$@gmail.com> I'm not sure what happens, when I'm testing and suddenly I will start getting this error. Error: /undefinedfilename in (1) Operand stack: Execution stack: %interp_exit .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval-- --nostringval-- --nostringval-- false 1 %stopped_push Dictionary stack: --dict:732/1123(ro)(G)-- --dict:0/20(G)-- --dict:75/200(L)-- Current allocation mode is local Last OS error: No such file or directory GPL Ghostscript 9.50: Unrecoverable error, exit code 1 -----Original Message----- From: Python-list On Behalf Of Bheesham Persaud Sent: Friday, February 14, 2020 1:26 AM To: python-list at python.org Subject: Re: ghostscripts in python with watchdog Hey! If you change the "-sOutputFile` parameter you pass into gswin64c. For example, something like: output_directory = os.path.join(os.path.dirname(input_src), "out") And then you should be able to modify the call to `os.system` to something like: os.system( "gswin64c -q -dBATCH -dNOPAUSE" "-sOutputFile={output_directory}/page{page:04d}.pdf" " -dFirstPage={page} -dLastPage={page}" " -sDEVICE=pdfwrite {input_pdf}" .format( page=i, input_pdf=input_pdf, output_directory=output_directory ) ) -- https://mail.python.org/mailman/listinfo/python-list From legaulph at gmail.com Fri Feb 14 07:58:34 2020 From: legaulph at gmail.com (legaulph at gmail.com) Date: Fri, 14 Feb 2020 07:58:34 -0500 Subject: ghostscripts in python with watchdog In-Reply-To: <002c01d5e335$ec1f1710$c45d4530$@gmail.com> References: <00b201d5e19a$0a224950$1e66dbf0$@gmail.com> <002c01d5e335$ec1f1710$c45d4530$@gmail.com> Message-ID: <003b01d5e336$7771bf20$66553d60$@gmail.com> I see it does not like spaces in the file name -----Original Message----- From: legaulph at gmail.com Sent: Friday, February 14, 2020 7:55 AM To: 'Bheesham Persaud' ; python-list at python.org Subject: RE: ghostscripts in python with watchdog I'm not sure what happens, when I'm testing and suddenly I will start getting this error. Error: /undefinedfilename in (1) Operand stack: Execution stack: %interp_exit .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval-- --nostringval-- --nostringval-- false 1 %stopped_push Dictionary stack: --dict:732/1123(ro)(G)-- --dict:0/20(G)-- --dict:75/200(L)-- Current allocation mode is local Last OS error: No such file or directory GPL Ghostscript 9.50: Unrecoverable error, exit code 1 -----Original Message----- From: Python-list On Behalf Of Bheesham Persaud Sent: Friday, February 14, 2020 1:26 AM To: python-list at python.org Subject: Re: ghostscripts in python with watchdog Hey! If you change the "-sOutputFile` parameter you pass into gswin64c. For example, something like: output_directory = os.path.join(os.path.dirname(input_src), "out") And then you should be able to modify the call to `os.system` to something like: os.system( "gswin64c -q -dBATCH -dNOPAUSE" "-sOutputFile={output_directory}/page{page:04d}.pdf" " -dFirstPage={page} -dLastPage={page}" " -sDEVICE=pdfwrite {input_pdf}" .format( page=i, input_pdf=input_pdf, output_directory=output_directory ) ) -- https://mail.python.org/mailman/listinfo/python-list From __peter__ at web.de Fri Feb 14 11:39:40 2020 From: __peter__ at web.de (Peter Otten) Date: Fri, 14 Feb 2020 17:39:40 +0100 Subject: ghostscripts in python with watchdog References: <00b201d5e19a$0a224950$1e66dbf0$@gmail.com> <002c01d5e335$ec1f1710$c45d4530$@gmail.com> <003b01d5e336$7771bf20$66553d60$@gmail.com> Message-ID: legaulph at gmail.com wrote: > os.system("... {input_pdf} ...".format(..., input_pdf=input_pdf)) > I see it does not like spaces in the file name Use subprocess.call(), not os.system(), then: >>> filename = "hello world.txt" >>> with open(filename, "w") as f: print("Hello, world!", file=f) ... >>> import os, subprocess Wrong, uses shell, and file name is not properly escaped: >>> os.system("cat " + filename) cat: hello: No such file or directory cat: world.txt: No such file or directory 256 Right, does not use shell, no escaping needed: >>> subprocess.call(["cat", filename]) Hello, world! 0 From tjreedy at udel.edu Fri Feb 14 12:54:21 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Fri, 14 Feb 2020 12:54:21 -0500 Subject: first time python learner In-Reply-To: References: Message-ID: On 2/13/2020 11:38 PM, Marty Konopko wrote: > Win 10 > Anti Virus off > [image: image.png] > > Any idea? Cameron already suggested a better title and question. If it is about IDLE startup, read https://docs.python.org/3/library/idle.html#startup-failure -- Terry Jan Reedy From drsalists at gmail.com Fri Feb 14 18:21:19 2020 From: drsalists at gmail.com (Dan Stromberg) Date: Fri, 14 Feb 2020 15:21:19 -0800 Subject: What I learned today In-Reply-To: References: Message-ID: On Fri, Feb 14, 2020 at 3:10 PM Stefan Ram wrote: > By trial and error (never read documentation!) I found > that you can count the number of e's in a text by just > > Counter( text ).get( 'e' ) > > (after ?from collections import Counter? that is). > Even simpler, though not suitable for all situations: "abcbdbe".count("b") The other thing I read in a book. I already knew that one > can zip using ... ?zip?. E.g., > Neat. From duncan at invalid.invalid Fri Feb 14 20:24:33 2020 From: duncan at invalid.invalid (duncan smith) Date: Sat, 15 Feb 2020 01:24:33 +0000 Subject: What I learned today In-Reply-To: References: Message-ID: On 14/02/2020 23:21, Dan Stromberg wrote: > On Fri, Feb 14, 2020 at 3:10 PM Stefan Ram wrote: > >> By trial and error (never read documentation!) I found >> that you can count the number of e's in a text by just >> >> Counter( text ).get( 'e' ) >> >> (after ?from collections import Counter? that is). >> > Even simpler, though not suitable for all situations: > "abcbdbe".count("b") > [snip] And by far the quickest way (that I've found) for counting the number of set bits in an int. >>> def popcount(n): cnt = 0 while n: n &= n-1 cnt += 1 return cnt >>> import timeit >>> timeit.timeit("popcount(19847998494279)", "from __main__ import popcount", number=10000) 0.034410387044772506 >>> timeit.timeit("bin(19847998494279).count('1')", number=10000) 0.004501901799812913 >>> OK, things turn around for large integers with very few set bits. But for my use case bin(n).count('1') wins hands down (which surprised me a little). Duncan From __peter__ at web.de Sat Feb 15 08:46:09 2020 From: __peter__ at web.de (Peter Otten) Date: Sat, 15 Feb 2020 14:46:09 +0100 Subject: What I learned today References: Message-ID: Stefan Ram wrote: > The other thing I read in a book. I already knew that one > can zip using ... ?zip?. E.g., > > x =( 'y', 'n', 'a', 'n', 't' ) > y =( 4, 2, 7, 3, 1 ) > z = zip( x, y ) > print( list( z )) > [('y', 4), ('n', 2), ('a', 7), ('n', 3), ('t', 1)] > > But the book told me that you can unzip using ... ?zip? again! > > z = zip( x, y ) > a, b = zip( *z ) > print( a ) > ('y', 'n', 'a', 'n', 't') > print( b ) > (4, 2, 7, 3, 1) > > Wow! > Another way to look at that is that if you write a matrix as a tuple of tuples >>> a = (1,2), (3,4), (5,6) you can transpose it with >>> def transposed(a): ... return tuple(zip(*a)) ... >>> transposed(a) ((1, 3, 5), (2, 4, 6)) and transposing twice gives the original matrix: >>> transposed(transposed(a)) == a True From markos at c2o.pro.br Sat Feb 15 19:50:24 2020 From: markos at c2o.pro.br (Markos) Date: Sat, 15 Feb 2020 21:50:24 -0300 Subject: I can't access dataframe fields Message-ID: Hi all, I created the following data frame (updated_distance_matrix) ???? P1??????????? P2??????????? P4??????????? P5?????????? (P3, P6) P1 0,000000 0,244307 0,367696 0,341760 0 P2 0.234307 0.000000 0.194165 0.1443178 0 P4 0.366969 0.194165 0.000000 0.284253 0 P5 0.341760 0.1443178 0.284253 0.000000 0 (P3, P6) 0.000000 0.000000 0.000000 0.000000 0 I can change the fields of columns and rows P1-P5 without problems. But when I try to access the fields of the row, or column, (P3, P6) print (updated_distance_matrix_df.loc [clusters [i], last_cluster]) the message appears: KeyError: 'the label [P3, P6] is not in the [index]' If I change find the "loc" by "at" method appears the error: print (updated_distance_matrix_df.at [clusters [i], last_cluster]) TypeError: unhashable type: 'list' And if you simply leave: print (updated_distance_matrix_df [clusters [i], last_cluster]) gives the error: TypeError: unhashable type: 'list' A last_cluster variable is of type list: print (last_cluster, type (last_cluster)) ['P3', 'P6'] And a variable cluster [i] is a string: print (clusters [i], type (clusters [i])) P5 Any tip? Thank you, Markos From python at mrabarnett.plus.com Sat Feb 15 21:36:53 2020 From: python at mrabarnett.plus.com (MRAB) Date: Sun, 16 Feb 2020 02:36:53 +0000 Subject: I can't access dataframe fields In-Reply-To: References: Message-ID: On 2020-02-16 00:50, Markos wrote: > Hi all, > > I created the following data frame (updated_distance_matrix) > > ???? P1??????????? P2??????????? P4??????????? P5?????????? (P3, P6) > P1 0,000000 0,244307 0,367696 0,341760 0 > P2 0.234307 0.000000 0.194165 0.1443178 0 > P4 0.366969 0.194165 0.000000 0.284253 0 > P5 0.341760 0.1443178 0.284253 0.000000 0 > (P3, P6) 0.000000 0.000000 0.000000 0.000000 0 > > I can change the fields of columns and rows P1-P5 without problems. > > But when I try to access the fields of the row, or column, (P3, P6) > > print (updated_distance_matrix_df.loc [clusters [i], last_cluster]) > > the message appears: > > KeyError: 'the label [P3, P6] is not in the [index]' > The rows and columns have "(P3, P6)", but you're looking for "[P3, P6]". They aren't the same. > If I change find the "loc" by "at" method appears the error: > > print (updated_distance_matrix_df.at [clusters [i], last_cluster]) > > TypeError: unhashable type: 'list' > Is it expecting a tuple instead of a list? Tuples are hashable, lists are not. > And if you simply leave: > > print (updated_distance_matrix_df [clusters [i], last_cluster]) > > gives the error: > > TypeError: unhashable type: 'list' > > A last_cluster variable is of type list: > > print (last_cluster, type (last_cluster)) > > ['P3', 'P6'] > > And a variable cluster [i] is a string: > > print (clusters [i], type (clusters [i])) > > P5 > > Any tip? > > Thank you, > From pahome.chen at mirlab.org Mon Feb 17 05:11:42 2020 From: pahome.chen at mirlab.org (lampahome) Date: Mon, 17 Feb 2020 18:11:42 +0800 Subject: Can anyone share experience about python backend developer? Message-ID: I have 3+years developer experience in python, but I always develop about peer-to-peer service. Have no backend experience in python. But now I want to change to backend engineer, somebody shares their job is to do like 1. Develop customize API to receive data from global 2. Develop tools with k8s 3. Experience about NoSQL After I heard above, it seems wide range and hard to start from scratch. Without comparing performance with other languages, how to dig into backend development?(Or some framework could help me?) thx From soyeomul at doraji.xyz Mon Feb 17 08:15:43 2020 From: soyeomul at doraji.xyz (=?utf-8?B?7Zmp67OR7Z2s?=) Date: Mon, 17 Feb 2020 22:15:43 +0900 Subject: What I learned today References: Message-ID: ram at zedat.fu-berlin.de (Stefan Ram) writes: > ... > But the book told me that you can unzip using ... ?zip? again! > > z = zip( x, y ) > a, b = zip( *z ) > print( a ) > ('y', 'n', 'a', 'n', 't') > print( b ) > (4, 2, 7, 3, 1) > > Wow! Usally i use zip so many, thanks for tip^^^ Sincerely, Byung-Hee -- ^????? _????_ ?????_^))// From voodoo.bender at gmail.com Mon Feb 17 11:47:54 2020 From: voodoo.bender at gmail.com (alberto) Date: Mon, 17 Feb 2020 08:47:54 -0800 (PST) Subject: insert data in python script Message-ID: Hi, I would use this script to evaluate fugacity coefficient with PENG-ROBINSON equation, but I don't understand the correct mode to insert data import numpy as np import matplotlib.pyplot as plt from scipy.optimize import newton R = 8.314e-5 # universal gas constant, m3-bar/K-mol class Molecule: """ Store molecule info here """ def __init__(self, name, Tc, Pc, omega): """ Pass parameters desribing molecules """ #! name self.name = name #! Critical temperature (K) self.Tc = Tc #! Critical pressure (bar) self.Pc = Pc #! Accentric factor self.omega = omega def print_params(self): """ Print molecule parameters. """ print("""Molecule: %s. \tCritical Temperature = %.1f K \tCritical Pressure = %.1f bar. \tAccentric factor = %f""" % (self.name, self.Tc, self.Pc, self.omega)) def preos(molecule, T, P, plotcubic=True, printresults=True): """ Peng-Robinson equation of state (PREOS) http://en.wikipedia.org/wiki/Equation_of_state#Peng.E2.80.93Robinson_equation_of_state :param molecule: Molecule molecule of interest :param T: float temperature in Kelvin :param P: float pressure in bar :param plotcubic: bool plot cubic polynomial in compressibility factor :param printresults: bool print off properties Returns a Dict() of molecule properties at this T and P. """ # build params in PREOS Tr = T / molecule.Tc # reduced temperature a = 0.457235 * R**2 * molecule.Tc**2 / molecule.Pc b = 0.0777961 * R * molecule.Tc / molecule.Pc kappa = 0.37464 + 1.54226 * molecule.omega - 0.26992 * molecule.omega**2 alpha = (1 + kappa * (1 - np.sqrt(Tr)))**2 A = a * alpha * P / R**2 / T**2 B = b * P / R / T # build cubic polynomial def g(z): """ Cubic polynomial in z from EOS. This should be zero. :param z: float compressibility factor """ return z**3 - (1 - B) * z**2 + (A - 2*B - 3*B**2) * z - ( A * B - B**2 - B**3) # Solve cubic polynomial for the compressibility factor z = newton(g, 1.0) # compressibility factor rho = P / (R * T * z) # density # fugacity coefficient comes from an integration fugacity_coeff = np.exp(z - 1 - np.log(z - B) - A / np.sqrt(8) / B * np.log( (z + (1 + np.sqrt(2)) * B) / (z + (1 - np.sqrt(2)) * B))) if printresults: print("""PREOS calculation at \t T = %.2f K \t P = %.2f bar""" % (T, P)) print("\tCompressibility factor : ", z) print("\tFugacity coefficient: ", fugacity_coeff) print("\tFugacity at pressure %.3f bar = %.3f bar" % ( P, fugacity_coeff * P)) print("\tDensity: %f mol/m3" % rho) print("\tMolar volume: %f L/mol" % (1.0 / rho * 1000)) print("\tDensity: %f v STP/v" % (rho * 22.4 / 1000)) print("\tDensity of ideal gas at same conditions: %f v STP/v" % ( rho * 22.4/ 1000 * z)) if plotcubic: # Plot the cubic equation to visualize the roots zz = np.linspace(0, 1.5) # array for plotting plt.figure() plt.plot(zz, g(zz), color='k') plt.xlabel('Compressibility, $z$') plt.ylabel('Cubic $g(z)$') plt.axvline(x=z) plt.axhline(y=0) plt.title('Root found @ z = %.2f' % z) plt.show() return {"density(mol/m3)": rho, "fugacity_coefficient": fugacity_coeff, "compressibility_factor": z, "fugacity(bar)": fugacity_coeff * P, "molar_volume(L/mol)": 1.0 / rho * 1000.0} def preos_reverse(molecule, T, f, plotcubic=False, printresults=True): """ Reverse Peng-Robinson equation of state (PREOS) to obtain pressure for a particular fugacity :param molecule: Molecule molecule of interest :param T: float temperature in Kelvin :param f: float fugacity in bar :param plotcubic: bool plot cubic polynomial in compressibility factor :param printresults: bool print off properties Returns a Dict() of molecule properties at this T and f. """ # build function to minimize: difference between desired fugacity and that obtained from preos def g(P): """ :param P: pressure """ return (f - preos(molecule, T, P, plotcubic=False, printresults=False)["fugacity(bar)"]) # Solve preos for the pressure P = newton(g, f) # pressure # Obtain remaining parameters pars = preos(molecule, T, P, plotcubic=plotcubic, printresults=printresults) rho = pars["density(mol/m3)"] fugacity_coeff = pars["fugacity_coefficient"] z = pars["compressibility_factor"] return {"density(mol/m3)": rho, "fugacity_coefficient": fugacity_coeff, "compressibility_factor": z, "pressure(bar)": P, "molar_volume(L/mol)": 1.0 / rho * 1000.0} # TODO: Implement mixture in object-oriented way as well def preos_mixture(molecule_a, molecule_b, delta, T, P_total, x, plotcubic=True, printresults=True): """ Peng-Robinson equation of state (PREOS) for a binary mixture http://en.wikipedia.org/wiki/Equation_of_state#Peng.E2.80.93Robinson_equation_of_state :param molecule_a: Molecule molecule 1 of interest :param molecule_b: Molecule molecule 2 of interest :param delta: binary interaction parameter between molecules a and b :param T: float temperature in Kelvin :param P_total: float total pressure in bar :param x: array mole fractions :param plotcubic: bool plot cubic polynomial in compressibility factor :param printresults: bool print off properties """ # build arrays of properties Tc = np.array([molecule_a.Tc, molecule_b.Tc]) Pc = np.array([molecule_a.Pc, molecule_b.Pc]) omega = np.array([molecule_a.omega, molecule_b.omega]) # build params in PREOS Tr = T / Tc # reduced temperature a0 = 0.457235 * R**2 * Tc**2 / Pc b = 0.0777961 * R * Tc / Pc kappa = 0.37464 + 1.54226 * omega - 0.26992 * omega**2 a = a0 * (1 + kappa * (1 - np.sqrt(Tr)))**2 # apply mixing rules aij = (1.0 - delta) * np.sqrt(a[0] * a[1]) a_mix = a[0] * x[0]**2 + a[1] * x[1]**2 + 2.0 * x[0] * x[1] * aij b_mix = x[0] * b[0] + x[1] * b[1] A = a_mix * P_total / R**2 / T**2 B = b_mix * P_total / R / T # build cubic polynomial def g(z): """ Cubic polynomial in z from EOS. This should be zero. :param z: float compressibility factor """ return z**3 - (1 - B) * z**2 + (A - 2*B - 3*B**2) * z - ( A * B - B**2 - B**3) # Solve cubic polynomial for the compressibility factor z = newton(g, 1.0) # compressibility factor rho = P_total / (R * T * z) # density Lnfug_0 = -np.log(z - B) + (z - 1.0) * b[0] / b_mix - A / np.sqrt(8) / B * (2.0 / a_mix * (x[0] * a[0] + x[1] * aij) - b[0] / b_mix) *\ np.log((z + (1.0 + np.sqrt(2)) * B) / (z + (1.0 - np.sqrt(2)) * B)) Lnfug_1 = -np.log(z - B) + (z - 1.0) * b[1] / b_mix - A / np.sqrt(8) / B * (2.0 / a_mix * (x[1] * a[1] + x[0] * aij) - b[1] / b_mix) *\ np.log((z + (1.0 + np.sqrt(2)) * B) / (z + (1.0 - np.sqrt(2)) * B)) # fugacity coefficient comes from an integration fugacity_coefs = np.exp(np.array([Lnfug_0, Lnfug_1])) if printresults: print("""PREOS calculation at \t T = %.2f K \t P, total = %.2f bar""" % (T, P_total)) print("\tDensity: %f mol/m3" % rho) print("\tCompressibility factor : %f" % z) print("Component 0, %s:" % molecule_a.name) print("\tFugacity coefficient: %f" % fugacity_coefs[0]) print("\tFugacity: %f bar" % (fugacity_coefs[0] * x[0] * P_total)) print("Component 1, %s:" % molecule_b.name) print("\tFugacity coefficient: %f" % fugacity_coefs[1]) print("\tFugacity: %f bar" % (fugacity_coefs[1] * x[1] * P_total)) if plotcubic: # Plot the cubic equation to visualize the roots zz = np.linspace(0, 1.5) # array for plotting plt.figure() plt.plot(zz, g(zz), color='k') plt.xlabel('Compressibility, $z$') plt.ylabel('Cubic $g(z)$') plt.axvline(x=z) plt.axhline(y=0) plt.title('Root found @ z = %.2f' % z) plt.show() return {"density(mol/m3)": rho, "fugacity_coefficients": fugacity_coefs, "compressibility_factor": z} the readme file says that As an example calculation, we consider methane at 65.0 bar and 298.0 K. Methane has a critical temperature of -82.59 deg. C and a critical pressure of 45.99 bar. Its accentric factor is 0.011. We first create a methane molecule object and print its stored parameters: import preos # pass name, Tc, Pc, omega methane = preos.Molecule("methane", -82.59 + 273.15, 45.99, 0.011) methane.print_params() Could I fix it regards Alberto From voodoo.bender at gmail.com Sun Feb 16 17:17:28 2020 From: voodoo.bender at gmail.com (alberto) Date: Sun, 16 Feb 2020 14:17:28 -0800 (PST) Subject: fugacity cofficient Message-ID: Hi, how I could realize a script to calculate fugacity coefficients with this formula https://wikimedia.org/api/rest_v1/media/math/render/svg/8743fb5a1e85edb8f4334fb7154727057f395eb8 in my input file.txt I have this data #p z 10.0 0.9850 20.0 0.9703 30.0 0.9560 40.0 0.9421 50.0 0.9287 regards Alberto From pkpearson at nowhere.invalid Mon Feb 17 13:40:00 2020 From: pkpearson at nowhere.invalid (Peter Pearson) Date: 17 Feb 2020 18:40:00 GMT Subject: fugacity cofficient References: Message-ID: On Sun, 16 Feb 2020 14:17:28 -0800 (PST), alberto wrote: > Hi, > how I could realize a script to calculate fugacity coefficients > with this formula > [snip] > > regards > > Alberto Welcome, Alberto. Can you make this look more like a Python question and less like a do-my-homework question? Show us what you've tried. -- To email me, substitute nowhere->runbox, invalid->com. From pkpearson at nowhere.invalid Mon Feb 17 13:41:28 2020 From: pkpearson at nowhere.invalid (Peter Pearson) Date: 17 Feb 2020 18:41:28 GMT Subject: fugacity cofficient References: Message-ID: On 17 Feb 2020 18:40:00 GMT, Peter Pearson wrote: > > Welcome, Alberto. > > Can you make this look more like a Python question and less like a > do-my-homework question? Show us what you've tried. Sorry. I see you already did exactly that. -- To email me, substitute nowhere->runbox, invalid->com. From markos at c2o.pro.br Mon Feb 17 13:41:39 2020 From: markos at c2o.pro.br (Markos) Date: Mon, 17 Feb 2020 15:41:39 -0300 Subject: I can't access dataframe fields In-Reply-To: References: Message-ID: <5f3d062f-c213-c0cb-ebff-e27f92df531c@c2o.pro.br> Hi MRAB, I changed last_cluster to tuple(last_cluster). From: print (updated_distance_matrix_df.loc [clusters [i], last_cluster]) to print (updated_distance_matrix_df.loc [clusters [i], tuple(last_cluster)]) And worked. Thank you, Markos Em 15-02-2020 23:36, MRAB escreveu: > On 2020-02-16 00:50, Markos wrote: >> Hi all, >> >> I created the following data frame (updated_distance_matrix) >> >> ? ???? P1??????????? P2??????????? P4??????????? P5 (P3, P6) >> P1 0,000000 0,244307 0,367696 0,341760 0 >> P2 0.234307 0.000000 0.194165 0.1443178 0 >> P4 0.366969 0.194165 0.000000 0.284253 0 >> P5 0.341760 0.1443178 0.284253 0.000000 0 >> (P3, P6) 0.000000 0.000000 0.000000 0.000000 0 >> >> I can change the fields of columns and rows P1-P5 without problems. >> >> But when I try to access the fields of the row, or column, (P3, P6) >> >> print (updated_distance_matrix_df.loc [clusters [i], last_cluster]) >> >> the message appears: >> >> KeyError: 'the label [P3, P6] is not in the [index]' >> > The rows and columns have "(P3, P6)", but you're looking for "[P3, > P6]". They aren't the same. > >> If I change find the "loc" by "at" method appears the error: >> >> print (updated_distance_matrix_df.at [clusters [i], last_cluster]) >> >> TypeError: unhashable type: 'list' >> > Is it expecting a tuple instead of a list? Tuples are hashable, lists > are not. > >> And if you simply leave: >> >> print (updated_distance_matrix_df [clusters [i], last_cluster]) >> >> gives the error: >> >> TypeError: unhashable type: 'list' >> >> A last_cluster variable is of type list: >> >> print (last_cluster, type (last_cluster)) >> >> ['P3', 'P6'] >> >> And a variable cluster [i] is a string: >> >> print (clusters [i], type (clusters [i])) >> >> P5 >> >> Any tip? >> >> Thank you, >> From maximealbi at outlook.com Mon Feb 17 13:46:29 2020 From: maximealbi at outlook.com (Maxime Albi) Date: Mon, 17 Feb 2020 18:46:29 +0000 Subject: Interpreter Python 3.8 not there to select from PyCharm In-Reply-To: References: Message-ID: I'm very new to Python and wanting to learn the basics. I downloaded and installed Python 3.8 and PyCharm for my Windows 10 machine. All good. Launched PyCharm and I started a new Project and tried to select an 'interpreter' such as Python 3.8 but no interpreter was available for me to select from the down arrow menu ..!?!? Any settings I need to do ?? Thanks, Maxime From PythonList at DancesWithMice.info Mon Feb 17 15:21:49 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Tue, 18 Feb 2020 09:21:49 +1300 Subject: Can anyone share experience about python backend developer? In-Reply-To: References: Message-ID: On 17/02/20 11:11 PM, lampahome wrote: > I have 3+years developer experience in python, but I always develop > about peer-to-peer service. Have no backend experience in python. > > But now I want to change to backend engineer, somebody shares their > job is to do like > 1. Develop customize API to receive data from global > 2. Develop tools with k8s > 3. Experience about NoSQL > > After I heard above, it seems wide range and hard to start from scratch. > > Without comparing performance with other languages, how to dig into > backend development?(Or some framework could help me?) Suggest a review of edX's and Coursera's (and possibly others) on-line training courses. IIRC there's at least one that aims specifically at the 'back-end' stack. -- Regards =dn From PythonList at DancesWithMice.info Mon Feb 17 16:37:38 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Tue, 18 Feb 2020 10:37:38 +1300 Subject: insert data in python script In-Reply-To: References: Message-ID: Please help us to help you! 1 is all of this code in a single file or spread across (at least) two modules? What are their names? What is the directory structure? 2 copy-paste the actual error message received. It works for me! 1 not knowing your circumstances, I put all the code in one file 2 updated one line (possibly due to above) # methane = preos.Molecule("methane", -82.59 + 273.15, 45.99, 0.011) methane = Molecule("methane", -82.59 + 273.15, 45.99, 0.011) dn $ python3 Projects/molecule.py Molecule: methane. Critical Temperature = 190.6 K Critical Pressure = 46.0 bar. Accentric factor = 0.011000 NB if the bulk of the code is stored in a module named preos.py then it is necessary to first: import peos and restore the above change. NBB under such conditions peos.py must be located in the file-system where the 'mainline' can find (and import) it! -- Regards =dn From voodoo.bender at gmail.com Tue Feb 18 02:47:12 2020 From: voodoo.bender at gmail.com (alberto) Date: Mon, 17 Feb 2020 23:47:12 -0800 (PST) Subject: insert data in python script In-Reply-To: References: Message-ID: <1de96119-fc36-40c1-94bc-600fdb851450@googlegroups.com> Il giorno luned? 17 febbraio 2020 17:48:07 UTC+1, alberto ha scritto: > Hi, > I would use this script to evaluate fugacity coefficient with PENG-ROBINSON equation, but I don't understand the correct mode to insert data > > import numpy as np > import matplotlib.pyplot as plt > from scipy.optimize import newton > > R = 8.314e-5 # universal gas constant, m3-bar/K-mol > class Molecule: > """ > Store molecule info here > """ > def __init__(self, name, Tc, Pc, omega): > """ > Pass parameters desribing molecules > """ > #! name > self.name = name > #! Critical temperature (K) > self.Tc = Tc > #! Critical pressure (bar) > self.Pc = Pc > #! Accentric factor > self.omega = omega > > def print_params(self): > """ > Print molecule parameters. > """ > print("""Molecule: %s. > \tCritical Temperature = %.1f K > \tCritical Pressure = %.1f bar. > \tAccentric factor = %f""" % (self.name, self.Tc, self.Pc, self.omega)) > > def preos(molecule, T, P, plotcubic=True, printresults=True): > """ > Peng-Robinson equation of state (PREOS) > http://en.wikipedia.org/wiki/Equation_of_state#Peng.E2.80.93Robinson_equation_of_state > :param molecule: Molecule molecule of interest > :param T: float temperature in Kelvin > :param P: float pressure in bar > :param plotcubic: bool plot cubic polynomial in compressibility factor > :param printresults: bool print off properties > Returns a Dict() of molecule properties at this T and P. > """ > # build params in PREOS > Tr = T / molecule.Tc # reduced temperature > a = 0.457235 * R**2 * molecule.Tc**2 / molecule.Pc > b = 0.0777961 * R * molecule.Tc / molecule.Pc > kappa = 0.37464 + 1.54226 * molecule.omega - 0.26992 * molecule.omega**2 > alpha = (1 + kappa * (1 - np.sqrt(Tr)))**2 > > A = a * alpha * P / R**2 / T**2 > B = b * P / R / T > > # build cubic polynomial > def g(z): > """ > Cubic polynomial in z from EOS. This should be zero. > :param z: float compressibility factor > """ > return z**3 - (1 - B) * z**2 + (A - 2*B - 3*B**2) * z - ( > A * B - B**2 - B**3) > > # Solve cubic polynomial for the compressibility factor > z = newton(g, 1.0) # compressibility factor > rho = P / (R * T * z) # density > > # fugacity coefficient comes from an integration > fugacity_coeff = np.exp(z - 1 - np.log(z - B) - A / np.sqrt(8) / B * np.log( > (z + (1 + np.sqrt(2)) * B) / (z + (1 - np.sqrt(2)) * B))) > > if printresults: > print("""PREOS calculation at > \t T = %.2f K > \t P = %.2f bar""" % (T, P)) > print("\tCompressibility factor : ", z) > print("\tFugacity coefficient: ", fugacity_coeff) > print("\tFugacity at pressure %.3f bar = %.3f bar" % ( > P, fugacity_coeff * P)) > print("\tDensity: %f mol/m3" % rho) > print("\tMolar volume: %f L/mol" % (1.0 / rho * 1000)) > print("\tDensity: %f v STP/v" % (rho * 22.4 / 1000)) > print("\tDensity of ideal gas at same conditions: %f v STP/v" % ( > rho * 22.4/ 1000 * z)) > > if plotcubic: > # Plot the cubic equation to visualize the roots > zz = np.linspace(0, 1.5) # array for plotting > > plt.figure() > plt.plot(zz, g(zz), color='k') > plt.xlabel('Compressibility, $z$') > plt.ylabel('Cubic $g(z)$') > plt.axvline(x=z) > plt.axhline(y=0) > plt.title('Root found @ z = %.2f' % z) > plt.show() > return {"density(mol/m3)": rho, "fugacity_coefficient": fugacity_coeff, > "compressibility_factor": z, "fugacity(bar)": fugacity_coeff * P, > "molar_volume(L/mol)": 1.0 / rho * 1000.0} > > def preos_reverse(molecule, T, f, plotcubic=False, printresults=True): > """ > Reverse Peng-Robinson equation of state (PREOS) to obtain pressure for a particular fugacity > :param molecule: Molecule molecule of interest > :param T: float temperature in Kelvin > :param f: float fugacity in bar > :param plotcubic: bool plot cubic polynomial in compressibility factor > :param printresults: bool print off properties > Returns a Dict() of molecule properties at this T and f. > """ > # build function to minimize: difference between desired fugacity and that obtained from preos > def g(P): > """ > :param P: pressure > """ > return (f - preos(molecule, T, P, plotcubic=False, printresults=False)["fugacity(bar)"]) > > # Solve preos for the pressure > P = newton(g, f) # pressure > > # Obtain remaining parameters > pars = preos(molecule, T, P, plotcubic=plotcubic, printresults=printresults) > rho = pars["density(mol/m3)"] > fugacity_coeff = pars["fugacity_coefficient"] > z = pars["compressibility_factor"] > > return {"density(mol/m3)": rho, "fugacity_coefficient": fugacity_coeff, > "compressibility_factor": z, "pressure(bar)": P, > "molar_volume(L/mol)": 1.0 / rho * 1000.0} > > # TODO: Implement mixture in object-oriented way as well > def preos_mixture(molecule_a, molecule_b, delta, T, P_total, x, plotcubic=True, printresults=True): > """ > Peng-Robinson equation of state (PREOS) for a binary mixture > http://en.wikipedia.org/wiki/Equation_of_state#Peng.E2.80.93Robinson_equation_of_state > :param molecule_a: Molecule molecule 1 of interest > :param molecule_b: Molecule molecule 2 of interest > :param delta: binary interaction parameter between molecules a and b > :param T: float temperature in Kelvin > :param P_total: float total pressure in bar > :param x: array mole fractions > :param plotcubic: bool plot cubic polynomial in compressibility factor > :param printresults: bool print off properties > """ > # build arrays of properties > Tc = np.array([molecule_a.Tc, molecule_b.Tc]) > Pc = np.array([molecule_a.Pc, molecule_b.Pc]) > omega = np.array([molecule_a.omega, molecule_b.omega]) > > # build params in PREOS > Tr = T / Tc # reduced temperature > a0 = 0.457235 * R**2 * Tc**2 / Pc > b = 0.0777961 * R * Tc / Pc > kappa = 0.37464 + 1.54226 * omega - 0.26992 * omega**2 > a = a0 * (1 + kappa * (1 - np.sqrt(Tr)))**2 > > # apply mixing rules > aij = (1.0 - delta) * np.sqrt(a[0] * a[1]) > a_mix = a[0] * x[0]**2 + a[1] * x[1]**2 + 2.0 * x[0] * x[1] * aij > b_mix = x[0] * b[0] + x[1] * b[1] > A = a_mix * P_total / R**2 / T**2 > B = b_mix * P_total / R / T > > # build cubic polynomial > def g(z): > """ > Cubic polynomial in z from EOS. This should be zero. > :param z: float compressibility factor > """ > return z**3 - (1 - B) * z**2 + (A - 2*B - 3*B**2) * z - ( > A * B - B**2 - B**3) > > # Solve cubic polynomial for the compressibility factor > z = newton(g, 1.0) # compressibility factor > rho = P_total / (R * T * z) # density > > Lnfug_0 = -np.log(z - B) + (z - 1.0) * b[0] / b_mix - A / np.sqrt(8) / B * (2.0 / a_mix * (x[0] * a[0] + x[1] * aij) - b[0] / b_mix) *\ > np.log((z + (1.0 + np.sqrt(2)) * B) / (z + (1.0 - np.sqrt(2)) * B)) > Lnfug_1 = -np.log(z - B) + (z - 1.0) * b[1] / b_mix - A / np.sqrt(8) / B * (2.0 / a_mix * (x[1] * a[1] + x[0] * aij) - b[1] / b_mix) *\ > np.log((z + (1.0 + np.sqrt(2)) * B) / (z + (1.0 - np.sqrt(2)) * B)) > > # fugacity coefficient comes from an integration > fugacity_coefs = np.exp(np.array([Lnfug_0, Lnfug_1])) > > if printresults: > print("""PREOS calculation at > \t T = %.2f K > \t P, total = %.2f bar""" % (T, P_total)) > print("\tDensity: %f mol/m3" % rho) > print("\tCompressibility factor : %f" % z) > print("Component 0, %s:" % molecule_a.name) > print("\tFugacity coefficient: %f" % fugacity_coefs[0]) > print("\tFugacity: %f bar" % (fugacity_coefs[0] * x[0] * P_total)) > print("Component 1, %s:" % molecule_b.name) > print("\tFugacity coefficient: %f" % fugacity_coefs[1]) > print("\tFugacity: %f bar" % (fugacity_coefs[1] * x[1] * P_total)) > > if plotcubic: > # Plot the cubic equation to visualize the roots > zz = np.linspace(0, 1.5) # array for plotting > > plt.figure() > plt.plot(zz, g(zz), color='k') > plt.xlabel('Compressibility, $z$') > plt.ylabel('Cubic $g(z)$') > plt.axvline(x=z) > plt.axhline(y=0) > plt.title('Root found @ z = %.2f' % z) > plt.show() > return {"density(mol/m3)": rho, "fugacity_coefficients": fugacity_coefs, > "compressibility_factor": z} > > > the readme file says that > > As an example calculation, we consider methane at 65.0 bar and 298.0 K. Methane has a critical temperature of -82.59 deg. C and a critical pressure of 45.99 bar. Its accentric factor is 0.011. We first create a methane molecule object and print its stored parameters: > > import preos > # pass name, Tc, Pc, omega > methane = preos.Molecule("methane", -82.59 + 273.15, 45.99, 0.011) > methane.print_params() > > Could I fix it > > regards > > Alberto Hi, my code preos in one file preos.py my commands are alberto at HENDRIX ~/PREOS $ python3.5 Python 3.5.2 (default, Oct 8 2019, 13:06:37) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import preos >>> methane = Molecule("methane", -82.59 + 273.15, 45.99, 0.011) Traceback (most recent call last): File "", line 1, in NameError: name 'Molecule' is not defined regards Alberto From onlinejudge95 at gmail.com Tue Feb 18 03:04:55 2020 From: onlinejudge95 at gmail.com (onlinejudge95) Date: Tue, 18 Feb 2020 13:34:55 +0530 Subject: Interpreter Python 3.8 not there to select from PyCharm In-Reply-To: References: Message-ID: On Tue, Feb 18, 2020 at 1:40 AM Maxime Albi wrote: > I'm very new to Python and wanting to learn the basics. > I downloaded and installed Python 3.8 and PyCharm for my Windows 10 > machine. All good. > > Launched PyCharm and I started a new Project and tried to select an > 'interpreter' such as Python 3.8 but no interpreter was available for me to > select from the down arrow menu ..!?!? > > Any settings I need to do ?? > PyCharm community would be a better source for asking this question > > Thanks, > Maxime > > -- > https://mail.python.org/mailman/listinfo/python-list > From PythonList at DancesWithMice.info Tue Feb 18 03:34:25 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Tue, 18 Feb 2020 21:34:25 +1300 Subject: insert data in python script In-Reply-To: <1de96119-fc36-40c1-94bc-600fdb851450@googlegroups.com> References: <1de96119-fc36-40c1-94bc-600fdb851450@googlegroups.com> Message-ID: ... >> import preos >> # pass name, Tc, Pc, omega >> methane = preos.Molecule("methane", -82.59 + 273.15, 45.99, 0.011) >> methane.print_params() ... > my code preos in one file preos.py > my commands are > > alberto at HENDRIX ~/PREOS $ python3.5 > Python 3.5.2 (default, Oct 8 2019, 13:06:37) > [GCC 5.4.0 20160609] on linux > Type "help", "copyright", "credits" or "license" for more information. >>>> import preos >>>> methane = Molecule("methane", -82.59 + 273.15, 45.99, 0.011) > Traceback (most recent call last): > File "", line 1, in > NameError: name 'Molecule' is not defined The first instruction (immediately above) imports the module preos.py. That works (no error message!). The second instruction refers to a Python class called Molecule. That fails. The error message says that 'Molecule' is not defined. Yet we can 'see' it. It *has* been defined! What is going on??? In this case, we need to tell Python that Molecule is part of the preos module. So back to your original code (top): methane = preos.Molecule("methane", -82.59 + 273.15, 45.99, 0.011) Please refer to earlier message. If Module were called from code in the preos.py file, then the "preos." prefix would not be necessary. The formal term for this situation is "namespaces". Because Molecule is defined within the preos.py module's namespace we need to tell Python exactly where Molecule can be found. In the same way that we might say: if someone in Antarctica wants to see Alberto, (s)he will have to go to Italy to find him... Don't hesitate to say if you think my reply is too complicated/advanced. People here are happy to help... -- Regards =dn From voodoo.bender at gmail.com Tue Feb 18 04:41:51 2020 From: voodoo.bender at gmail.com (alberto) Date: Tue, 18 Feb 2020 01:41:51 -0800 (PST) Subject: insert data in python script In-Reply-To: References: <1de96119-fc36-40c1-94bc-600fdb851450@googlegroups.com> Message-ID: <8313a962-4d86-464d-9ad5-f3a33faa0018@googlegroups.com> Il giorno marted? 18 febbraio 2020 09:34:51 UTC+1, DL Neil ha scritto: > ... > > >> import preos > >> # pass name, Tc, Pc, omega > >> methane = preos.Molecule("methane", -82.59 + 273.15, 45.99, 0.011) > >> methane.print_params() > > ... > > > my code preos in one file preos.py > > my commands are > > > > alberto at HENDRIX ~/PREOS $ python3.5 > > Python 3.5.2 (default, Oct 8 2019, 13:06:37) > > [GCC 5.4.0 20160609] on linux > > Type "help", "copyright", "credits" or "license" for more information. > >>>> import preos > >>>> methane = Molecule("methane", -82.59 + 273.15, 45.99, 0.011) > > Traceback (most recent call last): > > File "", line 1, in > > NameError: name 'Molecule' is not defined > > > The first instruction (immediately above) imports the module preos.py. > That works (no error message!). > > The second instruction refers to a Python class called Molecule. That > fails. The error message says that 'Molecule' is not defined. > > Yet we can 'see' it. It *has* been defined! What is going on??? > > In this case, we need to tell Python that Molecule is part of the preos > module. So back to your original code (top): > > methane = preos.Molecule("methane", -82.59 + 273.15, 45.99, 0.011) > > > Please refer to earlier message. If Module were called from code in the > preos.py file, then the "preos." prefix would not be necessary. > > The formal term for this situation is "namespaces". Because Molecule is > defined within the preos.py module's namespace we need to tell Python > exactly where Molecule can be found. In the same way that we might say: > if someone in Antarctica wants to see Alberto, (s)he will have to go to > Italy to find him... > > > Don't hesitate to say if you think my reply is too complicated/advanced. > People here are happy to help... > -- > Regards =dn hi honestly i don't understand what i have to do. I have been using python for too little time. could you help me understand regards Alberto From bouncingcats at gmail.com Tue Feb 18 05:00:44 2020 From: bouncingcats at gmail.com (David) Date: Tue, 18 Feb 2020 21:00:44 +1100 Subject: insert data in python script In-Reply-To: <8313a962-4d86-464d-9ad5-f3a33faa0018@googlegroups.com> References: <1de96119-fc36-40c1-94bc-600fdb851450@googlegroups.com> <8313a962-4d86-464d-9ad5-f3a33faa0018@googlegroups.com> Message-ID: On Tue, 18 Feb 2020 at 20:45, alberto wrote: > Il giorno marted? 18 febbraio 2020 09:34:51 UTC+1, DL Neil ha scritto: > > > my code preos in one file preos.py > > > my commands are > > > > > > alberto at HENDRIX ~/PREOS $ python3.5 > > > Python 3.5.2 (default, Oct 8 2019, 13:06:37) > > > [GCC 5.4.0 20160609] on linux > > > Type "help", "copyright", "credits" or "license" for more information. > > >>>> import preos > > >>>> methane = Molecule("methane", -82.59 + 273.15, 45.99, 0.011) > > > Traceback (most recent call last): > > > File "", line 1, in > > > NameError: name 'Molecule' is not defined > honestly i don't understand what i have to do. $ python3 Python 3.5.3 (default, Sep 27 2018, 17:25:39) [GCC 6.3.0 20170516] on linux Type "help", "copyright", "credits" or "license" for more information. >>> print(digits) Traceback (most recent call last): File "", line 1, in NameError: name 'digits' is not defined >>> print(string.digits) Traceback (most recent call last): File "", line 1, in NameError: name 'string' is not defined >>> import string >>> print(digits) Traceback (most recent call last): File "", line 1, in NameError: name 'digits' is not defined >>> print(string.digits) 0123456789 >>> From lukasz at langa.pl Tue Feb 18 05:10:48 2020 From: lukasz at langa.pl (=?utf-8?Q?=C5=81ukasz_Langa?=) Date: Tue, 18 Feb 2020 11:10:48 +0100 Subject: [RELEASE] Python 3.8.2rc2 is now available for testing Message-ID: Python 3.8.2rc2 is the second release candidate of the second maintenance release of Python 3.8. Go get it here: https://www.python.org/downloads/release/python-382rc2/ Why a second release candidate? The major reason for RC2 is that GH-16839 has been reverted. The original change was supposed to fix for some edge cases in urlparse (numeric paths, recognizing netlocs without //; details in BPO-27657 ). Unfortunately it broke third parties relying on the pre-existing undefined behavior. Sadly, the reverted fix has already been released as part of 3.8.1 (and 3.7.6 where it?s also reverted now). As such, even though the revert is itself a bug fix, it is incompatible with the behavior of 3.8.1. Please test. Timeline Assuming no critical problems are found prior to 2020-02-24, the currently scheduled release date for 3.8.2 (as well as 3.9.0 alpha 4!), no code changes are planned between this release candidate and the final release. That being said, please keep in mind that this is a pre-release of 3.8.2 and as such its main purpose is testing. Maintenance releases for the 3.8 series will continue at regular bi-monthly intervals, with 3.8.3 planned for April 2020 (during sprints at PyCon US). What?s new? The Python 3.8 series is the newest feature release of the Python language, and it contains many new features and optimizations. See the ?What?s New in Python 3.8 ? document for more information about features included in the 3.8 series. Detailed information about all changes made in version 3.8.2 specifically can be found in its change log . We hope you enjoy Python 3.8! Thanks to all of the many volunteers who help make Python Development and these releases possible! Please consider supporting our efforts by volunteering yourself or through organization contributions to the Python Software Foundation. https://www.python.org/psf/ - ? From torriem at gmail.com Tue Feb 18 09:53:59 2020 From: torriem at gmail.com (Michael Torrie) Date: Tue, 18 Feb 2020 07:53:59 -0700 Subject: insert data in python script In-Reply-To: <8313a962-4d86-464d-9ad5-f3a33faa0018@googlegroups.com> References: <1de96119-fc36-40c1-94bc-600fdb851450@googlegroups.com> <8313a962-4d86-464d-9ad5-f3a33faa0018@googlegroups.com> Message-ID: On 2/18/20 2:41 AM, alberto wrote: > Il giorno marted? 18 febbraio 2020 09:34:51 UTC+1, DL Neil ha scritto: >> The first instruction (immediately above) imports the module preos.py. >> That works (no error message!). >> >> The second instruction refers to a Python class called Molecule. That >> fails. The error message says that 'Molecule' is not defined. >> >> Yet we can 'see' it. It *has* been defined! What is going on??? >> >> In this case, we need to tell Python that Molecule is part of the preos >> module. So back to your original code (top): >> >> methane = preos.Molecule("methane", -82.59 + 273.15, 45.99, 0.011) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ He explicitly told you what to do. The problem was "Molecule" is part of the "preos" module, so you have to refer to it by the module name first. >> Please refer to earlier message. If Module were called from code in the >> preos.py file, then the "preos." prefix would not be necessary. >> >> The formal term for this situation is "namespaces". Because Molecule is >> defined within the preos.py module's namespace we need to tell Python >> exactly where Molecule can be found. In the same way that we might say: >> if someone in Antarctica wants to see Alberto, (s)he will have to go to >> Italy to find him... >> >> >> Don't hesitate to say if you think my reply is too complicated/advanced. >> People here are happy to help... >> -- >> Regards =dn > > hi > honestly i don't understand what i have to do. > I have been using python for too little time. > could you help me understand Did you read everything DL Neil said? He told you what to do, including giving you the line of code you need to replace, but also explained why. I don't know how one could make it more clear than what he said. Spend some time to really try to understand what DL Neil is saying. this is essential Python knowledge he's trying to impart. Learning to work with modules and namespaces in Python is pretty much required when learning and using Python. From mal at europython.eu Tue Feb 18 10:25:05 2020 From: mal at europython.eu (M.-A. Lemburg) Date: Tue, 18 Feb 2020 16:25:05 +0100 Subject: EuroPython 2020: Presenting our conference logo for Dublin Message-ID: <963bba26-ad78-af85-852f-f86c80e67bf0@europython.eu> We?re pleased to announce our official conference logo for EuroPython 2020, July 20-26, in Dublin, Ireland: * https://ep2020.europython.eu/ * The logo is inspired by the colors and symbols often associated with Ireland: the shamrock and the Celtic harp. It was again created by our designer Jessica Pe?a Moro from Sim?triko, who had already helped us in previous years with the conference design. Some additional updates: ------------------------ - We?re working on launching the mein website, the CFP and ticket sales in March. - We are also preparing the sponsorship packages and should have them ready early in March as well. Early bird sponsors will again receive a 10% discount on the package price. If you?re interested in becoming a launch sponsor, please contact our sponsor team at sponsoring at europython.eu. Help spread the word -------------------- Please help us spread this message by sharing it on your social networks as widely as possible. Thank you ! Link to the blog post: https://blog.europython.eu/post/190894113857/europython-2020-presenting-our-conference-logo Tweet: https://twitter.com/europython/status/1229770448516395008 Enjoy, -- EuroPython 2020 Team https://ep2020.europython.eu/ https://www.europython-society.org/ From voodoo.bender at gmail.com Tue Feb 18 10:52:41 2020 From: voodoo.bender at gmail.com (alberto) Date: Tue, 18 Feb 2020 07:52:41 -0800 (PST) Subject: insert data in python script In-Reply-To: References: <1de96119-fc36-40c1-94bc-600fdb851450@googlegroups.com> <8313a962-4d86-464d-9ad5-f3a33faa0018@googlegroups.com> Message-ID: Il giorno marted? 18 febbraio 2020 11:01:11 UTC+1, David ha scritto: > On Tue, 18 Feb 2020 at 20:45, alberto wrote: > > Il giorno marted? 18 febbraio 2020 09:34:51 UTC+1, DL Neil ha scritto: > > > > > my code preos in one file preos.py > > > > my commands are > > > > > > > > alberto at HENDRIX ~/PREOS $ python3.5 > > > > Python 3.5.2 (default, Oct 8 2019, 13:06:37) > > > > [GCC 5.4.0 20160609] on linux > > > > Type "help", "copyright", "credits" or "license" for more information. > > > >>>> import preos > > > >>>> methane = Molecule("methane", -82.59 + 273.15, 45.99, 0.011) > > > > Traceback (most recent call last): > > > > File "", line 1, in > > > > NameError: name 'Molecule' is not defined > > > honestly i don't understand what i have to do. > > $ python3 > Python 3.5.3 (default, Sep 27 2018, 17:25:39) > [GCC 6.3.0 20170516] on linux > Type "help", "copyright", "credits" or "license" for more information. > >>> print(digits) > Traceback (most recent call last): > File "", line 1, in > NameError: name 'digits' is not defined > >>> print(string.digits) > Traceback (most recent call last): > File "", line 1, in > NameError: name 'string' is not defined > >>> import string > >>> print(digits) > Traceback (most recent call last): > File "", line 1, in > NameError: name 'digits' is not defined > >>> print(string.digits) > 0123456789 > >>> Hi, I solve it with external file as follows import preos # pass name, Tc, Pc, omega methane = preos.Molecule("methane", -82.59 + 273.15, 45.99, 0.011) methane.print_params() thanks to everyone regards Alberto From kyosohma at gmail.com Tue Feb 18 14:13:35 2020 From: kyosohma at gmail.com (Mike Driscoll) Date: Tue, 18 Feb 2020 11:13:35 -0800 (PST) Subject: Python 101 2nd Edition book Message-ID: Hi, Years ago I posted about my first book, Python 101 on here and people really enjoyed it. I am working on a complete rewrite of the book and thought there might be people here who would enjoy knowing about it. You can read more here: https://www.blog.pythonlibrary.org/2020/02/17/python-101-2nd-edition-kickstarter-is-live/ Feel free to ask any questions that you might have as well. Thanks, Mike From PythonList at DancesWithMice.info Tue Feb 18 14:32:37 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Wed, 19 Feb 2020 08:32:37 +1300 Subject: insert data in python script In-Reply-To: References: <1de96119-fc36-40c1-94bc-600fdb851450@googlegroups.com> <8313a962-4d86-464d-9ad5-f3a33faa0018@googlegroups.com> Message-ID: On 19/02/20 4:52 AM, alberto wrote: > Hi, > I solve it with external file as follows > > import preos > # pass name, Tc, Pc, omega > methane = preos.Molecule("methane", -82.59 + 273.15, 45.99, 0.011) > methane.print_params() > > thanks to everyone It is difficult to learn a new programming language, even for professional programmers - and more-so if English is not one's native-language. Well done! Now, if you could tell us how to capture and control methane, perhaps the world would become a better place... Ciao! -- Regards =dn From duram at terra.com.br Wed Feb 19 09:22:48 2020 From: duram at terra.com.br (Duram) Date: Wed, 19 Feb 2020 11:22:48 -0300 Subject: Paper Print Help Message-ID: I have a drawing in a .gif file with (a,b) pixels and want to paperprint it in a position (x,y), what would be the code? From rhodri at kynesim.co.uk Wed Feb 19 10:17:25 2020 From: rhodri at kynesim.co.uk (Rhodri James) Date: Wed, 19 Feb 2020 15:17:25 +0000 Subject: Paper Print Help In-Reply-To: References: Message-ID: On 19/02/2020 14:22, Duram via Python-list wrote: > I have a drawing in a .gif file with (a,b) pixels and want to paperprint > it in a position (x,y), what would be the code? What have you tried? -- Rhodri James *-* Kynesim Ltd From privacy_please at filippo.it Wed Feb 19 17:15:59 2020 From: privacy_please at filippo.it (FilippoM) Date: Wed, 19 Feb 2020 17:15:59 -0500 Subject: Pandas rookie Message-ID: Hi, I've got a Pandas data frame that looks like this In [69]: data.head Out[69]: Hi all, I have some embedded Python code which looks like this in C++ _gstate = PyGILState_Ensure(); PyImport_ImportModule("a"); ... PyGILState_Release(_gstate); and is called from different threads which are created in C++. My module a.py then imports another module b in python, which defines a lot of functions. When several threads execute this simultaneously I often get a stacktrace saying some function near the end of module b is not defined, presumably because the module has been imported part-initialised. This only seems to happen when my Python modules are packaged in a zip file, not when they are ordinary files on disk. I have observed this in both Python 3.7 and Python 3.8. Does anyone have any insights or suggestions for how to debug this? It seems likely to be hard to produce a reproducible test case. Regards, Geoff Bache From please_no at spam.it Thu Feb 20 10:21:30 2020 From: please_no at spam.it (Luca) Date: Thu, 20 Feb 2020 10:21:30 -0500 Subject: What's the best forum to get help with Pandas? Message-ID: subject has it all. Thanks From rhodri at kynesim.co.uk Thu Feb 20 10:39:36 2020 From: rhodri at kynesim.co.uk (Rhodri James) Date: Thu, 20 Feb 2020 15:39:36 +0000 Subject: Paper Print Help In-Reply-To: References: Message-ID: <79736a5e-f0c2-944f-ca2e-50828c8f1ca7@kynesim.co.uk> On 20/02/2020 15:08, Duram wrote: > On 19/02/2020 12:17, Rhodri James wrote: >> On 19/02/2020 14:22, Duram via Python-list wrote: >>> I have a drawing in a .gif file with (a,b) pixels and want to >>> paperprint it in a position (x,y), what would be the code? >> >> What have you tried? >> > Nothing, I did not find the module that make to print to the paper Please don't reply to me directly; if it's a question worth asking in public then it's worth answering in public too! OK, let's backtrack a bit. First off, what operating system are you using? Second, do you have this GIF file in any sort of program at the moment, or do you want advice on how to write a program to handle the image? I suspect your question is a bit too specific at the moment, and you have some mistaken assumptions about how images and (most especially) printing work. -- Rhodri James *-* Kynesim Ltd From rosuav at gmail.com Thu Feb 20 10:41:59 2020 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 21 Feb 2020 02:41:59 +1100 Subject: Should PyImport_ImportModule be threadsafe when importing from zipfiles? In-Reply-To: References: Message-ID: On Fri, Feb 21, 2020 at 2:37 AM Geoff Bache wrote: > When several threads execute this simultaneously I often get a stacktrace > saying some function near the end of module b is not defined, presumably > because the module has been imported part-initialised. > This only seems to happen when my Python modules are packaged in a zip > file, not when they are ordinary files on disk. > > I have observed this in both Python 3.7 and Python 3.8. Does anyone have > any insights or suggestions for how to debug this? It seems likely to be > hard to produce a reproducible test case. One easy way to probe the bug would be to pre-import the module before starting any secondary threads. If you ever get the problem under that pattern, then it's not a concurrency problem (IOW have fun figuring out what *is* the problem). Another thing to try: Slap a print call at the top and bottom of the module. See if you get multiple of them. ChrisA From musbur at posteo.org Thu Feb 20 11:19:37 2020 From: musbur at posteo.org (musbur at posteo.org) Date: Thu, 20 Feb 2020 17:19:37 +0100 Subject: Pandas rookie In-Reply-To: References: Message-ID: <20200220171937.24c9d84e@nxp10225> On Wed, 19 Feb 2020 17:15:59 -0500 FilippoM wrote: > How can I use Pandas' dataframe magic to calculate, for each of the > possible 109 values, how many have VIDEO_OK, and how many have > VIDEO_FAILURE I have respectively? crosstab() From skip.montanaro at gmail.com Thu Feb 20 11:47:18 2020 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Thu, 20 Feb 2020 10:47:18 -0600 Subject: What's the best forum to get help with Pandas? In-Reply-To: References: Message-ID: I believe the Pandas people tend to refer people to Stack Overflow. I find that suboptimal as many questions go completely unanswered or get gruff responses. Aside from that, I suspect this list is as good a place as any to request help. Skip From rosuav at gmail.com Thu Feb 20 12:58:11 2020 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 21 Feb 2020 04:58:11 +1100 Subject: Should PyImport_ImportModule be threadsafe when importing from zipfiles? In-Reply-To: References: Message-ID: On Fri, Feb 21, 2020 at 3:06 AM Geoff Bache wrote: > > Hi Chris, > > Yes, I've tried both of these things already. I can confirm there are multiple calls, and that pre-importing the module fixes it. But pre-importing it is not a solution in practice. > Cool, good to know. Crazy idea: What would happen if you stick something temporarily into sys.modules["b"], then when you're done importing, set the module back into there? Might not help, but would be interesting to try, and might show a bit more of what's going on. ChrisA From geoff.bache at gmail.com Thu Feb 20 11:06:36 2020 From: geoff.bache at gmail.com (Geoff Bache) Date: Thu, 20 Feb 2020 17:06:36 +0100 Subject: Should PyImport_ImportModule be threadsafe when importing from zipfiles? In-Reply-To: References: Message-ID: Hi Chris, Yes, I've tried both of these things already. I can confirm there are multiple calls, and that pre-importing the module fixes it. But pre-importing it is not a solution in practice. Regards, Geoff On Thu, Feb 20, 2020 at 4:45 PM Chris Angelico wrote: > On Fri, Feb 21, 2020 at 2:37 AM Geoff Bache wrote: > > When several threads execute this simultaneously I often get a stacktrace > > saying some function near the end of module b is not defined, presumably > > because the module has been imported part-initialised. > > This only seems to happen when my Python modules are packaged in a zip > > file, not when they are ordinary files on disk. > > > > I have observed this in both Python 3.7 and Python 3.8. Does anyone have > > any insights or suggestions for how to debug this? It seems likely to be > > hard to produce a reproducible test case. > > One easy way to probe the bug would be to pre-import the module before > starting any secondary threads. If you ever get the problem under that > pattern, then it's not a concurrency problem (IOW have fun figuring > out what *is* the problem). > > Another thing to try: Slap a print call at the top and bottom of the > module. See if you get multiple of them. > > ChrisA > -- > https://mail.python.org/mailman/listinfo/python-list > From davidwihl at gmail.com Thu Feb 20 12:30:06 2020 From: davidwihl at gmail.com (David Wihl) Date: Thu, 20 Feb 2020 13:30:06 -0400 Subject: Idiom for partial failures Message-ID: ? (first post) I'm working on the Python client library [0]for the Google Ads API [1]. In some cases, we can start a request with a partial failure [2] flag = True. This means that the request may contain say 1000 operations. If any of the operations fail, the request will return with a success status without an exception. Then the developer has to iterate through the list of operation return statuses to determine which specific ones failed (example [3]). I believe that it would be more idiomatic in Python (and other languages like Ruby) to throw an exception when one of these partial errors occur. That way there would be the same control flow if a major or minor error occurred. The team is asking me for other examples or justification of this being idiomatic of Python. Can you recommend any examples or related best practices? [0] https://github.com/googleads/google-ads-python [1] https://developers.google.com/google-ads/api/docs/start [2] https://developers.google.com/google-ads/api/docs/best-practices/partial-failures [3] https://github.com/googleads/google-ads-python/blob/master/examples/error_handling/handle_partial_failure.py Thanks! -David From rgladkik at sfu.ca Thu Feb 20 15:57:54 2020 From: rgladkik at sfu.ca (rgladkik at sfu.ca) Date: Thu, 20 Feb 2020 12:57:54 -0800 (PST) Subject: Machine Learning program outputting wrong things Message-ID: <0b4a72cb-f996-4430-823a-8343282bb024@googlegroups.com> I am writing a program for an assignment (in a course I am auditing). I am pasting it below: # Assignment 2 skeleton code # This code shows you how to use the 'argparse' library to read in parameters import argparse import math import matplotlib.pyplot as plt import numpy as np import pandas as pd import random as rn from dispkernel import dispKernel # Command Line Arguments parser = argparse.ArgumentParser(description='generate training and validation data for assignment 2') parser.add_argument('trainingfile', help='name stub for training data and label output in csv format', default="train") parser.add_argument('validationfile', help='name stub for validation data and label output in csv format', default="valid") parser.add_argument('-numtrain', help='number of training samples', type= int, default=200) parser.add_argument('-numvalid', help='number of validation samples', type= int, default=20) parser.add_argument('seed', help='random seed', type= int, default=1) parser.add_argument('learningrate', help='learning rate', type= float, default=0.1) parser.add_argument('actfunction', help='activation functions', choices=['sigmoid', 'relu', 'linear'], default='linear') parser.add_argument('numepoch', help='number of epochs', type= int, default=50) args = parser.parse_args() traindataname = args.trainingfile + "data.csv" trainlabelname = args.trainingfile + "label.csv" print("training data file name: ", traindataname) print("training label file name: ", trainlabelname) validdataname = args.validationfile + "data.csv" validlabelname = args.validationfile + "label.csv" print("validation data file name: ", validdataname) print("validation label file name: ", validlabelname) print("number of training samples = ", args.numtrain) print("number of validation samples = ", args.numvalid) print("learning rate = ", args.learningrate) print("number of epoch = ", args.numepoch) print("activation function is ", args.actfunction) # read in training data t_data = pd.read_csv(args.trainingfile, ',', header=None).values t_label = pd.read_csv('trainlabel.csv', ',', header=None).values row_dim_t = t_data.shape[1] col_dim_t = t_data.shape[0] # read in validation data v_data = pd.read_csv(args.validationfile, ',', header=None).values v_label = pd.read_csv('validlabel.csv', ',', header=None).values row_dim_v = v_data.shape[1] col_dim_v = v_data.shape[0] np.random.seed(args.seed) # initialize weights w = np.random.rand(row_dim_t, 1) # initialize bias b = np.random.uniform(0, 1) n_epoch = [] loss_t = [] loss_v = [] accuracy_t = [] accuracy_v = [] Z_t = np.zeros([col_dim_t, 1]) Z_v = np.zeros([col_dim_v, 1]) guess_t_label = np.zeros([col_dim_t, 1]) guess_v_label = np.zeros([col_dim_v, 1]) accuracy_j_t = np.zeros([col_dim_t, 1]) accuracy_j_v = np.zeros([col_dim_v, 1]) Y_t = np.zeros([col_dim_t, 1]) Y_v = np.zeros([col_dim_v, 1]) loss_j_t = np.zeros([col_dim_t, 1]) loss_j_v = np.zeros([col_dim_v, 1]) grad_loss_w = np.zeros([col_dim_t, row_dim_v]) grad_loss_b = np.zeros([col_dim_t, 1]) class Linear: def __init__(self, Z, data, label): self.Z = Z self.data = data self.label = label # pass Z through an activation function def act_linear(self): return self.Z # gradient of the loss wrt weights def grad_loss_w(self, Y): return 2*(Y - self.label)*self.data # gradient of the loss wrt bias def grad_loss_b(self, Y): return 2*(Y - self.label) for i in range(0, args.numepoch): n_epoch.append(i) # calculate predictor for training data Z_t[:] = np.dot(t_data[:, :], w[:]) + b # predict training label based on output # of predictor guess_t_label[:] = (Z_t >= 0.5) # determine whether predicted label is # correct or not accuracy_j_t[:] = 1 - np.absolute(guess_t_label[:] - t_label[:]) # calculate accuracy for training data accuracy_t.append(np.sum(accuracy_j_t[:], axis=0)/col_dim_t) # calculate predictor for validation data Z_v[:] = np.dot(v_data[:, :], w[:]) + b # predict validation label based on output # of predictor guess_v_label[:] = (Z_v >= 0.5) # determine whether predicted label is # correct or not accuracy_j_v[:] = 1 - np.absolute(guess_v_label[:] - v_label[:]) # calculate accuracy for validation data accuracy_v.append(np.sum(accuracy_j_v[:], axis=0)/col_dim_v) l_t = Linear(Z_t, t_data, t_label) l_v = Linear(Z_v, v_data, v_label) # pass Z through an activation function Y_t[:] = l_t.act_linear() Y_v[:] = l_v.act_linear() # calculate loss across all training data loss_j_t[:] = (Y_t[:] - t_label)**2 loss_t.append(np.sum(loss_j_t[:], axis=0)/col_dim_t) # calculate loss across all validation data loss_j_v[:] = (Y_v[:] - v_label)**2 loss_v.append(np.sum(loss_j_v[:], axis=0)/col_dim_v) grad_loss_w[:] = l_t.grad_loss_w(Y_t) grad_loss_b[:] = l_t.grad_loss_b(Y_t) # average gradient across all inputs avg_loss_w = np.sum(grad_loss_w[:], axis=0)/col_dim_t avg_loss_b = np.sum(grad_loss_b[:], axis=0)/col_dim_t # update weights and bias w[:] -= np.reshape(avg_loss_w, (row_dim_t, 1))*args.learningrate b -= avg_loss_b*args.learningrate # plot loss vs number of epochs fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 6)) ax1.plot(n_epoch, loss_t, 'b.', label='Training Data') ax1.plot(n_epoch, loss_v, 'r.', label='Validation Data') ax1.set(xlabel='Epoch', ylabel='Loss', title='Loss vs Number of Epochs \n with Activation ' + str.capitalize(args.actfunction)) ax1.legend() # plot accuracy vs number of epochs ax2.plot(n_epoch, accuracy_t, 'b.', label='Training Data') ax2.plot(n_epoch, accuracy_v, 'r.', label='Validation Data') ax2.set(xlabel='Epoch', ylabel='Accuracy', title='Accuracy vs Number of Epochs \n with Activation ' + str.capitalize(args.actfunction)) ax2.legend() plt.savefig('loss_accuracy.png') The training file contains 200 rows of 9 columns. In each row, there's a series of 1s and 0s. If the arrangement of 1s and 0s forms an X pattern (ie [1, 0, 1, 0, 1, 0, 1, 0, 1], this is assigned a label 1. If the 1s and 0s don't form an X, the label is 0. I'm using a linear activation function, and a mean squared error loss function. I'm also using 15 for the seed, 0.3 for the learning rate, and 10 for the epoch number. However, I keep running into problems. At 0.3, the weights are correct- I plot the weights on a grid and get an X pattern. The plots of epoch vs loss and accuracy gives me rubbish- I get underfitted plots. At lower learning rates, the plots look ok (the accuracy still looks terrible no matter what I do), but the weights are wrong- the learning rate is too slow. Please help!! From ethan at stoneleaf.us Thu Feb 20 16:33:22 2020 From: ethan at stoneleaf.us (Ethan Furman) Date: Thu, 20 Feb 2020 13:33:22 -0800 Subject: Idiom for partial failures In-Reply-To: References: Message-ID: <1f05a64f-69ab-be34-b429-3b98212b1b9f@stoneleaf.us> On 02/20/2020 09:30 AM, David Wihl wrote: > I'm working on the Python client library for the Google Ads API. In some cases, we can start a request with a partial failure flag = True. This means that the request may contain say 1000 operations. If any of the operations fail, the request will return with a success status without an exception. Then the developer has to iterate through the list of operation return statuses to determine which specific ones failed. > > I believe that it would be more idiomatic in Python (and other languages like Ruby) to throw an exception when one of these partial errors occur. That way there would be the same control flow if a major or minor error occurred. What I have done in such circumstances is have a custom exception type, and store the errors there -- how much detail you save depends on how much you need to properly post-process the failed items. For example: # not tested class PartialFailure(Exception): def __init__(self, failures): self.failures = failures ... lots of code ... failures = [] try: an_operation_that_could_fail except SomeException: failures.append(debugging info) ... more code ... if failures: raise PartialFailure(failures) # in the calling code try: code_that_may_raise_partial_failures except PartialFailure as e: for failure in e.failures: handle_failure -- ~Ethan~ From rgaddi at highlandtechnology.invalid Thu Feb 20 17:03:00 2020 From: rgaddi at highlandtechnology.invalid (Rob Gaddi) Date: Thu, 20 Feb 2020 14:03:00 -0800 Subject: Idiom for partial failures In-Reply-To: References: Message-ID: On 2/20/20 9:30 AM, David Wihl wrote: > ? > (first post) > > I'm working on the Python client library [0]for the Google Ads API [1]. In some cases, we can start a request with a partial failure [2] flag = True. This means that the request may contain say 1000 operations. If any of the operations fail, the request will return with a success status without an exception. Then the developer has to iterate through the list of operation return statuses to determine which specific ones failed (example [3]). > > I believe that it would be more idiomatic in Python (and other languages like Ruby) to throw an exception when one of these partial errors occur. That way there would be the same control flow if a major or minor error occurred. > > The team is asking me for other examples or justification of this being idiomatic of Python. Can you recommend any examples or related best practices? > > [0] https://github.com/googleads/google-ads-python > > [1] https://developers.google.com/google-ads/api/docs/start > > [2] https://developers.google.com/google-ads/api/docs/best-practices/partial-failures > > [3] https://github.com/googleads/google-ads-python/blob/master/examples/error_handling/handle_partial_failure.py > > Thanks! > -David > Potentially stupid question, does your library to the API have to support partial failures? Sure Google Ads does, but does it really add value to do so? And then you've got to decide what to DO with those partially failed results. You could, as a library, just say "No, this library never sets the partial_failure field. We only support atomic transactions that fully succeed or fully fail and raise an exception." Makes your life a lot easier; so unless it makes your customer's lives a lot harder... From python.list at tim.thechases.com Thu Feb 20 17:25:43 2020 From: python.list at tim.thechases.com (Tim Chase) Date: Thu, 20 Feb 2020 16:25:43 -0600 Subject: Idiom for partial failures In-Reply-To: References: Message-ID: <20200220162543.7fd8b88b@bigbox.attlocal.net> On 2020-02-20 13:30, David Wihl wrote: > I believe that it would be more idiomatic in Python (and other > languages like Ruby) to throw an exception when one of these > partial errors occur. That way there would be the same control flow > if a major or minor error occurred. There are a variety of ways to do it -- I like Ethan's suggestion about tacking the failures onto the exception and raising it at the end. But you can also yield a tuple of success/failure iterators, something like this pseudocode: def process(input_iter): successes = [] failures = [] for thing in input_iter: try: result = process(thing) except ValueError as e: # catch appropriate exception(s) here failures.append((e, thing)) else: successes.append((result, thing)) return successes, failures def process(item): if item % 3: raise ValueError("Must be divisible by 3!") else: print(item) return item // 3 successes, failures = process(range(10)) for reason, thing in failures: print(f"Unable to process {thing} because {reason}") -tkc From Richard at Damon-Family.org Thu Feb 20 21:14:45 2020 From: Richard at Damon-Family.org (Richard Damon) Date: Thu, 20 Feb 2020 21:14:45 -0500 Subject: Idiom for partial failures In-Reply-To: References: Message-ID: <2df1e584-572d-4b4f-750a-ff66d23c7fa4@Damon-Family.org> On 2/20/20 12:30 PM, David Wihl wrote: > ? > (first post) > > I'm working on the Python client library [0]for the Google Ads API [1]. In some cases, we can start a request with a partial failure [2] flag = True. This means that the request may contain say 1000 operations. If any of the operations fail, the request will return with a success status without an exception. Then the developer has to iterate through the list of operation return statuses to determine which specific ones failed (example [3]). > > I believe that it would be more idiomatic in Python (and other languages like Ruby) to throw an exception when one of these partial errors occur. That way there would be the same control flow if a major or minor error occurred. > > The team is asking me for other examples or justification of this being idiomatic of Python. Can you recommend any examples or related best practices? > > [0] https://github.com/googleads/google-ads-python > > [1] https://developers.google.com/google-ads/api/docs/start > > [2] https://developers.google.com/google-ads/api/docs/best-practices/partial-failures > > [3] https://github.com/googleads/google-ads-python/blob/master/examples/error_handling/handle_partial_failure.py > > Thanks! > -David My first thought is that partial failure also means partial success, which means that it shouldn't throw. One key thing about exceptions is that they provide an easy way to ABORT a current operation on an error and trap to an error handler. They allow you to begin the operation starting a try block, have a number of operations that don't need to worry about all the little error conditions that would force you to abort the operation, and then handle all the errors at the end, and the code in the middle doesn't need to propagate the error codes, as the exception carries that information. If you throw on a partial failure/partial success, then you really need to IMMEDIATELY catch the error so you can continue the successes, at which point returning an error value is normally clearer. Now, an alternative would be rather than throwing an exception, would be to effectively raise a signal and call an error callback with the details of the failed operation, and let the call back handle (or record) the error information, so the caller doesn't need to go through all the successes to see if there was an error. Now, if the code was going to iterate through the success anyway, then there isn't as much of a cost to detect the errors that occured. -- Richard Damon From PythonList at DancesWithMice.info Thu Feb 20 23:45:39 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Fri, 21 Feb 2020 17:45:39 +1300 Subject: Idiom for partial failures In-Reply-To: References: Message-ID: On 21/02/20 10:05 AM, Stefan Ram wrote: > David Wihl writes: >> I believe that it would be more idiomatic in Python (and other languages lik= >> e Ruby) to throw an exception when one of these partial errors occur. > > I wonder whether the term "idiomatic" is too heavily > burdened here. > > Python offers an idiom for handling a failure to do an > operation - the exception. > > But you have special case of a run-time program of many > operations, and you want the execution of the program to > continue even in the case of failures to execute some of > the operations. I am not aware of Python offering an idiom > for this special case. > > I am always thinking about terminology first. So I'd say: > You need to /define/ what "success" and "failure" means in > the case of your operation. Then return normally in the case > of success and return by exception in the case of failure. Not arguing - and if I were the logical answer is "not Python", but... PyTest (runs unit-tests, enables TDD) offers options to stop the test-runner at the first error-found or to keep going for up to n-errors. We can test for an error condition and if experienced such will not 'count' or stop the test-run. It distinguishes between hard-errors and warnings, and enables us to choose to 'elevate' one to the level of the other, and vice-versa. Its run-report lists which tests worked and which didn't (the 'last' or the up-to "n") - a clear advance on the OP's experience. I think someone has already discussed, but if the intent is bulk-processing ("batch processing") then I'd expect to find a means of 'bailing-out' when an error is found, or of back-tracking to locate errors. Perhaps, like my good-looks, my expectations of a professional standard are higher-than-average? -- Regards =dn From frank at chagford.com Fri Feb 21 01:59:35 2020 From: frank at chagford.com (Frank Millman) Date: Fri, 21 Feb 2020 08:59:35 +0200 Subject: Asyncio question Message-ID: Hi all I use asyncio in my project, and it works very well without my having to understand what goes on under the hood. It is a multi-user client/server system, and I want it to scale to many concurrent users. I have a situation where I have to decide between two approaches, and I want to choose the least resource-intensive, but I find it hard to reason about which, if either, is better. I use HTTP. On the initial connection from a client, I set up a session object, and the session id is passed to the client. All subsequent requests from that client include the session id, and the request is passed to the session object for handling. It is possible for a new request to be received from a client before the previous one has been completed, and I want each request to be handled atomically, so each session maintains its own asyncio.Queue(). The main routine gets the session id from the request and 'puts' the request in the appropriate queue. The session object 'gets' from the queue and handles the request. It works well. The question is, how to arrange for each session to 'await' its queue. My first attempt was to create a background task for each session which runs for the life-time of the session, and 'awaits' its queue. It works, but I was concerned about having a lot a background tasks active at the same time. Then I came up with what I thought was a better idea. On the initial connection, I create the session object, send the response to the client, and then 'await' the method that sets up the session's queue. This also works, and there is no background task involved. However, I then realised that the initial response handler never completes, and will 'await' until the session is closed. Is this better, worse, or does it make no difference? If it makes no difference, I will lean towards the first approach, as it is easier to reason about what is going on. Thanks for any advice. Frank Millman From rosuav at gmail.com Fri Feb 21 03:10:07 2020 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 21 Feb 2020 19:10:07 +1100 Subject: Should PyImport_ImportModule be threadsafe when importing from zipfiles? In-Reply-To: References: Message-ID: On Fri, Feb 21, 2020 at 6:56 PM Geoff Bache wrote: > > I'm not sure I understand what you mean by "stick something" there. What did you have in mind? I can't just put anything there or the importing will fail anyhow. > Also, setting the module back into there afterwards isn't possible unless I've already imported it, and as mentioned I can't do that in practice. > The best object to put in there would be something that prints out all __getattr__ calls. Something like this: import sys _this_module = sys.modules[__name__] print("** Importing %s, module ID is %s **" % (__name__, id(_this_module))) class Marker: def __getattr__(self, attr): print("** Sentinel imported, looking for %s.%s **" % (__name__, attr)) sys.modules[__name__] = Marker() ... # rest of module goes here ... sys.modules[__name__] = _this_module del _this_module Untested, might need some tweaks. The idea is that, if anything imports the module while it's still running, it should either print out a second "importing" line with a different ID, or it'll get the sentinel object, and any use of it will trigger the message. (Feel free to use the logging module instead of print, same difference.) ChrisA From rosuav at gmail.com Fri Feb 21 06:24:23 2020 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 21 Feb 2020 22:24:23 +1100 Subject: Should PyImport_ImportModule be threadsafe when importing from zipfiles? In-Reply-To: References: Message-ID: On Fri, Feb 21, 2020 at 8:58 PM Geoff Bache wrote: > > But, as I say, I don't have the module loaded beforehand, so caching it from sys.modules and restoring it afterwards won't be possible. Those lines go into the actual file you're importing. > Basically I'm looking for hints as to information about known problems and whether this kind of thing is likely to work anyway, and also hints for debugging - as in extracting more information about possible causes rather than documenting the symptoms further. I think I already have a fairly good overview of the symptoms. > Yeah, changing the actual module that's being messed with might help with that. I am kinda clutching at straws though. ChrisA From geoff.bache at gmail.com Fri Feb 21 02:55:53 2020 From: geoff.bache at gmail.com (Geoff Bache) Date: Fri, 21 Feb 2020 08:55:53 +0100 Subject: Should PyImport_ImportModule be threadsafe when importing from zipfiles? In-Reply-To: References: Message-ID: I'm not sure I understand what you mean by "stick something" there. What did you have in mind? I can't just put anything there or the importing will fail anyhow. Also, setting the module back into there afterwards isn't possible unless I've already imported it, and as mentioned I can't do that in practice. /Geoff On Thu, Feb 20, 2020 at 6:59 PM Chris Angelico wrote: > On Fri, Feb 21, 2020 at 3:06 AM Geoff Bache wrote: > > > > Hi Chris, > > > > Yes, I've tried both of these things already. I can confirm there are > multiple calls, and that pre-importing the module fixes it. But > pre-importing it is not a solution in practice. > > > > Cool, good to know. > > Crazy idea: What would happen if you stick something temporarily into > sys.modules["b"], then when you're done importing, set the module back > into there? Might not help, but would be interesting to try, and might > show a bit more of what's going on. > > ChrisA > -- > https://mail.python.org/mailman/listinfo/python-list > From geoff.bache at gmail.com Fri Feb 21 04:57:51 2020 From: geoff.bache at gmail.com (Geoff Bache) Date: Fri, 21 Feb 2020 10:57:51 +0100 Subject: Should PyImport_ImportModule be threadsafe when importing from zipfiles? In-Reply-To: References: Message-ID: But, as I say, I don't have the module loaded beforehand, so caching it from sys.modules and restoring it afterwards won't be possible. Just investigating which calls are made doesn't seem likely to provide new information. I already know which call is made, it's the one that produces the stacktrace... Basically I'm looking for hints as to information about known problems and whether this kind of thing is likely to work anyway, and also hints for debugging - as in extracting more information about possible causes rather than documenting the symptoms further. I think I already have a fairly good overview of the symptoms. /Geoff On Fri, Feb 21, 2020 at 9:11 AM Chris Angelico wrote: > On Fri, Feb 21, 2020 at 6:56 PM Geoff Bache wrote: > > > > I'm not sure I understand what you mean by "stick something" there. What > did you have in mind? I can't just put anything there or the importing will > fail anyhow. > > Also, setting the module back into there afterwards isn't possible > unless I've already imported it, and as mentioned I can't do that in > practice. > > > > The best object to put in there would be something that prints out all > __getattr__ calls. Something like this: > > import sys > _this_module = sys.modules[__name__] > print("** Importing %s, module ID is %s **" % (__name__, id(_this_module))) > class Marker: > def __getattr__(self, attr): > print("** Sentinel imported, looking for %s.%s **" % (__name__, > attr)) > sys.modules[__name__] = Marker() > > ... > # rest of module goes here > ... > > sys.modules[__name__] = _this_module > del _this_module > > > Untested, might need some tweaks. The idea is that, if anything > imports the module while it's still running, it should either print > out a second "importing" line with a different ID, or it'll get the > sentinel object, and any use of it will trigger the message. > > (Feel free to use the logging module instead of print, same difference.) > > ChrisA > -- > https://mail.python.org/mailman/listinfo/python-list > From tdldev at gmail.com Fri Feb 21 12:32:44 2020 From: tdldev at gmail.com (Jack Dangler) Date: Fri, 21 Feb 2020 12:32:44 -0500 Subject: pip issue Message-ID: <2c29d2d0-8efe-e45f-0227-91467ec8dcc4@gmail.com> Hi, all Went to setup path and got an error. attempted to update pip and got the same error... The error being thrown is - Traceback (most recent call last): ? File "/home/jack/.local/bin/pip", line 11, in ??? sys.exit(main()) ? File "/home/jack/.local/lib/python2.7/site-packages/pip/_internal/cli/main.py", line 73, in main ??? command = create_command(cmd_name, isolated=("--isolated" in cmd_args)) ? File "/home/jack/.local/lib/python2.7/site-packages/pip/_internal/commands/__init__.py", line 96, in create_command ??? module = importlib.import_module(module_path) ? File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module ??? __import__(name) ? File "/home/jack/.local/lib/python2.7/site-packages/pip/_internal/commands/install.py", line 24, in ??? from pip._internal.cli.req_command import RequirementCommand ? File "/home/jack/.local/lib/python2.7/site-packages/pip/_internal/cli/req_command.py", line 15, in ??? from pip._internal.index.package_finder import PackageFinder ? File "/home/jack/.local/lib/python2.7/site-packages/pip/_internal/index/package_finder.py", line 21, in ??? from pip._internal.index.collector import parse_links ? File "/home/jack/.local/lib/python2.7/site-packages/pip/_internal/index/collector.py", line 12, in ??? from pip._vendor import html5lib, requests ? File "/home/jack/.local/lib/python2.7/site-packages/pip/_vendor/requests/__init__.py", line 97, in ??? from pip._vendor.urllib3.contrib import pyopenssl ? File "/home/jack/.local/lib/python2.7/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py", line 46, in ??? import OpenSSL.SSL ? File "/usr/lib/python2.7/dist-packages/OpenSSL/__init__.py", line 8, in ??? from OpenSSL import rand, crypto, SSL ? File "/usr/lib/python2.7/dist-packages/OpenSSL/SSL.py", line 118, in ??? SSL_ST_INIT = _lib.SSL_ST_INIT AttributeError: 'module' object has no attribute 'SSL_ST_INIT' Any input, as always, is appreciated. Regards From greg.ewing at canterbury.ac.nz Fri Feb 21 16:13:33 2020 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Sat, 22 Feb 2020 10:13:33 +1300 Subject: Asyncio question In-Reply-To: References: Message-ID: On 21/02/20 7:59 pm, Frank Millman wrote: > My first attempt was to create a background task for each session which > runs for the life-time of the session, and 'awaits' its queue. It works, > but I was concerned about having a lot a background tasks active at the > same time. The whole point of asyncio is to make tasks very lightweight, so you can use as many of them as is convenient without worries. One task per client sounds like the right thing to do here. -- Greg From davidwihl at gmail.com Fri Feb 21 12:18:10 2020 From: davidwihl at gmail.com (David Wihl) Date: Fri, 21 Feb 2020 13:18:10 -0400 Subject: Idiom for partial failures In-Reply-To: References: Message-ID: Yes, the API has to support partial failures across all six supported languages. Not all operations need to be atomic and there is considerable efficiency in having multiple operations sent in a single request. Thanks, -David On Thu, Feb 20, 2020 at 6:07 PM Rob Gaddi wrote: > On 2/20/20 9:30 AM, David Wihl wrote: > > ? > > (first post) > > > > I'm working on the Python client library [0]for the Google Ads API [1]. > In some cases, we can start a request with a partial failure [2] flag = > True. This means that the request may contain say 1000 operations. If any > of the operations fail, the request will return with a success status > without an exception. Then the developer has to iterate through the list of > operation return statuses to determine which specific ones failed (example > [3]). > > > > I believe that it would be more idiomatic in Python (and other languages > like Ruby) to throw an exception when one of these partial errors occur. > That way there would be the same control flow if a major or minor error > occurred. > > > > The team is asking me for other examples or justification of this being > idiomatic of Python. Can you recommend any examples or related best > practices? > > > > [0] https://github.com/googleads/google-ads-python > > > > [1] https://developers.google.com/google-ads/api/docs/start > > > > [2] > https://developers.google.com/google-ads/api/docs/best-practices/partial-failures > > > > [3] > https://github.com/googleads/google-ads-python/blob/master/examples/error_handling/handle_partial_failure.py > > > > Thanks! > > -David > > > > Potentially stupid question, does your library to the API have to support > partial failures? Sure Google Ads does, but does it really add value to > do so? > And then you've got to decide what to DO with those partially failed > results. > > You could, as a library, just say "No, this library never sets the > partial_failure field. We only support atomic transactions that fully > succeed > or fully fail and raise an exception." Makes your life a lot easier; so > unless > it makes your customer's lives a lot harder... > -- > https://mail.python.org/mailman/listinfo/python-list > From geoff.bache at gmail.com Fri Feb 21 11:01:57 2020 From: geoff.bache at gmail.com (Geoff Bache) Date: Fri, 21 Feb 2020 17:01:57 +0100 Subject: Should PyImport_ImportModule be threadsafe when importing from zipfiles? In-Reply-To: References: Message-ID: OK, I see what you mean with the import backup change now, though it seems like it changes the semantics of Python's import mechanism a bit... But I still don't really get what information we'd gain from doing this. What call is being made and is failing is pretty obvious from the stacktrace. Thanks for your replies, anyway. /Geoff On Fri, Feb 21, 2020 at 12:25 PM Chris Angelico wrote: > On Fri, Feb 21, 2020 at 8:58 PM Geoff Bache wrote: > > > > But, as I say, I don't have the module loaded beforehand, so caching it > from sys.modules and restoring it afterwards won't be possible. > > Those lines go into the actual file you're importing. > > > Basically I'm looking for hints as to information about known problems > and whether this kind of thing is likely to work anyway, and also hints for > debugging - as in extracting more information about possible causes rather > than documenting the symptoms further. I think I already have a fairly good > overview of the symptoms. > > > > Yeah, changing the actual module that's being messed with might help > with that. I am kinda clutching at straws though. > > ChrisA > -- > https://mail.python.org/mailman/listinfo/python-list > From rgaddi at highlandtechnology.invalid Fri Feb 21 17:51:39 2020 From: rgaddi at highlandtechnology.invalid (Rob Gaddi) Date: Fri, 21 Feb 2020 14:51:39 -0800 Subject: Idiom for partial failures In-Reply-To: References: Message-ID: On 2/21/20 9:18 AM, David Wihl wrote: > Yes, the API has to support partial failures across all six supported > languages. Not all operations need to be atomic and there is considerable > efficiency in having multiple operations sent in a single request. Thanks, > -David > > On Thu, Feb 20, 2020 at 6:07 PM Rob Gaddi > wrote: > >> On 2/20/20 9:30 AM, David Wihl wrote: >>> ? >>> (first post) >>> >>> I'm working on the Python client library [0]for the Google Ads API [1]. >> In some cases, we can start a request with a partial failure [2] flag = >> True. This means that the request may contain say 1000 operations. If any >> of the operations fail, the request will return with a success status >> without an exception. Then the developer has to iterate through the list of >> operation return statuses to determine which specific ones failed (example >> [3]). >>> >>> I believe that it would be more idiomatic in Python (and other languages >> like Ruby) to throw an exception when one of these partial errors occur. >> That way there would be the same control flow if a major or minor error >> occurred. >>> >>> The team is asking me for other examples or justification of this being >> idiomatic of Python. Can you recommend any examples or related best >> practices? >>> >>> [0] https://github.com/googleads/google-ads-python >>> >>> [1] https://developers.google.com/google-ads/api/docs/start >>> >>> [2] >> https://developers.google.com/google-ads/api/docs/best-practices/partial-failures >>> >>> [3] >> https://github.com/googleads/google-ads-python/blob/master/examples/error_handling/handle_partial_failure.py >>> >>> Thanks! >>> -David >>> >> >> Potentially stupid question, does your library to the API have to support >> partial failures? Sure Google Ads does, but does it really add value to >> do so? >> And then you've got to decide what to DO with those partially failed >> results. >> >> You could, as a library, just say "No, this library never sets the >> partial_failure field. We only support atomic transactions that fully >> succeed >> or fully fail and raise an exception." Makes your life a lot easier; so >> unless >> it makes your customer's lives a lot harder... >> -- >> https://mail.python.org/mailman/listinfo/python-list >> In that case, I think Richard Damon's answer smells rightest. A partial failure is a partial success and should not trigger a mandatory flow-control change, which is what an exception is. If there is any information in the successes, then I'd expect an operation like this to return me a list corresponding 1-to-1 with the list of operations such that I could: results = do_the_thing() for op, result in zip(operations, results): if isinstance(result, GoogleApiError): deal_with_error(op, result) If successes have nothing to add to the party, then I'd expect the operation to return a list containing only the errors, and an empty list means no errors. From frank at chagford.com Fri Feb 21 23:58:16 2020 From: frank at chagford.com (Frank Millman) Date: Sat, 22 Feb 2020 06:58:16 +0200 Subject: Asyncio question In-Reply-To: References: Message-ID: <07d16e91-82be-490c-4486-2f8ffd708fb5@chagford.com> On 2020-02-21 11:13 PM, Greg Ewing wrote: > On 21/02/20 7:59 pm, Frank Millman wrote: >> My first attempt was to create a background task for each session >> which runs for the life-time of the session, and 'awaits' its queue. >> It works, but I was concerned about having a lot a background tasks >> active at the same time. > > The whole point of asyncio is to make tasks very lightweight, so you > can use as many of them as is convenient without worries. One task > per client sounds like the right thing to do here. > Perfect. Thanks so much. Frank From frank at chagford.com Fri Feb 21 23:58:16 2020 From: frank at chagford.com (Frank Millman) Date: Sat, 22 Feb 2020 06:58:16 +0200 Subject: Asyncio question In-Reply-To: References: Message-ID: <07d16e91-82be-490c-4486-2f8ffd708fb5@chagford.com> On 2020-02-21 11:13 PM, Greg Ewing wrote: > On 21/02/20 7:59 pm, Frank Millman wrote: >> My first attempt was to create a background task for each session >> which runs for the life-time of the session, and 'awaits' its queue. >> It works, but I was concerned about having a lot a background tasks >> active at the same time. > > The whole point of asyncio is to make tasks very lightweight, so you > can use as many of them as is convenient without worries. One task > per client sounds like the right thing to do here. > Perfect. Thanks so much. Frank From markos at c2o.pro.br Sat Feb 22 10:03:58 2020 From: markos at c2o.pro.br (Markos) Date: Sat, 22 Feb 2020 12:03:58 -0300 Subject: Errors in testing the SciPy installation Message-ID: <7675e12e-a48f-be56-c536-43fd954c2e2a@c2o.pro.br> Hi, Following the guidelines of the book Learning SciPy for Numerical and Scientific Computing Second Edition I did the tests: >>> import scipy >>> scipy.test() and got some errors: Ran 23065 tests in 490.568s FAILED (KNOWNFAIL=60, SKIP=1795, errors=29) What should I do? Thank you, Markos From Saliyusufm at outlook.com Sat Feb 22 04:45:16 2020 From: Saliyusufm at outlook.com (S Y) Date: Sat, 22 Feb 2020 09:45:16 +0000 Subject: Help with oop Message-ID: How can I use remove,add and verify methods in class oop. Which has tuple with allowed values inside class. Like two classes cart and inventory Get Outlook for iOS From lberia460 at gmail.com Sat Feb 22 13:18:09 2020 From: lberia460 at gmail.com (lberia460 at gmail.com) Date: Sat, 22 Feb 2020 10:18:09 -0800 (PST) Subject: python Message-ID: hi guys can you help me.how to find maximum and minimum in list using while loop python From python at python.invalid Sat Feb 22 13:33:38 2020 From: python at python.invalid (Python) Date: Sat, 22 Feb 2020 19:33:38 +0100 Subject: python In-Reply-To: References: Message-ID: <5e517383$0$20331$426a74cc@news.free.fr> lberia460 at gmail.com wrote: > hi guys can you help me.how to find maximum and minimum in list using while loop python l = [1, 4, 2, -1, 0, 4, 2, 1, 10] for i in range(100): pass maximum = max(l) minimum = min(l) From python at mrabarnett.plus.com Sat Feb 22 15:37:23 2020 From: python at mrabarnett.plus.com (MRAB) Date: Sat, 22 Feb 2020 20:37:23 +0000 Subject: python In-Reply-To: References: Message-ID: <4cd3d10a-9d93-5910-e213-d966d2ca08ac@mrabarnett.plus.com> On 2020-02-22 18:18, lberia460 at gmail.com wrote: > hi guys can you help me.how to find maximum and minimum in list using while loop python > You don't need to use a loop. Use the 'max' and 'min' functions. From countryone77 at gmail.com Sat Feb 22 15:49:56 2020 From: countryone77 at gmail.com (Bev In TX) Date: Sat, 22 Feb 2020 14:49:56 -0600 Subject: python In-Reply-To: <4cd3d10a-9d93-5910-e213-d966d2ca08ac@mrabarnett.plus.com> References: <4cd3d10a-9d93-5910-e213-d966d2ca08ac@mrabarnett.plus.com> Message-ID: <21E8B241-370A-4F04-8921-155D4332E2A9@gmail.com> > On Feb 22, 2020, at 2:42 PM, MRAB wrote: > >> On 2020-02-22 18:18, lberia460 at gmail.com wrote: >> hi guys can you help me.how to find maximum and minimum in list using while loop python > You don't need to use a loop. Use the 'max' and 'min' functions. Unless it was a homework question, in which case a loop might have been required. From ethan at stoneleaf.us Sat Feb 22 16:10:05 2020 From: ethan at stoneleaf.us (Ethan Furman) Date: Sat, 22 Feb 2020 13:10:05 -0800 Subject: Idiom for partial failures In-Reply-To: References: Message-ID: <6bb96204-6264-e720-2fc9-da17a7bc55ac@stoneleaf.us> On 02/21/2020 02:51 PM, Rob Gaddi wrote: > On 2/21/20 9:18 AM, David Wihl wrote: >> Yes, the API has to support partial failures across all six supported >> languages. Not all operations need to be atomic and there is considerable >> efficiency in having multiple operations sent in a single request. Thanks, > > A partial failure is a partial success and should not trigger a mandatory flow-control change, which is what an exception is. Whether it should or not is a design question which won't always have the same answer. > If there is any information in the successes, then I'd expect an operation like this to return me a list corresponding 1-to-1 with the list of operations Sure, if there is processing still needed for the successes then that is the way I would choose, also. > If successes have nothing to add to the party, then I'd expect the operation to return a list containing only the errors, and an empty list means no errors. I would go the exception route here, for two reasons: - the code that handles failures is very obviously in one place - the program won't run merrily along if I forget to handle the failure case (an exception would draw attention to the problem) -- ~Ethan~ From frank at chagford.com Sun Feb 23 02:04:00 2020 From: frank at chagford.com (Frank Millman) Date: Sun, 23 Feb 2020 09:04:00 +0200 Subject: Why is passing loop argument to asyncio.Event deprecated? Message-ID: Hi all Why is 'explicit passing of a loop argument to asyncio.Event' deprecated (see What's new in Python 3.8)? I use this in my project. I can find a workaround, but it is not elegant. I can explain my use case if requested, but I was just curious to find out the reason. Thanks Frank Millman From lberia460 at gmail.com Sun Feb 23 02:26:53 2020 From: lberia460 at gmail.com (luka beria) Date: Sat, 22 Feb 2020 23:26:53 -0800 (PST) Subject: python Message-ID: <10593548-6ae6-45f2-96c0-d4f36bf66e63@googlegroups.com> hi guys i have another question.how to find the minimum and maximum numbers in this list without using the min () and max () functions use while loop From frank at chagford.com Sun Feb 23 02:44:52 2020 From: frank at chagford.com (Frank Millman) Date: Sun, 23 Feb 2020 09:44:52 +0200 Subject: python In-Reply-To: <10593548-6ae6-45f2-96c0-d4f36bf66e63@googlegroups.com> References: <10593548-6ae6-45f2-96c0-d4f36bf66e63@googlegroups.com> Message-ID: <444a92af-2898-f810-9869-54b38948fd71@chagford.com> On 2020-02-23 9:26 AM, luka beria wrote: > hi guys i have another question.how to find the minimum and maximum numbers in this list without using the min () and max () functions use while loop > Hi Luka Did you read the reply to your previous question from Dennis Lee Bieber? If not, here it is again - """ This smells like a homework assignment. We do NOT provide solutions to homework. In particular, we will not provide you with an algorithm to solve such a simple problem. We WILL provide help with Python syntax and semantics, but YOU need to provide a starting point of what you've tried, what the results are, and what you expected for the results. Suggestion: pretend you are the computer. Use a piece of paper to track current MAX and current MIN. You get one item from the list at a time -- how do you determine if it is to become a new MAX, a new MIN, or is ignored as neither. Now -- write a program does just that... """ Try his suggestion, and come back here if you get stuck. Frank Millman From frank at chagford.com Sun Feb 23 02:44:52 2020 From: frank at chagford.com (Frank Millman) Date: Sun, 23 Feb 2020 09:44:52 +0200 Subject: python In-Reply-To: <10593548-6ae6-45f2-96c0-d4f36bf66e63@googlegroups.com> References: <10593548-6ae6-45f2-96c0-d4f36bf66e63@googlegroups.com> Message-ID: <444a92af-2898-f810-9869-54b38948fd71@chagford.com> On 2020-02-23 9:26 AM, luka beria wrote: > hi guys i have another question.how to find the minimum and maximum numbers in this list without using the min () and max () functions use while loop > Hi Luka Did you read the reply to your previous question from Dennis Lee Bieber? If not, here it is again - """ This smells like a homework assignment. We do NOT provide solutions to homework. In particular, we will not provide you with an algorithm to solve such a simple problem. We WILL provide help with Python syntax and semantics, but YOU need to provide a starting point of what you've tried, what the results are, and what you expected for the results. Suggestion: pretend you are the computer. Use a piece of paper to track current MAX and current MIN. You get one item from the list at a time -- how do you determine if it is to become a new MAX, a new MIN, or is ignored as neither. Now -- write a program does just that... """ Try his suggestion, and come back here if you get stuck. Frank Millman From souvik.viksou at gmail.com Sun Feb 23 03:05:40 2020 From: souvik.viksou at gmail.com (Souvik Dutta) Date: Sun, 23 Feb 2020 13:35:40 +0530 Subject: python In-Reply-To: <10593548-6ae6-45f2-96c0-d4f36bf66e63@googlegroups.com> References: <10593548-6ae6-45f2-96c0-d4f36bf66e63@googlegroups.com> Message-ID: Try it yourself first. It is very easy. On Sun, Feb 23, 2020, 1:00 PM luka beria wrote: > hi guys i have another question.how to find the minimum and maximum > numbers in this list without using the min () and max () functions use > while loop > -- > https://mail.python.org/mailman/listinfo/python-list > From grant.b.edwards at gmail.com Sun Feb 23 10:52:25 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Sun, 23 Feb 2020 15:52:25 -0000 (UTC) Subject: python References: <5e517383$0$20331$426a74cc@news.free.fr> Message-ID: On 2020-02-22, Python wrote: > lberia460 at gmail.com wrote: >> hi guys can you help me.how to find maximum and minimum in list using while loop python > > l = [1, 4, 2, -1, 0, 4, 2, 1, 10] > for i in range(100): > pass > > maximum = max(l) > minimum = min(l) The requirement is to use a _while_ loop: l = [1, 4, 2, -1, 0, 4, 2, 1, 10] while True: maximum = max(l) minimum = min(l) break From PythonList at DancesWithMice.info Sun Feb 23 16:41:54 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Mon, 24 Feb 2020 10:41:54 +1300 Subject: Help with oop In-Reply-To: References: Message-ID: <81c4eae3-326c-ced7-7582-b0385603b26e@DancesWithMice.info> On 22/02/20 10:45 PM, S Y wrote: > How can I use remove,add and verify methods in class oop. Which has tuple with allowed values inside class. Like two classes cart and inventory Please show the code you have so-far. What are you removing, adding, and verifying? Are you aware of the Python-Tutor Discussion List? -- Regards =dn From PythonList at DancesWithMice.info Sun Feb 23 17:22:27 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Mon, 24 Feb 2020 11:22:27 +1300 Subject: Help with oop In-Reply-To: References: <81c4eae3-326c-ced7-7582-b0385603b26e@DancesWithMice.info> Message-ID: On 24/02/20 10:45 AM, S Y wrote: > """ The class Baggage will track inventory items added to or removed > from it. Inventory items will be represented by > inventory item objects created using the ?InventoryItem? class. When an > attempt is made to add an inventory > item to a Baggage object, the number of items in the Baggage object is > compared with maximum capacity and > allowable items. If space is left and the item is allowed, the item is > added, otherwise, the class returns a response indicating failure with a > short reason why""" > class Baggage: > ?#Constructor - sets initial values for all object attributes. > ?def __init__(self,capacity, inventory= [],allow_items=()): > ?self.inventory = [] > ?self.capacity = 5 > ?self.allow_items = ( ... > ?#Adds an item object to the Baggage object after checking that the mx > capacity has not been reached (i.e. 5 items) > ?def add_item(self, item_object): > ?if len(self.inventory) <= self.capacity: > ?self.inventory.append(item_object) > ?return True > ?else: > ?print("Reached max capacity") > ?return False > on behalf of DL > Neil via Python-list > *Sent:* Sunday, February 23, 2020 4:41:54 PM > *To:* python-list at python.org > *Subject:* Re: Help with oop > On 22/02/20 10:45 PM, S Y wrote: >> How can I use remove,add and verify methods in class oop. Which has tuple with allowed values inside class. Like two classes cart and inventory > > Please show the code you have so-far. > What are you removing, adding, and verifying? > Are you aware of the Python-Tutor Discussion List? Given that the data-structure is a list, perhaps list.remove()? What is the relevance of Baggage.allow_items()? Sorry to be nagging you but perhaps take a look at how Discussion Lists work: - top/bottom posting, ie not answer then question, - replying to list (not individual) so that others may also benefit, - formatting and readability (cf 'Microsoft makes it look nice because they know better than you') WebRef: 5. Data Structures? https://docs.python.org/3/tutorial/datastructures.html -- Regards =dn From PythonList at DancesWithMice.info Sun Feb 23 17:45:52 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Mon, 24 Feb 2020 11:45:52 +1300 Subject: Managing plug-ins Message-ID: <5f6a0ccf-7210-d0ec-463a-644232201c8b@etelligence.info> Please recommend a library which will manage plug-ins. (Regret that searching PyPi or using a web SE results in an overwhelming number of 'false positives') Not wanting to 'reinvent the wheel, have been looking for an 'approved' way to manage a set of previously-prepared routines plus user-added functionality: - user selects particular type of analysis (cmdLN) - take that string and convert to a function/method - 'plug-in' code could be located within application - 'plug-in' could be 'included' from user - interface standardisation/checking not part of question - Python3 Application is statistical analysis. Users want to control aspects such as data selection/inclusion policies, other data pre-processing/massaging, distribution curve to be applied, and similar. NB not looking for stats-code, but to easily manage a range of plug-ins from which users may select to suit their particular research objective. -- Regards, =dn From souvik.viksou at gmail.com Mon Feb 24 11:02:36 2020 From: souvik.viksou at gmail.com (Souvik Dutta) Date: Mon, 24 Feb 2020 21:32:36 +0530 Subject: How to get a place's longitude and latitude? Message-ID: Hi guys I want to make a program that kinda sends an sos message with the measures of longitude and latitude (which is super inconvenient) to someone. How can I do that I mean how can I get the longitude and latitude? Any help would be appreciated. From arj.python at gmail.com Mon Feb 24 11:06:41 2020 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Mon, 24 Feb 2020 20:06:41 +0400 Subject: How to get a place's longitude and latitude? In-Reply-To: References: Message-ID: On phone? On Mon, 24 Feb 2020, 20:02 Souvik Dutta, wrote: > Hi guys I want to make a program that kinda sends an sos message with the > measures of longitude and latitude (which is super inconvenient) to > someone. How can I do that I mean how can I get the longitude and latitude? > Any help would be appreciated. > -- > https://mail.python.org/mailman/listinfo/python-list > From rosuav at gmail.com Mon Feb 24 11:07:35 2020 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 25 Feb 2020 03:07:35 +1100 Subject: How to get a place's longitude and latitude? In-Reply-To: References: Message-ID: On Tue, Feb 25, 2020 at 3:04 AM Souvik Dutta wrote: > > Hi guys I want to make a program that kinda sends an sos message with the > measures of longitude and latitude (which is super inconvenient) to > someone. How can I do that I mean how can I get the longitude and latitude? > Any help would be appreciated. This is a difficult thing to do in general, so you're going to have to get specific. Are you building a desktop app? A phone app? Is it something that runs via a web browser? What sort of platform are you using, and are you okay with requiring the user to do some configuration beforehand in order to have an easy one-click "send help now"? ChrisA From aakashjana2002 at gmail.com Mon Feb 24 11:08:29 2020 From: aakashjana2002 at gmail.com (Aakash Jana) Date: Mon, 24 Feb 2020 21:38:29 +0530 Subject: How to get a place's longitude and latitude? In-Reply-To: References: Message-ID: You might use webscraping with requests and beautiful soup to scrape up some website for that gives such utility On Mon, 24 Feb 2020, 9:36 pm Souvik Dutta Hi guys I want to make a program that kinda sends an sos message with the > measures of longitude and latitude (which is super inconvenient) to > someone. How can I do that I mean how can I get the longitude and latitude? > Any help would be appreciated. > -- > https://mail.python.org/mailman/listinfo/python-list > From arj.python at gmail.com Mon Feb 24 11:11:19 2020 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Mon, 24 Feb 2020 20:11:19 +0400 Subject: How to get a place's longitude and latitude? In-Reply-To: References: Message-ID: Ever heard of QPython? It has a sl4a Api http://edu.qpython.org/qsl4a-develop/index.html?form=web You can pull in GPS coordinates! On Mon, 24 Feb 2020, 20:07 Souvik Dutta, wrote: > Yes. > > On Mon, 24 Feb, 2020, 9:36 pm Abdur-Rahmaan Janhangeer, < > arj.python at gmail.com> wrote: > >> On phone? >> >> On Mon, 24 Feb 2020, 20:02 Souvik Dutta, wrote: >> >>> Hi guys I want to make a program that kinda sends an sos message with the >>> measures of longitude and latitude (which is super inconvenient) to >>> someone. How can I do that I mean how can I get the longitude and >>> latitude? >>> Any help would be appreciated. >>> -- >>> https://mail.python.org/mailman/listinfo/python-list >>> >> From joel.goldstick at gmail.com Mon Feb 24 11:12:51 2020 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Mon, 24 Feb 2020 11:12:51 -0500 Subject: How to get a place's longitude and latitude? In-Reply-To: References: Message-ID: On Mon, Feb 24, 2020 at 11:10 AM Aakash Jana wrote: > > You might use webscraping with requests and beautiful soup to scrape up > some website for that gives such utility > > > On Mon, 24 Feb 2020, 9:36 pm Souvik Dutta > > Hi guys I want to make a program that kinda sends an sos message with the > > measures of longitude and latitude (which is super inconvenient) to > > someone. How can I do that I mean how can I get the longitude and latitude? > > Any help would be appreciated. > > -- > > https://mail.python.org/mailman/listinfo/python-list > > > -- > https://mail.python.org/mailman/listinfo/python-list I found this article for using a raspberry pi and a gps card. It might give you some ideas: https://tutorials-raspberrypi.com/build-raspberry-pi-gps-location-navigation-device/ -- Joel Goldstick http://joelgoldstick.com/blog http://cc-baseballstats.info/stats/birthdays From walkerqt at gmail.com Mon Feb 24 08:18:17 2020 From: walkerqt at gmail.com (qbit) Date: Mon, 24 Feb 2020 05:18:17 -0800 (PST) Subject: time.localtime add a parameter for timezone Message-ID: How about adding a time zone parameter to time.localtime? A offset just like the form: ? hh[:mm[:ss]]. From legaulph at gmail.com Mon Feb 24 12:16:49 2020 From: legaulph at gmail.com (legaulph at gmail.com) Date: Mon, 24 Feb 2020 12:16:49 -0500 Subject: How to get a place's longitude and latitude? In-Reply-To: References: Message-ID: <03f901d5eb36$338170a0$9a8451e0$@gmail.com> Try something like import requests import json url = "https://nominatim.openstreetmap.org/search.php?q=city+country&format=json&l imit=1" result = requests.get(url) dataobj = result.json() x = dataobj[0]['lat'] + "," + dataobj[0]['lon'] print(x) -----Original Message----- From: Python-list On Behalf Of Aakash Jana Sent: Monday, February 24, 2020 11:08 AM To: Souvik Dutta Cc: python-list at python.org Subject: Re: How to get a place's longitude and latitude? You might use webscraping with requests and beautiful soup to scrape up some website for that gives such utility On Mon, 24 Feb 2020, 9:36 pm Souvik Dutta Hi guys I want to make a program that kinda sends an sos message with > the measures of longitude and latitude (which is super inconvenient) > to someone. How can I do that I mean how can I get the longitude and latitude? > Any help would be appreciated. > -- > https://mail.python.org/mailman/listinfo/python-list > -- https://mail.python.org/mailman/listinfo/python-list From dieter at handshake.de Mon Feb 24 12:21:29 2020 From: dieter at handshake.de (Dieter Maurer) Date: Mon, 24 Feb 2020 18:21:29 +0100 Subject: time.localtime add a parameter for timezone In-Reply-To: References: Message-ID: <24148.1561.992531.425307@ixdm.fritz.box> qbit wrote at 2020-2-24 05:18 -0800: >How about adding a time zone parameter to time.localtime? > >A offset just like the form: ? hh[:mm[:ss]]. Why should this be necessary? `localtime` returns the time in the "local timezone" -- and the "local timezone" usually does not change between different calls to `localtime`. Thus, it is best not to pass the timezone to each call to `localtime` but use environment information. If your "local timezone" does change frequently, you have (at least) the following options: * use `time.tzset` to reset the internal variables used by `localtime` from the envvar `TZ` (which your have appropriately set earlier) * use `time.time` (instead of `time.localtime`) and add the offset yourself. `time.time` returns the UTC time. -- Dieter From rhodri at kynesim.co.uk Mon Feb 24 12:43:58 2020 From: rhodri at kynesim.co.uk (Rhodri James) Date: Mon, 24 Feb 2020 17:43:58 +0000 Subject: time.localtime add a parameter for timezone In-Reply-To: <24148.1561.992531.425307@ixdm.fritz.box> References: <24148.1561.992531.425307@ixdm.fritz.box> Message-ID: <9b0d96eb-9fd9-a31d-e4b3-4d21245aa708@kynesim.co.uk> On 24/02/2020 17:21, Dieter Maurer wrote: > qbit wrote at 2020-2-24 05:18 -0800: >> How about adding a time zone parameter to time.localtime? >> >> A offset just like the form: ? hh[:mm[:ss]]. > > Why should this be necessary? `localtime` returns the time > in the "local timezone" -- and the "local timezone" usually > does not change between different calls to `localtime`. It can if your calls to localtime() happen either side of a daylight saving time switch. That said, I agree that the timezone doesn't really belong in the output of localtime(). There are a very few occasions when you want it, but more often you should be working in UTC not local time. -- Rhodri James *-* Kynesim Ltd From none at invalid.com Mon Feb 24 16:29:17 2020 From: none at invalid.com (mm0fmf) Date: Mon, 24 Feb 2020 21:29:17 +0000 Subject: Tkinter layout designer Message-ID: Can anyone recommend a graphic layout designer for Tkinter programs. I have a number of older C# Windows Forms apps that need porting so they can run on Linux and Windows and this is the chance to re-write them in Python. However, after using the forms designer in Visual Studio, manually coding up the widget positions etc. is a real pain in the backside. So please, recommendations for a designer that is usable and functional please to save me working through everything a Google search throws up. Thanks, Andy From auriocus at gmx.de Tue Feb 25 01:32:47 2020 From: auriocus at gmx.de (Christian Gollwitzer) Date: Tue, 25 Feb 2020 07:32:47 +0100 Subject: Tkinter layout designer In-Reply-To: References: Message-ID: Am 24.02.20 um 22:29 schrieb mm0fmf: > Can anyone recommend a graphic layout designer for Tkinter programs. There is no such thing for Tkinter. There is an outdated designer for Tk called Visual Tcl, but it can generate only Tcl code, not TkInter, and uses only old-style widgets. > I > have a number of older C# Windows Forms apps that need porting so they > can run on Linux and Windows and this is the chance to re-write them in > Python. However, after using the forms designer in Visual Studio, > manually coding up the widget positions etc. is a real pain in the > backside > So please, recommendations for a designer that is usable and functional > please to save me working through everything a Google search throws up. If you want a designer, use QT, which brings the Qt Designer. Be careful though - if you misuse them, you can end up with inflexible GUIs, where changes in the font or display resolution can mess up your interface. Always test that your windows act sensibly upon resizing. Christian From souvik.viksou at gmail.com Tue Feb 25 02:06:35 2020 From: souvik.viksou at gmail.com (Souvik Dutta) Date: Tue, 25 Feb 2020 12:36:35 +0530 Subject: Tkinter layout designer In-Reply-To: References: Message-ID: There is one called PAGES On Tue, Feb 25, 2020, 12:05 PM Christian Gollwitzer wrote: > Am 24.02.20 um 22:29 schrieb mm0fmf: > > Can anyone recommend a graphic layout designer for Tkinter programs. > > There is no such thing for Tkinter. There is an outdated designer for Tk > called Visual Tcl, but it can generate only Tcl code, not TkInter, and > uses only old-style widgets. > > > I > > have a number of older C# Windows Forms apps that need porting so they > > can run on Linux and Windows and this is the chance to re-write them in > > Python. However, after using the forms designer in Visual Studio, > > manually coding up the widget positions etc. is a real pain in the > > backside > > > So please, recommendations for a designer that is usable and functional > > please to save me working through everything a Google search throws up. > > > If you want a designer, use QT, which brings the Qt Designer. Be careful > though - if you misuse them, you can end up with inflexible GUIs, where > changes in the font or display resolution can mess up your interface. > Always test that your windows act sensibly upon resizing. > > Christian > -- > https://mail.python.org/mailman/listinfo/python-list > From nulla.epistola at web.de Tue Feb 25 03:26:29 2020 From: nulla.epistola at web.de (Sibylle Koczian) Date: Tue, 25 Feb 2020 09:26:29 +0100 Subject: Tkinter layout designer In-Reply-To: References: Message-ID: <93108354-0420-2c16-c0fd-d2cce7f1498b@web.de> Am 25.02.2020 um 07:32 schrieb Christian Gollwitzer: > Am 24.02.20 um 22:29 schrieb mm0fmf: >> Can anyone recommend a graphic layout designer for Tkinter programs. > >> I have a number of older C# Windows Forms apps that need porting so >> they can run on Linux and Windows and this is the chance to re-write >> them in Python. However, after using the forms designer in Visual >> Studio, manually coding up the widget positions etc. is a real pain in >> the backside > > If you want a designer, use QT, which brings the Qt Designer. Be careful > though - if you misuse them, you can end up with inflexible GUIs, where > changes in the font or display resolution can mess up your interface. > Always test that your windows act sensibly upon resizing. > Coming from Windows Forms this is especially important. Windows Forms doesn't have a sensible geometry manager. Tkinter and PyQt / PySide both have them, and it's quite a change at first. But in the long run it's much more comfortable to put your controls into layouts (or pack / grid them - tkinter) instead of placing each and every thing yourself. Greetings Sibylle From nulla.epistola at web.de Tue Feb 25 03:26:29 2020 From: nulla.epistola at web.de (Sibylle Koczian) Date: Tue, 25 Feb 2020 09:26:29 +0100 Subject: Tkinter layout designer In-Reply-To: References: Message-ID: <93108354-0420-2c16-c0fd-d2cce7f1498b@web.de> Am 25.02.2020 um 07:32 schrieb Christian Gollwitzer: > Am 24.02.20 um 22:29 schrieb mm0fmf: >> Can anyone recommend a graphic layout designer for Tkinter programs. > >> I have a number of older C# Windows Forms apps that need porting so >> they can run on Linux and Windows and this is the chance to re-write >> them in Python. However, after using the forms designer in Visual >> Studio, manually coding up the widget positions etc. is a real pain in >> the backside > > If you want a designer, use QT, which brings the Qt Designer. Be careful > though - if you misuse them, you can end up with inflexible GUIs, where > changes in the font or display resolution can mess up your interface. > Always test that your windows act sensibly upon resizing. > Coming from Windows Forms this is especially important. Windows Forms doesn't have a sensible geometry manager. Tkinter and PyQt / PySide both have them, and it's quite a change at first. But in the long run it's much more comfortable to put your controls into layouts (or pack / grid them - tkinter) instead of placing each and every thing yourself. Greetings Sibylle From blindanagram at nowhere.com Tue Feb 25 07:38:36 2020 From: blindanagram at nowhere.com (BlindAnagram) Date: Tue, 25 Feb 2020 12:38:36 +0000 Subject: encapsulating a global variable Message-ID: I would appreciate advice on whether it is possible to avoid the use of a global variable used in a function by encapsulating it in a class without maaking any changes to the call interface (which I cannot change). I have: ---------------- seen = dict() def get_it(piece): ... return seen[piece] ---------------- and I am wondering if it is possible to use a class something like ---------------- class get_it(object): seen = dict() def __call__(piece): return seen[piece] ---------------- to avoid the global variable. Brian Gladman From rosuav at gmail.com Tue Feb 25 07:56:27 2020 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 25 Feb 2020 23:56:27 +1100 Subject: encapsulating a global variable In-Reply-To: References: Message-ID: On Tue, Feb 25, 2020 at 11:41 PM BlindAnagram wrote: > > I would appreciate advice on whether it is possible to avoid the use of > a global variable used in a function by encapsulating it in a class > without maaking any changes to the call interface (which I cannot change). Why bother? If you aren't changing where the function's called, then its state is effectively global anyway, so what's the point of the class? ChrisA From musbur at posteo.org Tue Feb 25 07:50:43 2020 From: musbur at posteo.org (Musbur) Date: Tue, 25 Feb 2020 13:50:43 +0100 Subject: encapsulating a global variable Message-ID: <0156cd74837f4a9a8afba3f0e086d8f5@posteo.de> Am 25.02.2020 13:38 schrieb BlindAnagram: > and I am wondering if it is possible to use a class something like > > class get_it(object): > > seen = dict() > > def __call__(piece): > return seen[piece] What happened when you tried it? From blindanagram at nowhere.com Tue Feb 25 08:09:27 2020 From: blindanagram at nowhere.com (BlindAnagram) Date: Tue, 25 Feb 2020 13:09:27 +0000 Subject: encapsulating a global variable In-Reply-To: References: Message-ID: On 25/02/2020 12:56, Chris Angelico wrote: > On Tue, Feb 25, 2020 at 11:41 PM BlindAnagram wrote: >> >> I would appreciate advice on whether it is possible to avoid the use of >> a global variable used in a function by encapsulating it in a class >> without maaking any changes to the call interface (which I cannot change). > > Why bother? If you aren't changing where the function's called, then > its state is effectively global anyway, so what's the point of the > class? It's a good question! The main reason is that I would like to know if it is possible as I then have a choice. The choice might not be there. Brian From blindanagram at nowhere.com Tue Feb 25 09:06:58 2020 From: blindanagram at nowhere.com (BlindAnagram) Date: Tue, 25 Feb 2020 14:06:58 +0000 Subject: encapsulating a global variable In-Reply-To: References: <0156cd74837f4a9a8afba3f0e086d8f5@posteo.de> Message-ID: On 25/02/2020 12:50, Musbur wrote: > > Am 25.02.2020 13:38 schrieb BlindAnagram: >> and I am wondering if it is possible to use a class something like >> >> class get_it(object): >> >> ? seen = dict() >> >> ? def __call__(piece): >> ??? return seen[piece] > > What happened when you tried it? The nearest I got was: ------------------------- class orientate(object): seen = defaultdict() @classmethod def do(self, piece, two_sided=False): ------------------------ which works but requires a change to the function call interface from orientate(piece) to orientate.do(piece). I was hoping that repalcing the above with: ------------------------- class orientate(object): seen = defaultdict() @classmethod def __call__(self, piece, two_sided=False): ------------------------ would eliminate the need for the 'do' but this gives the error: builtins.TypeError: orientate() takes no arguments Brian From rosuav at gmail.com Tue Feb 25 09:13:57 2020 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 26 Feb 2020 01:13:57 +1100 Subject: encapsulating a global variable In-Reply-To: References: Message-ID: On Wed, Feb 26, 2020 at 12:11 AM BlindAnagram wrote: > > On 25/02/2020 12:56, Chris Angelico wrote: > > On Tue, Feb 25, 2020 at 11:41 PM BlindAnagram wrote: > >> > >> I would appreciate advice on whether it is possible to avoid the use of > >> a global variable used in a function by encapsulating it in a class > >> without maaking any changes to the call interface (which I cannot change). > > > > Why bother? If you aren't changing where the function's called, then > > its state is effectively global anyway, so what's the point of the > > class? > > It's a good question! > > The main reason is that I would like to know if it is possible as I then > have a choice. The choice might not be there. > Well, yes, you can, but you would need a global instance of that class (or use the global class object itself). So you'd still have a global. But if this is a transitional thing, then the answer is a resounding YES. You can start by packaging up all your state with a class, and have a single global instance of that class; but then you can rework your function to take an optional parameter which is a non-global instance of the class. Then all your state is kept in there, and you actually truly *do* avoid global state. As a good example of how this works, check out Python's random module - you can call random.randrange() to get a random number in a particular range, or you can instantiate your own random.Random() object and call its randrange() method. The first form uses global state; the second form doesn't. ChrisA From rhodri at kynesim.co.uk Tue Feb 25 09:14:54 2020 From: rhodri at kynesim.co.uk (Rhodri James) Date: Tue, 25 Feb 2020 14:14:54 +0000 Subject: encapsulating a global variable In-Reply-To: References: Message-ID: <5f52945b-c0f9-bbfa-2afb-9be5364941eb@kynesim.co.uk> On 25/02/2020 12:38, BlindAnagram wrote: > I would appreciate advice on whether it is possible to avoid the use of > a global variable used in a function by encapsulating it in a class > without maaking any changes to the call interface (which I cannot change). > > I have: > > ---------------- > seen = dict() > > def get_it(piece): > ... > return seen[piece] > ---------------- > > and I am wondering if it is possible to use a class something like > > ---------------- > class get_it(object): > > seen = dict() > > def __call__(piece): > return seen[piece] > ---------------- > > to avoid the global variable. I wouldn't. Calling the class name creates an instance of the class, so won't actually do what you want. You could rewrite the class and create an instance to call instead: class GetIt: seen = dict() def __call__(self, piece): return GetIt.seen[piece] get_it = GetIt() but then you have a global class instance hanging around, which is not actually any better than a global dictionary. -- Rhodri James *-* Kynesim Ltd From hjp-python at hjp.at Tue Feb 25 09:26:42 2020 From: hjp-python at hjp.at (Peter J. Holzer) Date: Tue, 25 Feb 2020 15:26:42 +0100 Subject: time.localtime add a parameter for timezone In-Reply-To: <9b0d96eb-9fd9-a31d-e4b3-4d21245aa708@kynesim.co.uk> References: <24148.1561.992531.425307@ixdm.fritz.box> <9b0d96eb-9fd9-a31d-e4b3-4d21245aa708@kynesim.co.uk> Message-ID: <20200225142642.GA640@hjp.at> On 2020-02-24 17:43:58 +0000, Rhodri James wrote: > On 24/02/2020 17:21, Dieter Maurer wrote: > > qbit wrote at 2020-2-24 05:18 -0800: > > > How about adding a time zone parameter to time.localtime? > > > > > > A offset just like the form: ? hh[:mm[:ss]]. > > > > Why should this be necessary? `localtime` returns the time > > in the "local timezone" -- and the "local timezone" usually > > does not change between different calls to `localtime`. > > It can if your calls to localtime() happen either side of a daylight saving > time switch. > > That said, I agree that the timezone doesn't really belong in the output of > localtime(). I think it does (that POSIX omits it (and only includes the rather useless tm_isdst) is a historical oversight which was unfortunately never corrected). However, it doesn't have to be added, since it is already there: https://docs.python.org/3/library/time.html#time.struct_time 1084% python3 Python 3.6.9 (default, Nov 7 2019, 10:44:02) [GCC 8.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import time >>> t = time.localtime() >>> t.tm_gmtoff 3600 >>> t.tm_zone 'CET' However, this not a parameter but a field of the return value. I'm not sure what a parameter would do: Return the broken-down time for the specified timezone? If so, an offset is not sufficient: It needs to be a timezone name (something like "Europe/Vienna"). Proper general handling of timezones should probably be in datetime. > There are a very few occasions when you want it, but more often you > should be working in UTC not local time. If you are working in UTC, you don't need localtime(). 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 blindanagram at nowhere.com Tue Feb 25 09:56:52 2020 From: blindanagram at nowhere.com (BlindAnagram) Date: Tue, 25 Feb 2020 14:56:52 +0000 Subject: encapsulating a global variable In-Reply-To: References: <5f52945b-c0f9-bbfa-2afb-9be5364941eb@kynesim.co.uk> Message-ID: On 25/02/2020 14:14, Rhodri James wrote: > On 25/02/2020 12:38, BlindAnagram wrote: >> I would appreciate advice on whether it is possible to avoid the use of >> a global variable used in a function by encapsulating it in a class >> without maaking any changes to the call interface (which I cannot >> change). >> >> I have: >> >> ---------------- >> seen = dict() >> >> def get_it(piece): >> ??? ... >> ??? return seen[piece] >> ---------------- >> >> and I am wondering if it is possible to use a class something like >> >> ---------------- >> class get_it(object): >> >> ?? seen = dict() >> >> ?? def __call__(piece): >> ???? return seen[piece] >> ---------------- >> >> to avoid the global variable. > > I wouldn't.? Calling the class name creates an instance of the class, so > won't actually do what you want.? You could rewrite the class and create > an instance to call instead: > > class GetIt: > ? seen = dict() > > ? def __call__(self, piece): > ??? return GetIt.seen[piece] > > get_it = GetIt() > > but then you have a global class instance hanging around, which is not > actually any better than a global dictionary. Thanks. Does that not have the advantage of preventing the global directory being directly fiddled with elsewhere? Which is one of my reasons for thinking about this. Brian From blindanagram at nowhere.com Tue Feb 25 10:06:30 2020 From: blindanagram at nowhere.com (BlindAnagram) Date: Tue, 25 Feb 2020 15:06:30 +0000 Subject: encapsulating a global variable In-Reply-To: References: Message-ID: On 25/02/2020 14:13, Chris Angelico wrote: > On Wed, Feb 26, 2020 at 12:11 AM BlindAnagram wrote: >> >> On 25/02/2020 12:56, Chris Angelico wrote: >>> On Tue, Feb 25, 2020 at 11:41 PM BlindAnagram wrote: >>>> >>>> I would appreciate advice on whether it is possible to avoid the use of >>>> a global variable used in a function by encapsulating it in a class >>>> without maaking any changes to the call interface (which I cannot change). >>> >>> Why bother? If you aren't changing where the function's called, then >>> its state is effectively global anyway, so what's the point of the >>> class? >> >> It's a good question! >> >> The main reason is that I would like to know if it is possible as I then >> have a choice. The choice might not be there. >> > > Well, yes, you can, but you would need a global instance of that class > (or use the global class object itself). So you'd still have a global. > > But if this is a transitional thing, then the answer is a resounding > YES. You can start by packaging up all your state with a class, and > have a single global instance of that class; but then you can rework > your function to take an optional parameter which is a non-global > instance of the class. Then all your state is kept in there, and you > actually truly *do* avoid global state. As a good example of how this > works, check out Python's random module - you can call > random.randrange() to get a random number in a particular range, or > you can instantiate your own random.Random() object and call its > randrange() method. The first form uses global state; the second form > doesn't. Thanks, I think I understand most of this but the eample will help a lot. My interest in this stems from wanting to keep the dictionary only available to the function that uses it and also a worry about being called from threaded code. Brian From blindanagram at nowhere.com Tue Feb 25 10:20:39 2020 From: blindanagram at nowhere.com (BlindAnagram) Date: Tue, 25 Feb 2020 15:20:39 +0000 Subject: encapsulating a global variable In-Reply-To: References: <5f52945b-c0f9-bbfa-2afb-9be5364941eb@kynesim.co.uk> Message-ID: <86SdnQTPl7vapsjDnZ2dnUU78W-dnZ2d@brightview.co.uk> On 25/02/2020 14:14, Rhodri James wrote: > On 25/02/2020 12:38, BlindAnagram wrote: >> I would appreciate advice on whether it is possible to avoid the use of >> a global variable used in a function by encapsulating it in a class >> without maaking any changes to the call interface (which I cannot >> change). >> >> I have: >> >> ---------------- >> seen = dict() >> >> def get_it(piece): >> ??? ... >> ??? return seen[piece] >> ---------------- >> >> and I am wondering if it is possible to use a class something like >> >> ---------------- >> class get_it(object): >> >> ?? seen = dict() >> >> ?? def __call__(piece): >> ???? return seen[piece] >> ---------------- >> >> to avoid the global variable. > > I wouldn't.? Calling the class name creates an instance of the class, so > won't actually do what you want.? You could rewrite the class and create > an instance to call instead: > > class GetIt: > ? seen = dict() > > ? def __call__(self, piece): > ??? return GetIt.seen[piece] > > get_it = GetIt() > > but then you have a global class instance hanging around, which is not > actually any better than a global dictionary. This doesn't work for me since get_it(piece) returns the error: builtins.TypeError: get_it() takes no arguments Brian From rhodri at kynesim.co.uk Tue Feb 25 11:36:18 2020 From: rhodri at kynesim.co.uk (Rhodri James) Date: Tue, 25 Feb 2020 16:36:18 +0000 Subject: encapsulating a global variable In-Reply-To: <86SdnQTPl7vapsjDnZ2dnUU78W-dnZ2d@brightview.co.uk> References: <5f52945b-c0f9-bbfa-2afb-9be5364941eb@kynesim.co.uk> <86SdnQTPl7vapsjDnZ2dnUU78W-dnZ2d@brightview.co.uk> Message-ID: <12624652-efaf-0ed4-5279-f89bfb0b192d@kynesim.co.uk> On 25/02/2020 15:20, BlindAnagram wrote: >> class GetIt: >> ? seen = dict() >> >> ? def __call__(self, piece): >> ??? return GetIt.seen[piece] >> >> get_it = GetIt() >> >> but then you have a global class instance hanging around, which is not >> actually any better than a global dictionary. > This doesn't work for me since get_it(piece) returns the error: > > builtins.TypeError: get_it() takes no arguments It works for me (pace sticking something in GetIt.seen to avoid getting a KeyError). You aren't muddling up the class name and instance name are you? -- Rhodri James *-* Kynesim Ltd From blindanagram at nowhere.com Tue Feb 25 12:05:57 2020 From: blindanagram at nowhere.com (BlindAnagram) Date: Tue, 25 Feb 2020 17:05:57 +0000 Subject: encapsulating a global variable In-Reply-To: References: <5f52945b-c0f9-bbfa-2afb-9be5364941eb@kynesim.co.uk> <86SdnQTPl7vapsjDnZ2dnUU78W-dnZ2d@brightview.co.uk> <12624652-efaf-0ed4-5279-f89bfb0b192d@kynesim.co.uk> Message-ID: On 25/02/2020 16:36, Rhodri James wrote: > On 25/02/2020 15:20, BlindAnagram wrote: >>> class GetIt: >>> ?? seen = dict() >>> >>> ?? def __call__(self, piece): >>> ???? return GetIt.seen[piece] >>> >>> get_it = GetIt() >>> >>> but then you have a global class instance hanging around, which is not >>> actually any better than a global dictionary. >> This doesn't work for me since get_it(piece) returns the error: >> >> builtins.TypeError: get_it() takes no arguments > > It works for me (pace sticking something in GetIt.seen to avoid getting > a KeyError).? You aren't muddling up the class name and instance name > are you? Apologies, I misunderstoof your proposal - it woks fine now I have understood it Brian From dvl at psu.edu Tue Feb 25 12:16:18 2020 From: dvl at psu.edu (Christman, Roger Graydon) Date: Tue, 25 Feb 2020 17:16:18 +0000 Subject: encapsulating a global variable (BlindAnagram) Message-ID: > On Tue, 25 Feb 2020 3:06 PM BlindAnagram wrote: > My interest in this stems from wanting to keep the dictionary only > available to the function that uses it and also a worry about being > called from threaded code. It seems like the simplest solution for this is to make a completely new file (module) containing nothing but the dictionary and this one function that uses it. Then you can import the function from the module wherever it is called without importing the dictionary. The thing I find curious is that apparently no other function is allowed to create or populate the dictionary in the first place. Is it practical to have the entire dictionary statically defined? Roger Christman Pennsylvania State University From dieter at handshake.de Tue Feb 25 12:17:00 2020 From: dieter at handshake.de (Dieter Maurer) Date: Tue, 25 Feb 2020 18:17:00 +0100 Subject: encapsulating a global variable In-Reply-To: References: Message-ID: <24149.22156.38724.693449@ixdm.fritz.box> BlindAnagram wrote at 2020-2-25 12:38 +0000: >I would appreciate advice on whether it is possible to avoid the use of >a global variable used in a function by encapsulating it in a class >without maaking any changes to the call interface (which I cannot change). > >I have: > >---------------- >seen = dict() > >def get_it(piece): > ... > return seen[piece] >---------------- > >and I am wondering if it is possible to use a class something like > >---------------- >class get_it(object): > > seen = dict() > > def __call__(piece): > return seen[piece] >---------------- > >to avoid the global variable. Apparently, you are ready to change the function. In this case, you might be interested in `rebindFunction` from the package `dm.reuse`. Its primary purpose is to reuse a foreign function in one's own code with minor modifications. One of the supported minor modifications is to change globals seen by the function. From jfong at ms4.hinet.net Tue Feb 25 05:59:16 2020 From: jfong at ms4.hinet.net (jfong at ms4.hinet.net) Date: Tue, 25 Feb 2020 02:59:16 -0800 (PST) Subject: Tkinter layout designer In-Reply-To: References: Message-ID: <7d5a689b-6087-4908-8435-a8a71426c035@googlegroups.com> mm0fmf? 2020?2?25???? UTC+8??5?29?33???? > Can anyone recommend a graphic layout designer for Tkinter programs. I > have a number of older C# Windows Forms apps that need porting so they > can run on Linux and Windows and this is the chance to re-write them in > Python. However, after using the forms designer in Visual Studio, > manually coding up the widget positions etc. is a real pain in the > backside. > > So please, recommendations for a designer that is usable and functional > please to save me working through everything a Google search throws up. > > Thanks, > Andy Download PAGE here: https://sourceforge.net/projects/page/ --Jach From blindanagram at nowhere.com Tue Feb 25 13:10:37 2020 From: blindanagram at nowhere.com (BlindAnagram) Date: Tue, 25 Feb 2020 18:10:37 +0000 Subject: encapsulating a global variable (BlindAnagram) In-Reply-To: References: Message-ID: On 25/02/2020 17:16, Christman, Roger Graydon wrote: >> On Tue, 25 Feb 2020 3:06 PM BlindAnagram wrote: > >> My interest in this stems from wanting to keep the dictionary only >> available to the function that uses it and also a worry about being >> called from threaded code. > > It seems like the simplest solution for this is to make > a completely new file (module) containing nothing but > the dictionary and this one function that uses it. > Then you can import the function from the module > wherever it is called without importing the dictionary. > > The thing I find curious is that apparently no other > function is allowed to create or populate the dictionary > in the first place. Is it practical to have the entire > dictionary statically defined? The dictionary is a static variable of the function. It is updated by the function and must maintain values across function calls. Reading some more, it seems that I can create static function variables using attributes. Brian From none at invalid.com Tue Feb 25 13:23:41 2020 From: none at invalid.com (mm0fmf) Date: Tue, 25 Feb 2020 18:23:41 +0000 Subject: Tkinter layout designer In-Reply-To: References: Message-ID: I don't claim to be an expert on Windows Forms, I inherited the support role and have added the odd widget over the years. The apps work but scream that their UI has been incrementally arrived at by someone who was just tinkering. :-) Thanks for the suggestions, I'll give Page a try. From aakashjana2002 at gmail.com Tue Feb 25 15:45:39 2020 From: aakashjana2002 at gmail.com (Aakash Jana) Date: Wed, 26 Feb 2020 02:15:39 +0530 Subject: Difficulty in generating .exe from .py file Message-ID: I have made a simple web scraper that scrapes Wikipedia and prints some info on to the command line using requests and BeautifulSoup. Whenever I execute pyinstaller it gives an error "expected integer got type bytes" although the code runs perfectly. I am using python 3.8 From greg.ewing at canterbury.ac.nz Tue Feb 25 17:41:26 2020 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Wed, 26 Feb 2020 11:41:26 +1300 Subject: encapsulating a global variable In-Reply-To: References: Message-ID: On 26/02/20 4:06 am, BlindAnagram wrote: > My interest in this stems from wanting to keep the dictionary only > available to the function that uses it and also a worry about being > called from threaded code. Doing this won't make any difference to the way threaded code behaves. Threading problems need to be addressed by appropriate use of locks, etc. -- Greg From greg.ewing at canterbury.ac.nz Tue Feb 25 17:49:16 2020 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Wed, 26 Feb 2020 11:49:16 +1300 Subject: encapsulating a global variable In-Reply-To: References: <5f52945b-c0f9-bbfa-2afb-9be5364941eb@kynesim.co.uk> Message-ID: On 26/02/20 3:56 am, BlindAnagram wrote: > Does that not have the advantage of preventing the global > directory being directly fiddled with elsewhere? That depends on what you mean by "prevent". There is nothing to stop any code from directly accessing the .seen attribute of the class. It might make it less likely that someone will inadvertently write code that does this. If there will only ever be one instance of the dict, another approach would be to put it into a dedicated module together with the functions that access it. That will give you the same amount of protection, while ensuring that there really is only one instance, and making this fact clear to anyone reading the code. -- Greg From lukasz at langa.pl Tue Feb 25 19:56:59 2020 From: lukasz at langa.pl (=?utf-8?Q?=C5=81ukasz_Langa?=) Date: Wed, 26 Feb 2020 01:56:59 +0100 Subject: Python 3.8.2 and 3.9.0a4 are now available Message-ID: On behalf of the entire Python development community, and the currently serving Python release team in particular, I?m pleased to announce the release of two of the latest Python editions. Python 3.8.2 Python 3.8.2 is the second maintenance release of Python 3.8 and contains two months worth of bug fixes. Detailed information about all changes made in 3.8.2 can be found in its change log . Note that compared to 3.8.1, version 3.8.2 also contains the changes introduced in 3.8.2rc1 and 3.8.2rc2. The Python 3.8 series is the newest feature release of the Python language, and it contains many new features and optimizations. You can find Python 3.8.2 here: https://www.python.org/downloads/release/python-382/ See the ?What?s New in Python 3.8 ? document for more information about features included in the 3.8 series. Maintenance releases for the 3.8 series will continue at regular bi-monthly intervals, with 3.8.3 planned for April 2020 (at the PyCon US sprints ). Python 3.9.0a4 An early developer preview of Python 3.9 is also ready: https://www.python.org/downloads/release/python-390a4/ Python 3.9 is still in development. This releasee, 3.9.0a4 is the fourth of six planned alpha releases. Alpha releases are intended to make it easier to test the current state of new features and bug fixes and to test the release process. During the alpha phase, features may be added up until the start of the beta phase (2020-05-18) and, if necessary, may be modified or deleted up until the release candidate phase (2020-08-10). Please keep in mind that this is a preview release and its use is not recommended for production environments. We hope you enjoy both! Thanks to all of the many volunteers who help make Python Development and these releases possible! Please consider supporting our efforts by volunteering yourself or through organization contributions to the Python Software Foundation. https://www.python.org/psf/ Your friendly release team, Ned Deily Steve Dower ?ukasz Langa From arj.python at gmail.com Wed Feb 26 02:08:16 2020 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Wed, 26 Feb 2020 11:08:16 +0400 Subject: Difficulty in generating .exe from .py file In-Reply-To: References: Message-ID: Can you share your codes? Thank you! On Wed, 26 Feb 2020, 00:45 Aakash Jana, wrote: > I have made a simple web scraper that scrapes Wikipedia and prints some > info on to the command line using requests and BeautifulSoup. Whenever I > execute pyinstaller it gives an error "expected integer got type bytes" > although the code runs perfectly. I am using python 3.8 > -- > https://mail.python.org/mailman/listinfo/python-list > From rhodri at kynesim.co.uk Wed Feb 26 08:59:30 2020 From: rhodri at kynesim.co.uk (Rhodri James) Date: Wed, 26 Feb 2020 13:59:30 +0000 Subject: encapsulating a global variable In-Reply-To: References: Message-ID: <0964100a-63ca-71bf-da2c-d29d688f71b8@kynesim.co.uk> On 25/02/2020 15:06, BlindAnagram wrote: > My interest in this stems from wanting to keep the dictionary only > available to the function that uses it and also a worry about being > called from threaded code. Hiding your dictionary away inside a class or instance isn't going to protect it from threading disasters by itself, though it will make it easier to protect it as you need. -- Rhodri James *-* Kynesim Ltd From prakashsamal0105 at gmail.com Wed Feb 26 00:32:58 2020 From: prakashsamal0105 at gmail.com (Prakash Samal) Date: Tue, 25 Feb 2020 21:32:58 -0800 (PST) Subject: Need Help Urgently Message-ID: [ABCD client error]: Connection to broker at ?126.0.0.1:0000 lost! "timestamp":"Wed Feb 19 11:48:41 [XYZ]: Connection to broker at ?126.0.0.1:0000 lost! "timestamp":"Wed Feb 19 11:48:40 Note: I want to read the error code i.e ABCD Client error from the line and also wrt timestamp value. Let me know how to do? From mal at europython.eu Wed Feb 26 11:50:03 2020 From: mal at europython.eu (M.-A. Lemburg) Date: Wed, 26 Feb 2020 17:50:03 +0100 Subject: EuroPython 2020: Call for Proposals opens on March 9th Message-ID: We are happy to announce that the Call for Proposals will open on March 9. It will be left open for three weeks and then close on: Sunday, March 29 23:59:59 CEST While you wait for submissions to open, please check out the Call for Proposals details on our pre-launch website: https://ep2020.europython.eu/call-for-proposals/ We?re looking for proposals on every aspect of Python: all levels of programming from novice to advanced, applications, frameworks, data science, Python projects, internals or topics which you?re excited about, your experiences with Python and its ecosystem, creative or artistic things you?ve done with Python, to name a few. EuroPython is a community conference and we are eager to hear about your use of Python. Since feedback shows that our audience is very interested in advanced topics, we?d appreciate more entries in this category for EuroPython 2020. Please help spread word about Call for Proposals to anyone who might be interested. Thanks. Some additional updates: ------------------------ - We?re working on launching the website, CfP and ticket sales in March. - We are also preparing the sponsorship packages and should have them ready early in March as well. Early bird sponsors will again receive a 10% discount on the package price. If you?re interested in becoming a launch sponsor, please contact our sponsor team at sponsoring at europython.eu. Help spread the word -------------------- Please help us spread this message by sharing it on your social networks as widely as possible. Thank you ! Link to the blog post: https://blog.europython.eu/post/611042486524280832/europython-2020-call-for-proposals-opens-on-march Tweet: https://twitter.com/europython/status/1232708258525302784 Enjoy, -- EuroPython 2020 Team https://ep2020.europython.eu/ https://www.europython-society.org/ From bgailer at gmail.com Wed Feb 26 12:21:29 2020 From: bgailer at gmail.com (Bob Gailer) Date: Wed, 26 Feb 2020 12:21:29 -0500 Subject: Need Help Urgently In-Reply-To: References: Message-ID: On Feb 26, 2020 10:56 AM, "Prakash Samal" wrote: > > [ABCD client error]: Connection to broker at 126.0.0.1:0000 lost! > "timestamp":"Wed Feb 19 11:48:41 > > [XYZ]: Connection to broker at 126.0.0.1:0000 lost! > "timestamp":"Wed Feb 19 11:48:40 > > Note: I want to read the error code i.e ABCD Client error from the line and also wrt timestamp value. First a couple of pointers to help you get the results you want in future communications. Use a meaningful subject rather than help. Why? Because we keep track of a communication thread by the subject. It also helps us decide whether or not we can even tackle that particular problem. Send such requests to tutor at python.org. Understand that urgency on your part does not translate to urgency on our part. We are volunteers who donate some of our time to giving help. You can accomplish your objective by using various string processing functions or by using regular expressions. I will assume that you want to extract everything between square brackets as the error and everything following the 2nd quote as the timestamp. Let's use the string find method. With that you can get the index of a particular character and use string slicing with those indexes to get the actual strings. If you have a basic understanding of python that should be enough to get you started. Otherwise I suggest you start with a tutorial that will get you those basics. if you just want someone to write the program for you then one of us will be glad to act as a paid consultant and do that for you. Bob Gailer From grant.b.edwards at gmail.com Wed Feb 26 17:34:59 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Wed, 26 Feb 2020 22:34:59 -0000 (UTC) Subject: encapsulating a global variable (BlindAnagram) References: Message-ID: On 2020-02-25, Dennis Lee Bieber wrote: > We seem to have some confusion with the use of the word "static"... No doubt carrying on the tradition from C, where the 'static' keyword is used to mean two completely different, orthogonal things. -- Grant Edwards grant.b.edwards Yow! My face is new, my at license is expired, and I'm gmail.com under a doctor's care!!!! From rosuav at gmail.com Wed Feb 26 17:58:17 2020 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 27 Feb 2020 09:58:17 +1100 Subject: encapsulating a global variable (BlindAnagram) In-Reply-To: References: Message-ID: On Thu, Feb 27, 2020 at 9:45 AM Grant Edwards wrote: > > On 2020-02-25, Dennis Lee Bieber wrote: > > > We seem to have some confusion with the use of the word "static"... > > No doubt carrying on the tradition from C, where the 'static' keyword > is used to mean two completely different, orthogonal things. > ... neither of which has anything to do with what a physicist would define "static" as. ChrisA From grant.b.edwards at gmail.com Wed Feb 26 18:36:36 2020 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Wed, 26 Feb 2020 23:36:36 -0000 (UTC) Subject: encapsulating a global variable (BlindAnagram) References: Message-ID: On 2020-02-26, Chris Angelico wrote: > On Thu, Feb 27, 2020 at 9:45 AM Grant Edwards wrote: >> >> On 2020-02-25, Dennis Lee Bieber wrote: >> >> > We seem to have some confusion with the use of the word "static"... >> >> No doubt carrying on the tradition from C, where the 'static' keyword >> is used to mean two completely different, orthogonal things. >> > > ... neither of which has anything to do with what a physicist would > define "static" as. I'm not sure what the physics usage of 'static' is, but when used for local variables in C, it sort of makes sense: it means that the location of the variable within the address space won't ever change during the program's lifetime. However, that's only half of what it does in that context: it also means that the location won't be reused for other things, and the location's contents will not change unless it is "intentionally" written to by the program. OTOH, the C usage of 'static' for file-scope variables is completely off the wall. I suspect somebody just put all of the existing keywords that weren't yet valid in that context into a hat... -- Grant Edwards grant.b.edwards Yow! Remember, in 2039, at MOUSSE & PASTA will gmail.com be available ONLY by prescription!! From mocramis at gmail.com Thu Feb 27 05:48:05 2020 From: mocramis at gmail.com (Remy NOEL) Date: Thu, 27 Feb 2020 11:48:05 +0100 Subject: Managing concurrent.futures exit-handlers Message-ID: Hello ! I am currently using concurrent.futures ThreadPoolExecutor, but i am annoyed by its exit_handler preventing program exit if any of the jobs it is running is blocked. Currently i can workaround it by either unregister the exit handler concurrent.futures.thread._python_exit or by subclassing the threadpoolExecutor and overriding the _adjust_thread_count method with one that does not register its threads queues. Both seems kinda ugly though. I was wondering if there was a better way. Also, would adding an option to executors so that their worker threads is not be globally joined was conceivable. Thanks ! Remy Noel From valon.januzaj98 at gmail.com Thu Feb 27 15:29:04 2020 From: valon.januzaj98 at gmail.com (valon.januzaj98 at gmail.com) Date: Thu, 27 Feb 2020 12:29:04 -0800 (PST) Subject: Logging all the requests into a specific file Message-ID: Hello guys, I am new to python and all of this, I am using this FastAPI, to build API, I want when users hit any endpoint for ex /products, that to be written into a file , how do I do it? From PythonList at DancesWithMice.info Thu Feb 27 16:24:16 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Fri, 28 Feb 2020 10:24:16 +1300 Subject: Logging all the requests into a specific file In-Reply-To: References: Message-ID: On 28/02/20 9:29 AM, valon.januzaj98 at gmail.com wrote: > I am new to python and all of this, I am using this FastAPI, to build API, > I want when users hit any endpoint for ex /products, that to be written into a file , how do I do it? The Python Standard Library offers a Logging library. It has "handlers" to decide where each message to go, "filters" to determine 'levels' of messages, and "formatters" to organise the output. -- Regards =dn From rmlibre at riseup.net Thu Feb 27 18:37:31 2020 From: rmlibre at riseup.net (rmlibre at riseup.net) Date: Thu, 27 Feb 2020 15:37:31 -0800 Subject: Asyncio question (rmlibre) In-Reply-To: References: Message-ID: What resources are you trying to conserve? If you want to try conserving time, you shouldn't have to worry about starting too many background tasks. That's because asyncio code was designed to be extremely time efficient at handling large numbers of concurrent async tasks. For your application, it seems starting background tasks that appropriately await execution based on their designated queue is a good idea. This is more time efficient since it takes full advantage of async concurrency, while also allowing you to control the order of execution. Although, there may be other efficiency boosts to be had, for instance, if all but the precise changes that need to be atomic are run concurrently. However, if you want to conserve cpu cycles per unit time, then staggering the processing of requests sequentially is the best option, although, there's little need for async code if this is the case. Or, if you'd like to conserve memory, making the code more generator-based is a good option. Lazy computation is quite efficient on memory and time. Although, rewriting your codebase to run on generators can be a lot of work, and their efficiency won't really be felt unless your code is handling "big data" or very large requests. In any case, you'd probably want to run some benchmark and profiling tools against a mock-up runtime of your code and optimize/experiment only after you've noticed there's an efficiency problem and have deduced its causes. Barring that, it's just guess-work & may just be a waste of time. On 2020-02-21 17:00, python-list-request at python.org wrote: > Hi all > I use asyncio in my project, and it works very well without my having to understand what goes on under the hood. It is a multi-user client/server system, and I want it to scale to many concurrent users. I have a situation where I have to decide between two approaches, and I want to choose the least resource-intensive, but I find it hard to reason about which, if either, is better. > > I use HTTP. On the initial connection from a client, I set up a session object, and the session id is passed to the client. All subsequent requests from that client include the session id, and the request is passed to the session object for handling. > > It is possible for a new request to be received from a client before the previous one has been completed, and I want each request to be handled atomically, so each session maintains its own asyncio.Queue(). The main routine gets the session id from the request and 'puts' the request in the appropriate queue. The session object 'gets' from the queue and handles the request. It works well. > > The question is, how to arrange for each session to 'await' its queue. My first attempt was to create a background task for each session which runs for the life-time of the session, and 'awaits' its queue. It works, but I was concerned about having a lot a background tasks active at the same time. > > Then I came up with what I thought was a better idea. On the initial connection, I create the session object, send the response to the client, and then 'await' the method that sets up the session's queue. This also works, and there is no background task involved. However, I then realised that the initial response handler never completes, and will 'await' until the session is closed. > > Is this better, worse, or does it make no difference? If it makes no difference, I will lean towards the first approach, as it is easier to reason about what is going on. > > Thanks for any advice. > > Frank Millman From python at python.invalid Thu Feb 27 17:39:11 2020 From: python at python.invalid (Python) Date: Thu, 27 Feb 2020 23:39:11 +0100 Subject: Mental model of lookahead assertions In-Reply-To: References: Message-ID: <5e584471$0$4044$426a74cc@news.free.fr> Stefan Ram wrote: > One can count overlapping occurences as follows. > > |>>> print(len(findall('(?=aa)','caaaab'))) > |3 > > Every web page says that lookahead assertions do > not consume nor move the "current position". > > But what mental model can I make of the regex > engine that explains why it is not caught in an > endless loop matching "aa" at the same position > again and again and never advancing to the other > occurences? > > (Something with nondeterminism?) Old but EXCELLENT insight into how regular expressions works: https://perl.plover.com/yak/regex/ (pdf and html slides) From adam.preble at gmail.com Fri Feb 28 02:21:12 2020 From: adam.preble at gmail.com (Adam Preble) Date: Thu, 27 Feb 2020 23:21:12 -0800 (PST) Subject: Data model and attribute resolution in subclasses Message-ID: <584c712a-2476-44a6-b3e0-9b58c5695eea@googlegroups.com> I have been making some progress on my custom interpreter project but I found I have totally blown implementing proper subclassing in the data model. What I have right now is PyClass defining what a PyObject is. When I make a PyObject from a PyClass, the PyObject sets up a __dict__ that is used for attribute lookup. When I realized I needed to worry about looking up parent namespace stuff, this fell apart because my PyClass had no real notion of a namespace. I'm looking at the Python data model for inspiration. While I don't have to implement the full specifications, it helps me where I don't have an alternative. However, the data model is definitely a programmer document; it's one of those things where the prose is being very precise in what it's saying and that can foil a casual reading. Here's what I think is supposed to exist: 1. PyObject is the base. 2. It has an "internal dictionary." This isn't exposed as __dict__ 3. PyClass subclasses PyObject. 4. PyClass has a __dict__ Is there a term for PyObject's internal dictionary. It wasn't called __dict__ and I think that's for good reasons. I guess the idea is a PyObject doesn't have a namespace, but a PyClass does (?). Now to look something up. I assume that __getattribute__ is supposed to do something like: 1. The PyClass __dict__ for the given PyObject is consulted. 2. The implementation for __getattribute__ for the PyObject will default to looking into the "internal dictionary." 3. Assuming the attribute is not found, the subclasses are then consulted using the subclass' __getattribute__ calls. We might recurse on this. There's probably some trivia here regarding multiple inheritance; I'm not entirely concerned (yet). 4. Assuming it's never found, then the user sees an AttributeError Would each of these failed lookups result in an AttributeError? I don't know how much it matters to me right now that I implement exactly to that, but I was curious if that's really how that goes under the hood. From jon+usenet at unequivocal.eu Fri Feb 28 06:02:32 2020 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Fri, 28 Feb 2020 11:02:32 -0000 (UTC) Subject: Mental model of lookahead assertions References: Message-ID: On 2020-02-27, Stefan Ram wrote: > One can count overlapping occurences as follows. > >|>>> print(len(findall('(?=aa)','caaaab'))) >|3 > > Every web page says that lookahead assertions do > not consume nor move the "current position". > > But what mental model can I make of the regex > engine that explains why it is not caught in an > endless loop matching "aa" at the same position > again and again and never advancing to the other > occurences? Simply that when it's returning multiple matches it knows once it's found a match at position to start looking for the next potential match at position ? From quintin9g at gmail.com Fri Feb 28 07:13:48 2020 From: quintin9g at gmail.com (Edward Montague) Date: Sat, 29 Feb 2020 01:13:48 +1300 Subject: wxFormBuilder Message-ID: The videos on YouTube by fandangleproductions, have been of some use. However as I also use the Geany editor, I find that I need to append this extra code to the Python script generated from wxFormBuilder. # --------------------- extra code ------------------- class MyApp(wx.App): def OnInit(self): self.frame = frameMain(None) self.SetTopWindow(self.frame) self.frame.Show() return True # end of class MyApp if __name__ == "__main__": app = MyApp(0) app.MainLoop() Where frameMain is the name of this particular frame. This may help you with your Python coding. From PythonList at DancesWithMice.info Fri Feb 28 19:34:25 2020 From: PythonList at DancesWithMice.info (DL Neil) Date: Sat, 29 Feb 2020 13:34:25 +1300 Subject: Friday Finking: Poly more thick Message-ID: <39e3ffcb-628a-1761-67d7-2b020b80ca60@etelligence.info> How does one code a function/method signature so that it will accept either a set of key-value pairs, or the same data enclosed as a dict, as part of a general-case and polymorphic solution? Wikipedia: polymorphism is the provision of a single interface to entities of different types. ( https://en.wikipedia.org/wiki/Polymorphism_(computer_science) ) At the end of a code-sprint, one of 'my' teams was presenting. Everything went well. Fatefully, the client-manager then remembered that the latest work would extend a previous sprint's work. Despite it not being a deliverable (?), he asked to be shown the two working together. The team, flushed with pride at their 'success' (foolishly) agreed, and the attempt immediately crashed. (as such live-demos are wont to do!) Wisely, a 'coffee/tea break' was suggested, to give the team time to 'fix' things. Hence a panic-call to me, working from home. It turned-out that a new-ish and less-experienced coder had been given this job, and she had been shown the interface as key-value pairs (her interpretation) - and even on the white-board there were no braces to show it as a dict! Whereas the more experienced programmer who originally assembled the class/signature/interface, had used a dict. Unhappiness was evident, argument threatened... I quickly mocked-up the situation. (code below). The fastest solution, which didn't require altering any calling-code, seemed to be to change the class's signature to use *args and **kwargs, which thereafter required only a single 'normalisation' step to turn any/the kwargs into a dict - which in-turn enabled the existing code, unchanged. Quick and dirty to be sure! However, it allowed the demo to go ahead and recovered everyone's feelings of satisfaction/success! Aside from 'repairing' team spirit, (as regular readers will recognise) I wasn't going to let this pass without some thought and discussion (and perhaps I might learn something about Python interfacing)! Python's powerful polymorphic capabilities [insert expression of thanks here!] allow us to substitute collections - with care. So, a simple function, such as:) def f( colln ): for element in colln: print( element ) will work quite happily when (separately) fed either a tuple or a list. It will also work with a string (a collection of characters) - as long as we are happy with single characters being output. What about dicts as collections? It will work with dicts, as long as we consider the dict's keys to be 'the dict' (cf its collection of values). Well that's very flexible! However, whilst a set of key-value arguments 'quack' somewhat like a dict, or even a tuple (of k-v pairs), they will not be accepted as parameters. Crash! Yes it can be solved, with a 'normalisation' function, as described above, perhaps as a working-theory: def f( *colln_as_tuple, **key_value_pairs_as_dict ): my_dict = key_value_pairs_as_dict if key_value_pairs_as_dict \ else colln_as_tuple[ 0 ] # no change to existing code using my_dict ... However, this seems like a situation that "quacks like a duck", yet the built-in polymorphism doesn't auto-magically extend to cover it. So: - is that the way 'polymorphism' really works/should work? - is expecting the dict to work as a "collection", already 'taking things too far'? - is expecting the key-values to work, really 'taking things too far'? Remember that I am not an OOP-native! The discussion around-the-office diverged into two topics: (1) theoretical: the limits and capability of polymorphism, and (2) practical: the understanding and limits of a Python "collection". How do you see it? How would you solve the Python coding problem - without re-writing both sprints-worth of code? Did we leave polymorphism 'behind' and expect Python to perform magic? ### investigative and prototyping code ### def print_dict( dictionary ): # helper function only for key, value in dictionary.items(): print( "\t", key, value ) def f( **kwargs ): print( kwargs, type( kwargs ) ) print_dict( kwargs ) f( a=1, b=2 ) # arguments as key-value pairs ### {'a': 1, 'b': 2} ### a 1 ### b 2 d={ 'a':1, 'b':2 } # arguments as a dictionary try: f( d ) except TypeError: print( "N/A" ) ### N/A ### Traceback (most recent call last): ### File "", line 1, in ### TypeError: f() takes 0 positional arguments but 1 was given f( **d ) # yes, easy to edit arguments, but... ### {'a': 1, 'b': 2} ### a 1 ### b 2 try: f( { 'a':1, 'b':2 } ) # or modify API to accept single dict except TypeError: print( "N/A" ) ### N/A print( "\nwith g()\n" ) ### with g() def g( *args, **kwargs ): print( args, type( args ), kwargs, type( kwargs ) ) for arg in args: # handle single-objects, eg dict print( arg, type( arg ) ) print_dict( arg ) for k, v in kwargs.items(): # handle key-value pairs print( "\t\t", k, v ) g( a=1, b=2 ) # arguments as key-value pairs ### () {'a': 1, 'b': 2} ### a 1 ### b 2 g( d ) # argument as a dictionary ### {'a': 1, 'b': 2},) {} ### {'a': 1, 'b': 2} ### a 1 ### b 2 -- Regards, =dn From kenzi.sml at gmail.com Fri Feb 28 19:24:18 2020 From: kenzi.sml at gmail.com (Kenzi) Date: Fri, 28 Feb 2020 19:24:18 -0500 Subject: =?UTF-8?B?44CQUmVnYXJkaW5nIFBlcmZvcm1hbmNlIG9mIGEgUHl0aG9uIFNjcmlwdC4uLi7jgJE=?= Message-ID: Hello there, I have a question regarding a simple code snippet in Python: from subprocess import check_output for i in range(1024): check_output(['/bin/bash', '-c', 'echo 42'], close_fds=True) *I wonder why running it in Python 3.7 is much faster than Python 2.7? * (Python 3.7 is still faster, after I used *xrange * in Python 2.7) Thanks all! From tjreedy at udel.edu Fri Feb 28 13:04:23 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Fri, 28 Feb 2020 13:04:23 -0500 Subject: Data model and attribute resolution in subclasses In-Reply-To: <584c712a-2476-44a6-b3e0-9b58c5695eea@googlegroups.com> References: <584c712a-2476-44a6-b3e0-9b58c5695eea@googlegroups.com> Message-ID: On 2/28/2020 2:21 AM, Adam Preble wrote: > I have been making some progress on my custom interpreter project but I found I have totally blown implementing proper subclassing in the data model. What I have right now is PyClass defining what a PyObject is. When I make a PyObject from a PyClass, the PyObject sets up a __dict__ that is used for attribute lookup. When I realized I needed to worry about looking up parent namespace stuff, this fell apart because my PyClass had no real notion of a namespace. > > I'm looking at the Python data model for inspiration. While I don't have to implement the full specifications, it helps me where I don't have an alternative. However, the data model is definitely a programmer document; it's one of those things where the prose is being very precise in what it's saying and that can foil a casual reading. > > Here's what I think is supposed to exist: > 1. PyObject is the base. > 2. It has an "internal dictionary." This isn't exposed as __dict__ The internal mapping *is* visible. >>> object.__dict__ mappingproxy({'__repr__': , '__hash__': , '__str__': , '__getattribute__': , '__setattr__': , '__delattr__': , '__lt__': , '__le__': , '__eq__': , '__ne__': , '__gt__': , '__ge__': , '__init__': , '__new__': , '__reduce_ex__': , '__reduce__': , '__subclasshook__': , '__init_subclass__': , '__format__': , '__sizeof__': , '__dir__': , '__class__': , '__doc__': 'The base class of the class hierarchy.\n\nWhen called, it accepts no arguments and returns a new featureless\ninstance that has no instance attributes and cannot be given any.\n'}) The internal mapping is not an instance of dict, and need/should not be as it is frozen. >>> o = object() >>> o.a = 3 Traceback (most recent call last): File "", line 1, in o.a = 3 AttributeError: 'object' object has no attribute 'a' When classes and objects do have a dict __dict__, __dict__ is not in __dict__, to avoid recursion. gettattribute or __getattribute__ must special case '__dict__'. I am guessing this as what must be from the evidence, without seeing the actual code. > 3. PyClass subclasses PyObject. > 4. PyClass has a __dict__ > > Is there a term for PyObject's internal dictionary. It wasn't called __dict__ and I think that's for good reasons. I guess the idea is a PyObject doesn't have a namespace, but a PyClass does (?). > > Now to look something up. I assume that __getattribute__ is supposed to do something like: > 1. The PyClass __dict__ for the given PyObject is consulted. > 2. The implementation for __getattribute__ for the PyObject will default to looking into the "internal dictionary." > 3. Assuming the attribute is not found, the subclasses are then consulted using the subclass' __getattribute__ calls. We might recurse on this. There's probably some trivia here regarding multiple inheritance; I'm not entirely concerned (yet). For non-reserved names Attribute lookup starts with the object dict, then object class, then superclasses. Dunder names usually start with the object class. > 4. Assuming it's never found, then the user sees an AttributeError > > Would each of these failed lookups result in an AttributeError? I presume so. They are caught and only re-raised only if there is no where else to look. -- Terry Jan Reedy From lee.chiffre at secmail.pro Fri Feb 28 21:49:58 2020 From: lee.chiffre at secmail.pro (Mr. Lee Chiffre) Date: Fri, 28 Feb 2020 18:49:58 -0800 Subject: Help building python application from source Message-ID: sorry re posting because I forgot subject line in last email. I am a python noob. This is why I ask the python masters. There is a python software I want to install on the server it is called Electrumx. https://github.com/kyuupichan/electrumx is the link. I am having troubles with installing this. The short version is I am wanting to build this python application and needed dependencies from source code all from a local directory without relying on the python pip package servers. I only run software I can compile from source code because this is the only way to trust open source software. I also want to archive the software I use and be able to install it on systems in a grid down situation without relying on other servers such as python package servers. Here is a snippet from https://github.com/lee-chiffre/Announcements/blob/master/02.26.2020 that describes what I am trying to do > 1. I need a way I can download the source of ElectrumX and the dependency tree. 2. In a way that also verifies the integrity of those downloads. I dont think many of these python packages are even signed. 3. Then to be able to build ElectrumX and the needed dependencies from source on a computer that does not have connection to internet. Node2.0 does not connect to internet except for the Tor process. Torsocks is not an option here. I will be running ElectrumX and the python dependencies in a venv virtual environment. If I cannot build ElectrumX and the dependencies for it from source in a way that also verifies the integrity of the downloads then for security reasons I will not run it. If someone has a solution to this I will then run ElectrumX, and give you credit for the help. If you need me to pay bounty for this please reach out to me to negotiate on a price. < Python might be easy to code but simplicity of coding comes at the cost of complexity of the software. With C++ I usually only have only a few dependencies. With python it seems like it is almost 20 dependencies. With Electrumx I counted at least 15 dependencies in the dependency tree. Is it possible to download then build this from source with all needed dependencies? -- lee.chiffre at secmail.pro PGP 97F0C3AE985A191DA0556BCAA82529E2025BDE35 From frank at chagford.com Sat Feb 29 01:36:10 2020 From: frank at chagford.com (Frank Millman) Date: Sat, 29 Feb 2020 08:36:10 +0200 Subject: Asyncio question (rmlibre) In-Reply-To: References: Message-ID: <8d29039f-9f02-ce6c-083f-91842e858cee@chagford.com> On 2020-02-28 1:37 AM, rmlibre at riseup.net wrote: > What resources are you trying to conserve? > > If you want to try conserving time, you shouldn't have to worry about > starting too many background tasks. That's because asyncio code was > designed to be extremely time efficient at handling large numbers of > concurrent async tasks. > Thanks for the reply. That is exactly what I want, and in an earlier response Greg echoes what what you say here - background tasks are lightweight and are ideal for my situation. Frank From frank at chagford.com Sat Feb 29 01:36:10 2020 From: frank at chagford.com (Frank Millman) Date: Sat, 29 Feb 2020 08:36:10 +0200 Subject: Asyncio question (rmlibre) In-Reply-To: References: Message-ID: <8d29039f-9f02-ce6c-083f-91842e858cee@chagford.com> On 2020-02-28 1:37 AM, rmlibre at riseup.net wrote: > What resources are you trying to conserve? > > If you want to try conserving time, you shouldn't have to worry about > starting too many background tasks. That's because asyncio code was > designed to be extremely time efficient at handling large numbers of > concurrent async tasks. > Thanks for the reply. That is exactly what I want, and in an earlier response Greg echoes what what you say here - background tasks are lightweight and are ideal for my situation. Frank From frank.rentmeister at gmail.com Sat Feb 29 05:27:50 2020 From: frank.rentmeister at gmail.com (Frank Rentmeister) Date: Sat, 29 Feb 2020 02:27:50 -0800 (PST) Subject: Groovy to Python Converter ? Message-ID: <519395d5-75a8-4ce5-9a09-2df138e1c928@googlegroups.com> In my new project, I am supposed to bring the current test cases, all written in Groovy, to a Python base. We are talking about several thousand test cases that have accumulated over the last years. Since the test cases are also to be extended towards API gateway testing, and since we work with Python requests here, we want and need to convert everything. But here is the question, which I could not answer even after an intensive search: Is there a converter that can convert Groovy based test cases to Python? An example of how the tests are structured. They are pure web tests that ask for links and other questions with just one click. Actually, it's absolutely simple, but not suitable for us for broad-based tests, even in the direction of expansion. From hjp-python at hjp.at Sat Feb 29 09:23:55 2020 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sat, 29 Feb 2020 15:23:55 +0100 Subject: =?utf-8?Q?=E3=80=90Regarding_Performan?= =?utf-8?B?Y2Ugb2YgYSBQeXRob24gU2NyaXB0Li4uLuOAkQ==?= In-Reply-To: References: Message-ID: <20200229142355.GA28707@hjp.at> On 2020-02-28 19:24:18 -0500, Kenzi wrote: > I have a question regarding a simple code snippet in Python: > > from subprocess import check_output > for i in range(1024): > check_output(['/bin/bash', '-c', 'echo 42'], close_fds=True) > > *I wonder why running it in Python 3.7 is much faster than Python 2.7? * > (Python 3.7 is still faster, after I used *xrange * in Python 2.7) I think almost all of the time is spent in the child processes, so it doesn't matter whether you use range or xrange. On my laptop, the program takes about 2.1 seconds with python 2.7 and 1.6 seconds with python 3.6. So the difference is 0.5 seconds overall or about 500 ?s per execution. strace shows that python 2.7 explicitely closes all unneeded file descriptors below 1024 (even though most of them aren't actually open) in the child before execing bash, python 3 doesn't do that. I can see no other obvious difference. So that's ~ 1020 extra system calls. If this is indeed the only difference, that's about 500 ns per system call. That sounds plausible. 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 souvik.viksou at gmail.com Sat Feb 29 11:23:16 2020 From: souvik.viksou at gmail.com (Souvik Dutta) Date: Sat, 29 Feb 2020 21:53:16 +0530 Subject: What is the meaning of Building Wheel for ? Message-ID: What is the meaning of the subject I mean what does python internally do when it says this? From pkpearson at nowhere.invalid Sat Feb 29 13:54:22 2020 From: pkpearson at nowhere.invalid (Peter Pearson) Date: 29 Feb 2020 18:54:22 GMT Subject: Help building python application from source References: Message-ID: On Fri, 28 Feb 2020 18:49:58 -0800, Mr. Lee Chiffre wrote: [snip] > I am a python noob. This is why I ask the python masters. There is a > python software I want to install on the server it is called Electrumx. > https://github.com/kyuupichan/electrumx is the link. I am having troubles > with installing this. > The short version is I am wanting to build this python application and > needed dependencies from source code all from a local directory without > relying on the python pip package servers. I only run software I can > compile from source code because this is the only way to trust open source > software. I also want to archive the software I use and be able to install > it on systems in a grid down situation without relying on other servers > such as python package servers. (To make OP's requirements plainly visible, note that this appears to be a cryptocurrency application.) I'd suggest that building everything from source code might not be a realistic solution to your security concerns. I don't know what your threat model is, but if it's something like, "Hackers and gangsters who scatter password-harvesting trojans across the globe and then shlurp up what they can," you might find that you get better security by generating your keys on a computer that never communicates with the outside world. Your concerns are (1) that the random numbers from which your keys have been corrupted to make them predictable, or (2) that malicious software will send your keys to the bad guys. Isolating the key-generation machine takes care of #2. If you have Python code for generating keys, something as simple as XORing a fixed value of your choice with its random numbers will take care of #1. I admit that using an isolated machine introduces a lot of inconveniences, but I bet it compares favorably with building everything from source. -- To email me, substitute nowhere->runbox, invalid->com. From lee.chiffre at secmail.pro Sat Feb 29 18:01:13 2020 From: lee.chiffre at secmail.pro (Mr. Lee Chiffre) Date: Sat, 29 Feb 2020 15:01:13 -0800 Subject: Help building python application from source In-Reply-To: References: Message-ID: Thanks for the comments. > (To make OP's requirements plainly visible, note that this appears to > be a cryptocurrency application.) Correct. It is a software that does not store private keys but acts as a server to serve lightweight wallets that would connect to it remotely. Electrumx does not store or generate private keys but my concern is running binary blobs that someone else created. The advantages of open source software only apply if you can confirm it was created from the source code. This is why I compile everything I can or use binaries based on reproducible build process. I am also wanting to run electrumx in a virtual environment under a dedicated user account on the linux box with lowest privileges. And the reason I want to be able to build from a local directory so that I can be self sufficient and be able to archive the software source code and all needed dependencies to spin up other servers or replace the server in a post disaster situation where internet or python pip package servers might be down. My bitcoin server also has very strict firewall rules that would inhibit the ability to connect to python servers. This is why I want to download the all the source code on my laptop then transfer to the server. But there are SO MANY dependencies. Electrumx has a few dependencies then each of those dependencies have more dependencies and on and on. I guess it might be possible to do what I want by manually downloading the source code of the close to 20 dependencies, manually verify the git tags and signatures. Then "python setup.py install" each one individually in the right order. This might work? I didn't know if there was an easier way. I did find out I could "pip download -r requirements.txt" but this downloads binaries specific for x86. My cpu architecture is aarch64. Is there a way to pip download -r requirements.txt source only or specify aarch64? Thank you -- lee.chiffre at secmail.pro PGP 97F0C3AE985A191DA0556BCAA82529E2025BDE35 From dvl at psu.edu Sat Feb 29 21:08:20 2020 From: dvl at psu.edu (Christman, Roger Graydon) Date: Sun, 1 Mar 2020 02:08:20 +0000 Subject: Friday Finking: Poly more thick Message-ID: DL Neil asked: > How does one code a function/method signature so that > it will accept either a set of key-value pairs, > or the same data enclosed as a dict, as part of > a general-case and polymorphic solution? Will this do for you? def any_as_dict(*args, **kwargs): if len(args) == 0: my_dict = kwargs elif type(args[0]) == type(dict()): my_dict = args[0] else: my_dict = dict(args) print(type(my_dict),my_dict) >>> any_as_dict(a=1,b=2) {'a': 1, 'b': 2} >>> any_as_dict({'a':1, 'b':2}) {'a': 1, 'b': 2} >>> any_as_dict([('a',1), ('b',2)]) {('a', 1): ('b', 2)} >>> any_as_dict({('a',1), ('b',2)}) {('b', 2): ('a', 1)} This seems to address your apparent definition of "key-value pairs" in the form of a=1, b=2 and my interpretation as key-value tuples, either in a list, or set, or presumably any iterable collection, in addition to taking an actual dictionary. Roger Christman Pennsylvania State University From dvl at psu.edu Sat Feb 29 21:17:57 2020 From: dvl at psu.edu (Christman, Roger Graydon) Date: Sun, 1 Mar 2020 02:17:57 +0000 Subject: Friday Finking: Poly more thick Message-ID: Emending my own note from moments ago: def any_as_dict(*args, **kwargs): if len(args) == 0: my_dict = kwargs elif type(args[0]) == type(dict()): my_dict = args[0] else: my_dict = dict(args[0]) print(type(my_dict),my_dict) >>> any_as_dict(a=1,b=2) {'a': 1, 'b': 2} >>> any_as_dict({'a':1, 'b':2}) {'a': 1, 'b': 2} >>> any_as_dict([('a',1), ('b',2)]) {'a': 1, 'b': 2} >>> any_as_dict({('a',1), ('b',2)}) {'b': 2, 'a': 1} From python at mrabarnett.plus.com Sat Feb 29 21:33:26 2020 From: python at mrabarnett.plus.com (MRAB) Date: Sun, 1 Mar 2020 02:33:26 +0000 Subject: Friday Finking: Poly more thick In-Reply-To: References: Message-ID: On 2020-03-01 02:08, Christman, Roger Graydon wrote: > DL Neil asked: > >> How does one code a function/method signature so that >> it will accept either a set of key-value pairs, >> or the same data enclosed as a dict, as part of >> a general-case and polymorphic solution? > > > Will this do for you? > > def any_as_dict(*args, **kwargs): > if len(args) == 0: > my_dict = kwargs > elif type(args[0]) == type(dict()): > my_dict = args[0] > else: > my_dict = dict(args) > print(type(my_dict),my_dict) > > >>>> any_as_dict(a=1,b=2) > {'a': 1, 'b': 2} >>>> any_as_dict({'a':1, 'b':2}) > {'a': 1, 'b': 2} >>>> any_as_dict([('a',1), ('b',2)]) > {('a', 1): ('b', 2)} >>>> any_as_dict({('a',1), ('b',2)}) > {('b', 2): ('a', 1)} > > This seems to address your apparent definition of > "key-value pairs" in the form of a=1, b=2 > and my interpretation as key-value tuples, > either in a list, or set, or presumably any > iterable collection, in addition to taking an > actual dictionary. > That function can be simplified: def any_as_dict(*args, **kwargs): return dict(args[0]) if args else kwargs >>> any_as_dict(a=1,b=2) {'a': 1, 'b': 2} >>> any_as_dict({'a':1, 'b':2}) {'a': 1, 'b': 2} >>> any_as_dict([('a',1), ('b',2)]) {'a': 1, 'b': 2} >>> any_as_dict({('a',1), ('b',2)}) {'b': 2, 'a': 1} From tjreedy at udel.edu Sat Feb 29 14:20:27 2020 From: tjreedy at udel.edu (Terry Reedy) Date: Sat, 29 Feb 2020 14:20:27 -0500 Subject: What is the meaning of Building Wheel for ? In-Reply-To: References: Message-ID: On 2/29/2020 11:23 AM, Souvik Dutta wrote: > What is the meaning of the subject I mean what does python internally do > when it says this? Python does not normally 'build wheels'. So you must be running some particular program. Check the docs for that program. -- Terry Jan Reedy