From mats at wichmann.us Wed Apr 1 10:05:30 2020 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 1 Apr 2020 08:05:30 -0600 Subject: [Tutor] Beginners question In-Reply-To: <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info> References: <9ce8306447a1a36279947ed0e514c3ad@sonic.net> <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info> <79f2d4c9bda941b781d87e96a735703b@sonic.net> <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info> Message-ID: <80ee8ede-e998-9001-5d74-011b2d856829@wichmann.us> On 3/31/20 4:37 PM, DL Neil via Tutor wrote: > Earlier, I opined that the first code-snippet is "untidy". curious: why? > Has such become liable to a similar judgment in deciding whether, for > example; a complex list-comprehension expression should be coded in its > compact form, or broken-out into a more readable for-loop? > (particularly when dealing with lesser-mortals such as I). there's no question there are tradeoffs. a compact expression may have many advantages, for example more of the surrounding code can be seen in a viewable size snippet (you can make your terminal emulator or editor window able to show 100 lines, but the brain is going to want to "see" a much smaller chunk), making it easier to understand the code flow of the whole chunk, rather than just thinking about the readability of that one statement-or-expanded-out-loop piece. or, it may make it harder for the reader to comprehend because the statement becomes hard to read. "style dogma" is a thing, but there are no hard and fast answers in the end. > What more could we do? > > - users may have become habituated to typing "semaphores" such as "quit" > to end input. However, Python allows considerable flexibility over > previous generations of languages. Could we instead invite the user to > hit Enter (with no data)? sure you can, but this is an interface design decision. A lot of developers prefer to have a specific positive value in order to do something significant... easy to hit Enter without really thinking about it, but typing "quit" requires clear intent. That's not really a "programming" question, we programmers can make it work any way. From shuvromallik at gmail.com Wed Apr 1 04:21:45 2020 From: shuvromallik at gmail.com (Shuvro Mallik) Date: Wed, 1 Apr 2020 14:21:45 +0600 Subject: [Tutor] Seeking help for learning python Message-ID: <5e844daf.1c69fb81.f9fd5.3eb1@mx.google.com> Hey ! This is shuvro mallik . Currently I have completed my MBA afterwards I determined to learn python . Because of being business background ,I do have zero knowledge on coding .Could you plz help me like which sector (AI, DATA SCIENCE,WEB DEVELOPMENT or alike) I should choose to work through python . Plz share some guidelines. Thanks !! Sent from Mail for Windows 10 From PyTutor at danceswithmice.info Wed Apr 1 18:48:46 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Thu, 2 Apr 2020 11:48:46 +1300 Subject: [Tutor] Beginners question In-Reply-To: <80ee8ede-e998-9001-5d74-011b2d856829@wichmann.us> References: <9ce8306447a1a36279947ed0e514c3ad@sonic.net> <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info> <79f2d4c9bda941b781d87e96a735703b@sonic.net> <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info> <80ee8ede-e998-9001-5d74-011b2d856829@wichmann.us> Message-ID: On 2/04/20 3:05 AM, Mats Wichmann wrote: > On 3/31/20 4:37 PM, DL Neil via Tutor wrote: >> Earlier, I opined that the first code-snippet is "untidy". > curious: why? Old f...s like me remember writing monolithic programs and the overwhelming chaos of 'spaghetti code'. The greatest influence which ushered-in the concepts of modular code and "structured programming" was probably Edgar Dijkstra's paper "Goto considered harmful" - which spawned a whole genre of xyz-considered harmful wannabes... Amongst such realisations was the 'virtue' of single-entry, single-exit routines/modules, and how such style both simplified reading and saved us various 'evils'. Thus, the code-blocks we know-and-love today, eg while... and for... The original construct, as required by the OP, consisted of a while loop with a break. The 'book of words' says: <<<"while" assignment_expression ":" suite>>>. Which most of us will understand as: "while condition: do-something". In the proposed-code/answer, this construct is used/abused, by removing the condition, ie to say: "loop forever". As such, it is necessary to add a second structure, an "if-it's-the-end" or a "raise exception", in order to realise some condition under which the while-loop should terminate. So, rather than the while-condition deciding whether to loop (or not), we now have, effectively, two conditions for the price of one. No! We have the price of two conditions, in order to achieve one loop. OK, enough theory. To me the original code looks, if not 'untidy', at least ungainly. (clearly a personal opinion/matter of taste) The question about the "walrus operator", was to establish if we might be able to 'simplify' *the logic* back to having a single condition (entry/exit), and thus a 'standard', simple, while-loop? At the same time, the while's condition would become more complex. So, at the code-level, the question becomes one of simplicity and readability vs compact-concentration and coding-power. Again, and as you say, largely a matter of taste. I was sufficiently intrigued to wonder if folk had any particular opinions, preferably based upon experience, one-way or the other... (particularly as I haven't progressed to v3.8 and such 'delights' as the walrus-operator, myself - yet... My wanting to 'stand on the shoulders of giants', etc, etc) >> Has such become liable to a similar judgment in deciding whether, for >> example; a complex list-comprehension expression should be coded in its >> compact form, or broken-out into a more readable for-loop? >> (particularly when dealing with lesser-mortals such as I). > > there's no question there are tradeoffs. a compact expression may have > many advantages, for example more of the surrounding code can be seen in > a viewable size snippet (you can make your terminal emulator or editor > window able to show 100 lines, but the brain is going to want to "see" a > much smaller chunk), making it easier to understand the code flow of the > whole chunk, rather than just thinking about the readability of that one > statement-or-expanded-out-loop piece. or, it may make it harder for the > reader to comprehend because the statement becomes hard to read. "style > dogma" is a thing, but there are no hard and fast answers in the end. As I age (and my eyes do too - at about the same rate!) I'm finding that my comfortable "chunking"* is decreasing in size, whilst my interest in 'simplicity' rises in direct proportion. (hey, perhaps I'm just becoming more cautious/conservative in my old-age?) Vis-a-vis dogma: a regular criticism is that I tend to use more classes and more methods/functions than (some) others might - but no-one has reached the level of criticism which would demand a re-write. (yet?) It does however give excuse for another round of jokes at 'grandpa's' expense, which amusement keeps us going until someone needs help... Yesterday, I found myself with a method containing exactly one line of code, ie almost more docstring than code. What??? Yes, it did come-about due to TDD re-factoring, but when I looked again, I realised that even though the various attribute names *are* descriptive, having a method-call, and thus 'labeling', actually improved readability/provided its own explanation of the functionality - which would otherwise have required at least an inline-comment. So, I left it (for now). The same thing applies to the width of a code-line. Even though I move my eyes when reading, and have a daily regimen which includes neck exercises, I really dislike scanning from side-to-side to be able to read a single line. Accordingly, I stick with the recommended 79?80-characters per line - and yes, I can spell "Hollerith punched card", even bemoan their passing and that of the IBM 029 Card Punch machine (but not the LOUD noise it made). Reject cards made excellent book-marks - but wait, who uses paper-books these days...? * "chunking" is the correct (cognitive-)psychological term. For those to whom it is unfamiliar, it refers to the quantity of data a person is comfortable 'holding' at one time. Thus, a raw beginner may need to look-up the syntax of a for-statement in order to type the code, whereas a programming-master will 'see' or 'think' in terms of the entire loop, and more, at once. >> What more could we do? >> >> - users may have become habituated to typing "semaphores" such as "quit" >> to end input. However, Python allows considerable flexibility over >> previous generations of languages. Could we instead invite the user to >> hit Enter (with no data)? > > sure you can, but this is an interface design decision. A lot of > developers prefer to have a specific positive value in order to do > something significant... easy to hit Enter without really thinking about > it, but typing "quit" requires clear intent. That's not really a > "programming" question, we programmers can make it work any way. Oh? You're baiting me with 'dogma', right? OK, here's the 'hook, line, and sinker':- In the abstract, this is correct. A responsibly-minded professional would not let it lie though, feeling that we have a responsibility towards usability and other aspects that cannot be measured in lines-of-code. Perhaps those of us who are not 'just' programmers, spend more time in arena where such discussions are more relevant? (with any due apologies) Modern (whatever that means) working environments are much more "Agile". As such, it is recognised that users should be part of a dev.team. Thus, their thoughts, feelings, preferences, etc, are communicated to tech.staff; and by the same process, users become better 'educated' in what is possible, and informed about the choices which will affect them every day (thereafter), and such-like. All to mutual advantage! Back to the topic: if the application doesn't actually have a practical use for the semaphore-word, ie future = input( "Do you want to keep your job or quit?" ) users may actually prefer an alternative. Such alternatives may even simplify and thus improve the quality of 'our' code... Web.Refs: https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf https://docs.python.org/3/reference/compound_stmts.html#the-while-statement https://en.wikipedia.org/wiki/Unit_record_equipment -- Regards =dn From PyTutor at DancesWithMice.info Wed Apr 1 19:04:23 2020 From: PyTutor at DancesWithMice.info (DL Neil) Date: Thu, 2 Apr 2020 12:04:23 +1300 Subject: [Tutor] Seeking help for learning python In-Reply-To: <5e844daf.1c69fb81.f9fd5.3eb1@mx.google.com> References: <5e844daf.1c69fb81.f9fd5.3eb1@mx.google.com> Message-ID: <0ad2dbad-6d9f-b949-82cc-ec536cfb0d95@DancesWithMice.info> On 1/04/20 9:21 PM, Shuvro Mallik wrote: > Hey ! This is shuvro mallik . Currently I have completed my MBA afterwards I determined to learn python . Because of being business background ,I do have zero knowledge on coding .Could you plz help me like which sector (AI, DATA SCIENCE,WEB DEVELOPMENT or alike) I should choose to work through python . Plz share some guidelines. Hi, welcome to the Python community! This is a perennial question, and you will find many answers by inspecting the Discussion List's archives which mention books and web-sites (including that of our ListAdmin - I'm usually guilty of making jokes at his expense, so it's fair to sing his praises! Right, (take a deep breath) now that's done, I'm back to...) Having a good study-habit, you may find the on-line courses available from edX, Coursera, and others; a learning-path to your liking. Recommendation: Either choose *one* from the above list of (widely varying) specialisations and search for applicable courses, or start with a general 'intro to Python' offering and upon 'graduation' you might feel more aware and thus better-placed to specialise... A good place to start looking for on-line courses is: https://www.classcentral.com/ Disclaimer: I use the edX platform, but do not present Python courses. -- Regards =dn From mats at wichmann.us Wed Apr 1 19:10:42 2020 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 1 Apr 2020 17:10:42 -0600 Subject: [Tutor] Beginners question In-Reply-To: References: <9ce8306447a1a36279947ed0e514c3ad@sonic.net> <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info> <79f2d4c9bda941b781d87e96a735703b@sonic.net> <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info> <80ee8ede-e998-9001-5d74-011b2d856829@wichmann.us> Message-ID: <91eb4517-6e08-1186-4645-234eedca270d@wichmann.us> On 4/1/20 4:48 PM, DL Neil via Tutor wrote: > On 2/04/20 3:05 AM, Mats Wichmann wrote: ah, too much to reply to there, David :) >> On 3/31/20 4:37 PM, DL Neil via Tutor wrote: >>> Earlier, I opined that the first code-snippet is "untidy". >> curious: why? > The 'book of words' says: <<<"while" assignment_expression ":" suite>>>. > Which most of us will understand as: "while condition: do-something". > > In the proposed-code/answer, this construct is used/abused, by removing > the condition, ie to say: "loop forever". > > As such, it is necessary to add a second structure, an "if-it's-the-end" > or a "raise exception", in order to realise some condition under which > the while-loop should terminate. well, it's a restatement, not really a fundamental change. You can write it thus: get something while something != exitvalue: do summat with something get something or thus like the example you're grumping at: while condition-that-always succeeds: get something if something == exitvalue: break do summat with something I guess pick the one you like better? (some seem to find the initial fetch/set before starting the loop obnoxious, I don't really care). > Accordingly, I stick with the recommended > 79?80-characters per line - and yes, I can spell "Hollerith punched > card", even bemoan their passing and that of the IBM 029 Card Punch > machine (but not the LOUD noise it made). Reject cards made excellent > book-marks - but wait, who uses paper-books these days...? *I* don't miss unjamming cards... one with maybe a fractionally bent spot on the edge would catch, and then the next six or so cards in flight behind it would smash in behind it and make an unholy mess... but you reminided me: those punchcards were also "indentation matters", just like Python :) (Fortran II - statements had to begin in column 7, because the first six columns were reserved, including for line numbers for, yes, something to GOTO. However... it's time to forget those days. From wescpy at gmail.com Thu Apr 2 00:07:49 2020 From: wescpy at gmail.com (wesley chun) Date: Wed, 1 Apr 2020 21:07:49 -0700 Subject: [Tutor] Python Beginner Book Advice In-Reply-To: References: <75d8dc0f-4e06-b6d7-a18f-2bfc36ee3311@DancesWithMice.info> Message-ID: Apologies I'm late to this thread and thx to some of you who recommended my book[s], "Core Python *", however the intended audience of that book is for developers who are already familiar with another high-level language like C/C++, Java, PHP, Ruby, etc. While those with less experience can certainly use it, it's not the best tool for the job, so I have some recommendations too, which include some of the books in the OP. More specifically about Core Python: the 3rd edition splits up the original language fundamentals (part 1) and applications topics (part 2). So the current "3rd ed" that's on the market (http://amzn.com/0132678209) is 2.x & 3.x but is only part 2 (applications), hence the slight rename. This book wouldn't be advised because it's for people who already know Python but want to learn what they can do with it. (I'm still working on the 3rd ed of the language fundamentals part 1... honestly, it's been challenging to complete due to a busy day job. I hope to find more time to work on it soon! Perhaps some of you can help me with the reviews since you would be a good audience for this next edition.) Cheers, --Wesley On Fri, Mar 20, 2020 at 2:59 AM Alan Gauld via Tutor wrote: > On 20/03/2020 02:52, DL Neil via Tutor wrote: > > On 20/03/20 3:37 PM, boB Stepp wrote: > > >>> Mark Sommerville's "Programming in Python 3" from Addison Wesley. > > > assistance), I would criticise the latter as a new-learner's tool. The > > first chapter is called "Rapid Introduction to Procedural Programming", > > Its not for newbies to programming that's for sure. But the OP said > they knew Javascript so I figured it would be OK for a transitioning > programmer. > > > -- > 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 > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "A computer never does what you want... only what you tell it." +wesley chun : wescpy at gmail : @wescpy Python training & consulting : http://CyberwebConsulting.com "Core Python" books : http://CorePython.com Python blog: http://wescpy.blogspot.com From saramn610 at gmail.com Thu Apr 2 04:49:56 2020 From: saramn610 at gmail.com (Sara Mn) Date: Thu, 2 Apr 2020 11:49:56 +0300 Subject: [Tutor] A question Message-ID: <2B393A04-947C-4F1C-AD1C-0535999EF009@gmail.com> Hello Sir/Madam, I have a question regarding passing arguments to another function, I have made this code fragment: def question1(): print("Q1) What subject of the below subjects you find most intresting:\na-Biology\nb-Chemistry\nc-Math\nd-Physics\ne-Business Studies\nf-Computer Science\ng-Art") answer1=input("Enter your answer's letter Or enter X to exit the program: ").lower() if answer1 in answerList1 : return answer1 elif answer1=='x': sys.exit(0) else: while True: print("\nThe answer you entred is invalid, you have two more tries. If you wish to exit the program enter X") answer1=input("Enter your answer: ") if answer1 in answerList1 : return answer1 break elif answer1=='x': sys.exit(0) else: print("The answer you entred is invalid, you have one more try. If you wish to exit the program enter X") answer1=input("Enter your answer: ") return answer1 if answer1 in answerList1: return answer1 break elif answer1=='x': sys.exit(0) else: print("The answer you entred is invalid. The program is being terminated as you have reached your maximum number of tries") sys.exit(0) def AnswerCollection(): n1=question1() print(n1) However I can?t just pass the local variable answer1 to the function AnswerCollection() it passes the whole function with the question. What can I do to pass only the local variable. Also, I have 6 different functions with the same format. How can I pass 6 different local variables from 6 different functions to one function. Thank You . From alan.gauld at yahoo.co.uk Thu Apr 2 05:46:14 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 2 Apr 2020 10:46:14 +0100 Subject: [Tutor] Seeking help for learning python In-Reply-To: <5e844daf.1c69fb81.f9fd5.3eb1@mx.google.com> References: <5e844daf.1c69fb81.f9fd5.3eb1@mx.google.com> Message-ID: On 01/04/2020 09:21, Shuvro Mallik wrote: > .... Currently I have completed my MBA afterwards I determined to learn python. Interesting choice, but one which this list would naturally applaud. :-) > I do have zero knowledge on coding . That's a sad truism. Business courses in this day and age should at least include a basic programming course. The skills of analysing a program and coding it are directly relevant to business process design! Also most businesses today are critically dependant on their IT systems. When the CEO cannot understand how his mission critical resources work, at least conceptually, he/she is in trouble! > Could you plz help me like which sector (AI, DATA SCIENCE,WEB DEVELOPMENT Your question is a bit like someone asking "I'd like to play the piano, should I specialize in 18th century chamber music or early 20th century ragtime or 1970's prog rock?" You need the basics first. First learn to program. That is the most basic and most valuable skill. Once you can write basic programs you may have a better idea of the kind of programs you might want to create. Then you can specialize. -- 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 Thu Apr 2 06:00:48 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 2 Apr 2020 11:00:48 +0100 Subject: [Tutor] A question In-Reply-To: <2B393A04-947C-4F1C-AD1C-0535999EF009@gmail.com> References: <2B393A04-947C-4F1C-AD1C-0535999EF009@gmail.com> Message-ID: On 02/04/2020 09:49, Sara Mn wrote: > Hello Sir/Madam, > I have a question regarding passing arguments to another function, I have made this code fragment: > > def question1(): > print("Q1) What subject of the below subjects you find most intresting:\na-Biology\nb-Chemistry\nc-Math\nd-Physics\ne-Business Studies\nf-Computer Science\ng-Art") > answer1=input("Enter your answer's letter Or enter X to exit the program: ").lower() > if answer1 in answerList1 : > return answer1 > > elif answer1=='x': > sys.exit(0) > > else: > while True: > print("\nThe answer you entred is invalid, you have two more tries. If you wish to exit the program enter X") > answer1=input("Enter your answer: ") > if answer1 in answerList1 : > > return answer1 > break > elif answer1=='x': > sys.exit(0) > else: > print("The answer you entred is invalid, you have one more try. If you wish to exit the program enter X") > answer1=input("Enter your answer: ") > return answer1 > if answer1 in answerList1: > > return answer1 > break > elif answer1=='x': > sys.exit(0) > > else: > print("The answer you entred is invalid. The program is being terminated as you have reached your maximum number of tries") > sys.exit(0) Notice tat you are repeating what is almost identical code multiple times. You should be able to restructure your function so you only do things once(or at most twice!). (It might help to split it into two functions, one to get the input and the other to monitor how many tries.) Also you should be able to pass in the question so that you only need one function not one per question. That will make your code easier to read and maintain/modify. > def AnswerCollection(): > n1=question1() > print(n1) > However I can?t just pass the local variable answer1 to the function AnswerCollection() > it passes the whole function with the question. I don't understand what you are trying to do. answer1 only exists inside question1() so you can only use it if you are calling AnswerCollection from inside question1. But you call question1 from inside AnswerCollection? It might help if you post the code where you try to pass the parameter and any error messages so we can see what you are trying to do. At the moment it is not clear. > What can I do to pass only the local variable. Also, I have 6 different > functions with the same format.> How can I pass 6 different local variables from 6 different functions to one function. Again I'm not sure what you mean. If you can show us - even with just two functions instead of 6... In general a function has a number of input parameters. You can call that functio from as many places as you like passing in the required values. The function doesn't know or care where it is called from, it just works with what you give it. Of course one of the parameters can be a list, so if you build the list and pass it each time then the function can see the previous values. But I don't know if that's what you want? -- 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 Thu Apr 2 06:56:14 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 2 Apr 2020 11:56:14 +0100 Subject: [Tutor] A question In-Reply-To: References: <2B393A04-947C-4F1C-AD1C-0535999EF009@gmail.com> Message-ID: On 02/04/2020 11:00, Alan Gauld via Tutor wrote: > You should be able to restructure your function so you only do things > once(or at most twice!). OK, I was bored. So came up with this: ######################## import sys AnswerList = "a-Biology\nb-Chemistry\nc-Math\nd-Physics\ne-Business Studies\nf-Computer Science\ng-Art".split('\n') def question(query,options): print(query + "\n" + "\n".join(options)) answer = input("Enter your answer's letter or X to exit: ").lower() tries = 0 while tries < 2: tries += 1 if answer in [a[0] for a in options] : return answer elif answer == 'x': print("Goodbye...") sys.exit(0) else: print("\nThe answer", answer, "is invalid, you have %d more tries.\nIf you wish to exit the program enter X" % (3-tries)) answer=input("Enter your answer: ") else: print("The answer", answer, "is still invalid.\nThe program is being terminated as you have reached your maximum number of tries") sys.exit(0) choice = question("Q1) Which of the following subjects do you find most interesting:", AnswerList) print("\n\nThe answer was:", choice) ################### But that doesn't explain what you were really asking about passing parameters to AnswerCollection() -- 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 afreer2 at netzero.net Thu Apr 2 10:35:13 2020 From: afreer2 at netzero.net (afreer2 at netzero.net) Date: Thu, 2 Apr 2020 14:35:13 GMT Subject: [Tutor] pdfminer.six Message-ID: <20200402.073513.23018.0@webmail13.dca.untd.com> where do I get pdfminer.six to edit pdf files here with this site(other sites have pdfminer.six)Is it the best or are there better optionsMy first python experience From jf_byrnes at comcast.net Thu Apr 2 10:02:33 2020 From: jf_byrnes at comcast.net (Jim) Date: Thu, 2 Apr 2020 09:02:33 -0500 Subject: [Tutor] Seeking help for learning python In-Reply-To: References: <5e844daf.1c69fb81.f9fd5.3eb1@mx.google.com> Message-ID: On 4/2/20 4:46 AM, Alan Gauld via Tutor wrote: > On 01/04/2020 09:21, Shuvro Mallik wrote: >> .... Currently I have completed my MBA afterwards I determined to learn python. > > Interesting choice, but one which this list would naturally applaud. :-) > >> I do have zero knowledge on coding . > > That's a sad truism. Business courses in this day and age should at > least include a basic programming course. The skills of analysing a > program and coding it are directly relevant to business process > design! > > Also most businesses today are critically dependant on their IT > systems. When the CEO cannot understand how his mission critical > resources work, at least conceptually, he/she is in trouble! > So true. Way back when (50 years ago) I was getting my accounting degree and we had to take a programming course. I can't even remember what language it was, maybe that's why I became interested in programming as a hobby. My daughter now teaches at that university and she tells me that many of her students are meteorology majors. With covid 19 now sweeping the US she is teaching C++ and Android classes from my dining room table. She says that next semester the intro course will be Python so maybe she will actually ask me some questions. Regards, Jim From __peter__ at web.de Fri Apr 3 05:19:51 2020 From: __peter__ at web.de (Peter Otten) Date: Fri, 03 Apr 2020 11:19:51 +0200 Subject: [Tutor] Beginners question References: <9ce8306447a1a36279947ed0e514c3ad@sonic.net> <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info> <79f2d4c9bda941b781d87e96a735703b@sonic.net> <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info> Message-ID: DL Neil via Tutor wrote: > With apologies to the OP for 'hi-jacking' the thread, a further > question, if I may:- > > > On 1/04/20 12:50 AM, Peter Otten wrote: > >>>>> while True: >>>>> # get input >>>>> # if input means quit >>>>> break # break out of the loop >>>>> # proceed with whatever you want to do > >>>> The above always looks so untidy to my eye. Could we use the 'walrus >>>> operator' instead of while True:? >> While I prefer the old-fashioned way here's how to spell the while loop >> without break: > >>>>> while (word:=input("Enter a word: ")) != "quit": >> ... print(f"The word is {word!r}") > @Peter: why the preference for "the old-fashioned way"? > (perhaps answered below...) Indeed ;) Basically an expression with embedded assignments appears as "untidy" as a loop with breaks. I read PEP 572, and the only convincing examples are those from copy.py and sysconfig.py where a sequence of tests that required nested if-s and can be flattened into if...elif...elif... Over the years there were some really cool additions to Python (generators, list comprehensions, context managers), but for some time my impression is that the language is going from lean and mean to baroque. From alan.gauld at yahoo.co.uk Fri Apr 3 07:35:00 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 3 Apr 2020 12:35:00 +0100 Subject: [Tutor] Beginners question In-Reply-To: References: <9ce8306447a1a36279947ed0e514c3ad@sonic.net> <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info> <79f2d4c9bda941b781d87e96a735703b@sonic.net> <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info> Message-ID: On 03/04/2020 10:19, Peter Otten wrote: > Over the years there were some really cool additions to Python (generators, > list comprehensions, context managers), but for some time my impression is > that the language is going from lean and mean to baroque. I think that is an inevitable consequence of Python's leap in popularity over the last 5 years or so. Everybody wants their pet feature added. It was the same with C++ in the mid-90s. C++ went from a fairly straightforward extension to C to provide OOP features to a horrible mess of new extensions and paradigms. C++ is slowly evolving into a new version of itself, very different to its C origins. And many of the features added in the mid 90's are now deprecated, and replaced by newer ideas. But the modern C++ is so different to the C++ I learned around 1990 that I've decided to approach it as a completely new language with its own idioms. I've been putting this off but Covid19 has provided the time and opportunity to get stuck in! Hopefully Python will never go quite that far down the road of feature creep... But the walrus operator is IMHO a horrible addition which I don't intend using. While it avoids the worst feature of C's assignment expression it is still ugly and overly complex. Perhaps the worst example in Python is string formatting. We now have at least 4 different ways of formatting strings. That's at least 2 too many... -- 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 robertvstepp at gmail.com Fri Apr 3 19:19:03 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Fri, 3 Apr 2020 18:19:03 -0500 Subject: [Tutor] Beginners question In-Reply-To: References: <9ce8306447a1a36279947ed0e514c3ad@sonic.net> <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info> <79f2d4c9bda941b781d87e96a735703b@sonic.net> <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info> Message-ID: On Fri, Apr 3, 2020 at 6:35 AM Alan Gauld via Tutor wrote: > Perhaps the worst example in Python is string formatting. > We now have at least 4 different ways of formatting strings. > That's at least 2 too many... Out of curiosity, which one(s) do you prefer to use and what shapes your preference(s)? -- boB From alan.gauld at yahoo.co.uk Sat Apr 4 02:17:39 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 4 Apr 2020 07:17:39 +0100 Subject: [Tutor] Beginners question In-Reply-To: References: <9ce8306447a1a36279947ed0e514c3ad@sonic.net> <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info> <79f2d4c9bda941b781d87e96a735703b@sonic.net> <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info> Message-ID: On 04/04/2020 00:19, boB Stepp wrote: > On Fri, Apr 3, 2020 at 6:35 AM Alan Gauld via Tutor wrote: > >> Perhaps the worst example in Python is string formatting. >> We now have at least 4 different ways of formatting strings. >> That's at least 2 too many... > > Out of curiosity, which one(s) do you prefer to use and what shapes > your preference(s)? > I like C printf style for conciseness and the new format strings(f"...") look promising although I haven't used them yet. The format() method is too cumbersome for my taste although it does offer some extra features over printf. (Although I suspect they could be incorporated into printf with a bit of thought) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From cs at cskk.id.au Sat Apr 4 04:27:55 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Sat, 4 Apr 2020 19:27:55 +1100 Subject: [Tutor] Beginners question In-Reply-To: References: Message-ID: <20200404082755.GA31207@cskk.homeip.net> On 03Apr2020 18:19, boB Stepp wrote: >On Fri, Apr 3, 2020 at 6:35 AM Alan Gauld via Tutor wrote: >> Perhaps the worst example in Python is string formatting. >> We now have at least 4 different ways of formatting strings. >> That's at least 2 too many... > >Out of curiosity, which one(s) do you prefer to use and what shapes >your preference(s)? I tend to use % formatting with my debugging statements and log messages (which use %-formatting out of the box anyway). Eg: warning("badness! foo=%r", foo) which will render "badness! foo=%r"%foo if the emit method fires. And in the same pattern my Pfx() message prefixer uses implicit percent formatting like the logging calls do: with Pfx("mkdir(%r)", dirpath): os.mkdir(dirpath) which will render "mkdir(%r)"%dirpath is the prefix is used. I do use modern f"{foo} blah" format strings something. They're particularly handy for template style strings because it is so easy to directly control where values land in the output. For example, I'm working on something at present which accepts a "-o format_string" command line option which lets the user specify the output message filled in from stuff from the programme. Cheers, Cameron Simpson From mats at wichmann.us Sat Apr 4 09:57:39 2020 From: mats at wichmann.us (Mats Wichmann) Date: Sat, 4 Apr 2020 07:57:39 -0600 Subject: [Tutor] Beginners question In-Reply-To: References: <9ce8306447a1a36279947ed0e514c3ad@sonic.net> <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info> <79f2d4c9bda941b781d87e96a735703b@sonic.net> <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info> Message-ID: On 4/3/20 5:19 PM, boB Stepp wrote: > On Fri, Apr 3, 2020 at 6:35 AM Alan Gauld via Tutor wrote: > >> Perhaps the worst example in Python is string formatting. >> We now have at least 4 different ways of formatting strings. >> That's at least 2 too many... > > Out of curiosity, which one(s) do you prefer to use and what shapes > your preference(s)? For me, as an old C programmer, the printf-style formatting style is fine, I'm used to it - that's where Python's syntax came from. If that were the only style available, I'm pretty sure that would be holding Python back, and that's almost certainly the reason other methods have developed. I sure wish they'd thought of f-strings before inventing the .format method, that's the one we could do without - because it doesn't fix one of the two big problems with string formatting, that of having to match up the arguments with the format string. How many of us get that wrong over and over when there's a lengthy list of args? msg = "error %d, file %s line %d" % (e, f, l) msg = "error {}, file {} line {}".format(e, f, l) wow, what a difference!! :( I constantly find myself realizing I needed to print out one more value, and then forget to add the corresponding entry to the tuple or format args, and get a traceback... But: msg = f"error {e}, file {f}, line {l}" and for quick debug prints (yeah, yeah, I know - don't debug with prints, use proper logging): print(f"error {e=}, file {f=}, line {l=}") which shortcuts having to manually write the name of the variable together with the the value, i.e. it is sugar for: print(f"error e={e}, file f={f}, line l={l}") which obviously matters more when you use proper identifier names that are more than one character! all the format-specificiers are possible, e.g. I can write the number 10 as a float with two digits on the rhs: print(f"{10:.2f}") 10.00 and full expressions are possible within the braces {} f-strings are definitely my preference - keeping what you're interpolating into the string closely coupled with how you're doing so just seems like a massive win in readability, maintainanbility, etc. From nickli.1540489 at gmail.com Sat Apr 4 16:14:13 2020 From: nickli.1540489 at gmail.com (Nick) Date: Sat, 4 Apr 2020 13:14:13 -0700 Subject: [Tutor] GUI program Message-ID: <5e88eaaa.1c69fb81.3e3de.6940@mx.google.com> You can try this code: ? import tkinter ? class MyGUI: ??? def __init__(self): ??????? self.main_window = tkinter.Tk() ??????? # Creates the frames ??????? self.top_frame = tkinter.Frame(self.main_window) ??????? self.bottom_frame = tkinter.Frame(self.main_window) ??????? # StringVar object to display in Label ??????? self.texta = tkinter.StringVar() ??????? self.textb = tkinter.StringVar() ??????? self.textc = tkinter.StringVar() ??????? # Creating the label and associate it with the StringVar object above ??????? self.name_label = tkinter.Label(self.top_frame, textvariable = self.texta) ??????? self.street_label = tkinter.Label(self.top_frame, textvariable = self.textb) ??????? self.state_label = tkinter.Label(self.top_frame, textvariable = self.textc) ??????? self.my_button = tkinter.Button(self.bottom_frame, text = 'Show Info', command = self.do_something) ??????? self.quit_button = tkinter.Button(self.bottom_frame, text = 'Quit', command = self.main_window.destroy) ??????? # Packing the Labels from top to bottom ??????? self.name_label.pack(side = 'top') ??????? self.street_label.pack(side = 'top') ??????? self.state_label.pack(side = 'top') ??????? # Packing the Buttons from left to right ??????? self.my_button.pack(side = 'left') ??????? self. quit_button.pack(side = 'left') ??????? # Packing the frames ??????? self.top_frame.pack() ??????? self.bottom_frame.pack() ??????? # Enter the tkinter main loop ??????? tkinter.mainloop() def do_something(self): ??? # Text Sets update the widgets above ??????? self.texta.set(Steven Marcus') ??????? self.textb.set('274 Baily Drive') ??????? self.textc.set('Waynesville, NC 27999') my_gui = MyGUI() ? Sent from [1]Mail for Windows 10 ? References Visible links 1. https://go.microsoft.com/fwlink/?LinkId=550986 From alan.gauld at yahoo.co.uk Sat Apr 4 19:50:53 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 5 Apr 2020 00:50:53 +0100 Subject: [Tutor] GUI program In-Reply-To: <5e88eaaa.1c69fb81.3e3de.6940@mx.google.com> References: <5e88eaaa.1c69fb81.3e3de.6940@mx.google.com> Message-ID: On 04/04/2020 21:14, Nick wrote: > You can try this code: I'm sure there are some very brave or foolhardy people who will run random code sent by a complete stranger on the internet. I'm not one of them. Can you tell us what you expect to gain from the post? Do you have a problem with the code? If so post any error messages or describe the issue. Or do you just want a code critique? (see below) Or somethoing else? > import tkinter > > class MyGUI: > ??? def __init__(self): > ??????? self.main_window = tkinter.Tk() > ??????? self.top_frame = tkinter.Frame(self.main_window) > ??????? self.bottom_frame = tkinter.Frame(self.main_window) > ??????? self.texta = tkinter.StringVar() > ??????? self.textb = tkinter.StringVar() > ??????? self.textc = tkinter.StringVar() > ??????? self.name_label = tkinter.Label(self.top_frame, textvariable = self.texta) > ??????? self.street_label = tkinter.Label(self.top_frame, textvariable = self.textb) > ??????? self.state_label = tkinter.Label(self.top_frame, textvariable = self.textc) > ??????? self.my_button = tkinter.Button(self.bottom_frame, text = 'Show Info', command = self.do_something) > ??????? self.quit_button = tkinter.Button(self.bottom_frame, text = 'Quit', command = self.main_window.destroy) > ??????? # Packing the Labels from top to bottom > ??????? self.name_label.pack(side = 'top') > ??????? self.street_label.pack(side = 'top') > ??????? self.state_label.pack(side = 'top') > ??????? # Packing the Buttons from left to right > ??????? self.my_button.pack(side = 'left') > ??????? self. quit_button.pack(side = 'left') > ??????? # Packing the frames > ??????? self.top_frame.pack() > ??????? self.bottom_frame.pack() > ??????? # Enter the tkinter main loop > ??????? tkinter.mainloop() Shouldn't that be self.main_window.mainloop() > def do_something(self): This needs to be aligned with the def __init__() line above. > ??? # Text Sets update the widgets above > ??????? self.texta.set(Steven Marcus') > ??????? self.textb.set('274 Baily Drive') > ??????? self.textc.set('Waynesville, NC 27999') > > my_gui = MyGUI() -- 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 akleider at sonic.net Sat Apr 4 21:53:51 2020 From: akleider at sonic.net (Alex Kleider) Date: Sat, 04 Apr 2020 18:53:51 -0700 Subject: [Tutor] Beginners question In-Reply-To: References: <9ce8306447a1a36279947ed0e514c3ad@sonic.net> <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info> <79f2d4c9bda941b781d87e96a735703b@sonic.net> <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info> Message-ID: I've been surprised not to have seen, in this thread, any mention made of the following use pattern: print("{first} {last}, {address}, {city}, {province}, {code}, {country}".format(**record)) Is this possible with any of the other (is it three) formatting methods? It's a pattern I've come to appreciate very very much. PS it is of course assumed that 'record' is a dict with values for keys 'first', 'last', .... From PyTutor at danceswithmice.info Sat Apr 4 23:05:57 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Sun, 5 Apr 2020 15:05:57 +1200 Subject: [Tutor] Beginners question In-Reply-To: References: <9ce8306447a1a36279947ed0e514c3ad@sonic.net> <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info> <79f2d4c9bda941b781d87e96a735703b@sonic.net> <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info> Message-ID: <2d23e677-4647-c1ea-db01-0112b2639418@DancesWithMice.info> On 5/04/20 1:53 PM, Alex Kleider wrote: > > I've been surprised not to have seen, in this thread, any mention made > of the following use pattern: > > print("{first} {last}, {address}, {city}, {province}, {code}, > {country}".format(**record)) > > Is this possible with any of the other (is it three) formatting methods? > It's a pattern I've come to appreciate very very much. +1 Possibly not as popular as deserved because it tastes of commercial application, and thus falls outside the ambit of scientists, data scientists, ML/AI engineers, liars, damned liars, statisticians... I dislike using relative positioning for anything (it slows reading/comprehension) - which condemns older string-formatting methods (in my eyes). If the mix of data-values and string-constants reaches a certain point, instead of throwing the usual tuple of data at print(), I find f-strings coming into play. Contrarily, when working with classes/objects I rapidly grew sick of writing self. or instanceNM. in front of every attribute to be printed! That in-turn became a recommendation for classes to include an as_dict() method (or two), eg class Person(): def __init__( self, first, last, ...): ... @property def address_as_dict( self ): return ... then the above print() becomes: print( "{first} {last}, {address}, {city}, {province}, {code}, {country}".format( instance.address_as_dict ) ) (even easier if that combination of fields is already a data-structure within the class) -- Regards =dn From __peter__ at web.de Sun Apr 5 05:27:07 2020 From: __peter__ at web.de (Peter Otten) Date: Sun, 05 Apr 2020 11:27:07 +0200 Subject: [Tutor] Formatting objects, was Re: Beginners question References: <9ce8306447a1a36279947ed0e514c3ad@sonic.net> <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info> <79f2d4c9bda941b781d87e96a735703b@sonic.net> <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info> <2d23e677-4647-c1ea-db01-0112b2639418@DancesWithMice.info> Message-ID: DL Neil via Tutor wrote: > On 5/04/20 1:53 PM, Alex Kleider wrote: >> >> I've been surprised not to have seen, in this thread, any mention made >> of the following use pattern: >> >> print("{first} {last}, {address}, {city}, {province}, {code}, >> {country}".format(**record)) >> >> Is this possible with any of the other (is it three) formatting methods? >> It's a pattern I've come to appreciate very very much. > > > +1 > > Possibly not as popular as deserved because it tastes of commercial > application, and thus falls outside the ambit of scientists, data > scientists, ML/AI engineers, liars, damned liars, statisticians... > > I dislike using relative positioning for anything (it slows > reading/comprehension) - which condemns older string-formatting methods > (in my eyes). > > If the mix of data-values and string-constants reaches a certain point, > instead of throwing the usual tuple of data at print(), I find f-strings > coming into play. > > Contrarily, when working with classes/objects I rapidly grew sick of > writing self. or instanceNM. in front of every attribute to be printed! > > That in-turn became a recommendation for classes to include an as_dict() > method (or two), eg > > class Person(): > def __init__( self, first, last, ...): > ... > @property > def address_as_dict( self ): > return ... > > then the above print() becomes: > > print( "{first} {last}, {address}, {city}, {province}, {code}, > {country}".format( instance.address_as_dict ) ) > > (even easier if that combination of fields is already a data-structure > within the class) An as_dict property (or method, to indicate it's not a lightweight operation) may often be useful, but if you are only requiring it for string formatting I'd rather write a helper function that can handle arbitrary objects: $ cat tmp.py class AsDictAdapter: def __init__(self, obj): self.obj = obj def __getitem__(self, name): try: return getattr(self.obj, name) except AttributeError: raise KeyError(name) def format_object(template, obj): return template.format_map(AsDictAdapter(obj)) class Person: def __init__(self, first, last, profession): self.first = first self.last = last self.profession = profession person = Person("Jim", "Knopf", "Lokomotivf?hrer") print(format_object("{last}, {first}: {profession}", person)) $ python3 tmp.py Knopf, Jim: Lokomotivf?hrer $ From mats at wichmann.us Sun Apr 5 09:44:05 2020 From: mats at wichmann.us (Mats Wichmann) Date: Sun, 5 Apr 2020 07:44:05 -0600 Subject: [Tutor] Beginners question In-Reply-To: References: <9ce8306447a1a36279947ed0e514c3ad@sonic.net> <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info> <79f2d4c9bda941b781d87e96a735703b@sonic.net> <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info> Message-ID: <7696656f-78f8-f2ee-3767-6ed16f6175ba@wichmann.us> On 4/4/20 7:53 PM, Alex Kleider wrote: > > I've been surprised not to have seen, in this thread, any mention made > of the following use pattern: > > print("{first} {last}, {address}, {city}, {province}, {code}, > {country}".format(**record)) > > Is this possible with any of the other (is it three) formatting methods? > It's a pattern I've come to appreciate very very much. > > PS it is of course assumed that 'record' is a dict with values for keys > 'first', 'last', .... I deal with a project codebase which does tons of that with %-style formatting in building up tests - the reasoning being that because some information is not known until runtime, constructing the test code or the expected responses is deferred until runtime, when things like path-to-the-test-directory are finally known. Example: sub1_f1a_out = os.path.join('sub1', 'f1a.out') sub2_f1b_out = os.path.join('sub2', 'f1b.out') sub1_f2a_out = os.path.join('sub1', 'f2a.out') sub2_f2b_out = os.path.join('sub2', 'f2b.out') expect = test.wrap_stdout("""\ batch_build(["%(sub1_f1a_out)s", "%(sub2_f1b_out)s"], ["f1a.in", "f1b.in"]) batch_build(["%(sub1_f2a_out)s", "%(sub2_f2b_out)s"], ["f2a.in", "f2b.in"]) """ % locals()) to understand this you need to know that locals() returns a dictionary of the values in the current local scope: >>> type(locals()) >>> greet = "Hello" >>> locals() {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': , '__spec__': None, '__annotations__': {}, '__builtins__': , 'x': 'Hello', 'greet': 'Hello'} and that %(key)s is the placeholder in the string to be substituted with the value picked from the dict. Frankly, there are other ways to solve this problem and this approach always makes me mildly queasy when I look at it. But is it possible? Yes. From alan.gauld at yahoo.co.uk Sun Apr 5 13:41:39 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 5 Apr 2020 18:41:39 +0100 Subject: [Tutor] Beginners question In-Reply-To: <2d23e677-4647-c1ea-db01-0112b2639418@DancesWithMice.info> References: <9ce8306447a1a36279947ed0e514c3ad@sonic.net> <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info> <79f2d4c9bda941b781d87e96a735703b@sonic.net> <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info> <2d23e677-4647-c1ea-db01-0112b2639418@DancesWithMice.info> Message-ID: On 05/04/2020 04:05, DL Neil via Tutor wrote: > Contrarily, when working with classes/objects I rapidly grew sick of > writing self. or instanceNM. in front of every attribute to be printed! You can of course override the __str__ method so you only need to say print(myobject) or print (" My object is ", myobject) But it is less flexible since you must decide in advance which fields and in which order/format they appear. But it is definitely more OO than accessing the fields directly just to print it! Which makes me wonder.... Does anyone know if thee are hooks into the formatting data that can be applied when writing a __str__ method? For example with floats you can specify width and precision options in the format string. It would be cool if there was a way to access those from within __str__() so that you could honor them (for example use them in fomatting numeric values before outputting the string representation.) But I suspect those specifiers are only visible in the string format method. As it is all you can do is specify string formatting, which boils down to length, padding and justification. -- 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 __peter__ at web.de Sun Apr 5 15:36:22 2020 From: __peter__ at web.de (Peter Otten) Date: Sun, 05 Apr 2020 21:36:22 +0200 Subject: [Tutor] Beginners question References: <9ce8306447a1a36279947ed0e514c3ad@sonic.net> <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info> <79f2d4c9bda941b781d87e96a735703b@sonic.net> <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info> <2d23e677-4647-c1ea-db01-0112b2639418@DancesWithMice.info> Message-ID: Alan Gauld via Tutor wrote: > On 05/04/2020 04:05, DL Neil via Tutor wrote: > >> Contrarily, when working with classes/objects I rapidly grew sick of >> writing self. or instanceNM. in front of every attribute to be printed! > > You can of course override the __str__ method so you only need to say > > print(myobject) > > or > > print (" My object is ", myobject) > > But it is less flexible since you must decide in advance which > fields and in which order/format they appear. > > But it is definitely more OO than accessing the fields directly > just to print it! Which makes me wonder.... > > Does anyone know if thee are hooks into the formatting data that > can be applied when writing a __str__ method? For example with floats > you can specify width and precision options in the format string. It > would be cool if there was a way to access those from within > __str__() so that you could honor them (for example use them > in fomatting numeric values before outputting the string > representation.) But I suspect those specifiers are only visible > in the string format method. > > As it is all you can do is specify string formatting, which > boils down to length, padding and justification. You can write a custom __format__() method: $ cat tmp.py class Person: def __init__(self, first, last): self.first = first self.last = last def __format__(self, spec): first = self.first last = self.last if spec == "debug": return f"{first=}, {last=}" elif spec == "long": return f"{first} {last}" elif spec == "short": return f"{first[:1]}{last[:1]}" elif spec == "": return str(self) raise ValueError(f"format_spec {spec!r} not supported") def __str__(self): return "S:" + format(self, "long") def __repr__(self): return "R:" + format(self, "debug") p = Person("Alan", "Gauld") print(f"default: {p}") print(f"debug: {p:debug}") print(f"explicit !s: {p!s}") print(f"explicit !r: {p!r}") print(f"long: {p:long}") print(f"short: {p:short}") $ python3.8 tmp.py default: S:Alan Gauld debug: first='Alan', last='Gauld' explicit !s: S:Alan Gauld explicit !r: R:first='Alan', last='Gauld' long: Alan Gauld short: AG $ From mambafrutty at gmail.com Sun Apr 5 18:31:22 2020 From: mambafrutty at gmail.com (K. Lunzner) Date: Mon, 6 Apr 2020 00:31:22 +0200 Subject: [Tutor] ArcPro Add Field Toolbox Message-ID: Hello everybody, I've been attending a Python course for a few weeks now. In this course we briefly went through the basics. Now we have to make an Add Field toolbox, similar to the original one (AddField_management). > import arcpy > arcpy.env.workspace ?C:?? > inputFC = arcpy.GetParameterAsText(0) > inputString = arcpy.GetParameterAsText(1) > fieldList =inputString.split(";") > inputString = arcpy.ValidateFieldName(inputString, arcpy.env.workspace) > fieldType = arcpy.GetParameterAsText(2) > fieldLength = arcpy.GetParameterAsText(2) > for fieldName in fieldList: > arcpy.AddField_management(inputFC , fieldName, fieldType) > > arcpy.AddMessage("Field created:" + fieldName) > arcpy.AddMessage ("Process completed") Problem 1: fieldLength The field should only be selectable if you enter "text" in the fieldtype. I tried: > def updateParameters(self): > if self.params[2].value: # check that parameter has a value > if self.params[2].value == "TEXT": > self.params[3].enabled = True > else: > self.params[3].enabled = False but it is not working Problem 2: ValidateField Entry with special characters or spacing is still possible. It appears in the table: ?A !? Problem 3: > existingFields = [f.name for f in arcpy.ListFields(inputFC)] > for fieldName in fieldList: > if fieldName in existingFields: > arcpy.AddMessage('Feld mit folgendem Name existiert bereits: %s'%(fieldName)) If the name of a field type already exists, a message should appear and inform the user. It still shows that the field was created. Tried a listfield function (iflen ..) but it didn't work either... I've been trying for days now and have gone through all Esri aids in the meantime, but haven't been able to solve any of these problems so far. Thank you very much for any help! From alan.gauld at yahoo.co.uk Sun Apr 5 18:50:07 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 5 Apr 2020 23:50:07 +0100 Subject: [Tutor] Beginners question In-Reply-To: References: <9ce8306447a1a36279947ed0e514c3ad@sonic.net> <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info> <79f2d4c9bda941b781d87e96a735703b@sonic.net> <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info> <2d23e677-4647-c1ea-db01-0112b2639418@DancesWithMice.info> Message-ID: On 05/04/2020 20:36, Peter Otten wrote: > Alan Gauld via Tutor wrote: >> Does anyone know if thee are hooks into the formatting data that >> can be applied when writing a __str__ method? > You can write a custom __format__() method: Cool. I completely missed that. Time to start reading the docs and having a play. Looking at the code below, does this only work with format strings? Or was it only introduced with format strings? I'm still on 3.6 so that may be why I've never seen it before... > class Person: > def __init__(self, first, last): > self.first = first > self.last = last > > def __format__(self, spec): > first = self.first > last = self.last > > if spec == "debug": > return f"{first=}, {last=}" > print(f"debug: {p:debug}") > debug: first='Alan', last='Gauld' -- 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 Apr 5 19:28:17 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 6 Apr 2020 00:28:17 +0100 Subject: [Tutor] OT: Membership status Message-ID: Just a FYI for those who were around prior to the great unsubscription event back in August The membership just climbed past 1000 again, we are getting close to pre-unsub numbers. :-) -- 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 PyTutor at danceswithmice.info Sun Apr 5 21:25:18 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Mon, 6 Apr 2020 13:25:18 +1200 Subject: [Tutor] OT: Membership status In-Reply-To: References: Message-ID: On 6/04/20 11:28 AM, Alan Gauld via Tutor wrote: > Just a FYI for those who were around prior to the great > unsubscription event back in August > > The membership just climbed past 1000 again, we are getting > close to pre-unsub numbers. :-) Thanks for all your efforts, Alan! -- Regards =dn From akleider at sonic.net Sun Apr 5 22:54:46 2020 From: akleider at sonic.net (Alex Kleider) Date: Sun, 05 Apr 2020 19:54:46 -0700 Subject: [Tutor] OT: Membership status In-Reply-To: References: Message-ID: <12001c623af77c90d4f4f37b0f3c3120@sonic.net> On 2020-04-05 18:25, DL Neil via Tutor wrote: > On 6/04/20 11:28 AM, Alan Gauld via Tutor wrote: >> Just a FYI for those who were around prior to the great >> unsubscription event back in August >> >> The membership just climbed past 1000 again, we are getting >> close to pre-unsub numbers. :-) > > > Thanks for all your efforts, Alan! ditto From cs at cskk.id.au Mon Apr 6 01:52:19 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Mon, 6 Apr 2020 15:52:19 +1000 Subject: [Tutor] Beginners question In-Reply-To: References: Message-ID: <20200406055219.GA96163@cskk.homeip.net> On 05Apr2020 23:50, Alan Gauld wrote: >Looking at the code below, does this only work with >format strings? Or was it only introduced with >format strings? I'm still on 3.6 so that may be why >I've never seen it before... > >> class Person: >> def __init__(self, first, last): >> self.first = first >> self.last = last >> >> def __format__(self, spec): >> first = self.first >> last = self.last >> >> if spec == "debug": >> return f"{first=}, {last=}" > >> print(f"debug: {p:debug}") > >> debug: first='Alan', last='Gauld' If you mean the "{first=}" notation, that is very recent. Maybe 3.8? Cheers, Cameron Simpson From gffaulkner at gmail.com Mon Apr 6 05:11:22 2020 From: gffaulkner at gmail.com (Gary) Date: Mon, 6 Apr 2020 11:11:22 +0200 Subject: [Tutor] Beginners question In-Reply-To: <20200406055219.GA96163@cskk.homeip.net> References: <20200406055219.GA96163@cskk.homeip.net> Message-ID: <000301d60bf3$5ab57c10$10207430$@com> Syntax error and multiple statement vs single statement partially sorted thanks when using IDLE. Thanks Gary Faulkner +27661755182 (W) -----Original Message----- From: Tutor [mailto:tutor-bounces+gffaulkner=gmail.com at python.org] On Behalf Of Cameron Simpson Sent: Monday, 06 April 2020 07:52 To: tutor at python.org Subject: Re: [Tutor] Beginners question On 05Apr2020 23:50, Alan Gauld wrote: >Looking at the code below, does this only work with >format strings? Or was it only introduced with >format strings? I'm still on 3.6 so that may be why >I've never seen it before... > >> class Person: >> def __init__(self, first, last): >> self.first = first >> self.last = last >> >> def __format__(self, spec): >> first = self.first >> last = self.last >> >> if spec == "debug": >> return f"{first=}, {last=}" > >> print(f"debug: {p:debug}") > >> debug: first='Alan', last='Gauld' If you mean the "{first=}" notation, that is very recent. Maybe 3.8? Cheers, Cameron Simpson _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From alan.gauld at yahoo.co.uk Mon Apr 6 05:41:19 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 6 Apr 2020 10:41:19 +0100 Subject: [Tutor] Beginners question In-Reply-To: <20200406055219.GA96163@cskk.homeip.net> References: <20200406055219.GA96163@cskk.homeip.net> Message-ID: On 06/04/2020 06:52, Cameron Simpson wrote: > On 05Apr2020 23:50, Alan Gauld wrote: >> Looking at the code below, does this only work with >> format strings? Or was it only introduced with >> format strings? I'm still on 3.6 so that may be why >> I've never seen it before... > If you mean the "{first=}" notation, that is very recent. Maybe 3.8? No, I meant the ability to provide a __format__() operation in a class. -- 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 Mon Apr 6 07:10:09 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 6 Apr 2020 12:10:09 +0100 Subject: [Tutor] Beginners question In-Reply-To: References: <20200406055219.GA96163@cskk.homeip.net> Message-ID: On 06/04/2020 10:41, Alan Gauld via Tutor wrote: >> If you mean the "{first=}" notation, that is very recent. Maybe 3.8? > > No, I meant the ability to provide a __format__() operation in a class. > Ok, I modified Peter's code to work in Python 3.6 with the format() string method and it worked. So obviously __format__ capability has been around for a while. I just missed it... This is very good news, it means there is no real valid reason for printing internal attributes of objects in production code (different for debugging). I like it! -- 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 breamoreboy at gmail.com Mon Apr 6 08:04:42 2020 From: breamoreboy at gmail.com (Mark Lawrence) Date: Mon, 6 Apr 2020 13:04:42 +0100 Subject: [Tutor] Beginners question In-Reply-To: References: <20200406055219.GA96163@cskk.homeip.net> Message-ID: On 06/04/2020 12:10, Alan Gauld via Tutor wrote: > On 06/04/2020 10:41, Alan Gauld via Tutor wrote: > >>> If you mean the "{first=}" notation, that is very recent. Maybe 3.8? >> >> No, I meant the ability to provide a __format__() operation in a class. >> > > Ok, I modified Peter's code to work in Python 3.6 with the > format() string method and it worked. > So obviously __format__ capability has been around for a while. > I just missed it... > Not by much https://docs.python.org/3/whatsnew/3.0.html#pep-3101-a-new-approach-to-string-formatting :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From mats at wichmann.us Mon Apr 6 12:23:37 2020 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 06 Apr 2020 10:23:37 -0600 Subject: [Tutor] ArcPro Add Field Toolbox In-Reply-To: References: Message-ID: <36C32319-A7FA-4298-9733-B8FDC5D84938@wichmann.us> If you don't get an answer, it may be because this is specialized stuff. I've certainly never heard of ArcPro / arcpy. Perhaps there's a community for it you could try? On April 5, 2020 4:31:22 PM MDT, "K. Lunzner" wrote: >Hello everybody, > > > >I've been attending a Python course for a few weeks now. In this course >we >briefly went through the basics. Now we have to make an Add Field >toolbox, >similar to the original one (AddField_management). > > > > > >> import arcpy > >> arcpy.env.workspace ?C:?? > >> inputFC = arcpy.GetParameterAsText(0) > >> inputString = arcpy.GetParameterAsText(1) > >> fieldList =inputString.split(";") > >> inputString = arcpy.ValidateFieldName(inputString, >arcpy.env.workspace) > >> fieldType = arcpy.GetParameterAsText(2) > >> fieldLength = arcpy.GetParameterAsText(2) > >> for fieldName in fieldList: > >> arcpy.AddField_management(inputFC , fieldName, fieldType) > >> > >> arcpy.AddMessage("Field created:" + fieldName) > >> arcpy.AddMessage ("Process completed") > > > >Problem 1: fieldLength > > > >The field should only be selectable if you enter "text" in the >fieldtype. I >tried: > > > >> def updateParameters(self): > >> if self.params[2].value: # check that parameter has a value > >> if self.params[2].value == "TEXT": > >> self.params[3].enabled = True > >> else: > >> self.params[3].enabled = False > > > >but it is not working > > > >Problem 2: ValidateField > >Entry with special characters or spacing is still possible. It appears >in >the table: ?A !? > > > >Problem 3: > > > >> existingFields = [f.name for f in arcpy.ListFields(inputFC)] > >> for fieldName in fieldList: > >> if fieldName in existingFields: > >> arcpy.AddMessage('Feld mit folgendem Name existiert bereits: >%s'%(fieldName)) > > > >If the name of a field type already exists, a message should appear and >inform the user. It still shows that the field was created. Tried a >listfield function (iflen ..) but it didn't work either... > > > >I've been trying for days now and have gone through all Esri aids in >the >meantime, but haven't been able to solve any of these problems so far. >Thank you very much for any help! >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor -- Sent from my Android device with K-9 Mail. Please excuse my brevity. From rbaer25 at gmail.com Wed Apr 8 06:28:06 2020 From: rbaer25 at gmail.com (Rudolf Baer) Date: Wed, 8 Apr 2020 12:28:06 +0200 Subject: [Tutor] spectutils Message-ID: <4728A745-7EC0-485E-84A2-30C5E0ECE467@gmail.com> I am working on a macbook pro OS X Yosemite 10.10.5, python 2.7 , jupyter notebook. The first code given in the the manual import numpy as np import astropy.units as u import matplotlib.pyplot as plt from specutils import Spectrum1D flux = np.random.randn(200)*u.Jy wavelength = np.arange(5100, 5300)*u.AA spec1d = Spectrum1D(spectral_axis=wavelength, flux=flux) ax = plt.subplots()[1] ax.plot(spec1d.spectral_axis, spec1d.flux) ax.set_xlabel("Dispersion") ax.set_ylabel("Flux?) ends in TypeError Traceback (most recent call last) in () 5 flux = np.random.randn(200)*u.Jy 6 wavelength = np.arange(5100, 5300)*u.AA ----> 7 spec1d = Spectrum1D(spectral_axis=wavelength, flux=flux) 8 ax = plt.subplots()[1] 9 ax.plot(spec1d.spectral_axis, spec1d.flux) TypeError: __init__() takes at least 3 arguments (2 given) How can this be fixed? with kind regards R. Baer From alan.gauld at yahoo.co.uk Wed Apr 8 09:46:36 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 8 Apr 2020 14:46:36 +0100 Subject: [Tutor] spectutils In-Reply-To: <4728A745-7EC0-485E-84A2-30C5E0ECE467@gmail.com> References: <4728A745-7EC0-485E-84A2-30C5E0ECE467@gmail.com> Message-ID: On 08/04/2020 11:28, Rudolf Baer wrote: > I am working on a macbook pro OS X Yosemite 10.10.5, python 2.7 , jupyter notebook. > from specutils import Spectrum1D > flux = np.random.randn(200)*u.Jy > wavelength = np.arange(5100, 5300)*u.AA > spec1d = Spectrum1D(spectral_axis=wavelength, flux=flux) > > TypeError Traceback (most recent call last) > in () > 6 wavelength = np.arange(5100, 5300)*u.AA > ----> 7 spec1d = Spectrum1D(spectral_axis=wavelength, flux=flux) > > TypeError: __init__() takes at least 3 arguments (2 given) This isn't really a python issue but a specutils package issue. If you are very lucky you will find a user of specutils on this list who can help, but you may need to ask on a specutils forum (or at least the SciPy forum where you are more likely to find a fellow user). The basic error is self explanatory, your code doesn't provide enough arguments. But unless we see the definition of the SpectrumID __init__() method we can't guess what the missing item is. You might get a clue by using the built in help: >>> import specutils >>> help(specutils.SpectrumID) But that depends a lot on how diligent the author of the package was in writing documentation. -- 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 __peter__ at web.de Wed Apr 8 11:51:35 2020 From: __peter__ at web.de (Peter Otten) Date: Wed, 08 Apr 2020 17:51:35 +0200 Subject: [Tutor] spectutils References: <4728A745-7EC0-485E-84A2-30C5E0ECE467@gmail.com> Message-ID: Rudolf Baer wrote: > I am working on a macbook pro OS X Yosemite 10.10.5, python 2.7 , jupyter > notebook. The first code given in the the manual > > import numpy as np > import astropy.units as u > import matplotlib.pyplot as plt > from specutils import Spectrum1D > flux = np.random.randn(200)*u.Jy > wavelength = np.arange(5100, 5300)*u.AA > spec1d = Spectrum1D(spectral_axis=wavelength, flux=flux) > ax = plt.subplots()[1] > ax.plot(spec1d.spectral_axis, spec1d.flux) > ax.set_xlabel("Dispersion") > ax.set_ylabel("Flux?) > > ends in > > TypeError Traceback (most recent call > last) in () > 5 flux = np.random.randn(200)*u.Jy > 6 wavelength = np.arange(5100, 5300)*u.AA > ----> 7 spec1d = Spectrum1D(spectral_axis=wavelength, flux=flux) > 8 ax = plt.subplots()[1] > 9 ax.plot(spec1d.spectral_axis, spec1d.flux) > > TypeError: __init__() takes at least 3 arguments (2 given) Judging by the code in https://github.com/astropy/specutils/blame/master/specutils/spectra/spectrum1d.py#L51 the code you gave above will not fail with the current Spectrum1D.__init__(). So you seem to be using the current documentation in combination with an outdated implementation. > How can this be fixed? I suggest that you switch to Python 3 and a specutils version that is a bit more up-to-date (specutils 1.0 requires Python 3.5): https://pypi.org/project/specutils/ https://specutils.readthedocs.io/en/stable/installation.html From jf_byrnes at comcast.net Wed Apr 8 14:52:15 2020 From: jf_byrnes at comcast.net (Jim) Date: Wed, 8 Apr 2020 13:52:15 -0500 Subject: [Tutor] Pyautogui clicking on a modal pop-up dialog Message-ID: I am using OOSheet and Pyautogui to update a Libreoffice calc sheet. The following code snippet works until it hits the paste() function. cols_to_copy = copy_cellrange() # Copy the columns necessary to calculate the portfolios diversity colA = S(cols_to_copy[0]).copy() S('Diversification.R1').paste() pyautogui.click() Once I get to paste() it pops up a Libreoffice dialog warning me I am pasting into cells that contain data, do I want to paste. The cursor sits over the OK button but the click() never runs. Is there anyway to get Pyautogui to click the button? Thanks, Jim From jf_byrnes at comcast.net Wed Apr 8 15:28:45 2020 From: jf_byrnes at comcast.net (Jim) Date: Wed, 8 Apr 2020 14:28:45 -0500 Subject: [Tutor] Pyautogui clicking on a modal pop-up dialog [solved] Message-ID: I am using OOSheet and Pyautogui to update a Libreoffice calc sheet. The following code snippet works until it hits the paste() function. cols_to_copy = copy_cellrange() # Copy the columns necessary to calculate the portfolios diversity colA = S(cols_to_copy[0]).copy() S('Diversification.R1').paste() pyautogui.click() Once I get to paste() it pops up a Libreoffice dialog warning me I am pasting into cells that contain data, do I want to paste. The cursor sits over the OK button but the click() never runs. Is there anyway to get Pyautogui to click the button? Thanks, Jim If I use the following code the pop-up does not appear so I don't need Pyautogui. cols_to_copy = copy_cellrange() # Copy the columns necessary to calculate the portfolios diversity colA = S(cols_to_copy[0]).copy() # ~ S('Diversification.R1').paste() S().dispatch('GoToCell', ('ToPoint', 'Diversification.R1')) S().dispatch('PasteSpecial', ('Format', 0)) Note: My original message hasn't appeared yet so I could not reply to it. Regards, Jim From PyTutor at danceswithmice.info Wed Apr 8 19:58:53 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Thu, 9 Apr 2020 11:58:53 +1200 Subject: [Tutor] Pyautogui clicking on a modal pop-up dialog [solved] In-Reply-To: References: Message-ID: On 9/04/20 7:28 AM, Jim wrote: > Is there anyway to get Pyautogui to click the button? > If I use the following code the pop-up does not appear so I don't need > Pyautogui. > > cols_to_copy = copy_cellrange() > # Copy the columns necessary to calculate the portfolios diversity > colA = S(cols_to_copy[0]).copy() > # ~ S('Diversification.R1').paste() > S().dispatch('GoToCell', ('ToPoint', 'Diversification.R1')) > S().dispatch('PasteSpecial', ('Format', 0)) Well done for solving your own problem! (I was going to suggest clearing the cell first, or Paste-Special, but only off-the-top-of-my-head...) > Note: My original message hasn't appeared yet so I could not reply to it. Yes, and we won't even blame Comcast (!). Mailman seems to have had a hold-up/pause during the evening (your time). -- Regards =dn From jf_byrnes at comcast.net Wed Apr 8 20:38:40 2020 From: jf_byrnes at comcast.net (Jim) Date: Wed, 8 Apr 2020 19:38:40 -0500 Subject: [Tutor] Pyautogui clicking on a modal pop-up dialog [solved] In-Reply-To: References: Message-ID: On 4/8/20 6:58 PM, DL Neil via Tutor wrote: > On 9/04/20 7:28 AM, Jim wrote: >> Is there anyway to get Pyautogui to click the button? > >> If I use the following code the pop-up does not appear so I don't need >> Pyautogui. >> >> cols_to_copy = copy_cellrange() >> # Copy the columns necessary to calculate the portfolios diversity >> colA = S(cols_to_copy[0]).copy() >> # ~ S('Diversification.R1').paste() >> S().dispatch('GoToCell', ('ToPoint', 'Diversification.R1')) >> S().dispatch('PasteSpecial', ('Format', 0)) > > Well done for solving your own problem! > (I was going to suggest clearing the cell first, or Paste-Special, but > only off-the-top-of-my-head...) Clearing the cells probable would have worked. I never even considered doing it. Turned out for the better though. Because it made me learn more about how to use dispatch() with OOSheet. > >> Note: My original message hasn't appeared yet so I could not reply to it. > Yes, and we won't even blame Comcast (!). Mailman seems to have had a > hold-up/pause during the evening (your time). Could be though sometimes I think my email is somehow listed as bad. I used to be able to post to the libreoffice group but now nothing goes through. Regards, JIm From peterjennings1999 at gmail.com Thu Apr 9 02:03:59 2020 From: peterjennings1999 at gmail.com (Peter Jennings) Date: Thu, 9 Apr 2020 16:03:59 +1000 Subject: [Tutor] Question Message-ID: <95502E26-C846-40B1-AFF9-993F542F9375@gmail.com> Hey Guys, I?m relatively new to Python and I have to complete a coding unit with my University course. I?ve been struggling to complete this question I have been given. Essentially, we got an extensive Dataset on car crashes which has a number of columns (index, age, year, crash month, crash day, crash time, road user, gender, crash type) and thousands of data records. I have to create a function which inputs four variables; crash month, crash day, crash time and year and outputs a day of the week Monday - Sunday, the time of the day characterised into Morning, Afternoon, Evening and Night and the season and if any input parameter is incorrect the function returns INVALID in all outputs. I was wondering if you had any advice on this, I?m really struggling. I?ve attached the question to see if you had any pointers. Thanks, Peter From reply.here at rocketmail.com Thu Apr 9 00:19:34 2020 From: reply.here at rocketmail.com (Niro One) Date: Thu, 9 Apr 2020 04:19:34 +0000 (UTC) Subject: [Tutor] Python ConfigParser Tkinter update configuration file between modules References: <919686033.1931539.1586405974930.ref@mail.yahoo.com> Message-ID: <919686033.1931539.1586405974930@mail.yahoo.com> I have two Tkinter windows main and configuration. Main window provides button link to configuration. In configuration main window editable. Configuration window provides button link for main window return. Configuration edit successful at Sypder IDE print. Configuration edit successful at write to disk. Returning to main window, configuration update FAIL.? Close/restart main update PASS. Close/restart configuration update PASS. Changing 'r' to 'r+' at read_file wipes out configuration write. Thanks for having a look! '''mdf.py''' import os import sysimport cnfimport tkinter as tk from configparser import ConfigParser config = ConfigParser(allow_no_value=True) cfg_key = 0 if os.path.isfile('ini.ini') and os.access('ini.ini', os.R_OK):? ? try:? ? ? ? with open ('ini.ini', 'r') as cfg:? ? ? ? ? ? config.read_file(cfg)? ? ? ? ? ? print (config.sections())? ? ? ? ? ??? ? ? ? ? ? """[ins_exe]"""? ? ? ? ? ? ins_exe = config.get('ins_exe', 'ins_exe') ? ? ? ? ? ? cfg.close()??? ? except:? ? ? ? cfg_key = 1? ? ? ? print ("INI_ERR")? ? ? ? print () else:? ? cfg_key = 1? ? print ("INI_BAK")? ? print () if cfg_key == 1:? ? print ("INI_SET")? ? print () ? ? """[ins_exe]"""? ? ins_exe = '0' class Application(tk.Frame):? ? def __init__(self, *args, **kwargs):? ? ? ? super().__init__(*args, **kwargs)? ? ? ? self.GetChk() ? ? def GetChk(self):? ? ? ? lbl_mdf = tk.StringVar()? ? ? ? lbl_mdf = tk.Label(self.master, text='mdf_exe')? ? ? ? lbl_mdf.place(x=35, y=15)? ? ? ? global ent_mdf? ? ? ? ent_mdf = tk.StringVar()? ? ? ? ent_mdf = tk.Entry(self.master, width=10, justify=tk.CENTER)? ? ? ? ent_mdf.place(x=25, y=40)? ? ? ? ent_mdf.insert(0, (ins_exe))? ? ? ? rtn_cnf = tk.Button(self.master, text='cnf_fmt', width=10,? ? ? ? ? ? ? ? ? ? ? ? ? ? command=self.CnfOpn)? ? ? ? rtn_cnf.place(x=115, y=20)? ? ? ? run = tk.Button(self.master, text='mdf_exe', width=10,? ? ? ? ? ? ? ? ? ? ? ? command=self.ChkOut)? ? ? ? run.place(x=115, y=55)? ??? ? def ChkOut(self):? ? ? ? print ('mdf_exe =', ent_mdf.get())? ? ? ? self.FileOpn()? ??? ? def CnfOpn(self, *args):? ? ? ? print ('mdf_cfg')? ? ? ? ask_cfg = tk.messagebox.askokcancel('mdf', " proceed cnf_fmt ? ")? ? ? ? if ask_cfg == True:? ? ? ? ? ? self.master.destroy()? ? ? ? ? ? cnf.CreateConfiguration()? ? ? ? else:? ? ? ? ? ? pass? ??? ? def FileOpn(self):? ? ? ? stdoutOrigin=sys.stdout?? ? ? ? sys.stdout = open('MAIN.txt', 'w')? ? ? ? print ("%")? ? ? ? print ()? ? ? ? print ('mdf_exe =', ent_mdf.get())? ? ? ? print ()? ? ? ? print ("%")? ? ? ? sys.stdout.close()? ? ? ? sys.stdout=stdoutOrigin def CreateApplication():? ? root = tk.Tk()? ? root.title('mdf')? ? root.geometry('210x100+125+250')? ? root.resizable(0,0)? ? app = Application(root)? ? app.mainloop()? ??if __name__ == "__main__":? ? CreateApplication() '''cnf.py''' import osimport mdfimport tkinter as tk from configparser import ConfigParser config = ConfigParser(allow_no_value=True) cfg_key = 0 if os.path.isfile('ini.ini') and os.access('ini.ini', os.R_OK):? ? try:? ? ? ? with open ('ini.ini', 'r') as cfg:? ? ? ? ? ? config.read_file(cfg)? ? ? ? ? ? print (config.sections())? ? ? ? ? ??? ? ? ? ? ? """[ins_exe]"""? ? ? ? ? ? ins_exe = config.get('ins_exe', 'ins_exe') ? ? ? ? ? ? cfg.close()? ??? ? except:? ? ? ? cfg_key = 1? ? ? ? print ("INI_ERR")? ? ? ? print () else:? ? cfg_key = 1? ? print ("INI_BAK")? ? print () if cfg_key == 1:? ??? ? print ("INI_SET")? ? print () ? ? """[ins_exe]"""? ? ins_exe = '0' class Configuration(tk.Frame):? ? def __init__(self, *args, **kwargs):? ? ? ? super().__init__(*args, **kwargs)? ? ? ? self.GetChk() ? ? def GetChk(self): ? ? ? ? lbl_cnf = tk.StringVar()? ? ? ? lbl_cnf = tk.Label(self.master, text='cnf_fmt')? ? ? ? lbl_cnf.place(x=35, y=15)? ? ? ? global ent_cnf? ? ? ? ent_cnf = tk.StringVar()? ? ? ? ent_cnf = tk.Entry(self.master, width=10, justify=tk.CENTER)? ? ? ? ent_cnf.place(x=25, y=40)? ? ? ? ent_cnf.insert(0, (ins_exe))? ? ? ? rtn_mdf = tk.Button(self.master, text='mdf_exe', width=10,? ? ? ? ? ? ? ? ? ? ? ? ? ? command=self.MdfOpn)? ? ? ? rtn_mdf.place(x=115, y=20)? ? ? ? run = tk.Button(self.master, text='cnf_fmt', width=10,? ? ? ? ? ? ? ? ? ? ? ? command=self.ChkOut)? ? ? ? run.place(x=115, y=55)? ??? ? def ChkOut(self):? ? ? ? print ('cnf_fmt =', ent_cnf.get())? ? ? ? self.FileOpn() ? ? def MdfOpn(self, *args):? ? ? ? print ('mdf_cfg')? ? ? ? ask_cfg = tk.messagebox.askokcancel('cnf', " proceed mdf_exe ? ")? ? ? ? if ask_cfg == True:? ? ? ? ? ? self.master.destroy()? ? ? ? ? ? mdf.CreateApplication()? ? ? ? else:? ? ? ? ? ? pass ? ? def FileOpn(self):? ? ? ??? ? ? ? ins_exe =? ent_cnf.get()? ? ? ??? ? ? ? config['ins_exe'] = {? ? ? ? ? ? ? ? 'ins_exe' : ins_exe,? ? ? ? ? ? ? ? }? ? ? ??? ? ? ??? ? ? ? with open('ini.ini', 'w+') as cfg:? ? ? ? ? ? print ('cnf_fmt = ini_w+')? ? ? ? ? ? config.write(cfg)? ? ? ? ? ? cfg.close() def CreateConfiguration():? ? root = tk.Tk()? ? root.title('cnf')? ? root.geometry('210x100+300+300')? ? root.resizable(0,0)? ? app = Configuration(root)? ? app.mainloop()? ??if __name__ == "__main__":? ? CreateConfiguration() From joel.goldstick at gmail.com Thu Apr 9 04:38:22 2020 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Thu, 9 Apr 2020 04:38:22 -0400 Subject: [Tutor] Question In-Reply-To: <95502E26-C846-40B1-AFF9-993F542F9375@gmail.com> References: <95502E26-C846-40B1-AFF9-993F542F9375@gmail.com> Message-ID: On Thu, Apr 9, 2020 at 4:06 AM Peter Jennings wrote: > > Hey Guys, > > I?m relatively new to Python and I have to complete a coding unit with my University course. > > I?ve been struggling to complete this question I have been given. Essentially, we got an extensive Dataset on car crashes which has a number of columns (index, age, year, crash month, crash day, crash time, road user, gender, crash type) and thousands of data records. I have to create a function which inputs four variables; crash month, crash day, crash time and year and outputs a day of the week Monday - Sunday, the time of the day characterised into Morning, Afternoon, Evening and Night and the season and if any input parameter is incorrect the function returns INVALID in all outputs. I was wondering if you had any advice on this, I?m really struggling. I?ve attached the question to see if you had any pointers. > > Thanks, > Peter > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor Welcome. This list doesn't allow attachments. Cut and paste a single line of your data set here. What is it that you know how to do? Have you written code to read the data set? How have you decided to store the data? For instance, using a list of dictionaries? If you can write the code to read the data set you are well on your way. If you can write code to input the parameters asked for, you are further on your way. Try those tasks and come back with your code and your next question(s). Good luck -- Joel Goldstick http://joelgoldstick.com/blog http://cc-baseballstats.info/stats/birthdays From alan.gauld at yahoo.co.uk Thu Apr 9 04:43:44 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 9 Apr 2020 09:43:44 +0100 Subject: [Tutor] Question In-Reply-To: <95502E26-C846-40B1-AFF9-993F542F9375@gmail.com> References: <95502E26-C846-40B1-AFF9-993F542F9375@gmail.com> Message-ID: On 09/04/2020 07:03, Peter Jennings wrote: > we got an extensive Dataset on car crashes > which has a number of columns > (index, age, year, crash month, crash day, crash time, road user, gender, crash type) Can you read that dataset one line at a time into a tuple? > I have to create a function which inputs four variables; crash month, crash day, crash time and year > and outputs a day of the week, the time of the day and the season> and if any input parameter is incorrect the function returns INVALID in all outputs. Can you create such a function? And, although you don't explicitly say that you need to, can you call the function using data selected from your input tuples? Finally, what are you expected to output? Another file perhaps? In the format of your function output? Do you know how to do that? > I?ve attached the question to see if you had any pointers. This is a text only list so any non text attachments get stripped by the server. Tell us which parts you are having problems with. Show us the code you have so far. Explain what's wrong(include any error messages) We will try to help you reach your goal. -- 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 PyTutor at danceswithmice.info Thu Apr 9 04:46:09 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Thu, 9 Apr 2020 20:46:09 +1200 Subject: [Tutor] Question In-Reply-To: <95502E26-C846-40B1-AFF9-993F542F9375@gmail.com> References: <95502E26-C846-40B1-AFF9-993F542F9375@gmail.com> Message-ID: <9ef8dc8c-d6c9-88b0-350c-6e656d5a9289@DancesWithMice.info> > I?m relatively new to Python and I have to complete a coding unit with my University course. How much Python have you done? > I?ve been struggling to complete this question I have been given. Essentially, we got an extensive Dataset on car crashes which has a number of columns (index, age, year, crash month, crash day, crash time, road user, gender, crash type) and thousands of data records. I have to create a function which inputs four variables; crash month, crash day, crash time and year and outputs a day of the week Monday - Sunday, the time of the day characterised into Morning, Afternoon, Evening and Night and the season and if any input parameter is incorrect the function returns INVALID in all outputs. I was wondering if you had any advice on this, I?m really struggling. I?ve attached the question to see if you had any pointers. NB either not attached, or perhaps the format is not acceptable to the mailing list - it should be a text format. Firstly, understand your data and detect patterns which you could use to organise, eg does it make sense to talk about "...month...day...time..." and then "year"? Does "year" belong first in that sequence? (see also ISO 8601) Then look at each control parameter in-turn, eg "day of the week". How will you transform the data-provided into such terms? Thus, will you be able to define "valid" or "invalid" for each record? If you need to ask further questions, please copy-paste your Python code into your email message to give us something concrete we can help you with. -- Regards =dn From alan.gauld at yahoo.co.uk Thu Apr 9 04:45:43 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 9 Apr 2020 09:45:43 +0100 Subject: [Tutor] Python ConfigParser Tkinter update configuration file between modules In-Reply-To: <919686033.1931539.1586405974930@mail.yahoo.com> References: <919686033.1931539.1586405974930.ref@mail.yahoo.com> <919686033.1931539.1586405974930@mail.yahoo.com> Message-ID: The tutor list requires plain text to retain code formatting. As you will see below your code is so screwed up its impossible to guess what it loked ike originally. Please repost using plain text. On 09/04/2020 05:19, Niro One via Tutor wrote: > I have two Tkinter windows main and configuration. Main window provides button link to configuration. In configuration main window editable. Configuration window provides button link for main window return. Configuration edit successful at Sypder IDE print. Configuration edit successful at write to disk. Returning to main window, configuration update FAIL.? > > Close/restart main update PASS. Close/restart configuration update PASS. > Changing 'r' to 'r+' at read_file wipes out configuration write. > Thanks for having a look! > > '''mdf.py''' > import os > import sysimport cnfimport tkinter as tk > from configparser import ConfigParser > config = ConfigParser(allow_no_value=True) > cfg_key = 0 > if os.path.isfile('ini.ini') and os.access('ini.ini', os.R_OK):? ? try:? ? ? ? with open ('ini.ini', 'r') as cfg:? ? ? ? ? ? config.read_file(cfg)? ? ? ? ? ? print (config.sections())? ? ? ? ? ??? ? ? ? ? ? """[ins_exe]"""? ? ? ? ? ? ins_exe = config.get('ins_exe', 'ins_exe') > ? ? ? ? ? ? cfg.close()??? ? except:? ? ? ? cfg_key = 1? ? ? ? print ("INI_ERR")? ? ? ? print () > else:? ? cfg_key = 1? ? print ("INI_BAK")? ? print () > if cfg_key == 1:? ? print ("INI_SET")? ? print () > ? ? """[ins_exe]"""? ? ins_exe = '0' > class Application(tk.Frame):? ? def __init__(self, *args, **kwargs):? ? ? ? super().__init__(*args, **kwargs)? ? ? ? self.GetChk() > ? ? def GetChk(self):? ? ? ? lbl_mdf = tk.StringVar()? ? ? ? lbl_mdf = tk.Label(self.master, text='mdf_exe')? ? ? ? lbl_mdf.place(x=35, y=15)? ? ? ? global ent_mdf? ? ? ? ent_mdf = tk.StringVar()? ? ? ? ent_mdf = tk.Entry(self.master, width=10, justify=tk.CENTER)? ? ? ? ent_mdf.place(x=25, y=40)? ? ? ? ent_mdf.insert(0, (ins_exe))? ? ? ? rtn_cnf = tk.Button(self.master, text='cnf_fmt', width=10,? ? ? ? ? ? ? ? ? ? ? ? ? ? command=self.CnfOpn)? ? ? ? rtn_cnf.place(x=115, y=20)? ? ? ? run = tk.Button(self.master, text='mdf_exe', width=10,? ? ? ? ? ? ? ? ? ? ? ? command=self.ChkOut)? ? ? ? run.place(x=115, y=55)? ??? ? def ChkOut(self):? ? ? ? print ('mdf_exe =', ent_mdf.get())? ? ? ? self.FileOpn()? ??? ? def CnfOpn(self, *args):? ? ? ? print ('mdf_cfg')? ? ? ? ask_cfg = tk.messagebox.askokcancel('mdf', " proceed cnf_fmt ? ")? ? ? ? if ask_cfg == True:? ? ? ? ? ? self.master.destroy()? ? ? ? ? ? cnf.CreateConfiguration()? ? ? ? else:? ? ? ? ? ? pass? ??? ? def FileOpn(self):? ? ? ? stdoutOrigin=sys.stdout?? ? ? ? sys.stdout = open('MAIN.txt', 'w')? ? ? ? print ("%")? ? ? ? print ()? ? ? ? print ('mdf_exe =', ent_mdf.get())? ? ? ? print ()? ? ? ? print ("%")? ? ? ? sys.stdout.close()? ? ? ? sys.stdout=stdoutOrigin > def CreateApplication():? ? root = tk.Tk()? ? root.title('mdf')? ? root.geometry('210x100+125+250')? ? root.resizable(0,0)? ? app = Application(root)? ? app.mainloop()? ??if __name__ == "__main__":? ? CreateApplication() > > '''cnf.py''' > import osimport mdfimport tkinter as tk > from configparser import ConfigParser > config = ConfigParser(allow_no_value=True) > cfg_key = 0 > if os.path.isfile('ini.ini') and os.access('ini.ini', os.R_OK):? ? try:? ? ? ? with open ('ini.ini', 'r') as cfg:? ? ? ? ? ? config.read_file(cfg)? ? ? ? ? ? print (config.sections())? ? ? ? ? ??? ? ? ? ? ? """[ins_exe]"""? ? ? ? ? ? ins_exe = config.get('ins_exe', 'ins_exe') > ? ? ? ? ? ? cfg.close()? ??? ? except:? ? ? ? cfg_key = 1? ? ? ? print ("INI_ERR")? ? ? ? print () > else:? ? cfg_key = 1? ? print ("INI_BAK")? ? print () > if cfg_key == 1:? ??? ? print ("INI_SET")? ? print () > ? ? """[ins_exe]"""? ? ins_exe = '0' > class Configuration(tk.Frame):? ? def __init__(self, *args, **kwargs):? ? ? ? super().__init__(*args, **kwargs)? ? ? ? self.GetChk() > ? ? def GetChk(self): > ? ? ? ? lbl_cnf = tk.StringVar()? ? ? ? lbl_cnf = tk.Label(self.master, text='cnf_fmt')? ? ? ? lbl_cnf.place(x=35, y=15)? ? ? ? global ent_cnf? ? ? ? ent_cnf = tk.StringVar()? ? ? ? ent_cnf = tk.Entry(self.master, width=10, justify=tk.CENTER)? ? ? ? ent_cnf.place(x=25, y=40)? ? ? ? ent_cnf.insert(0, (ins_exe))? ? ? ? rtn_mdf = tk.Button(self.master, text='mdf_exe', width=10,? ? ? ? ? ? ? ? ? ? ? ? ? ? command=self.MdfOpn)? ? ? ? rtn_mdf.place(x=115, y=20)? ? ? ? run = tk.Button(self.master, text='cnf_fmt', width=10,? ? ? ? ? ? ? ? ? ? ? ? command=self.ChkOut)? ? ? ? run.place(x=115, y=55)? ??? ? def ChkOut(self):? ? ? ? print ('cnf_fmt =', ent_cnf.get())? ? ? ? self.FileOpn() > ? ? def MdfOpn(self, *args):? ? ? ? print ('mdf_cfg')? ? ? ? ask_cfg = tk.messagebox.askokcancel('cnf', " proceed mdf_exe ? ")? ? ? ? if ask_cfg == True:? ? ? ? ? ? self.master.destroy()? ? ? ? ? ? mdf.CreateApplication()? ? ? ? else:? ? ? ? ? ? pass > ? ? def FileOpn(self):? ? ? ??? ? ? ? ins_exe =? ent_cnf.get()? ? ? ??? ? ? ? config['ins_exe'] = {? ? ? ? ? ? ? ? 'ins_exe' : ins_exe,? ? ? ? ? ? ? ? }? ? ? ??? ? ? ??? ? ? ? with open('ini.ini', 'w+') as cfg:? ? ? ? ? ? print ('cnf_fmt = ini_w+')? ? ? ? ? ? config.write(cfg)? ? ? ? ? ? cfg.close() > def CreateConfiguration():? ? root = tk.Tk()? ? root.title('cnf')? ? root.geometry('210x100+300+300')? ? root.resizable(0,0)? ? app = Configuration(root)? ? app.mainloop()? ??if __name__ == "__main__":? ? CreateConfiguration() > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- 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 reply.here at rocketmail.com Thu Apr 9 09:31:59 2020 From: reply.here at rocketmail.com (Niro One) Date: Thu, 9 Apr 2020 13:31:59 +0000 (UTC) Subject: [Tutor] Python ConfigParser Tkinter update configuration file between modules References: <167234205.2019874.1586439119288.ref@mail.yahoo.com> Message-ID: <167234205.2019874.1586439119288@mail.yahoo.com> Hi Alan Strange. First time, when sent, it did not appear garbled.Second time, sent to myself, did not?not appear garbled.Then forward you fellas. I have two Tkinter windows main (mdf.py) and configuration (cnf.py).?Main window provides button link to configuration. In configuration main?window editable. Configuration window provides button link for mainwindow return. Configuration edit successful at Sypder IPython Console.?Configuration edit successful at write to disk. Returning to main window,?configuration update FAIL. Close/restart main update PASS. Close/restart configuration update PASS. Changing 'r' to 'r+' at read_file wipes out configuration write. Sending both mdf.txt cnf.txt Thank-you for your patience. Sergio. -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: cnf.txt URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: mdf.txt URL: From reply.here at rocketmail.com Thu Apr 9 09:36:56 2020 From: reply.here at rocketmail.com (Niro One) Date: Thu, 9 Apr 2020 13:36:56 +0000 (UTC) Subject: [Tutor] re Python ConfigParser Tkinter PLAIN TXT ISSUE References: <197697460.2019059.1586439416446.ref@mail.yahoo.com> Message-ID: <197697460.2019059.1586439416446@mail.yahoo.com> Hi Alan using YMAIL at bottom switch to plain txt mode. I've never had this issue Below is snip of code plain txt enabled Kindly reply with 'result' '''mdf.py''' import os import sys import cnf import tkinter as tk from configparser import ConfigParser config = ConfigParser(allow_no_value=True) cfg_key = 0 if os.path.isfile('ini.ini') and os.access('ini.ini', os.R_OK): ? ? try: ? ? ? ? with open('ini.ini', 'r') as cfg: ? ? ? ? ? ? config.read_file(cfg) ? ? ? ? ? ? print(config.sections()) ? ? ? ? ? ?? ? ? ? ? ? ? """[ins_exe]""" ? ? ? ? ? ? ins_exe = config.get('ins_exe', 'ins_exe') From alan.gauld at yahoo.co.uk Thu Apr 9 12:47:04 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 9 Apr 2020 17:47:04 +0100 Subject: [Tutor] re Python ConfigParser Tkinter PLAIN TXT ISSUE In-Reply-To: <197697460.2019059.1586439416446@mail.yahoo.com> References: <197697460.2019059.1586439416446.ref@mail.yahoo.com> <197697460.2019059.1586439416446@mail.yahoo.com> Message-ID: On 09/04/2020 14:36, Niro One via Tutor wrote: > Hi Alan using YMAIL at bottom switch to plain txt mode. Yes that works. Please post using that option in future, its easier than opening attachments - when they get through the server.... > '''mdf.py''' > > import os > import sys > import cnf > import tkinter as tk > > > from configparser import ConfigParser > > > config = ConfigParser(allow_no_value=True) > > > cfg_key = 0 > > > if os.path.isfile('ini.ini') and os.access('ini.ini', os.R_OK): > ? ? try: > ? ? ? ? with open('ini.ini', 'r') as cfg: > ? ? ? ? ? ? config.read_file(cfg) -- 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 zulfadli.azh at gmail.com Fri Apr 10 05:10:34 2020 From: zulfadli.azh at gmail.com (Zulfadli Azhar) Date: Fri, 10 Apr 2020 19:10:34 +1000 Subject: [Tutor] Function - Python Message-ID: Hi Alan, I just started to learn Python this week. I have some confusion here. Please see below the code that I created. I supposed to come out with a Return #0000ff but it's not. def color_translator(color): if color == "red": hex_color = "#ff0000" elif color == "green": hex_color = "#00ff00" elif color == "blue": hex_color = "#0000ff" else: hex_color = "unknown" return "blue" print(color_translator("blue")) # Should be #0000ff print(color_translator("yellow")) # Should be unknown print(color_translator("red")) # Should be #ff0000 print(color_translator("black")) # Should be unknown print(color_translator("green")) # Should be #00ff00 print(color_translator("")) # Should be unknown Please do not tell me a direct answer but I need an explanation on how to come out with a Return #0000ff. I have 3 more questions to ask as I have spent my whole day today to figure get the correct code by referring from other sources. Thank you ZUL From alan.gauld at yahoo.co.uk Fri Apr 10 06:34:34 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 10 Apr 2020 11:34:34 +0100 Subject: [Tutor] Python ConfigParser Tkinter update configuration file between modules In-Reply-To: <167234205.2019874.1586439119288@mail.yahoo.com> References: <167234205.2019874.1586439119288.ref@mail.yahoo.com> <167234205.2019874.1586439119288@mail.yahoo.com> Message-ID: On 09/04/2020 14:31, Niro One via Tutor wrote: I've pasted you code below. The two classes are so close to identical that you should consider creating a superclass that they can both inherit from. Then you just need to write the changes in each and the common code will be shared. That aside, there are several common issues in the code (I ignored the config stuff at the top, it looks ok at a quick glance): import mdf ins_exe = config.get('ins_exe', 'ins_exe') class Configuration(tk.Frame): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.GetChk() def GetChk(self): lbl_cnf = tk.StringVar() lbl_cnf = tk.Label(self.master, text='cnf_fmt') lbl_cnf.place(x=35, y=15) Two things here. First if you want to access lbl_cnf outside this method you must declare it self.lbl_cnf otherwise the name dissappears when you exit the method. It is a local variable. Second, you create a StringVar then immediately throw it away by reassigning the variable to a Label. That makes no sense. I'm not sure what you thought would happen, but the first assignment is basically doing nothing. global ent_cnf This says look for a variable called ent_conf outside the class (and if it doesn't exist creates one) That's really bad practice in a class. Just create a class attribute called ent_cfg by adding a self prefix. ent_cnf = tk.StringVar() ent_cnf = tk.Entry(self.master, width=10, justify=tk.CENTER) ent_cnf.place(x=25, y=40) ent_cnf.insert(0, (ins_exe)) Same problem as before the StringVar is thrown away when you reassign the variable. Although you don't appear to be using the StringVars for anything so it doesn't matter apart from wasting a few machine cycles... rtn_mdf = tk.Button(self.master, text='mdf_exe', width=10, command=self.MdfOpn) rtn_mdf.place(x=115, y=20) run = tk.Button(self.master, text='cnf_fmt', width=10, command=self.ChkOut) run.place(x=115, y=55) def ChkOut(self): print('cnf_fmt =', ent_cnf.get()) self.FileOpn() def MdfOpn(self, *args): print('mdf_cfg') ask_cfg = tk.messagebox.askokcancel('cnf', " proceed mdf_exe ? ") if ask_cfg == True: self.master.destroy() mdf.CreateApplication() else: pass You seem to be closing the Tkinter GUI down then starting a new one, and then repeating to come back. Are you aware of the TopLevel widget that allows you to have multiple windows alive at the same time. You can then just hide/show them to control visibility. Its much more efficient (and faster0 that closing down the entire GUI framework and starting a new event loop each time. def FileOpn(self): ins_exe = ent_cnf.get() config['ins_exe'] = { 'ins_exe' : ins_exe, } with open('ini.ini', 'w+') as cfg: print('cnf_fmt = ini_w+') config.write(cfg) cfg.close() def CreateConfiguration(): root = tk.Tk() root.title('cnf') root.geometry('210x100+300+300') root.resizable(0, 0) app = Configuration(root) app.mainloop() if __name__ == "__main__": CreateConfiguration() -- 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 PyTutor at danceswithmice.info Fri Apr 10 07:13:09 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Fri, 10 Apr 2020 23:13:09 +1200 Subject: [Tutor] Function - Python In-Reply-To: References: Message-ID: <2828ce2c-4c75-2bbb-b036-1765b7253c52@DancesWithMice.info> On 10/04/20 9:10 PM, Zulfadli Azhar wrote: > I just started to learn Python this week. I have some confusion here. Which course are you attempting, or which book are you following? > Please see below the code that I created. I supposed to come out with a > Return #0000ff but it's not. > > def color_translator(color): > if color == "red": > hex_color = "#ff0000" > elif color == "green": > hex_color = "#00ff00" > elif color == "blue": > hex_color = "#0000ff" > else: > hex_color = "unknown" > return "blue" Notice how there is a change in the last two lines? See below, you are expecting the function to return an RGB-triplet, but above what is being returned on the last line? Which gives you a hint for dealing with the other three possibilities. What should be return-ed? Is there a statement to do-so? > print(color_translator("blue")) # Should be #0000ff > print(color_translator("yellow")) # Should be unknown > print(color_translator("red")) # Should be #ff0000 > print(color_translator("black")) # Should be unknown > print(color_translator("green")) # Should be #00ff00 > print(color_translator("")) # Should be unknown Here's a little extra idea for you: assert color_translator( "blue" ) == "0000ff" will smile at you if all is correct, but will raise an error (message) if not. The computer does the work and saves you from reading and checking - every time! > Please do not tell me a direct answer but I need an explanation on how to > come out with a Return #0000ff. Good for you, this is the way to learn! ...and there you have written your own answer! Perhaps you've spent so long looking at the problem, you've confused yourself. Sometimes it is a good idea to stop what's confusing you, and go off to do something else. Nine out of ten times: when you return the answer will be obvious... > I have 3 more questions to ask as I have spent my whole day today to figure > get the correct code by referring from other sources. One at a time helps stay organised! Please copy-paste the code straight into (simple-test) email. The above code has lost all indentation which may be 'hiding' other errors! -- Regards =dn From mats at wichmann.us Fri Apr 10 07:33:20 2020 From: mats at wichmann.us (Mats Wichmann) Date: Fri, 10 Apr 2020 05:33:20 -0600 Subject: [Tutor] Function - Python In-Reply-To: References: Message-ID: <53C4E968-97AC-44BD-B72C-D709BA25A64E@wichmann.us> On April 10, 2020 3:10:34 AM MDT, Zulfadli Azhar wrote: >Hi Alan, > >I just started to learn Python this week. I have some confusion here. >Please see below the code that I created. I supposed to come out with a >Return #0000ff but it's not. > >def color_translator(color): >if color == "red": >hex_color = "#ff0000" >elif color == "green": >hex_color = "#00ff00" >elif color == "blue": >hex_color = "#0000ff" >else: >hex_color = "unknown" >return "blue" > >print(color_translator("blue")) # Should be #0000ff >print(color_translator("yellow")) # Should be unknown >print(color_translator("red")) # Should be #ff0000 >print(color_translator("black")) # Should be unknown >print(color_translator("green")) # Should be #00ff00 >print(color_translator("")) # Should be unknown > >Please do not tell me a direct answer but I need an explanation on how >to >come out with a Return #0000ff. > >I have 3 more questions to ask as I have spent my whole day today to >figure >get the correct code by referring from other sources. > >Thank you >ZUL >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor when you call a function, it returns a value. the function can set that with the return statement, or if it doesn't have one, the special value None is returned. look at what you are returning... you take the trouble to set hex_value, but that isn't what you return. -- Sent from a mobile device with K-9 Mail. Please excuse my brevity. From Jon_Davies17 at hotmail.co.uk Fri Apr 10 12:20:55 2020 From: Jon_Davies17 at hotmail.co.uk (Jon Davies) Date: Fri, 10 Apr 2020 16:20:55 +0000 Subject: [Tutor] Use of states to control Tkinter app navigation Message-ID: Hi there, I've been progressing with the creation of my Petrol station Pay-at-pump app using Tkinter, which is aiming to provide language translation/currency conversion. I have been steered towards the use of states to help provide clearer navigation of my app, as well as provide the function to completely reset the app at various stages to a fresh instance (i.e. to reverse any changes to widgets, variables etc.). The concept of states seems simple and easy to understand, although again with my limited knowledge of implementation it has proven to be a bit of a challenge. I've made a duplicate of my previous working version of the file to test the functionality (see attached). I can provide the working code/file as well if needed. I've tried to implement the use of states to control the movement of frames through the buttons (i.e. instead of show_frame function that I have used previously). I've also tried to create individual restart methods for each frame using the state model. I think my syntax is now correct, but when I try to run it gives me "NameError: name 'SelectLanguagePage' is not defined" at line 36 (i.e. where I outline the state dictionary). I can only imagine this is because the states section is perhaps not in the right place? Or does each state/class need to be outlined within the init of each class? I've attached a video of the problems I was facing with my working file, i.e. the use of the show_frame function to navigate frames - it was not functioning properly and showing pages in strange orders depending on buttons clicked. Essentially, I want to the app to have simple navigation from start to finish through the use of the buttons (and states), i.e. select language > select payment type > select currency > start fuelling > finish page. Kind regards, Jon From mysecretrobotfactory at gmail.com Fri Apr 10 18:11:53 2020 From: mysecretrobotfactory at gmail.com (Chris C) Date: Fri, 10 Apr 2020 15:11:53 -0700 Subject: [Tutor] push a keyboard button to run a function Message-ID: Hi all: I am trying to invoke a function in my python code by using a keyboard keystroke. Alternatively, I need to change a variable's value from true to false and false to true everytime when I push this button, How can I do this? Thanks! From alan.gauld at yahoo.co.uk Fri Apr 10 19:16:44 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 11 Apr 2020 00:16:44 +0100 Subject: [Tutor] push a keyboard button to run a function In-Reply-To: References: Message-ID: On 10/04/2020 23:11, Chris C wrote: > I am trying to invoke a function in my python code by using a keyboard > keystroke. You need to tell us more. Is this a CLI program or a GUI? If a GUI which toolkit? Tkinter? wxPython? other... If a CLI which OS? If it is Unix like then the curses module is your friend. If its Windows the msvcrt module will help. > Alternatively, I need to change a variable's value from true to false and > false to true everytime when I push this button, > variable = not variable will toggle a boolean between true/false. But we need more context information to answer fully. Ideally some code (even if it doesn't work) to see what you are attempting. -- 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 Fri Apr 10 19:19:00 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 11 Apr 2020 00:19:00 +0100 Subject: [Tutor] Use of states to control Tkinter app navigation In-Reply-To: References: Message-ID: On 10/04/2020 17:20, Jon Davies wrote: > I've attached a video of the problems I was facing tutor is a text only list. We don't even see rich text let alone videos! You can post a link to the video, but any non-text attachments get lost in the server. -- 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 PyTutor at danceswithmice.info Fri Apr 10 19:53:36 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Sat, 11 Apr 2020 11:53:36 +1200 Subject: [Tutor] push a keyboard button to run a function In-Reply-To: References: Message-ID: <87f92e48-adbe-3e97-f892-ada149dd9bbc@DancesWithMice.info> On 11/04/20 11:16 AM, Alan Gauld via Tutor wrote: > On 10/04/2020 23:11, Chris C wrote: > >> I am trying to invoke a function in my python code by using a keyboard >> keystroke. > > You need to tell us more. > Is this a CLI program or a GUI? If a GUI which toolkit? > Tkinter? wxPython? other... > If a CLI which OS? If it is Unix like then the curses module > is your friend. > If its Windows the msvcrt module will help. > >> Alternatively, I need to change a variable's value from true to false and >> false to true everytime when I push this button, >> > > variable = not variable > > will toggle a boolean between true/false. > > But we need more context information to answer fully. > Ideally some code (even if it doesn't work) to see what > you are attempting. Concur. If the "keystroke" is/can be the Enter key, then an input() will do. There is a keyboard library in Pypi (https://pypi.org/project/keyboard/) See also curses, Pygame, and more... -- Regards =dn From robertvstepp at gmail.com Sat Apr 11 01:57:19 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 11 Apr 2020 00:57:19 -0500 Subject: [Tutor] Using string formatting inside function docstrings Message-ID: I was looking at an online article, "Python 101 ? Working with Strings", at https://www.blog.pythonlibrary.org/2020/04/07/python-101-working-with-strings/ In the section, "Formatting Strings with f-strings", the author made a comment that intrigued me: "The expressions that are contained inside of f-strings are evaluated at runtime. This makes it impossible to use an f-string as a docstring to a function, method or class if it contains an expression. The reason being that docstrings are defined at function definition time." The intriguing part was the idea of using string formatting inside a function, method or class docstring. Why would one want to do this? Can anyone give an interesting and practical example? The only possibility that occurs to me is rewriting an new version of the source code containing the docstring to be formatted and then saved. Would this be something someone would want to do during a package installation perhaps feeding in appropriate environment parameters? The author says that this cannot be done with f-string formatting, but this suggested it might be possible with the other formatting techniques. So I started playing around with printf-style formatting and by trying to be too clever got into some trouble. This runs: def fmt(*args): """Prints arguments of %s.""" % args[0] for i, arg in enumerate(args): print("arg #%s = %s " % (i, arg), end="") print() fmt("Robert", "V.", "Stepp") Giving: bob at Dream-Machine1:~/Projects/Tutor_Help$ python3 s* arg #0 = Robert arg #1 = V. arg #2 = Stepp But my original idea of using this for the docstring: """Prints arguments of %s.""" % args Throws an exception: bob at Dream-Machine1:~/Projects/Tutor_Help$ python3 s* Traceback (most recent call last): File "str_fmt.py", line 11, in fmt("Robert", "V.", "Stepp") File "str_fmt.py", line 5, in fmt """Prints arguments of %s.""" % args TypeError: not all arguments converted during string formatting I am not understanding why this is happening (yet). An explanation please? Anyway, the running code demonstrates that one can use printf-style formatting in docstrings... -- boB From robertvstepp at gmail.com Sat Apr 11 02:20:41 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 11 Apr 2020 01:20:41 -0500 Subject: [Tutor] Using string formatting inside function docstrings In-Reply-To: References: Message-ID: On Sat, Apr 11, 2020 at 12:57 AM boB Stepp wrote: > This runs: > > def fmt(*args): > """Prints arguments of %s.""" % args[0] > for i, arg in enumerate(args): > print("arg #%s = %s " % (i, arg), end="") > print() > > > fmt("Robert", "V.", "Stepp") > > Giving: > > bob at Dream-Machine1:~/Projects/Tutor_Help$ python3 s* > arg #0 = Robert arg #1 = V. arg #2 = Stepp > > But my original idea of using this for the docstring: > > """Prints arguments of %s.""" % args > > Throws an exception: > > bob at Dream-Machine1:~/Projects/Tutor_Help$ python3 s* > Traceback (most recent call last): > File "str_fmt.py", line 11, in > fmt("Robert", "V.", "Stepp") > File "str_fmt.py", line 5, in fmt > """Prints arguments of %s.""" % args > TypeError: not all arguments converted during string formatting Ah, I see why now. There is only one "%s", but it is expecting three "%s" based on the number of arguments passed in. It is too late to be trying to be too clever! -- boB From jon_davies17 at hotmail.co.uk Sat Apr 11 05:54:02 2020 From: jon_davies17 at hotmail.co.uk (Jon Davies) Date: Sat, 11 Apr 2020 09:54:02 +0000 Subject: [Tutor] Use of states to control Tkinter app navigation In-Reply-To: References: Message-ID: Hi, My apologies - didn't think about the files. I've attached some links below to the aforementioned video/code. Hopefully they work! https://www.dropbox.com/s/ybk3hpa989yt666/bandicam%202020-04-03%2013-03-20-920.mp4?dl=0 https://www.dropbox.com/s/ybk3hpa989yt666/bandicam%202020-04-03%2013-03-20-920.mp4?dl=0 Kind regards, Jon ________________________________ From: Jon Davies Sent: 10 April 2020 17:20 To: tutor at python.org Subject: Use of states to control Tkinter app navigation Hi there, I've been progressing with the creation of my Petrol station Pay-at-pump app using Tkinter, which is aiming to provide language translation/currency conversion. I have been steered towards the use of states to help provide clearer navigation of my app, as well as provide the function to completely reset the app at various stages to a fresh instance (i.e. to reverse any changes to widgets, variables etc.). The concept of states seems simple and easy to understand, although again with my limited knowledge of implementation it has proven to be a bit of a challenge. I've made a duplicate of my previous working version of the file to test the functionality (see attached). I can provide the working code/file as well if needed. I've tried to implement the use of states to control the movement of frames through the buttons (i.e. instead of show_frame function that I have used previously). I've also tried to create individual restart methods for each frame using the state model. I think my syntax is now correct, but when I try to run it gives me "NameError: name 'SelectLanguagePage' is not defined" at line 36 (i.e. where I outline the state dictionary). I can only imagine this is because the states section is perhaps not in the right place? Or does each state/class need to be outlined within the init of each class? I've attached a video of the problems I was facing with my working file, i.e. the use of the show_frame function to navigate frames - it was not functioning properly and showing pages in strange orders depending on buttons clicked. Essentially, I want to the app to have simple navigation from start to finish through the use of the buttons (and states), i.e. select language > select payment type > select currency > start fuelling > finish page. Kind regards, Jon From jon_davies17 at hotmail.co.uk Sat Apr 11 05:55:41 2020 From: jon_davies17 at hotmail.co.uk (Jon Davies) Date: Sat, 11 Apr 2020 09:55:41 +0000 Subject: [Tutor] Use of states to control Tkinter app navigation In-Reply-To: References: , Message-ID: And just realised I sent the same link twice. See the code file below. https://www.dropbox.com/s/d8k2b3hgzzhhgoh/Oleum%20%28state%20test%29.zip?dl=0 ________________________________ From: Jon Davies Sent: 11 April 2020 10:54 To: tutor at python.org Subject: Re: Use of states to control Tkinter app navigation Hi, My apologies - didn't think about the files. I've attached some links below to the aforementioned video/code. Hopefully they work! https://www.dropbox.com/s/ybk3hpa989yt666/bandicam%202020-04-03%2013-03-20-920.mp4?dl=0 https://www.dropbox.com/s/ybk3hpa989yt666/bandicam%202020-04-03%2013-03-20-920.mp4?dl=0 Kind regards, Jon ________________________________ From: Jon Davies Sent: 10 April 2020 17:20 To: tutor at python.org Subject: Use of states to control Tkinter app navigation Hi there, I've been progressing with the creation of my Petrol station Pay-at-pump app using Tkinter, which is aiming to provide language translation/currency conversion. I have been steered towards the use of states to help provide clearer navigation of my app, as well as provide the function to completely reset the app at various stages to a fresh instance (i.e. to reverse any changes to widgets, variables etc.). The concept of states seems simple and easy to understand, although again with my limited knowledge of implementation it has proven to be a bit of a challenge. I've made a duplicate of my previous working version of the file to test the functionality (see attached). I can provide the working code/file as well if needed. I've tried to implement the use of states to control the movement of frames through the buttons (i.e. instead of show_frame function that I have used previously). I've also tried to create individual restart methods for each frame using the state model. I think my syntax is now correct, but when I try to run it gives me "NameError: name 'SelectLanguagePage' is not defined" at line 36 (i.e. where I outline the state dictionary). I can only imagine this is because the states section is perhaps not in the right place? Or does each state/class need to be outlined within the init of each class? I've attached a video of the problems I was facing with my working file, i.e. the use of the show_frame function to navigate frames - it was not functioning properly and showing pages in strange orders depending on buttons clicked. Essentially, I want to the app to have simple navigation from start to finish through the use of the buttons (and states), i.e. select language > select payment type > select currency > start fuelling > finish page. Kind regards, Jon From mysecretrobotfactory at gmail.com Fri Apr 10 19:31:17 2020 From: mysecretrobotfactory at gmail.com (Chris C) Date: Fri, 10 Apr 2020 16:31:17 -0700 Subject: [Tutor] push a keyboard button to run a function In-Reply-To: References: Message-ID: It's CLI under windows, with no GUI Can i just use this ? msvcrt.getch() thanks! On Fri, Apr 10, 2020 at 4:17 PM Alan Gauld via Tutor wrote: > On 10/04/2020 23:11, Chris C wrote: > > > I am trying to invoke a function in my python code by using a keyboard > > keystroke. > > You need to tell us more. > Is this a CLI program or a GUI? If a GUI which toolkit? > Tkinter? wxPython? other... > If a CLI which OS? If it is Unix like then the curses module > is your friend. > If its Windows the msvcrt module will help. > > > Alternatively, I need to change a variable's value from true to false and > > false to true everytime when I push this button, > > > > variable = not variable > > will toggle a boolean between true/false. > > But we need more context information to answer fully. > Ideally some code (even if it doesn't work) to see what > you are attempting. > > -- > 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 > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From mysecretrobotfactory at gmail.com Fri Apr 10 19:32:21 2020 From: mysecretrobotfactory at gmail.com (Chris C) Date: Fri, 10 Apr 2020 16:32:21 -0700 Subject: [Tutor] push a keyboard button to run a function In-Reply-To: References: Message-ID: how about while msvcrt.getch() != 'F2': time.sleep(1) On Fri, Apr 10, 2020 at 4:31 PM Chris C wrote: > It's CLI under windows, with no GUI > > Can i just use this ? msvcrt.getch() > > thanks! > > On Fri, Apr 10, 2020 at 4:17 PM Alan Gauld via Tutor > wrote: > >> On 10/04/2020 23:11, Chris C wrote: >> >> > I am trying to invoke a function in my python code by using a keyboard >> > keystroke. >> >> You need to tell us more. >> Is this a CLI program or a GUI? If a GUI which toolkit? >> Tkinter? wxPython? other... >> If a CLI which OS? If it is Unix like then the curses module >> is your friend. >> If its Windows the msvcrt module will help. >> >> > Alternatively, I need to change a variable's value from true to false >> and >> > false to true everytime when I push this button, >> > >> >> variable = not variable >> >> will toggle a boolean between true/false. >> >> But we need more context information to answer fully. >> Ideally some code (even if it doesn't work) to see what >> you are attempting. >> >> -- >> 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 >> >> >> _______________________________________________ >> Tutor maillist - Tutor at python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> > From mysecretrobotfactory at gmail.com Fri Apr 10 20:06:17 2020 From: mysecretrobotfactory at gmail.com (Michael C) Date: Fri, 10 Apr 2020 17:06:17 -0700 Subject: [Tutor] push a keyboard button to run a function In-Reply-To: <87f92e48-adbe-3e97-f892-ada149dd9bbc@DancesWithMice.info> References: <87f92e48-adbe-3e97-f892-ada149dd9bbc@DancesWithMice.info> Message-ID: Oh, I am not trying to wait for a keystroke while the rest of the program waits! I think I need to be able to push a key and change a variable from true to false and back and then when the next time the program checks that variable, the program does something. Sent from my iPhone > On Apr 10, 2020, at 4:54 PM, DL Neil via Tutor wrote: > > ?On 11/04/20 11:16 AM, Alan Gauld via Tutor wrote: >>> On 10/04/2020 23:11, Chris C wrote: >>> I am trying to invoke a function in my python code by using a keyboard >>> keystroke. >> You need to tell us more. >> Is this a CLI program or a GUI? If a GUI which toolkit? >> Tkinter? wxPython? other... >> If a CLI which OS? If it is Unix like then the curses module >> is your friend. >> If its Windows the msvcrt module will help. >>> Alternatively, I need to change a variable's value from true to false and >>> false to true everytime when I push this button, >>> >> variable = not variable >> will toggle a boolean between true/false. >> But we need more context information to answer fully. >> Ideally some code (even if it doesn't work) to see what >> you are attempting. > > > Concur. > > If the "keystroke" is/can be the Enter key, then an input() will do. > > There is a keyboard library in Pypi (https://pypi.org/project/keyboard/) > > See also curses, Pygame, and more... > > -- > Regards =dn > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From alan.gauld at yahoo.co.uk Sat Apr 11 06:49:26 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 11 Apr 2020 11:49:26 +0100 Subject: [Tutor] push a keyboard button to run a function In-Reply-To: References: Message-ID: On 11/04/2020 00:32, Chris C wrote: > how about? > > > while msvcrt.getch() != 'F2': > ? ? time.sleep(1) Sort of, except you need to read the docs for getch() closely. Notice that 1) it returns bytes not a string 2) if the key is special - eg a Function Key - you need a second getch() call to get the real key... If you read the "Event Driven programming topic in my tutor(see .sig) you will see an example of using msvcrt.getch() -- 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 Sat Apr 11 06:49:26 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 11 Apr 2020 11:49:26 +0100 Subject: [Tutor] push a keyboard button to run a function In-Reply-To: References: Message-ID: On 11/04/2020 00:32, Chris C wrote: > how about? > > > while msvcrt.getch() != 'F2': > ? ? time.sleep(1) Sort of, except you need to read the docs for getch() closely. Notice that 1) it returns bytes not a string 2) if the key is special - eg a Function Key - you need a second getch() call to get the real key... If you read the "Event Driven programming topic in my tutor(see .sig) you will see an example of using msvcrt.getch() -- 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 __peter__ at web.de Sat Apr 11 09:27:28 2020 From: __peter__ at web.de (Peter Otten) Date: Sat, 11 Apr 2020 15:27:28 +0200 Subject: [Tutor] Using string formatting inside function docstrings References: Message-ID: boB Stepp wrote: > On Sat, Apr 11, 2020 at 12:57 AM boB Stepp wrote: > >> This runs: >> >> def fmt(*args): >> """Prints arguments of %s.""" % args[0] >> for i, arg in enumerate(args): >> print("arg #%s = %s " % (i, arg), end="") >> print() >> >> >> fmt("Robert", "V.", "Stepp") >> >> Giving: >> >> bob at Dream-Machine1:~/Projects/Tutor_Help$ python3 s* >> arg #0 = Robert arg #1 = V. arg #2 = Stepp >> >> But my original idea of using this for the docstring: >> >> """Prints arguments of %s.""" % args >> >> Throws an exception: >> >> bob at Dream-Machine1:~/Projects/Tutor_Help$ python3 s* >> Traceback (most recent call last): >> File "str_fmt.py", line 11, in >> fmt("Robert", "V.", "Stepp") >> File "str_fmt.py", line 5, in fmt >> """Prints arguments of %s.""" % args >> TypeError: not all arguments converted during string formatting > > Ah, I see why now. There is only one "%s", but it is expecting three > "%s" based on the number of arguments passed in. It is too late to be > trying to be too clever! If you want to use %-formatting safely you have to write an explicit tuple: """Prints arguments of %s.""" % (args,) By the way, what you are formatting is not a docstring, just a throwaway value: >>> def fmt(*args): ... """Prints arguments of %s.""" % args[0] ... for i, arg in enumerate(args): ... print("arg #%s = %s " % (i, arg), end="") ... print() ... >>> fmt.__doc__ is None True How you format the string you throw away doesn't matter ;) >>> def fmt(*args): ... f"""Prints arguments of {args[0]}.""" ... >>> fmt.__doc__ is None True > The intriguing part was the idea of using string formatting inside a > function, method or class docstring. Why would one want to do this? > Can anyone give an interesting and practical example? Not very interesting, but practical -- occasionally I generate a docstring in a factory function: >>> def make_startswith(prefix): ... def startswith(s): ... return s.startswith(prefix) ... startswith.__doc__ = f"Check if `s` starts with {prefix!r}." ... return startswith ... >>> startswith = make_startswith("http://") >>> help(startswith) Help on function startswith in module __main__: startswith(s) Check if `s` starts with 'http://'. >>> From ian.laffey at steinertus.com Sat Apr 11 18:55:04 2020 From: ian.laffey at steinertus.com (Laffey, Ian) Date: Sat, 11 Apr 2020 22:55:04 +0000 Subject: [Tutor] Early Coder problem Message-ID: <169057dbb7e34f43a3373e9a773e99a6@steinertus.com> Hi tutors! I was unaware that this service was available and just found it so let me know if there is a better format for me to ask for help. Anyways, I have two questions. First, I was wondering why I have so many Python related folders. I think the easy answer is that I have unfortunately spread it across three drives (2 SSD and 1 HDD) but I wanted to clarify how I know where something Is pulling directories from when executing, specifically using PyCharm I am having issues with the interpreter. Secondarily, I have tried to pip install PyAudio a dozen times this past week and each time I get an annoying, illegible error code. Can you help me figure out my issue here, also using PyCharm for this, but having same issue and error in Visual Studio. Thanks so much! Ian Laffey | Scrap Territory Manager Phone: +1 (800) 595-4014-109 | Mobile: +1 (859) 757-2085 Fax: +1 (800) 511-8714 | ian.laffey at steinertus.com STEINERTUS Inc. 285 Shorland Drive | Walton KY 41094 | steinertus.com [Steinert logo] This message is intended for the addressee or its representative only. Any form of unauthorized use, publication, reproduction, copying or disclosure of the content of this e-mail is not permitted. If you are not the intended recipient of this e-mail message and its contents, please notify the sender immediately and delete this message and all its attachments subsequently. From __peter__ at web.de Sun Apr 12 05:17:30 2020 From: __peter__ at web.de (Peter Otten) Date: Sun, 12 Apr 2020 11:17:30 +0200 Subject: [Tutor] Early Coder problem References: <169057dbb7e34f43a3373e9a773e99a6@steinertus.com> Message-ID: Laffey, Ian wrote: > Secondarily, I have tried to pip install PyAudio a dozen times this past > week and each time I get an annoying, illegible error code. Chances are that you find someone who can read the "illegible" error codes if you post them here, verbatim, including the preceding output (the so- called traceback). > Can you help > me figure out my issue here, also using PyCharm for this, but having same > issue and error in Visual Studio. If you are on Windows you may consider installing from the the whl provided by Christoph Gohlke: https://www.lfd.uci.edu/~gohlke/pythonlibs/ From mats at wichmann.us Sun Apr 12 08:40:35 2020 From: mats at wichmann.us (Mats Wichmann) Date: Sun, 12 Apr 2020 06:40:35 -0600 Subject: [Tutor] Early Coder problem In-Reply-To: <169057dbb7e34f43a3373e9a773e99a6@steinertus.com> References: <169057dbb7e34f43a3373e9a773e99a6@steinertus.com> Message-ID: <654fd461-0411-566c-6fdf-a90f8085392e@wichmann.us> On 4/11/20 4:55 PM, Laffey, Ian wrote: > Hi tutors! I was unaware that this service was available and just found it so let me know if there is a better format for me to ask for help. > > Anyways, I have two questions. First, I was wondering why I have so many Python related folders. I think the easy answer is that I have unfortunately spread it across three drives (2 SSD and 1 HDD) but I wanted to clarify how I know where something Is pulling directories from when executing, specifically using PyCharm I am having issues with the interpreter. > > Secondarily, I have tried to pip install PyAudio a dozen times this past week and each time I get an annoying, illegible error code. Can you help me figure out my issue here, also using PyCharm for this, but having same issue and error in Visual Studio. Turns out for this problem, not only could we decode the errors, but it's something I've been asked about elsewhere several times in the last couple of weeks, so it's familiar. The fault is with the PyAudio project, not you. tl;dr - just follow Peter's suggestion, I keep forgetting about that really useful site of "not official builds, but really get you out of a hole where there isn't one" Python software. === If you wanted some explanation, for education purposes - /guessing/ that your crazy message has to do with Visual Studio, etc: When the author of a Python module writes their module, they can write it either in pure Python, or they can use the extension mechanism to bind C/C++ language code to the Python. The latter is often done if the module code has performance-critical aspects, although there are also other reasons for choosing that approach. In the former case, the module can easily be installed, in the latter, it is necessary to make sure the binary compiled parts are present, and those are system-specific. Of course the best way for the module author to meet that requirement is to package up the binary pieces. When you ask for a pip install, the pip module reaches out to the server on pypi.org and requests a complete package (these are called "wheels" and have a filename suffix of .whl) that meets the requirements of the requesting system - operating system, 32 or 64-bit if applicable, Python version. If found, that is downloaded and installed, and you're good to go if nothing went wrong. If not found, the fallback source code version (called by Python people an "sdist") is downloaded, unpacked, and the unpacked code's "setup.py" script is executed to try to get everything in order. In your case, you can see this is what is happening - it is trying to run setup.py (indicating a suitable wheel with the binary parts was not found), and it's failing because there is no compiler present to build the "_portaudio" extension. On Windows this is normally the case - a compiler is not present by default, and if present may require specialized setup. If you search on pypi.org for your module, and then click on "download files", it has the helpful effect of showing you which files are available to download - the same information pip would get. https://pypi.org/project/PyAudio/#files here's that listing: PyAudio-0.2.11-cp27-cp27m-win32.whl (49.3 kB) Wheel cp27 Mar 18, 2017 PyAudio-0.2.11-cp27-cp27m-win_amd64.whl (52.5 kB) Wheel cp27 Mar 18, 2017 PyAudio-0.2.11-cp34-cp34m-win32.whl (49.3 kB) Wheel cp34 Mar 18, 2017 PyAudio-0.2.11-cp34-cp34m-win_amd64.whl (52.5 kB) Wheel cp34 Mar 18, 2017 PyAudio-0.2.11-cp35-cp35m-win32.whl (49.3 kB) Wheel cp35 Mar 18, 2017 PyAudio-0.2.11-cp35-cp35m-win_amd64.whl (52.6 kB) Wheel cp35 Mar 18, 2017 PyAudio-0.2.11-cp36-cp36m-win32.whl (49.3 kB) Wheel cp36 Mar 18, 2017 PyAudio-0.2.11-cp36-cp36m-win_amd64.whl (52.6 kB) Wheel cp36 Mar 18, 2017 PyAudio-0.2.11.tar.gz (37.4 kB) Source None Mar 18, 2017 here we can see wheels for CPython 2.7 (cp27) on windows 32-bit, and for windows 64-bit; same for 3.4, 3.5 and 3.6, and the fallback source code version, the .tar.gz file. None of these are newer than March, 2017. So the module author has not uploaded wheels for Python 3.7 or 3.8 - that's why pip tried to fall back to building, which then failed. From mixipilixi at gmail.com Sun Apr 12 09:03:31 2020 From: mixipilixi at gmail.com (mixipilixi .) Date: Sun, 12 Apr 2020 08:03:31 -0500 Subject: [Tutor] Solving physics problems with python Message-ID: I am a physicist and am learning python. I wonder if you could recommend a beginners reference for me to learn python with focus on physics applications. I would like to learn to do calculations and plot curves effectively on basic physics. Eventually I would like to move to more complex physics subjects. One of my interests is quantum computing, among others. Thank you for having this wonderful resource available to us users, especially us beginners Humberto figueroa From alan.gauld at yahoo.co.uk Sun Apr 12 10:11:08 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 12 Apr 2020 15:11:08 +0100 Subject: [Tutor] Solving physics problems with python In-Reply-To: References: Message-ID: On 12/04/2020 14:03, mixipilixi . wrote: > I am a physicist and am learning python. I wonder if you could recommend a > beginners reference for me to learn python with focus on physics > applications. I would like to learn to do calculations and plot curves > effectively on basic physics. Eventually I would like to move to more > complex physics subjects. One of my interests is quantum computing, among > others. > > Thank you for having this wonderful resource available to us users, > especially us beginners > > Humberto figueroa Hi Humberto. If you are doing science with python you should install(if you haven't already) one of the SciPy distributions of Python. (You can install all the bits separately but its much easier to get it all in one) The best known example is Anaconda. (Another option is Enthought Canopy) As a physicist I'll assume you already know how to program in some other language and can pick up the basics of the Python language from the official tutor at python.org. After that head to the SciPy website where there are many tutorials on the various scipy packages. Thee is also a web forum where other science users hang out. https://www.scipy.org/getting-started.html This forum is fine for general python/programming questions but only a relatively small proportion of our members are working in science. -- 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 Apr 12 10:23:13 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 12 Apr 2020 15:23:13 +0100 Subject: [Tutor] Early Coder problem In-Reply-To: <169057dbb7e34f43a3373e9a773e99a6@steinertus.com> References: <169057dbb7e34f43a3373e9a773e99a6@steinertus.com> Message-ID: On 11/04/2020 23:55, Laffey, Ian wrote: > First, I was wondering why I have so many Python related folders. No idea! Python does install a lot of folders but they should all be under one top-level one. (Actually in Unix-like OS that's not strictly true, the executable sits separate from the folders...) You can have multiple pythons installed, in which case they may all have their own "Home" folder structure. But you will need to tell us more - give some examples of where these folders are -before we can say much more. > I think the easy answer is that I have unfortunately spread > it across three drives (2 SSD and 1 HDD) Maybe but I don't know how you would have done that since the installer just asks for a home location (if it asks anything at all!). Unless you are talking about your own project directories, in which case that will have been your own choice (or maybe your IDE if you use one) >I wanted to clarify how I know where something Is pulling directories from when executing, You can put a debug statement in that asks python the filename of a module(*). and you can examine the sys.path value which lists all the places python looks for files. (*) print(somemodule.__file__) -- 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 adameyring at gmail.com Sun Apr 12 11:04:39 2020 From: adameyring at gmail.com (Adam Eyring) Date: Sun, 12 Apr 2020 11:04:39 -0400 Subject: [Tutor] Solving physics problems with python In-Reply-To: References: Message-ID: Humberto, Within the scipy website that Alan mentioned, you'll see matplotlib. That's an excellent way to do 2-D plotting. This gallery has some wonderful examples: https://matplotlib.org/gallery/index.html AME On Sun, Apr 12, 2020 at 10:11 AM Alan Gauld via Tutor wrote: > On 12/04/2020 14:03, mixipilixi . wrote: > > I am a physicist and am learning python. I wonder if you could recommend > a > > beginners reference for me to learn python with focus on physics > > applications. I would like to learn to do calculations and plot curves > > effectively on basic physics. Eventually I would like to move to more > > complex physics subjects. One of my interests is quantum computing, > among > > others. > > > > Thank you for having this wonderful resource available to us users, > > especially us beginners > > > > Humberto figueroa > > Hi Humberto. > > If you are doing science with python you should install(if you haven't > already) one of the SciPy distributions of Python. (You can install all > the bits separately but its much easier to get it all in one) > The best known example is Anaconda. (Another option is Enthought Canopy) > > As a physicist I'll assume you already know how to program in some other > language and can pick up the basics of the Python language from the > official tutor at python.org. > > After that head to the SciPy website where there are many tutorials on > the various scipy packages. Thee is also a web forum where other science > users hang out. > > https://www.scipy.org/getting-started.html > > This forum is fine for general python/programming questions but only > a relatively small proportion of our members are working in science. > > -- > 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 > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > Virus-free. www.avast.com <#m_-6451175552701997241_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2> From oscar.j.benjamin at gmail.com Sun Apr 12 15:36:05 2020 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Sun, 12 Apr 2020 20:36:05 +0100 Subject: [Tutor] Solving physics problems with python In-Reply-To: References: Message-ID: On Sun, 12 Apr 2020 at 14:04, mixipilixi . wrote: > > I am a physicist and am learning python. I wonder if you could recommend a > beginners reference for me to learn python with focus on physics > applications. I would like to learn to do calculations and plot curves > effectively on basic physics. Eventually I would like to move to more > complex physics subjects. One of my interests is quantum computing, among > others. Another library you might find interesting is sympy for doing symbolic calculations: https://www.sympy.org/en/index.html If you have sympy installed then you can do things like: >>> from sympy import * >>> x = Symbol('x') >>> equation = 2*x**2 - 1 >>> equation 2*x**2 - 1 >>> equation.diff(x) 4*x >>> solve(equation, x) [-sqrt(2)/2, sqrt(2)/2] Sympy also has a subsection for various topics in physics including some quantum computing: https://docs.sympy.org/latest/modules/physics/index.html -- Oscar From cs at cskk.id.au Sun Apr 12 19:59:27 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Mon, 13 Apr 2020 09:59:27 +1000 Subject: [Tutor] Using string formatting inside function docstrings In-Reply-To: References: Message-ID: <20200412235927.GA68584@cskk.homeip.net> On 11Apr2020 00:57, boB Stepp wrote: >I was looking at an online article, "Python 101 ? Working with >Strings", at https://www.blog.pythonlibrary.org/2020/04/07/python-101-working-with-strings/ > In the section, "Formatting Strings with f-strings", the author made >a comment that intrigued me: > >"The expressions that are contained inside of f-strings are evaluated >at runtime. This makes it impossible to use an f-string as a docstring >to a function, method or class if it contains an expression. The >reason being that docstrings are defined at function definition time." > >The intriguing part was the idea of using string formatting inside a >function, method or class docstring. Why would one want to do this? >Can anyone give an interesting and practical example? I do this. My primary case is to document both the name of a module constant and its value so that help(thing) recites both. I do this often nough that I have a @fmtdoc decorator for this purpose. You can fetch my "cs.deco" module from PyPI to obtain this: https://pypi.org/project/cs.deco/ The documentation of @fmtdoc is about halfway down: Decorator to replace a function's docstring with that string formatted against the function's module __dict__. This supports simple formatted docstrings: ENVVAR_NAME = 'FUNC_DEFAULT' @fmtdoc def func(): """Do something with os.environ[{ENVVAR_NAME}].""" print(os.environ[ENVVAR_NAME]) This gives func this docstring: Do something with os.environ[FUNC_DEFAULT]. Warning: this decorator is intended for wiring "constants" into docstrings, not for dynamic values. Use for other types of values should be considered with trepidation. Note that warning. Anyway, I find this quite handy. Cheers, Cameron Simpson From alan.gauld at btinternet.com Sun Apr 12 19:08:05 2020 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 13 Apr 2020 00:08:05 +0100 Subject: [Tutor] Solving physics problems with python In-Reply-To: References: Message-ID: <11d22a04-fcc8-605b-eec1-7a330c5878c4@btinternet.com> On 12/04/2020 20:36, Oscar Benjamin wrote: > Another library you might find interesting is sympy for doing symbolic > calculations: Hi Oscar, isn't sympy part of scipy? I thought it was but I might be mistaken. It's certainly an impressive package, one of the few scipy modules I've played with. (A friend was looking for a cheap mathematica replacement and I looked at sympy as an option for him.) -- 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 christian.lfonts at gmail.com Mon Apr 13 12:25:31 2020 From: christian.lfonts at gmail.com (Christian Liz-Fonts) Date: Mon, 13 Apr 2020 13:25:31 -0300 Subject: [Tutor] Sending Pickled Data from Server to Client via Sockets Message-ID: I first tried message = pickle.dumps(s2) cs.sendall(message) on my server and for my client msg = ns.recv(32,768) this returned msg = ns.recv(32,768) OSError: [WinError 10045] The attempted operation is not supported for the type of object referenced So I then tried, my server being HL = 10 ... message = pickle.dumps(s2) message_header - bytes(f"{len(message):<{HL}}", "utf-8")+messae cs.send(message_header + message) and this being my client while True: full_msg = b'' new_msg = True while True: msg = ns.recv(16) if new_msg: print("new msg len:", msg[:HL]) msglen = int(msg[:HL]) new_msg = False print(f"full message length: {msglen}") full_msg += msg print("adding other parts together") print(len(full_msg)) if len(full_msg)-HL == msglen: new_msg = True full_msg = b"" print("full msg recvd") print(full_msg[HL:]) this returned new msg len: b'5575 ' then it printed out full message length: 5575 adding other parts together 16 until reaching full message length: 5575 adding other parts together 11160 as you can imagine my log is a bit lengthy as it is going up by 16 bytes each time. Also it seems as if the last is statement does not run if len(full_msg)-HL == msglen: I imagine this is because len(full_msg)-HL is exceeding msglen? what should I do was the first direction I was heading in the correct one or the second? I am sending and receiving files between my own clients to my host so no other person will be sending data to me so it does not need to be secure, I just need to most efficient method to do what I need to do have been trying to correct this error for 36 hours and decided to give this a try. Please advice me on how to proceed. From owendavies00 at gmail.com Mon Apr 13 16:14:12 2020 From: owendavies00 at gmail.com (Owen Davies) Date: Mon, 13 Apr 2020 21:14:12 +0100 Subject: [Tutor] Help with pip Message-ID: Hi, I have recently started learning python and really nejoying it. I got to a tutorial where they were showing how to install modules through pip. However when i put this into terminal i cannot install docx : $ python3 Python 3.8.2 (v3.8.2:7b3ab5921f, Feb 24 2020, 17:52:18) [Clang 6.0 (clang-600.0.57)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> pip install python-docx File "", line 1 pip install python-docx ^ SyntaxError: invalid syntax >>> Please can you give me any tips on why pip isn't working? I have installed GCC and Homebrew too? I am on a Mac V10.14.6 Thanks, Owen From mats at wichmann.us Mon Apr 13 20:37:04 2020 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 13 Apr 2020 18:37:04 -0600 Subject: [Tutor] Help with pip In-Reply-To: References: Message-ID: <9BF964BB-009C-4B3D-97CF-E714E7002DF7@wichmann.us> On April 13, 2020 2:14:12 PM MDT, Owen Davies wrote: >Hi, > >I have recently started learning python and really nejoying it. > >I got to a tutorial where they were showing how to install modules >through >pip. > >However when i put this into terminal i cannot install docx : > >$ python3 > >Python 3.8.2 (v3.8.2:7b3ab5921f, Feb 24 2020, 17:52:18) > >[Clang 6.0 (clang-600.0.57)] on darwin > >Type "help", "copyright", "credits" or "license" for more information. > >>>> pip install python-docx > > File "", line 1 > > pip install python-docx > > ^ > >SyntaxError: invalid syntax > >>>> > > >Please can you give me any tips on why pip isn't working? I have >installed >GCC and Homebrew too? I am on a Mac V10.14.6 > > >Thanks, >Owen >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor pip is invoked from the shell, not from inside python. also, recommend this form: python -m pip install python-docx -- Sent from a mobile device with K-9 Mail. Please excuse my brevity. From __peter__ at web.de Tue Apr 14 11:36:53 2020 From: __peter__ at web.de (Peter Otten) Date: Tue, 14 Apr 2020 17:36:53 +0200 Subject: [Tutor] Sending Pickled Data from Server to Client via Sockets References: Message-ID: Christian Liz-Fonts wrote: > I first tried This looks like an unfiltered brain dump. If you want to do this as an exercise I suggest that you start with something that works (like the echo client/server example in the socket library documentation), and then add features. If it's not an excercise, consider something ready-to-use, like, maybe https://pyro4.readthedocs.io/en/stable/intro.html > > message = pickle.dumps(s2) > cs.sendall(message) > > on my server and for my client > > msg = ns.recv(32,768) For those who are not an expert: what does that 768 mean? > this returned > > msg = ns.recv(32,768) OSError: [WinError 10045] The attempted operation is > not supported for the type of object referenced > > > So I then tried, my server being > > > HL = 10 > ... > > message = pickle.dumps(s2) > > message_header - bytes(f"{len(message):<{HL}}", "utf-8")+messae Please always cut and paste the code you are actually using. > > cs.send(message_header + message) > > and this being my client > > while True: > full_msg = b'' > new_msg = True > while True: > msg = ns.recv(16) > if new_msg: > print("new msg len:", msg[:HL]) > msglen = int(msg[:HL]) > new_msg = False > print(f"full message length: {msglen}") > full_msg += msg > print("adding other parts together") > print(len(full_msg)) > if len(full_msg)-HL == msglen: > new_msg = True > full_msg = b"" > print("full msg recvd") print(full_msg[HL:]) > > > this returned > > new msg len: b'5575 ' > > then it printed out > > full message length: 5575 > adding other parts together > 16 > > until reaching > > full message length: 5575 > adding other parts together > 11160 > > as you can imagine my log is a bit lengthy as it is going up by 16 bytes > each time. The 16 bytes seem to be your choice, no one is stopping you from specifying 17, say ;) > Also it seems as if the last is statement does not run > > if len(full_msg)-HL == msglen: > > I imagine this is because len(full_msg)-HL is exceeding msglen? That would be my guess, too. > what should I do was the first direction I was heading in the correct one > or the second? I am sending and receiving files between my own clients to > my host so no other person will be sending data to me so it does not need > to be secure, I just need to most efficient method to do what I need to do > have been trying to correct this error for 36 hours and decided to give > this a try. Please advice me on how to proceed. I seems like you want to send a succession of length-of-data pickled-data pairs and are stuck on how to break these apart. To debug your problem you do not need the client/server infrastructure. Just make some test data and a mock connection: import pickle DIGITS = 10 def format_record(record): item = pickle.dumps(record) data = b"%*d%s" % (DIGITS, len(item), item) assert len(data) == DIGITS + len(item) return data class Conn: def __init__(self): self.pos = 0 records = ((i, "Hello World", 42.0) for i in range(100)) self.data = b"".join(format_record(record) for record in records) def recv(self, size): result = self.data[self.pos:self.pos + size] self.pos += size return result conn = Conn() # experiment with your loop here ... while True: ... print("GOT", pickle.loads(data[:item_len])) ... chunk = conn.recv(32) Once you see $ python3.8 demo.py GOT (0, 'Hello World', 42.0) GOT (1, 'Hello World', 42.0) GOT (2, 'Hello World', 42.0) ... GOT (99, 'Hello World', 42.0) (come here with more specific questions if you're stuck) you can pretty much copy and paste the loop into your client. From oscar.j.benjamin at gmail.com Tue Apr 14 12:54:34 2020 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Tue, 14 Apr 2020 17:54:34 +0100 Subject: [Tutor] Solving physics problems with python In-Reply-To: <11d22a04-fcc8-605b-eec1-7a330c5878c4@btinternet.com> References: <11d22a04-fcc8-605b-eec1-7a330c5878c4@btinternet.com> Message-ID: On Mon, 13 Apr 2020 at 01:53, Alan Gauld via Tutor wrote: > > On 12/04/2020 20:36, Oscar Benjamin wrote: > > > Another library you might find interesting is sympy for doing symbolic > > calculations: > > Hi Oscar, > isn't sympy part of scipy? I thought it was but I might be mistaken. > > It's certainly an impressive package, one of the few scipy modules > I've played with. (A friend was looking for a cheap mathematica > replacement and I looked at sympy as an option for him.) Hi Alan, SymPy is not part of scipy but both are part of the broader scientific python ecosystem. Your suggestion to install Anaconda would result in all of numpy, scipy, matplotlib, sympy and many more being installed together. Scipy is a library built on top of numpy combining Python, C and Fortran code for doing numerical work predominantly in floating point. SymPy is a pure Python library that has only mpmath (also pure Python) as a hard dependency although gmpy2 is recommended for speed. The two libraries overlap in the sense that many functions you can find in numpy/scipy you can also find in sympy but sympy is symbolic and can work with multiprecision whereas the other are purely numeric libraries mainly for fixed precision floating point calculations. SymPy can also be used together with numpy/scipy for example: >>> from sympy import Symbol, lambdify >>> x = Symbol('x') >>> expr = 1/(1 - x) >>> expr 1/(1 - x) >>> expr2 = expr.diff(x) >>> expr2 (1 - x)**(-2) So we've used sympy to perform some algebraic manipulation which gives us an expression we are interested in. Now we want to evaluate this for a large number of floating point inputs but that's faster with numpy: >>> eval_expr2 = lambdify(x, expr2, 'numpy') >>> from numpy import arange >>> xvals = arange(0, 1, 0.1) >>> eval_expr2(xvals) array([ 1. , 1.2345679 , 1.5625 , 2.04081633, 2.77777778, 4. , 6.25 , 11.11111111, 25. , 100. ]) The lamdify function can be used to bridge the gap between sympy and other numeric libraries. Sympy does not automatically use numpy/scipy under the hood even though they are faster because (apart from them not being pure python) sympy uses exact calculations or multiprecision mpmath so e.g.: >>> from sympy import Rational >>> expr2.subs(x, Rational(1, 10)) 100/81 >>> expr2.subs(x, Rational(1, 10)).n() 1.23456790123457 >>> expr2.subs(x, Rational(1, 10)).n(30). # Have as many digits as you like... 1.23456790123456790123456790123 There is a lot of overlap between sympy users and numpy/scipy users (although sympy's userbase is smaller). Perhaps unlike some of the other scientific libraries sympy has a good chunk of users who only use sympy and don't even know what python is let alone what scipy is. Related are users of sage which incorporates both sympy and scipy as internal dependencies and presents something like mathematica to the end user. -- Oscar From cranky.frankie at gmail.com Wed Apr 15 09:24:14 2020 From: cranky.frankie at gmail.com (Cranky Frankie) Date: Wed, 15 Apr 2020 09:24:14 -0400 Subject: [Tutor] Why is this printing None? Message-ID: I have this simple class in Python 3.8. When I run this in IDLE or at the command prompt the word None gets printed after the employee name. Why? class Employee: def __init__ (self, name): self.name = name def displayEmployee(self): print("Name : ", self.name) if __name__ == '__main__': emp1 = Employee('Zara') print(emp1.displayEmployee()) Frank L. "Cranky Frankie" Palmeri, Risible Riding Raconteur & Writer WORK Hard - PLAY Hard - READ Hard - THINK Hard From bouncingcats at gmail.com Wed Apr 15 09:36:07 2020 From: bouncingcats at gmail.com (David) Date: Wed, 15 Apr 2020 23:36:07 +1000 Subject: [Tutor] Why is this printing None? In-Reply-To: References: Message-ID: On Wed, 15 Apr 2020 at 23:25, Cranky Frankie wrote: > > I have this simple class in Python 3.8. When I run this in IDLE or at the > command prompt the word None gets printed after the employee name. Why? > > class Employee: > > def __init__ (self, name): > self.name = name > > def displayEmployee(self): > print("Name : ", self.name) > > if __name__ == '__main__': > emp1 = Employee('Zara') > print(emp1.displayEmployee()) emp1.displayEmployee() has a return value of None, so print(emp1.displayEmployee()) is the same as print(None) Do you need to call print() twice? From mats at wichmann.us Wed Apr 15 09:37:01 2020 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 15 Apr 2020 07:37:01 -0600 Subject: [Tutor] Why is this printing None? In-Reply-To: References: Message-ID: <3a7bef42-60dd-e1ef-273b-a8e80b523edc@wichmann.us> On 4/15/20 7:24 AM, Cranky Frankie wrote: > I have this simple class in Python 3.8. When I run this in IDLE or at the > command prompt the word None gets printed after the employee name. Why? > > class Employee: > > def __init__ (self, name): > self.name = name > > def displayEmployee(self): > print("Name : ", self.name) > > if __name__ == '__main__': > emp1 = Employee('Zara') > print(emp1.displayEmployee()) Your last line here prints the value returned by displayEmployee(). What is that method returning? Hint: if a function/method does not explicitly return something via a return statement, it returns None. From david at graniteweb.com Wed Apr 15 10:07:44 2020 From: david at graniteweb.com (David Rock) Date: Wed, 15 Apr 2020 09:07:44 -0500 Subject: [Tutor] Why is this printing None? In-Reply-To: References: Message-ID: <57FB3EA5-0A9E-4768-9CDC-EC84C2144AD3@graniteweb.com> > On Apr 15, 2020, at 08:24, Cranky Frankie wrote: > > I have this simple class in Python 3.8. When I run this in IDLE or at the > command prompt the word None gets printed after the employee name. Why? > > class Employee: > > def __init__ (self, name): > self.name = name > > def displayEmployee(self): > print("Name : ", self.name) > > if __name__ == '__main__': > emp1 = Employee('Zara') > print(emp1.displayEmployee()) As others have pointed out, you aren?t printing what you think should be printed. emp1.displayEmployee() prints the name, then you are printing the return value of displayEmployee() If you change your code to this, it will do what you probably want, but this might not be the best way to do it (but fits the intentions of what your code implies). if __name__ == '__main__?: emp1 = Employee('Zara?) emp1.displayEmployee() Note that what I?m doing is allowing the Class method to handle the printing (your external print is redundant, and the reason for the ?None?) as already noted. If you want the external print statement, instead of having a displayEmployee() method, maybe use a __str__ method to dictate what printing the object means, or have a getter method that just returns self.name so it can be printed. It all depends what your overall needs are. ? David Rock david at graniteweb.com From cranky.frankie at gmail.com Wed Apr 15 10:08:13 2020 From: cranky.frankie at gmail.com (Cranky Frankie) Date: Wed, 15 Apr 2020 10:08:13 -0400 Subject: [Tutor] Why is this printing None? In-Reply-To: <3a7bef42-60dd-e1ef-273b-a8e80b523edc@wichmann.us> References: <3a7bef42-60dd-e1ef-273b-a8e80b523edc@wichmann.us> Message-ID: It prints the word Zara like it should, then the word None on the next line which it shouldn't. I got the example from: https://www.tutorialspoint.com/python/python_classes_objects.htm When they show the results, the word None is not output. I don't know why this is happening. Frank L. "Cranky Frankie" Palmeri, Risible Riding Raconteur & Writer WORK Hard - PLAY Hard - READ Hard - THINK Hard On Wed, Apr 15, 2020 at 9:37 AM Mats Wichmann wrote: > On 4/15/20 7:24 AM, Cranky Frankie wrote: > > I have this simple class in Python 3.8. When I run this in IDLE or at the > > command prompt the word None gets printed after the employee name. Why? > > > > class Employee: > > > > def __init__ (self, name): > > self.name = name > > > > def displayEmployee(self): > > print("Name : ", self.name) > > > > if __name__ == '__main__': > > emp1 = Employee('Zara') > > print(emp1.displayEmployee()) > > Your last line here prints the value returned by displayEmployee(). > > What is that method returning? > > Hint: if a function/method does not explicitly return something via a > return statement, it returns None. > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From david at graniteweb.com Wed Apr 15 10:15:52 2020 From: david at graniteweb.com (David Rock) Date: Wed, 15 Apr 2020 09:15:52 -0500 Subject: [Tutor] Why is this printing None? In-Reply-To: References: <3a7bef42-60dd-e1ef-273b-a8e80b523edc@wichmann.us> Message-ID: <3B006350-DDF9-439A-8326-64A83D5805E1@graniteweb.com> > On Apr 15, 2020, at 09:08, Cranky Frankie wrote: > > It prints the word Zara like it should, then the word None on the next line > which it shouldn't. I got the example from: > > https://www.tutorialspoint.com/python/python_classes_objects.htm > > When they show the results, the word None is not output. > > I don't know why this is happening. Ok, that clarifies and reinforces what I sent. You are not doing the same thing that?s in that example. In this section: Accessing Attributes You access the object's attributes using the dot operator with object. Class variable would be accessed using class name as follows ? emp1.displayEmployee() emp2.displayEmployee() note that it is calling emp1.displayEmployee() directly, NOT printing the result of it (i.e., print(emp1.displayEmployee()) By introducing the external print, your code has two print statements, not one: the print statement inside the method, and a second print statement outside the method. ? David Rock david at graniteweb.com From cranky.frankie at gmail.com Wed Apr 15 10:39:15 2020 From: cranky.frankie at gmail.com (Cranky Frankie) Date: Wed, 15 Apr 2020 10:39:15 -0400 Subject: [Tutor] Why is this printing None? In-Reply-To: <57FB3EA5-0A9E-4768-9CDC-EC84C2144AD3@graniteweb.com> References: <57FB3EA5-0A9E-4768-9CDC-EC84C2144AD3@graniteweb.com> Message-ID: That was the answer, tanking the function out of the print statement. Thanks. Frank L. "Cranky Frankie" Palmeri, Risible Riding Raconteur & Writer WORK Hard - PLAY Hard - READ Hard - THINK Hard On Wed, Apr 15, 2020 at 10:08 AM David Rock wrote: > > > On Apr 15, 2020, at 08:24, Cranky Frankie > wrote: > > > > I have this simple class in Python 3.8. When I run this in IDLE or at the > > command prompt the word None gets printed after the employee name. Why? > > > > class Employee: > > > > def __init__ (self, name): > > self.name = name > > > > def displayEmployee(self): > > print("Name : ", self.name) > > > > if __name__ == '__main__': > > emp1 = Employee('Zara') > > print(emp1.displayEmployee()) > > > As others have pointed out, you aren?t printing what you think should be > printed. > emp1.displayEmployee() prints the name, then you are printing the return > value of displayEmployee() > > If you change your code to this, it will do what you probably want, but > this might not be the best way to do it (but fits the intentions of what > your code implies). > > if __name__ == '__main__?: > emp1 = Employee('Zara?) > emp1.displayEmployee() > > Note that what I?m doing is allowing the Class method to handle the > printing (your external print is redundant, and the reason for the ?None?) > as already noted. > > If you want the external print statement, instead of having a > displayEmployee() method, maybe use a __str__ method to dictate what > printing the object means, or have a getter method that just returns > self.name so it can be printed. > > It all depends what your overall needs are. > > > ? > David Rock > david at graniteweb.com > > > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From alan.gauld at yahoo.co.uk Wed Apr 15 19:15:02 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 16 Apr 2020 00:15:02 +0100 Subject: [Tutor] Why is this printing None? In-Reply-To: References: Message-ID: On 15/04/2020 14:24, Cranky Frankie wrote: > I have this simple class in Python 3.8. When I run this in IDLE or at the > command prompt the word None gets printed after the employee name. Why? > > class Employee: > > def __init__ (self, name): > self.name = name > > def displayEmployee(self): > print("Name : ", self.name) > > if __name__ == '__main__': > emp1 = Employee('Zara') > print(emp1.displayEmployee()) Others have answered your original question. It is worth pointing out that putting a print() inside a class like this is usually the wrong thing to do. It is better if the class returns a string which can be printed by the caller. This is known as separation of presentation and logic. And it is better still, in this case, if the function returning the string is called __str__(). That then means the object can be printed directly: class Employee: def __init__ (self, name): self.name = name def __str__(self): return "Name : " + self.name if __name__ == '__main__': emp1 = Employee('Zara') print(emp1) Notice we print the object (no need to call any methods) and print internally calls the obj.__str__() method to get the string. -- 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 Jon_Davies17 at hotmail.co.uk Wed Apr 15 16:09:21 2020 From: Jon_Davies17 at hotmail.co.uk (Jon Davies) Date: Wed, 15 Apr 2020 20:09:21 +0000 Subject: [Tutor] Dynamic variables changed via Tkinter button Message-ID: Hi, As part of my Petrol Pay at Pump Tkinter GUI, I need to implement two labels (displaying dynamic variables) that will change based on a button being held. The variables (counters) need to increase based on a calculation "Fuel amount in Litres * (Fuel Price * Chosen Currency)", as a "Fuel Lever" is pressed and held. I assume as part of the calculation, some sort of flow variable will be required, but not sure how best to implement this. I've tried to implement the below so far, through defining the FUEL_PRICE_RATE, the various currencies and then implementing FUEL_LITRE_var and FUEL_PRICE_var as IntVars, which should then be updated through running a function def fuelHold - although I don't think I've actually configured this correctly. This is is pure guesswork at the moment, so more looking for suggestions as to how this can be achieved, as I am getting basic errors e.g. . AttributeError: 'BeginFuellingPage' object has no attribute 'FUEL_LITRE' import tkinter as tk from tkinter import ttk import gettext Constants FUEL_PRICE_RATE = 1.17 GBP = 1.00 EUR = 1.14 USD = 1.24 class SelectCurrencyPage(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller self.currency_lbl = tk.Label(self, text = _("PLEASE SELECT CURRENCY"), font = LARGE_FONT) self.currency_lbl.pack(pady = 10, padx = 10) self.GBP_btn = tk.Button(self, text = "? GBP", command = lambda c = "?": self.doCurrency(c)) self.GBP_btn.pack() self.USD_btn = tk.Button(self, text = "$ USD", command = lambda c = "$": self.doCurrency(c)) self.USD_btn.pack() self.EUR_btn = tk.Button(self, text = "? EUR", command = lambda c = "?": self.doCurrency(c)) self.EUR_btn.pack() self.restart_btn = tk.Button(self, text = _("RESTART"), command = lambda: self.controller.setState('restart')) self.restart_btn.pack() def doCurrency(self, currency): self.controller.setCurrency(currency) self.controller.setState('fuel') class BeginFuellingPage(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller self.begin_fuel_lbl = tk.Label(self, text = _("BEGIN FUELLING"), font = LARGE_FONT) self.begin_fuel_lbl.pack(pady = 10, padx = 10) self.fuel_litre_lbl = tk.Label(self, textvariable = self.FUEL_LITRE_var, font = LARGE_FONT) self.fuel_litre_lbl.pack(pady = 10, padx = 10) self.fuel_price_lbl = tk.Label(self, textvariable = self.FUEL_PRICE_var, font = LARGE_FONT) self.fuel_price_lbl.pack(pady = 10, padx = 10) self.FUEL_LITRE_var = tk.IntVar(self, value = 0) self.FUEL_PRICE_var = tk.IntVar(self, value = 0) self.fuel_lever_btn = tk.Button(self, text = _("FUEL LEVER"), command = self.fuelHold) self.fuel_lever_btn.pack() self.finish_btn = tk.Button(self, text = "FINISH", command = self.doFinish) self.finish_btn.pack() self.restart_btn = tk.Button(self, text = _("RESTART"), command = lambda: self.controller.setState('restart')) self.restart_btn.pack() def fuelHold(self): self.begin_fuel_lbl.config(text = _("FUELLING IN PROGRESS")) self.restart_btn.destroy() self.FUEL_LITRE_var.set(FUEL_LITRE_var.get() + fuel flow?) self.FUEL_PRICE_var.set(FUEL_PRICE_var.get() + (FUEL_PRICE_RATE * currency?)) def doFinish(self): self.begin_fuel_lbl.config(text = _("FUELLING COMPLETE")) self.lever_btn.config(state='active') self.finish_btn.config(state='disabled') self.controller.setState('finish') class Oleum(tk.Tk): states = { SelectLanguagePage: { 'cancel' : SelectLanguagePage, 'language' : SelectPaymentPage }, SelectPaymentPage: { 'restart' : SelectLanguagePage, 'pump' : InsertCardPage, 'kiosk' : SelectCurrencyPage, 'other' : SelectPaymentPage }, InsertCardPage: { 'restart' : SelectLanguagePage, 'currency' : SelectCurrencyPage, 'other' : InsertCardPage }, SelectCurrencyPage: { 'restart' : SelectLanguagePage, 'fuel' : BeginFuellingPage, 'other' : SelectCurrencyPage }, BeginFuellingPage: { 'restart' : SelectLanguagePage, 'finish' : TotalGoodbyePage, 'other' : BeginFuellingPage }, TotalGoodbyePage: { 'any' : SelectLanguagePage } } def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) self.events = self.states.keys() self.currentState = SelectLanguagePage self.currency = None self.container = tk.Frame(self) self.container.grid(row=0,column=0,sticky='news') view = SelectLanguagePage(self.container,self) view.grid(row=0,column=0,sticky='news') self.frames = {SelectLanguagePage : view} self.show_frame() def setFrames(self): for F in ( SelectPaymentPage, InsertCardPage, SelectCurrencyPage, BeginFuellingPage, TotalGoodbyePage): view = F(self.container,self) view.grid(row=0,column=0,sticky='news') self.frames[F] = view def show_frame(self, view=None): if view == None: view = self.currentState frame = self.frames[view] frame.tkraise() def setState(self,event): self.currentState = self.states[self.currentState].get(event, SelectLanguagePage) self.show_frame() def setCurrency(self, c): self.currency = c if __name__ == "__main__": app = Oleum() app.title('Oleum') app.configure(background = DARK_PURPLE) app.geometry("420x380") app.resizable(0,0) app.mainloop() Thanks, Jon From akleider at sonic.net Wed Apr 15 19:43:20 2020 From: akleider at sonic.net (Alex Kleider) Date: Wed, 15 Apr 2020 16:43:20 -0700 Subject: [Tutor] Fwd: Re: Why is this printing None? In-Reply-To: References: Message-ID: <2b1e9373965a14594f41f07e767645cc@sonic.net> Sorry, I hit reply rather than reply-all -------- Original Message -------- Subject: Re: [Tutor] Why is this printing None? Date: 2020-04-15 16:42 From: Alex Kleider To: Cranky Frankie On 2020-04-15 06:24, Cranky Frankie wrote: > I have this simple class in Python 3.8. When I run this in IDLE or at > the > command prompt the word None gets printed after the employee name. Why? > > class Employee: > > def __init__ (self, name): > self.name = name > > def displayEmployee(self): > print("Name : ", self.name) > > if __name__ == '__main__': > emp1 = Employee('Zara') > print(emp1.displayEmployee()) > > the last statement of your code is asking that the result of the displayEmployee method be printed. Any method/function without a specific return statement returns None by default and that's what's getting printed. Change your last line by removing the word 'print' (and, optionally, remove a set of ().) From alan.gauld at yahoo.co.uk Thu Apr 16 05:28:48 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 16 Apr 2020 10:28:48 +0100 Subject: [Tutor] Dynamic variables changed via Tkinter button In-Reply-To: References: Message-ID: On 15/04/2020 21:09, Jon Davies wrote: > I need to implement two labels (displaying dynamic variables) that will change based on a button being held. Working on the basis of a button being held is not normal GUI behaviour so you won;t find any standard events to deal with that. Instead you will need to look for mouse button events on the button. So when the button is first pressed you need to start a pseudo loop which performs the calculation and then pauses briefly - say for 50ms - then repeats until the mouse button up is received. So in your code you need to 1) bind the and events to your GUI Button 2) On ButtonPressed set a state value of "fuelling"(or whatever you call it)) Note this is a local state value in your Fuelling view, this is not in the application level states table.(although it could be if you want.) 3) Start a loop using the after() method that checks the state for fuelling and updates the label and then repeats the after() call. If the state is not fuelling it updates the label and does not repeat but calls your controller.setState() method to navigate to the appropriate screen. 4) On ButtonReleased you change that state from "fuelling" I think that is what you are trying to achieve... So in pseudo code: class Fuellingscreen(tk.Frame): def __init__(self,controller): .... self.fuelButton.bind(, self.beginFuelling) self.fuelbutton.bind(, self.endFuelling) set.state = 'idle' ... def beginFuelling(self): set label set self.state = 'fuelling' ... anything else.... self.after(50,self.updateFuel) def updateFuel(self): do calculation update label self.update_idletasks() # forces redraw of GUI if self.state == 'fuelling': self.after(50,self.updateFuel) #go again def endFuelling(self): self.state = 'idle' Hopefully that's enough to get you started BTW I didn't check the event names so you may need to look them up. -- 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 Thu Apr 16 07:53:49 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 16 Apr 2020 12:53:49 +0100 Subject: [Tutor] Dynamic variables changed via Tkinter button In-Reply-To: References: Message-ID: On 15/04/2020 21:09, Jon Davies wrote: > I need to implement two labels (displaying dynamic variables) that will change based on a button being held. Here is some runnable code that illustrates what you want, i think... import tkinter as tk class App(): def __init__(self,parent): self.main = tk.Frame(parent) self.main.pack() self.state='idle' self.count = 0 self.lbl = tk.Label(self.main, text="Count = 0") self.lbl.pack() self.btn = tk.Button(self.main, text="Press & Hold") self.btn.pack() self.btn.bind('', self.press) self.btn.bind("", self.stop) def press(self,evt): self.state='working' self.btn.after(100,self.update) def update(self): self.count += 0.1 self.lbl['text'] = "Count = %f" % self.count self.main.update_idletasks() if self.state == 'working': self.btn.after(100, self.update) def stop(self,evt): self.state = 'idle' top = tk.Tk() app = App(top) top.mainloop() -- 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 imran041999 at gmail.com Fri Apr 17 00:22:59 2020 From: imran041999 at gmail.com (imran) Date: Fri, 17 Apr 2020 09:52:59 +0530 Subject: [Tutor] i want to studt python from basics Message-ID: From alan.gauld at yahoo.co.uk Fri Apr 17 03:48:03 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 17 Apr 2020 08:48:03 +0100 Subject: [Tutor] i want to studt python from basics In-Reply-To: References: Message-ID: On 17/04/2020 05:22, imran wrote: Start with one of the tutorials listed here: If you have never programmed before: https://wiki.python.org/moin/BeginnersGuide/NonProgrammers Or if you already know another language: https://wiki.python.org/moin/BeginnersGuide/Programmers If you have any questions or problems come back here to ask questions. Or you could try my tutorial below... -- 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 basicbare at gmail.com Fri Apr 17 09:25:54 2020 From: basicbare at gmail.com (Alan Thwaits) Date: Fri, 17 Apr 2020 09:25:54 -0400 Subject: [Tutor] Attribution Error Message-ID: I can't resolve an attribution error message in the script for my first text-based rooms-and-choices game. After reading everything I could find about it online, I'm still banging my head in frustration. Any help, direction, or suggestions would be greatly appreciated. The error message I get is this: Traceback (most recent call last): File "C:\Users\Alan\Documents\Python\ex45.py", line 350, in a_game.play() File "C:\Users\Alan\Documents\Python\ex45.py", line 59, in play next_scene_name = current_scene.enter() AttributeError: 'NoneType' object has no attribute 'enter' The code blocks referenced in the above are: # make a map, then hand it to an Engine before calling play to make the game work a_map = Map('aware') a_game = Engine(a_map) a_game.play() < References: Message-ID: <05de6b0f-6d6d-dafd-e3f5-e32ab2a7da5f@wichmann.us> On 4/17/20 7:25 AM, Alan Thwaits wrote: > I can't resolve an attribution error message in the script for my first > text-based rooms-and-choices game. After reading everything I could find > about it online, I'm still banging my head in frustration. Any help, > direction, or suggestions would be greatly appreciated. > > The error message I get is this: > > Traceback (most recent call last): > File "C:\Users\Alan\Documents\Python\ex45.py", line 350, in > a_game.play() > File "C:\Users\Alan\Documents\Python\ex45.py", line 59, in play > next_scene_name = current_scene.enter() > AttributeError: 'NoneType' object has no attribute 'enter' Once you get used to it, this error message is quite straightforward, although in the beginning it is a little daunting. It means: you tried to access an attribute of an object, but the object doesn't have that attribute. Per the error message, the object is actually the special object None, which has no attributes. you have an unexpected value, and need to add some form of error handling. > current_scene = self.scene_map.opening_scene() > last_scene = self.scene_map.next_scene('finished') > > while current_scene != last_scene: > next_scene_name = current_scene.enter() << line 59 > current_scene = self.scene_map.next_scene(next_scene_name) so one of these two calls, "scene_map_opening_scene()" or inside the loop "scene_map_next_scene()" has returned None instead of a valid scene instance. From alan.gauld at yahoo.co.uk Fri Apr 17 12:29:53 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 17 Apr 2020 17:29:53 +0100 Subject: [Tutor] Attribution Error In-Reply-To: References: Message-ID: On 17/04/2020 14:25, Alan Thwaits wrote: > Traceback (most recent call last): > File "C:\Users\Alan\Documents\Python\ex45.py", line 350, in > a_game.play() > File "C:\Users\Alan\Documents\Python\ex45.py", line 59, in play > next_scene_name = current_scene.enter() > AttributeError: 'NoneType' object has no attribute 'enter' Note that is says that NoneType has no attribute enter so it is telling you that, at some point, current_scene is being set to None. So you need to find that point and either fix it or detect it. The simplest way is simply to insert print statements after each current_scene assignment. If you are familiar with debuggers such as those in eclipse or VS Code you can set a watch or conditional breakpoint instead. But a print is usually easiest! Just remember to take them all out again when done. > class Engine(object): > def play(self): > current_scene = self.scene_map.opening_scene() print("Current scene: ", current_scene) > last_scene = self.scene_map.next_scene('finished') > > while current_scene != last_scene: > next_scene_name = current_scene.enter() << line 59 > current_scene = self.scene_map.next_scene(next_scene_name) print("Current scene: ", current_scene) My suspicion is that you are somehow encountering an error in the next_scene code, or simply running off the end of the scene map... -- 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 basicbare at gmail.com Fri Apr 17 18:59:51 2020 From: basicbare at gmail.com (Alan Thwaits) Date: Fri, 17 Apr 2020 18:59:51 -0400 Subject: [Tutor] Attribution Error In-Reply-To: References: Message-ID: Can you give me an example of "insert print statements after each current_scene assignment"? I know it sounds simple, but I'm a bit at sea with it. Thanks! Alan On Fri, Apr 17, 2020 at 12:30 PM Alan Gauld via Tutor wrote: > On 17/04/2020 14:25, Alan Thwaits wrote: > > > Traceback (most recent call last): > > File "C:\Users\Alan\Documents\Python\ex45.py", line 350, in > > a_game.play() > > File "C:\Users\Alan\Documents\Python\ex45.py", line 59, in play > > next_scene_name = current_scene.enter() > > AttributeError: 'NoneType' object has no attribute 'enter' > > Note that is says that NoneType has no attribute enter so it is telling > you that, at some point, current_scene is being set to None. > So you need to find that point and either fix it or detect it. > > The simplest way is simply to insert print statements after each > current_scene assignment. > > If you are familiar with debuggers such as those in eclipse or > VS Code you can set a watch or conditional breakpoint instead. > But a print is usually easiest! Just remember to take them all > out again when done. > > > class Engine(object): > > def play(self): > > current_scene = self.scene_map.opening_scene() > print("Current scene: ", current_scene) > > > last_scene = self.scene_map.next_scene('finished') > > > > while current_scene != last_scene: > > next_scene_name = current_scene.enter() << line 59 > > current_scene = self.scene_map.next_scene(next_scene_name) > > print("Current scene: ", current_scene) > > My suspicion is that you are somehow encountering an error in the > next_scene code, or simply running off the end of the scene map... > > -- > 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 > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From alan.gauld at yahoo.co.uk Fri Apr 17 20:00:22 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 18 Apr 2020 01:00:22 +0100 Subject: [Tutor] Attribution Error In-Reply-To: References: Message-ID: On 17/04/2020 23:59, Alan Thwaits wrote: > Can you give me an example of "insert print statements after each > current_scene assignment"? I already did. They are in the code below... >>> class Engine(object): >>> def play(self): >>> current_scene = self.scene_map.opening_scene() >> print("Current scene: ", current_scene) The line above is a debug print statement. >> >>> last_scene = self.scene_map.next_scene('finished') >>> >>> while current_scene != last_scene: >>> next_scene_name = current_scene.enter() << line 59 >>> current_scene = self.scene_map.next_scene(next_scene_name>> print("Current scene: ", current_scene) And so it the one above here... -- 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 basicbare at gmail.com Sat Apr 18 05:16:01 2020 From: basicbare at gmail.com (Alan Thwaits) Date: Sat, 18 Apr 2020 05:16:01 -0400 Subject: [Tutor] Attribution Error In-Reply-To: References: Message-ID: My apologies. I can't see how I missed that. Alan On Fri, Apr 17, 2020 at 8:00 PM Alan Gauld via Tutor wrote: > On 17/04/2020 23:59, Alan Thwaits wrote: > > Can you give me an example of "insert print statements after each > > current_scene assignment"? > > I already did. They are in the code below... > > >>> class Engine(object): > >>> def play(self): > >>> current_scene = self.scene_map.opening_scene() > >> print("Current scene: ", current_scene) > > The line above is a debug print statement. > > >> > >>> last_scene = self.scene_map.next_scene('finished') > >>> > >>> while current_scene != last_scene: > >>> next_scene_name = current_scene.enter() << line 59 > >>> current_scene = > self.scene_map.next_scene(next_scene_name>> print("Current > scene: ", current_scene) > And so it the one above here... > > > > -- > 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 > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From jon_davies17 at hotmail.co.uk Sat Apr 18 10:22:49 2020 From: jon_davies17 at hotmail.co.uk (Jon Davies) Date: Sat, 18 Apr 2020 14:22:49 +0000 Subject: [Tutor] Dynamic variables changed via Tkinter button In-Reply-To: References: , Message-ID: Hi Alan, As always, thanks for your insight - that gives me exactly the sort of base I was hoping to build on. I had researched on the web on whether it was possible, but given your note that typically this wouldn't considered as standard GUI behavior, explains why I maybe didn't find much (or perhaps I didn't look hard enough!). I've now adapted the below and implemented something similar as part of my wider Petrol Pump program code and I've managed to get it functioning. However, now I am looking to enhance this further (using the selected currency as input to a calculation, which you are already aware of). Given I need two labels (one for Fuel Price, one for Litres), I've implemented two counts (fuelcount and pricecount) and separated these within the "update" function. For the pricecount, I am looking to enable an increase based on "fuelcount * (currency * petrol_price)". See below for what I've tried to implement. def update(self): self.fuelcount += 0.1 self.pricecount += 0.1 * (self.currency * PETROL_PRICE) self.litre_lbl['text'] = "Litres = %f" % self.fuelcount self.price_lbl['text'] = "Price = %f" % self.pricecount self.update_idletasks() if self.state == 'working': self.lever_btn.after(100, self.update) I tried to configure the calculation to use the fuelcount value directly i.e. (0.1), but I found that this started to increase the pricecount exponentially, so for now I have just aligned the values at 0.1. The code doesn't seem to recognise self.currency (starting that AttributeError: 'BeginFuellingPage' object has no attribute 'currency'). If I replaced self.currency with a number, then it works. I am trying to reference the currency variable that was set earlier on in the GUI via the SelectCurrencyPage. class SelectCurrencyPage(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller self.currency_lbl = tk.Label(self, text = _("PLEASE SELECT CURRENCY"), font = LARGE_FONT) self.currency_lbl.pack(pady = 10, padx = 10) self.GBP_btn = tk.Button(self, text = "? GBP", command = lambda c = "?": self.setGBP(c)) self.GBP_btn.pack() self.USD_btn = tk.Button(self, text = "$ USD", command = lambda c = "$": self.setUSD(c)) self.USD_btn.pack() self.EUR_btn = tk.Button(self, text = "? EUR", command = lambda c = "?": self.setEUR(c)) self.EUR_btn.pack() self.restart_btn = tk.Button(self, text = _("RESTART"), command = lambda: self.controller.setState('restart')) self.restart_btn.pack() def setGBP(self, currency): self.controller.setCurrency(GBP) self.controller.setState('fuel') def setUSD(self, currency): self.controller.setCurrency(USD) self.controller.setState('fuel') def setEUR(self, currency): self.controller.setCurrency(EUR) self.controller.setState('fuel') Here are my constants: import tkinter as tk from tkinter import ttk import gettext #Constants LARGE_FONT = ("Arial", 12) MEDIUM_FONT = ("Arial", 9) DARK_PURPLE = ("#7030a0") LIGHT_PURPLE = ("#9f60ce") PETROL_PRICE = 1.17 GBP = 1.00 EUR = 1.14 USD = 1.24 And here is the setCurrency function that you helped define as part of the overarching app (Oleum) class, under the states: class Oleum(tk.Tk): #other code omitted to shorten email def setCurrency(self, c): self.currency = c My other question would be how do I go about indicating the chosen currency symbol (?, $, ?) on my "fueling" frame as part of the fuel price count label. Kind regards, Jon ________________________________ From: Tutor on behalf of Alan Gauld via Tutor Sent: 16 April 2020 12:53 To: tutor at python.org Subject: Re: [Tutor] Dynamic variables changed via Tkinter button On 15/04/2020 21:09, Jon Davies wrote: > I need to implement two labels (displaying dynamic variables) that will change based on a button being held. Here is some runnable code that illustrates what you want, i think... import tkinter as tk class App(): def __init__(self,parent): self.main = tk.Frame(parent) self.main.pack() self.state='idle' self.count = 0 self.lbl = tk.Label(self.main, text="Count = 0") self.lbl.pack() self.btn = tk.Button(self.main, text="Press & Hold") self.btn.pack() self.btn.bind('', self.press) self.btn.bind("", self.stop) def press(self,evt): self.state='working' self.btn.after(100,self.update) def update(self): self.count += 0.1 self.lbl['text'] = "Count = %f" % self.count self.main.update_idletasks() if self.state == 'working': self.btn.after(100, self.update) def stop(self,evt): self.state = 'idle' top = tk.Tk() app = App(top) top.mainloop() -- 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 _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor _______________________________________________________________________________________________________________________________________________________ From: Tutor on behalf of Alan Gauld via Tutor Sent: 16 April 2020 10:28 To: tutor at python.org Subject: Re: [Tutor] Dynamic variables changed via Tkinter button On 15/04/2020 21:09, Jon Davies wrote: > I need to implement two labels (displaying dynamic variables) that will change based on a button being held. Working on the basis of a button being held is not normal GUI behaviour so you won;t find any standard events to deal with that. Instead you will need to look for mouse button events on the button. So when the button is first pressed you need to start a pseudo loop which performs the calculation and then pauses briefly - say for 50ms - then repeats until the mouse button up is received. So in your code you need to 1) bind the and events to your GUI Button 2) On ButtonPressed set a state value of "fuelling"(or whatever you call it)) Note this is a local state value in your Fuelling view, this is not in the application level states table.(although it could be if you want.) 3) Start a loop using the after() method that checks the state for fuelling and updates the label and then repeats the after() call. If the state is not fuelling it updates the label and does not repeat but calls your controller.setState() method to navigate to the appropriate screen. 4) On ButtonReleased you change that state from "fuelling" I think that is what you are trying to achieve... So in pseudo code: class Fuellingscreen(tk.Frame): def __init__(self,controller): .... self.fuelButton.bind(, self.beginFuelling) self.fuelbutton.bind(, self.endFuelling) set.state = 'idle' ... def beginFuelling(self): set label set self.state = 'fuelling' ... anything else.... self.after(50,self.updateFuel) def updateFuel(self): do calculation update label self.update_idletasks() # forces redraw of GUI if self.state == 'fuelling': self.after(50,self.updateFuel) #go again def endFuelling(self): self.state = 'idle' Hopefully that's enough to get you started BTW I didn't check the event names so you may need to look them up. -- 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 _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From __peter__ at web.de Sat Apr 18 11:52:33 2020 From: __peter__ at web.de (Peter Otten) Date: Sat, 18 Apr 2020 17:52:33 +0200 Subject: [Tutor] Dynamic variables changed via Tkinter button References: Message-ID: Jon Davies wrote: > Hi Alan, > > As always, thanks for your insight - that gives me exactly the sort of > base I was hoping to build on. I had researched on the web on whether it > was possible, but given your note that typically this wouldn't considered > as standard GUI behavior, explains why I maybe didn't find much (or > perhaps I didn't look hard enough!). > > I've now adapted the below and implemented something similar as part of my > wider Petrol Pump program code and I've managed to get it functioning. > > However, now I am looking to enhance this further (using the selected > currency as input to a calculation, which you are already aware of). > > Given I need two labels (one for Fuel Price, one for Litres), I've > implemented two counts (fuelcount and pricecount) and separated these > within the "update" function. For the pricecount, I am looking to enable > an increase based on "fuelcount * (currency * petrol_price)". See below > for what I've tried to implement. > > def update(self): > self.fuelcount += 0.1 > self.pricecount += 0.1 * (self.currency * PETROL_PRICE) > self.litre_lbl['text'] = "Litres = %f" % self.fuelcount > self.price_lbl['text'] = "Price = %f" % self.pricecount Don't use two independent counters; count the litres of fuel only, and calculate the price from that: price = self.fuelcount * self.currency * PETROL_PRICE self.price_lbl["text"] = "Price = %f" % price (I'm not sure, but self.currency might actually have to be self.controller.currency) > self.update_idletasks() > if self.state == 'working': > self.lever_btn.after(100, self.update) > > I tried to configure the calculation to use the fuelcount value directly > i.e. (0.1), but I found that this started to increase the pricecount > exponentially, so for now I have just aligned the values at 0.1. The code > doesn't seem to recognise self.currency (starting that AttributeError: > 'BeginFuellingPage' object has no attribute 'currency'). If I replaced > self.currency with a number, then it works. > > I am trying to reference the currency variable that was set earlier on in > the GUI via the SelectCurrencyPage. class SelectCurrencyPage(tk.Frame): > def __init__(self, parent, controller): > tk.Frame.__init__(self, parent) > self.controller = controller > > self.currency_lbl = tk.Label(self, text = _("PLEASE SELECT > CURRENCY"), font = LARGE_FONT) self.currency_lbl.pack(pady = 10, > padx = 10) > > self.GBP_btn = tk.Button(self, text = "? GBP", > command = lambda c = "?": self.setGBP(c)) > self.GBP_btn.pack() > > self.USD_btn = tk.Button(self, text = "$ USD", > command = lambda c = "$": self.setUSD(c)) > self.USD_btn.pack() > > self.EUR_btn = tk.Button(self, text = "? EUR", > command = lambda c = "?": self.setEUR(c)) > self.EUR_btn.pack() > > self.restart_btn = tk.Button(self, text = _("RESTART"), > command = lambda: > self.controller.setState('restart')) > self.restart_btn.pack() There's a lot of redundancy here. You can simplify that with a helper method: def makeCurrencyButton(self, code, symbol, conversion): button = tk.Button( self, text=f"{symbol} {code}", command=lambda: self.setCurrency(conversion) ) button.pack() return button > > def setGBP(self, currency): > self.controller.setCurrency(GBP) > self.controller.setState('fuel') > > def setUSD(self, currency): > self.controller.setCurrency(USD) > self.controller.setState('fuel') > > def setEUR(self, currency): > self.controller.setCurrency(EUR) > self.controller.setState('fuel') Replace these with def setCurrency(self, conversion): self.controller.setCurrency(conversion) self.controller.setState("fuel") Now > self.GBP_btn = tk.Button(self, text = "? GBP", > command = lambda c = "?": self.setGBP(c)) > self.GBP_btn.pack() > > self.USD_btn = tk.Button(self, text = "$ USD", > command = lambda c = "$": self.setUSD(c)) > self.USD_btn.pack() > > self.EUR_btn = tk.Button(self, text = "? EUR", > command = lambda c = "?": self.setEUR(c)) > self.EUR_btn.pack() becomes self.GBP_btn = self.makeCurrencyButton("GBP", "?", GBP) self.USD_btn = self.makeCurrencyButton("USD", "$", USD) self.EUR_btn = self.makeCurrencyButton("EUR", "?", EUR) If you go one step further and use a list to store the (code, symbol, conversion-rate) triples CURRENCIES = [("EUR", "?", 1.14), ...] and the buttons self.currency_buttons = [ self.makeCurrencyButton(*currency) for currency in CURRENCIES ] it will become very easy to add or remove currencies. Regarding your actual question, I guess that you are making a mess by using the currency attribute for two different purposes -- but my idea of your program is not concrete enough to tell you how to fix that, or if that even is the correct diagnosis. You have to wait for Alan or someone else to chime in -- or provide the complete runnable source code somewhere. From afreer2 at netzero.net Sat Apr 18 12:02:21 2020 From: afreer2 at netzero.net (afreer2 at netzero.net) Date: Sat, 18 Apr 2020 16:02:21 GMT Subject: [Tutor] new to python Message-ID: <20200418.090221.28082.0@webmail04.dca.untd.com> I HANDICAP HORSE RACESPython will do what I could never do with Ms AccessI say this because it would be nice if the person who might respond has some interest in handicappingIt is the same as the stock market with less competition but faster pay offsI would like to learn everything PDF using Camelot.whl Camelot finds tables fast Python does AI data science and moreBTY I am in my 80's and my mind thinks like a teenager,my body does not agreeI like using Jupyter notebook I have python v 3.8.2 ,anaconda installedMy pc is a surface 64 bit machineThank you for any help in adavaceAnson From alan.gauld at yahoo.co.uk Sat Apr 18 19:33:46 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 19 Apr 2020 00:33:46 +0100 Subject: [Tutor] new to python In-Reply-To: <20200418.090221.28082.0@webmail04.dca.untd.com> References: <20200418.090221.28082.0@webmail04.dca.untd.com> Message-ID: On 18/04/2020 17:02, afreer2 at netzero.net wrote: > I HANDICAP HORSE RACESPython will do what I could never do with Ms Access I'll take your word for the first point and tend to agree about the second. > it would be nice if the person who might respond has some interest in handicapping I know nothing about handicapping. But the list works by you posting questions about python or its standard libraries and anyone from the list who is interested offering answers, advice or pointers to information. > I would like to learn everything PDF using Camelot. You may need to explain that. Assume the people reading do not know about your particular area. The more specialized the topic the fewer the number who know it. > I like using Jupyter notebook > I have python v 3.8.2 ,anaconda installed > My pc is a surface 64 bit machine Thanks for that, it helps to know. If you have any specific questions let us know. Tell us what you are studying or trying to write. Show us the full text of any errors along with the code causing it. Show us sample data if it is pertinent. -- 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 Apr 19 07:08:48 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 19 Apr 2020 12:08:48 +0100 Subject: [Tutor] Dynamic variables changed via Tkinter button In-Reply-To: References: Message-ID: On 18/04/2020 15:22, Jon Davies wrote: > Given I need two labels (one for Fuel Price, one for Litres), I've implemented two counts > (fuelcount and pricecount) and separated these within the "update" function. For the pricecount, > I am looking to enable an increase based on "fuelcount * (currency * petrol_price)". The currency*price value only needs to be calculated one when the currency is selected. So in your selectCurrency event handler you should set the currency symbol and a fuel_rate attribute in your controller class. Then in the fuelling update method use fetch the rate from the controller and do the multiplication using that rate. See below for what I've tried to implement. > > def update(self): > self.fuelcount += 0.1 > self.pricecount += 0.1 * (self.currency * PETROL_PRICE) The price should not increment it should be calculated. self.price = self.controller.fuel_rate * self.fuelcount > self.litre_lbl['text'] = "Litres = %f" % self.fuelcount > self.price_lbl['text'] = "Price = %f" % self.price > self.update_idletasks() > if self.state == 'working': > self.lever_btn.after(100, self.update) > The code doesn't seem to recognise self.currency (starting that > AttributeError: 'BeginFuellingPage' object has no attribute 'currency'). Where did you set the currency? Was it in the fuelling object or in another class instance? Any data that you want to share between your objects will need to go into the controller object since it is the only thing that all the other objects can see. (This is one reason I don't like this style of GUI design, the controller becomes the owner of lots of data that should really be in the other objects.) > I am trying to reference the currency variable that was set earlier on in the GUI via the SelectCurrencyPage. > class SelectCurrencyPage(tk.Frame): > def __init__(self, parent, controller): > tk.Frame.__init__(self, parent) > self.controller = controller > > self.currency_lbl = tk.Label(self, text = _("PLEASE SELECT CURRENCY"), font = LARGE_FONT) > self.currency_lbl.pack(pady = 10, padx = 10) > > self.GBP_btn = tk.Button(self, text = "? GBP", > command = lambda c = "?": self.setGBP(c)) > self.GBP_btn.pack() > > self.USD_btn = tk.Button(self, text = "$ USD", > command = lambda c = "$": self.setUSD(c)) > self.USD_btn.pack() > > self.EUR_btn = tk.Button(self, text = "? EUR", > command = lambda c = "?": self.setEUR(c)) > self.EUR_btn.pack() As Peter has pointed out you don't need or want lots of separate methods to set currency. You just want one that gets called with the appropriate currency. That method is the one that should notify the controller of the selected currency and the exchange_rate. The controller can then calculate the fuel_price based on its base rate * exchange_rate. In an ideal world the knowledge about currency and rates would stay in the Currency object and the controller methods would query it from there. So you would have a get_exchange_details() method in the controller, called by the Fuelling object. And that method would fetch the currency symbol and exchange rate from the currency object. But that frankly complicates matters, so for now just put the data in the controller... -- 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 s_poodle at hotmail.co.uk Sun Apr 19 06:19:50 2020 From: s_poodle at hotmail.co.uk (Helen Warren) Date: Sun, 19 Apr 2020 10:19:50 +0000 Subject: [Tutor] Advice needed on Python Programming Third Ed. Challenge on P85 No.2 Message-ID: Hello My name is Helen Warren and I am new to programming. I have bought Python Programming - Third Edition. I have spent several hours attempting the Challenges No. 2 - 4 on page 85. I cannot work out how to create a loop that counts. Is there the code online to give me the correct way to do this? I have been unable to find this. I have attached my code. Thank you for your advice. Helen -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: Testing2.py URL: From alan.gauld at yahoo.co.uk Sun Apr 19 09:15:57 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 19 Apr 2020 14:15:57 +0100 Subject: [Tutor] Advice needed on Python Programming Third Ed. Challenge on P85 No.2 In-Reply-To: References: Message-ID: On 19/04/2020 11:19, Helen Warren wrote: > My name is Helen Warren and I am new to programming. Hi Helen. Just for future reference, the list server doesn't like attachments and usually strips them off if they are non text (although this time its OK sometimes .py files are seen as non text because they could potentially be executed - dangerous.) As a result its better to simply paste your code into the body of the mail. That does mean you need to set the format to plain text, since html will strip out spaces and other formatting. I've pasted your code at the end for reference. > import random > print ("\tThe Heads of Tails game") > >count = 100 >tries = 1 >flip =random.randint(1, 2) Note, you only set flip once. It will never change again throughout the while loop so you will always follow the same route through the loop.. You probably want to put it inside the while loop, just after the while statement. >heads = 0 >tails = 0 > >while count > 0: > if flip == 1: > heads += 1 > count -= tries > else: > flip == 2 You are comparing flip to 2 but throwing away the result. You maybe meant to use elif flip == 2: But you don't need to compare flip here because you know it can only ever be 1 or 2, and the if test proved it was not 1, so you can just assume that if you are inside the else clause it must be 2. > tails += 2 Why do you increase tails by 2? Surely you only want to increase by 1? > count -= tries Notice you do this whether flip is 1 or 2. You could save some typing by putting this before the if/else If you make those changes it should work. Although for testing purposes I suggest you set the number of loops to a lower number than 100! I'd suggest somewhere between 5-10. Original code: # Heads and Tails # Tests while loop 100 time. import random print ("\tThe Heads of Tails game") count = 100 tries = 1 flip =random.randint(1, 2) heads = 0 tails = 0 while count > 0: if flip == 1: heads += 1 count -= tries else: flip == 2 tails += 2 count -= tries print ("Your have had:, ", count, "you have", tries, "left.\n") print ("You have flipped", heads, "heads and", tails, "tails." ) input ("\n\nPress the Enter key to exit") HTH -- 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 Apr 19 10:11:34 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 19 Apr 2020 15:11:34 +0100 Subject: [Tutor] Fwd: Re: Dynamic variables changed via Tkinter button In-Reply-To: References: Message-ID: <9ac4284b-dcab-09cb-7d87-6e3f6b71f709@yahoo.co.uk> Forwarding to list -------- Forwarded Message -------- Subject: Re: [Tutor] Dynamic variables changed via Tkinter button Date: Sun, 19 Apr 2020 11:57:47 +0000 From: Jon Davies To: Alan Gauld , Peter Otten Hi Peter, Alan, Thanks for your both of your responses. Having reviewed your responses, I have now made the respective changes and I have a working solution! * I've now removed the duplicate fuelprice counter, and based the label on a calculation using fuelcount * currency * fuel_price * As you both mentioned, it seemed that I'd forgot to include controller as as part of self.controller.currency, that seemed to do the trick? * Also simplified the SelectCurrencyPage by introducing a single "makeCurrencyButtons" based on the list of CURRENCIES outlined in the constants (which I've now included at the beginning of my code). This definitely makes sense, as it makes expansion to provide more currencies so much simpler * The set currency function now seems to work, and through testing the fuel_lever, the fuel litres versus the price (based on the calculations) are correct, which is great! CURRENCIES?=?[("GBP",?"?",?1.00),?("EUR",?"?",?1.14),?("USD",?"$",?1.24)] class?SelectCurrencyPage(tk.Frame): ????def?__init__(self,?parent,?controller): ????????tk.Frame.__init__(self,?parent) ????????self.controller?=?controller ????????self.currency_lbl?=?tk.Label(self,?text?=?_("PLEASE?SELECT?CURRENCY"),?font?=?LARGE_FONT) ????????self.currency_lbl.pack(pady?=?10,?padx?=?10) ????????self.currency_buttons?=?[ ????????????self.makeCurrencyButton(*currency) ????????????for?currency?in?CURRENCIES ????????] ??????? ????????self.restart_btn?=?tk.Button(self,?text?=?_("RESTART"),? ????????????????????????????command?=?lambda:?self.controller.setState('restart')) ????????self.restart_btn.pack() ????def?makeCurrencyButton(self,?code,?symbol,?conversion): ????????currency_button?=?tk.Button( ????????????self, ????????????text=f"{symbol}?{code}", ????????????command=lambda:?self.setCurrency(conversion) ????) ????????currency_button.pack() ????????return?currency_button ????def?setCurrency(self,?conversion): ????????self.controller.setCurrency(conversion) ????????self.controller.setState("fuel")? ? ? I suppose my only question now, to seal the deal, is how can I display the selected currency symbol as part of the price label in the Fuelling page? While I can verify that the currency selection/conversion is working through looking at the actual numbers that are presented, showing the actual currency symbol would make it a lot more evident. I'd assumed it would be something like the below (having taken inspiration from the def MakeCurrencyButton above) ????????self.litre_lbl?=?tk.Label(self,?text?=?_("Fuel?=?0")) ????????self.litre_lbl.pack(pady?=?10,?padx?=?10) ????????self.price_lbl?=?tk.Label(self,?text?=?_(f"{symbol}" +?"Price?=?0")) ????????self.price_lbl.pack(pady?=?10,?padx?=?10) ????def?update(self,?symbol):??????????????????????????????????????????? ????????self.fuelcount?+=?0.1 ????????total_price?=?self.fuelcount?*?self.controller.currency?*?PETROL_PRICE ????????self.litre_lbl['text']?=?_("Litres?=?%f")?%?self.fuelcount ????????self.price_lbl['text']?=?_(f"{symbol}"?+?"Price?=?%f")?%?total_price ????????self.update_idletasks() ????????if?self.state?==?'working': ????????????self.lever_btn.after(100,?self.update) But the main thing is, the functionality that I required from the start has now finally been implemented (translation and currency conversion), so this is a huge milestone for me and I can now look at tweaking the design parts. I could not have done it without your help so much appreciated as always. Kind regards, ------------------------------------------------------------------------ *From:* Tutor on behalf of Alan Gauld via Tutor *Sent:* 19 April 2020 12:08 *To:* tutor at python.org *Subject:* Re: [Tutor] Dynamic variables changed via Tkinter button ? On 18/04/2020 15:22, Jon Davies wrote: > Given I need two labels (one for Fuel Price, one for Litres), I've implemented two counts > (fuelcount and pricecount) and separated these within the "update" function. For the pricecount, > I am looking to enable an increase based on "fuelcount * (currency * petrol_price)".? The currency*price value only needs to be calculated one when the currency is selected. So in your selectCurrency event handler you should set the currency symbol and a fuel_rate attribute in your controller class. Then in the fuelling update method use fetch the rate from the controller and do the multiplication using that rate. See below for what I've tried to implement. > >???? def update(self): >???????? self.fuelcount += 0.1 >???????? self.pricecount += 0.1 * (self.currency * PETROL_PRICE) The price should not increment it should be calculated. ????????? self.price = self.controller.fuel_rate * self.fuelcount >???????? self.litre_lbl['text'] = "Litres = %f" % self.fuelcount >???????? self.price_lbl['text'] = "Price = %f" % self.price >???????? self.update_idletasks() >???????? if self.state == 'working': >???????????? self.lever_btn.after(100, self.update) > The code doesn't seem to recognise self.currency (starting that > AttributeError: 'BeginFuellingPage' object has no attribute 'currency'). Where did you set the currency? Was it in the fuelling object or in another class instance? Any data that you want to share between your objects will need to go into the controller object since it is the only thing that all the other objects can see. (This is one reason I don't like this style of GUI design, the controller becomes the owner of lots of data that should really be in the other objects.) > I am trying to reference the currency variable that was set earlier on in the GUI via the SelectCurrencyPage. > class SelectCurrencyPage(tk.Frame): >???? def __init__(self, parent, controller): >???????? tk.Frame.__init__(self, parent) >???????? self.controller = controller > >???????? self.currency_lbl = tk.Label(self, text = _("PLEASE SELECT CURRENCY"), font = LARGE_FONT) >???????? self.currency_lbl.pack(pady = 10, padx = 10) > >???????? self.GBP_btn = tk.Button(self, text = "? GBP", >???????????????????????????? command = lambda c = "?": self.setGBP(c)) >???????? self.GBP_btn.pack() > >???????? self.USD_btn = tk.Button(self, text = "$ USD", >???????????????????????????? command = lambda c = "$": self.setUSD(c)) >???????? self.USD_btn.pack() > >???????? self.EUR_btn = tk.Button(self, text = "? EUR", >???????????????????????????? command = lambda c = "?": self.setEUR(c)) >???????? self.EUR_btn.pack() As Peter has pointed out you don't need or want lots of separate methods to set currency. You just want one that gets called with the appropriate currency. That method is the one that should notify the controller of the selected currency and the exchange_rate. The controller can then calculate the fuel_price based on its base rate * exchange_rate. In an ideal world the knowledge about currency and rates would stay in the Currency object and the controller methods would query it from there. So you would have a get_exchange_details() method in the controller, called by the Fuelling object. And that method would fetch the currency symbol and exchange rate from the currency object. But that frankly complicates matters, so for now just put the data in the controller... -- 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 _______________________________________________ Tutor maillist? -? Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor ------------------------------------------------------------------------ *From:*?Tutor on behalf of Peter Otten <__peter__ at web.de> *Sent:*?18 April 2020 16:52 *To:*?tutor at python.org *Subject:*?Re: [Tutor] Dynamic variables changed via Tkinter button ? Jon Davies wrote: > Hi Alan, >? > As always, thanks for your insight - that gives me exactly the sort of > base I was hoping to build on. I had researched on the web on whether it > was possible, but given your note that typically this wouldn't considered > as standard GUI behavior, explains why I maybe didn't find much (or > perhaps I didn't look hard enough!). >? > I've now adapted the below and implemented something similar as part of my > wider Petrol Pump program code and I've managed to get it functioning. >? > However, now I am looking to enhance this further (using the selected > currency as input to a calculation, which you are already aware of). >? > Given I need two labels (one for Fuel Price, one for Litres), I've > implemented two counts (fuelcount and pricecount) and separated these > within the "update" function. For the pricecount, I am looking to enable > an increase based on "fuelcount * (currency * petrol_price)".? See below > for what I've tried to implement. >? >???? def update(self): >???????? self.fuelcount += 0.1 >???????? self.pricecount += 0.1 * (self.currency * PETROL_PRICE) >???????? self.litre_lbl['text'] = "Litres = %f" % self.fuelcount >???????? self.price_lbl['text'] = "Price = %f" % self.pricecount Don't use two independent counters; count the litres of fuel only, and? calculate the price from that: ??????? price = self.fuelcount * self.currency * PETROL_PRICE ????????? self.price_lbl["text"] = "Price = %f" % price (I'm not sure, but self.currency might actually have to be? self.controller.currency) >???????? self.update_idletasks() >???????? if self.state == 'working': >???????????? self.lever_btn.after(100, self.update) >? > I tried to configure the calculation to use the fuelcount value directly > i.e. (0.1), but I found that this started to increase the pricecount > exponentially, so for now I have just aligned the values at 0.1. The code > doesn't seem to recognise self.currency (starting that AttributeError: > 'BeginFuellingPage' object has no attribute 'currency'). If I replaced > self.currency with a number, then it works. >? > I am trying to reference the currency variable that was set earlier on in > the GUI via the SelectCurrencyPage. class SelectCurrencyPage(tk.Frame): >???? def __init__(self, parent, controller): >???????? tk.Frame.__init__(self, parent) >???????? self.controller = controller >? >???????? self.currency_lbl = tk.Label(self, text = _("PLEASE SELECT >???????? CURRENCY"), font = LARGE_FONT) self.currency_lbl.pack(pady = 10, >???????? padx = 10) >? >???????? self.GBP_btn = tk.Button(self, text = "? GBP", >???????????????????????????? command = lambda c = "?": self.setGBP(c)) >???????? self.GBP_btn.pack() >? >???????? self.USD_btn = tk.Button(self, text = "$ USD", >???????????????????????????? command = lambda c = "$": self.setUSD(c)) >???????? self.USD_btn.pack() >? >???????? self.EUR_btn = tk.Button(self, text = "? EUR", >???????????????????????????? command = lambda c = "?": self.setEUR(c)) >???????? self.EUR_btn.pack() >? >???????? self.restart_btn = tk.Button(self, text = _("RESTART"), >???????????????????????????? command = lambda: >???????????????????????????? self.controller.setState('restart')) >???????? self.restart_btn.pack() There's a lot of redundancy here. You can simplify that with a helper? method: def makeCurrencyButton(self, code, symbol, conversion): ??? button = tk.Button( ??????? self,? ??????? text=f"{symbol} {code}",? ??????? command=lambda: self.setCurrency(conversion) ??? ) ??? button.pack() ??? return button >? >???? def setGBP(self, currency): >???????? self.controller.setCurrency(GBP) >???????? self.controller.setState('fuel') >? >???? def setUSD(self, currency): >???????? self.controller.setCurrency(USD) >???????? self.controller.setState('fuel') >? >???? def setEUR(self, currency): >???????? self.controller.setCurrency(EUR) >???????? self.controller.setState('fuel') Replace these with def setCurrency(self, conversion): ??? self.controller.setCurrency(conversion) ??? self.controller.setState("fuel")???????? Now >???????? self.GBP_btn = tk.Button(self, text = "? GBP", >???????????????????????????? command = lambda c = "?": self.setGBP(c)) >???????? self.GBP_btn.pack() >? >???????? self.USD_btn = tk.Button(self, text = "$ USD", >???????????????????????????? command = lambda c = "$": self.setUSD(c)) >???????? self.USD_btn.pack() >? >???????? self.EUR_btn = tk.Button(self, text = "? EUR", >???????????????????????????? command = lambda c = "?": self.setEUR(c)) >???????? self.EUR_btn.pack() becomes ??? self.GBP_btn = self.makeCurrencyButton("GBP", "?", GBP) ??? self.USD_btn = self.makeCurrencyButton("USD", "$", USD) ??? self.EUR_btn = self.makeCurrencyButton("EUR", "?", EUR) If you go one step further and use a list to store the (code, symbol,? conversion-rate) triples CURRENCIES = [("EUR", "?", 1.14), ...] and the buttons ??? self.currency_buttons = [ ??????? self.makeCurrencyButton(*currency) ??????? for currency in CURRENCIES ??? ] it will become very easy to add or remove currencies. Regarding your actual question, I guess that you are making a mess by using? the currency attribute for two different purposes -- but my idea of your? program is not concrete enough to tell you how to fix that, or if that even? is the correct diagnosis. You have to wait for Alan or someone else to chime? in -- or provide the complete runnable source code somewhere. _______________________________________________ Tutor maillist? -? Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From alan.gauld at yahoo.co.uk Sun Apr 19 10:21:40 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 19 Apr 2020 15:21:40 +0100 Subject: [Tutor] Fwd: Re: Dynamic variables changed via Tkinter button In-Reply-To: <9ac4284b-dcab-09cb-7d87-6e3f6b71f709@yahoo.co.uk> References: <9ac4284b-dcab-09cb-7d87-6e3f6b71f709@yahoo.co.uk> Message-ID: On 19/04/2020 15:11, Alan Gauld via Tutor wrote: > I suppose my only question now, to seal the deal, is how can I display > the selected currency symbol as part of the price label in the Fuelling > page? While I can verify that the currency selection/conversion is > working through looking at the actual numbers that are presented, > showing the actual currency symbol would make it a lot more evident. > > I'd assumed it would be something like the below (having taken > inspiration from the def MakeCurrencyButton above) > > > ????????self.price_lbl?=?tk.Label(self,?text?=?_(f"{symbol}" +?"Price?=?0")) > ????????self.price_lbl.pack(pady?=?10,?padx?=?10) > > ????def?update(self,?symbol):??????????????????????????????????????????? > ????????self.fuelcount?+=?0.1 > ????????total_price?=?self.fuelcount?*?self.controller.currency?*?PETROL_PRICE > ????????self.litre_lbl['text']?=?_("Litres?=?%f")?%?self.fuelcount > ????????self.price_lbl['text']?=?_(f"{symbol}"?+?"Price?=?%f")?%?total_price Yes, it is just a matter of using string formatting. (You don't need to worry about internationalization/gettext issues because the currency symbol is the same regardless of language). So you don't need the _() around the symbol - and indeed the symbol would require you to duplicate the translation for each currency symbol! However, in the line above you use two different formatting mechanisms in the same string. While that is allowed and works it is better for consistency to use a single style. Since you seem to have Pyhthon 3.8 format strings is probably the best option: self.price_lbl['text'] = f"{symbol}" + _("Price = ") + f"{total_price}") Note: Only the literal string "Price = " needs to have the _() gettext marker. -- 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 __peter__ at web.de Sun Apr 19 10:55:21 2020 From: __peter__ at web.de (Peter Otten) Date: Sun, 19 Apr 2020 16:55:21 +0200 Subject: [Tutor] Fwd: Re: Dynamic variables changed via Tkinter button References: <9ac4284b-dcab-09cb-7d87-6e3f6b71f709@yahoo.co.uk> Message-ID: Alan Gauld via Tutor wrote: [Jon Davies] > Thanks for your both of your responses. Having reviewed your responses, > I have now made the respective changes and I have a working solution! Congrats! One final remark: true internationalisation has many traps waiting for the unsuspecting programmer. There is a Python project that tries to wrap the differences nicely: >>> babel.numbers.format_currency(1234.56, 'USD', locale='en_US') '$1,234.56' >>> babel.numbers.format_currency(1234.56, 'USD', locale='de_DE') '1.234,56\xa0$' Comma and dot swapped places with the country, and the currency symbel went from start to end of the string. "\xa0" is a NO-BREAK SPACE: >>> print(_) 1.234,56 $ You might at least take a look at http://babel.pocoo.org/en/latest/index.html From jon_davies17 at hotmail.co.uk Sun Apr 19 11:00:10 2020 From: jon_davies17 at hotmail.co.uk (Jon Davies) Date: Sun, 19 Apr 2020 15:00:10 +0000 Subject: [Tutor] Fwd: Re: Dynamic variables changed via Tkinter button In-Reply-To: References: <9ac4284b-dcab-09cb-7d87-6e3f6b71f709@yahoo.co.uk>, Message-ID: Hi Alan, Have tried amending to the below: def update(self): self.fuelcount += 0.1 total_price = self.fuelcount * self.controller.currency * PETROL_PRICE self.litre_lbl['text'] = _("Litres = %f") % self.fuelcount self.price_lbl['text'] = f"{symbol}" + _("Price = %f") + f"{total_price}" self.update_idletasks() if self.state == 'working': self.lever_btn.after(100, self.update) But providing me this error: NameError: name 'symbol' is not defined self.price_lbl['text'] = f"{self.symbol}" + _("Price = %f") + f"{total_price}" If I try including self.symbol I get: AttributeError: 'BeginFuellingPage' object has no attribute 'symbol' self.price_lbl['text'] = f"{self.controller.symbol}" + _("Price = %f") + f"{total_price}" If I try including self.controller.symbol, I get: AttributeError: '_tkinter.tkapp' object has no attribute 'symbol' Do I need to define it in the BeginFuellingPage, as the only other place symbol is referenced is in SelectCurrencyPage? class SelectCurrencyPage(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller self.currency_lbl = tk.Label(self, text = _("PLEASE SELECT CURRENCY"), font = LARGE_FONT) self.currency_lbl.pack(pady = 10, padx = 10) self.currency_buttons = [ self.makeCurrencyButton(*currency) for currency in CURRENCIES ] self.restart_btn = tk.Button(self, text = _("RESTART"), command = lambda: self.controller.setState('restart')) self.restart_btn.pack() def makeCurrencyButton(self, code, symbol, conversion): currency_button = tk.Button( self, text=f"{symbol} {code}", command=lambda: self.setCurrency(conversion) ) currency_button.pack() return currency_button def setCurrency(self, conversion): self.controller.setCurrency(conversion) self.controller.setState("fuel") class BeginFuellingPage(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller self.state='idle' self.fuelcount = 0 self.pricecount = 0 self.begin_fuel_lbl = tk.Label(self, text = _("BEGIN FUELLING"), font = LARGE_FONT) self.begin_fuel_lbl.pack(pady = 10, padx = 10) self.litre_lbl = tk.Label(self, text = _("Fuel = 0")) self.litre_lbl.pack(pady = 10, padx = 10) self.price_lbl = tk.Label(self, text = _("Price = 0")) self.price_lbl.pack(pady = 10, padx = 10) self.lever_btn = tk.Button(self, text = _("FUEL LEVER"), command = self.fuel_lever) self.lever_btn.pack() self.lever_btn.bind('', self.press) self.lever_btn.bind("", self.stop) self.finish_btn = tk.Button(self, text = _("FINISH"), command = self.doFinish) self.finish_btn.pack() self.restart_btn = tk.Button(self, text = _("RESTART"), command = lambda: self.controller.setState('restart')) self.restart_btn.pack() def fuel_lever(self): self.begin_fuel_lbl.config(text = _("FUELLING IN PROGRESS")) self.restart_btn.destroy() def press(self,evt): self.state='working' self.lever_btn.after(100,self.update) def update(self): self.fuelcount += 0.1 total_price = self.fuelcount * self.controller.currency * PETROL_PRICE self.litre_lbl['text'] = _("Litres = %f") % self.fuelcount self.price_lbl['text'] = f"{symbol}" + _("Price = %f") + f"{total_price}" self.update_idletasks() if self.state == 'working': self.lever_btn.after(100, self.update) def stop(self,evt): self.state = 'idle' def doFinish(self): self.begin_fuel_lbl.config(text = _("FUELLING COMPLETE")) self.lever_btn.config(state = 'active') self.finish_btn.config(state = 'disabled') self.controller.setState('finish') Kind regards, Jon ________________________________ From: Tutor on behalf of Alan Gauld via Tutor Sent: 19 April 2020 15:21 To: tutor at python.org Subject: Re: [Tutor] Fwd: Re: Dynamic variables changed via Tkinter button On 19/04/2020 15:11, Alan Gauld via Tutor wrote: > I suppose my only question now, to seal the deal, is how can I display > the selected currency symbol as part of the price label in the Fuelling > page? While I can verify that the currency selection/conversion is > working through looking at the actual numbers that are presented, > showing the actual currency symbol would make it a lot more evident. > > I'd assumed it would be something like the below (having taken > inspiration from the def MakeCurrencyButton above) > > > self.price_lbl = tk.Label(self, text = _(f"{symbol}" + "Price = 0")) > self.price_lbl.pack(pady = 10, padx = 10) > > def update(self, symbol): > self.fuelcount += 0.1 > total_price = self.fuelcount * self.controller.currency * PETROL_PRICE > self.litre_lbl['text'] = _("Litres = %f") % self.fuelcount > self.price_lbl['text'] = _(f"{symbol}" + "Price = %f") % total_price Yes, it is just a matter of using string formatting. (You don't need to worry about internationalization/gettext issues because the currency symbol is the same regardless of language). So you don't need the _() around the symbol - and indeed the symbol would require you to duplicate the translation for each currency symbol! However, in the line above you use two different formatting mechanisms in the same string. While that is allowed and works it is better for consistency to use a single style. Since you seem to have Pyhthon 3.8 format strings is probably the best option: self.price_lbl['text'] = f"{symbol}" + _("Price = ") + f"{total_price}") Note: Only the literal string "Price = " needs to have the _() gettext marker. -- 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 _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From alan.gauld at yahoo.co.uk Sun Apr 19 12:01:21 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 19 Apr 2020 17:01:21 +0100 Subject: [Tutor] Fwd: Re: Dynamic variables changed via Tkinter button In-Reply-To: References: <9ac4284b-dcab-09cb-7d87-6e3f6b71f709@yahoo.co.uk> Message-ID: On 19/04/2020 16:00, Jon Davies wrote: > Hi Alan, > > Have tried amending to the below: > def update(self): > self.fuelcount += 0.1 > total_price = self.fuelcount * self.controller.currency * PETROL_PRICE > self.litre_lbl['text'] = _("Litres = %f") % self.fuelcount > self.price_lbl['text'] = f"{symbol}" + _("Price = %f") + f"{total_price}" > self.update_idletasks() > if self.state == 'working': > self.lever_btn.after(100, self.update) > But providing me this error: > NameError: name 'symbol' is not defined Sorry, the symbol needs to be whatever the currency symbol is. (Presu,ably fetched from the controller. Maybe create a controller method that returns both symbol and exchange rate as a tuple? getCurrencyDetails() perhaps? Also you don't want the %f inside the _(). - see below... In fact you don't need %f at all, the new format string uses the simpler substitution mechanism so the f"{total_price}" is equivalent to "%f" % total_price using the older printf(%) formatting Regarding the use of _() in gettext. This is not magic - although it can seem like it! When you call the GNU translation init mechanism it builds a translation dictionary that has your literal strings as keys and the translation strings from your translation file as values. It then defines the _() function as just a function like any other. Python calls it with a string argument. Inside _() it looks like this, in pseudo code: def _(theString): return translationTable[thestring] Now that requires that the string you pass in to _() matches exactly the string in the table, which in turn has been previously extracted from your code by gettext. So, if you have a string like: _("%s Price = ") getext will extract that string - including the %s part - and expect a literal translation. So in your translation file you would need to put in something like "? Price =" for uk English and "$ Price =" for US English etc... Which limits you to having one currency per language file which is not good. It all gets very messy. That's why it's better not to have the currency symbol inside the translated string. Something like symbol + _(" Price = ") + f"{value}" -- 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 ericatszying at yahoo.com.hk Sun Apr 19 12:16:55 2020 From: ericatszying at yahoo.com.hk (tsz ying tsang) Date: Sun, 19 Apr 2020 16:16:55 +0000 (UTC) Subject: [Tutor] K-means and Python Beginner - The clusters shown in the graph seems wrong References: <1368923784.1924723.1587313015680.ref@mail.yahoo.com> Message-ID: <1368923784.1924723.1587313015680@mail.yahoo.com> Dear Tutor, I have recently signed up an online class on coursera - Data Science - K-mean Clustering, and i had submitted an assignment about using k-means to build a model distinguishing the genuine and fake banknotes by the "banknote authentication dataset" on OpenML (our assignment used a simplified one as attached) I have written some code on Python and plt graph (k=2). But the clusters I get is quite different from most of my online classmates. May I know what i did wrong in my code that can't generate the same cluster.? How to re-run the k-means to make sure the cluster is stable? Thanks so much for help first The below is my classmate's one. From PyTutor at DancesWithMice.info Sun Apr 19 19:12:42 2020 From: PyTutor at DancesWithMice.info (DL Neil) Date: Mon, 20 Apr 2020 11:12:42 +1200 Subject: [Tutor] K-means and Python Beginner - The clusters shown in the graph seems wrong In-Reply-To: <1368923784.1924723.1587313015680@mail.yahoo.com> References: <1368923784.1924723.1587313015680.ref@mail.yahoo.com> <1368923784.1924723.1587313015680@mail.yahoo.com> Message-ID: On 20/04/20 4:16 AM, tsz ying tsang via Tutor wrote: > Dear Tutor, > I have recently signed up an online class on coursera - Data Science - K-mean Clustering, and i had submitted an assignment about using k-means to build a model distinguishing the genuine and fake banknotes by the "banknote authentication dataset" on OpenML (our assignment used a simplified one as attached) > I have written some code on Python and plt graph (k=2). But the clusters I get is quite different from most of my online classmates. May I know what i did wrong in my code that can't generate the same cluster. > How to re-run the k-means to make sure the cluster is stable? > Thanks so much for help first > The below is my classmate's one. Regret to advise that this Discussion List does not accept attachments unless they are simple-text. That sounds like an interesting course. Why don't you post this question on the Discussion List for the applicable week of your course - that's one of the reasons it is there! You are likely to find a class-colleague or a Teaching Assistant who is familiar with the actual problem-set, who will help you... That said, there are a few people 'here' who may be able to help, once we can 'see' the problem... May I further suggest, that in addition to any code and data you may care to send, that you first explain your approach (in English rather than Python). Yes, the difference may be explained by a coding error, but it is usually the clustering criteria which account for such differences! -- Regards =dn From afreer2 at netzero.net Mon Apr 20 14:28:35 2020 From: afreer2 at netzero.net (afreer2 at netzero.net) Date: Mon, 20 Apr 2020 18:28:35 GMT Subject: [Tutor] Using wheel/.whl in juypter Message-ID: <20200420.112835.26595.0@webmail09.dca.untd.com> pasted from juypter notebookpip install wheel Requirement already satisfied: wheel in c:\users\grandpa\anaconda3\lib\site-packages (0.34.2) Note: you may need to restart the kernel to use updated packages. I did restart kernel and got same message This file is in my downloads camelot_py-0.7.3-py3-none-any.whl I am so new to phython I never know if I ask the right question If the syntax correct how do I get the file in the download to juypter? Will juypter tell me? From thuhineshreddy2002 at gmail.com Tue Apr 21 12:30:31 2020 From: thuhineshreddy2002 at gmail.com (thuhinesh reddy) Date: Tue, 21 Apr 2020 22:00:31 +0530 Subject: [Tutor] I need the full code for as soon as possible, within few hours... Message-ID: <9B35E8D8-143F-47A5-B981-A8D1F81E4146@gmail.com> Infographic In this PA, you will be writing a program that reads in a text file (perhaps containing the contents of a book, poem, article, etc) and produces an infographic based on the text. You will need to use one or more dictionaries to count words in the program. You may also use lists and / or sets. Below, you can see three example infographics that your program should be able to generate: The infographic should contain the following information about the text: The name of the text file The total number of unique words. The most used small, medium, and large words in the file. Both the word and the count should be included, as shown in the image. For the purposes of this PA, the definitions of a small, medium, and large word is: small: length 0-4, inclusive. medium: length 5-7, inclusive. large: length 8+, inclusive. A Bar-chart representing the proportion of unique small, medium, and large words. A Bar-chart representing the proportion of capitalized and non-capitalized words. A capitalized word is any word that begins with an upper-case letter. All other words can be considered non-capitalized, even if they begin with a non-letter character like a digit or punctuation. Extra-Credit: A Bar-chart representing the proportion of punctuated and non-punctuated words. A Punctuated word is any word that ends in a period, comma, question-mark, or exclamation-point. All other words should be considered non-punctuated. You can take creative liberty with the colors, but the text and graphics displayed should be in roughly the same positions as what is show on this spec. The canvas size should be proportional to mine (650 pixels wide, 700 pixels tall), but it does not have to be exactly this. Name the file infographic.py. You should also re-download graphics.py , and use that for the graphical component. Development Strategy (1) Reading and processing the file The first step should be to ask the user for the input file that they would like to have an infographic created for. Once the file has been selected, you can read in all of the lines and strip the newlines off of the ends. To get the words, all you have to do is split each line on whitespace. To accomplish this, just call split() on each line string, with no argument. You can then append each individual word to a python list. You do not need to strip off punctuation from the words or normalize the cases. For example, if you input file had the following content: two forks. one knife. two glasses. one plate. one naptkin. his glasses. his knife. The words list should have the following content after processing the file: words = ['two', 'forks.', 'one', 'knife.', 'two', 'glasses.', \ 'one', 'plate.', 'one', 'naptkin.', 'his,' 'glasses.', 'his', 'knife.'] (2) Counting words Once you have a list of all of the words from the file, you can count the occurrences. You should use a dictionary for this. Continuing from the example of the last step, the dictionary should have the following contents: word_counts = {'two':2, 'one':3, 'forks.':1, 'knife.':2, \ 'glasses.':2, 'plate.':1, 'naptkin.':1, 'his':2} (3) Finding most occurrences Next, you can find the small, medium, and large words that occur the most. In the example, it would be one for small, knife.for medium, and glasses. for large. You can do this by iterating through the key and value pairs in the word_countsdictionary, and keeping track of which has the highest count. Then, display these on the canvas. (4) Counting Capitalized Next, compute how many unique capitalized and non-capitalized. You can do this by getting the keys of the word_countsdictionary as a list, and then looping through them all. (5) Counting Punctuated (Extra Credit) Compute how many unique punctuated and non-punctuated words there are. Use a similar process as you did for step (4). (6) Building the bar charts You should display two (or three, if doing the extra credit) bar charts on the infographic. This section will walk though how to build it the Small, Medium, and Large word Bar Chart (SMLBC). You can apply similar steps to the other two. Let?s say you were trying to build the SMLBC for an input file with 10 unique short words, 3 unique medium words, and 5 unique large words. In total, this is 18 unique words. The small box should consume 10/18 of the whole bar, the medium bar should consume 3/18 of the whole bar, the large word bar should consume 5/18 of the whole bar. To calculate the height in pixels of each bar, use the formula: (pixel_height / total_item_count) * category_item_count For example, if the total height of the bar chart should be 450 pixels, then to get the height in pixels of the small word bar: (450 / 18) * 10. Take a look at the image below for reference Use this information to draw the other one or two bar charts. Resource Files Below are some resource files you might find interesting to run your program with. poem.txt Bible.txt Cat_in_the_Hat.txt If you?d like to try the program on other books, you can visit www.gutenberg.org . Most of the test cases on Gradescope will not be super large. They will be 1000 lines of text at most. Examples Below are several examples, with the input files included. If you are not completing the extra credit, you only need to include the first two bar charts. words.txt Cat_in_the_Hat.txt Poetics.txt values.txt Submission Submit this program to Gradescope by Tuesday, 4/21 by 7:00pm. From joel.goldstick at gmail.com Tue Apr 21 13:49:10 2020 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Tue, 21 Apr 2020 13:49:10 -0400 Subject: [Tutor] I need the full code for as soon as possible, within few hours... In-Reply-To: <9B35E8D8-143F-47A5-B981-A8D1F81E4146@gmail.com> References: <9B35E8D8-143F-47A5-B981-A8D1F81E4146@gmail.com> Message-ID: On Tue, Apr 21, 2020 at 1:32 PM thuhinesh reddy wrote: > > Infographic > > In this PA, you will be writing a program that reads in a text file (perhaps containing the contents of a book, poem, article, etc) and produces an infographic based on the text. You will need to use one or more dictionaries to count words in the program. You may also use lists and / or sets. Below, you can see three example infographics that your program should be able to generate: > > The infographic should contain the following information about the text: > > The name of the text file > The total number of unique words. > The most used small, medium, and large words in the file. Both the word and the count should be included, as shown in the image. For the purposes of this PA, the definitions of a small, medium, and large word is: > small: length 0-4, inclusive. > medium: length 5-7, inclusive. > large: length 8+, inclusive. > A Bar-chart representing the proportion of unique small, medium, and large words. > A Bar-chart representing the proportion of capitalized and non-capitalized words. A capitalized word is any word that begins with an upper-case letter. All other words can be considered non-capitalized, even if they begin with a non-letter character like a digit or punctuation. > Extra-Credit: A Bar-chart representing the proportion of punctuated and non-punctuated words. A Punctuated word is any word that ends in a period, comma, question-mark, or exclamation-point. All other words should be considered non-punctuated. > You can take creative liberty with the colors, but the text and graphics displayed should be in roughly the same positions as what is show on this spec. The canvas size should be proportional to mine (650 pixels wide, 700 pixels tall), but it does not have to be exactly this. Name the file infographic.py. You should also re-download graphics.py , and use that for the graphical component. > > Development Strategy > (1) Reading and processing the file > The first step should be to ask the user for the input file that they would like to have an infographic created for. Once the file has been selected, you can read in all of the lines and strip the newlines off of the ends. To get the words, all you have to do is split each line on whitespace. To accomplish this, just call split() on each line string, with no argument. You can then append each individual word to a python list. You do not need to strip off punctuation from the words or normalize the cases. > > For example, if you input file had the following content: > > two forks. > one knife. > two glasses. > one plate. > one naptkin. > his glasses. > his knife. > The words list should have the following content after processing the file: > > words = ['two', 'forks.', 'one', 'knife.', 'two', 'glasses.', \ > 'one', 'plate.', 'one', 'naptkin.', 'his,' 'glasses.', 'his', 'knife.'] > (2) Counting words > Once you have a list of all of the words from the file, you can count the occurrences. You should use a dictionary for this. Continuing from the example of the last step, the dictionary should have the following contents: > > word_counts = {'two':2, 'one':3, 'forks.':1, 'knife.':2, \ > 'glasses.':2, 'plate.':1, 'naptkin.':1, 'his':2} > (3) Finding most occurrences > Next, you can find the small, medium, and large words that occur the most. In the example, it would be one for small, knife.for medium, and glasses. for large. You can do this by iterating through the key and value pairs in the word_countsdictionary, and keeping track of which has the highest count. Then, display these on the canvas. > > (4) Counting Capitalized > Next, compute how many unique capitalized and non-capitalized. You can do this by getting the keys of the word_countsdictionary as a list, and then looping through them all. > > (5) Counting Punctuated (Extra Credit) > Compute how many unique punctuated and non-punctuated words there are. Use a similar process as you did for step (4). > > (6) Building the bar charts > You should display two (or three, if doing the extra credit) bar charts on the infographic. This section will walk though how to build it the Small, Medium, and Large word Bar Chart (SMLBC). You can apply similar steps to the other two. > > Let?s say you were trying to build the SMLBC for an input file with 10 unique short words, 3 unique medium words, and 5 unique large words. In total, this is 18 unique words. The small box should consume 10/18 of the whole bar, the medium bar should consume 3/18 of the whole bar, the large word bar should consume 5/18 of the whole bar. To calculate the height in pixels of each bar, use the formula: > > (pixel_height / total_item_count) * category_item_count > For example, if the total height of the bar chart should be 450 pixels, then to get the height in pixels of the small word bar: (450 / 18) * 10. Take a look at the image below for reference > > > Use this information to draw the other one or two bar charts. > > Resource Files > Below are some resource files you might find interesting to run your program with. > > poem.txt > Bible.txt > Cat_in_the_Hat.txt > If you?d like to try the program on other books, you can visit www.gutenberg.org . > > Most of the test cases on Gradescope will not be super large. They will be 1000 lines of text at most. > > Examples > Below are several examples, with the input files included. If you are not completing the extra credit, you only need to include the first two bar charts. > > words.txt > Cat_in_the_Hat.txt > Poetics.txt > values.txt > Submission > Submit this program to Gradescope by Tuesday, 4/21 by 7:00pm. > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor This list is not a homework writing service. If you need to do this assignment completely within the time you state in your subject line, i suspect you haven't been diligent in your studies. However, if you provide a copy of your code to date, what problems you are having you will often get helpful pointers to move you toward your goal. This list is great for people who try to solve their python problems, but get stuck and don't know what to do next. So, come back with more information about how you have proceeded so far. -- Joel Goldstick http://joelgoldstick.com/blog http://cc-baseballstats.info/stats/birthdays From alan.gauld at yahoo.co.uk Tue Apr 21 14:02:21 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 21 Apr 2020 19:02:21 +0100 Subject: [Tutor] I need the full code for as soon as possible, within few hours... In-Reply-To: <9B35E8D8-143F-47A5-B981-A8D1F81E4146@gmail.com> References: <9B35E8D8-143F-47A5-B981-A8D1F81E4146@gmail.com> Message-ID: On 21/04/2020 17:30, thuhinesh reddy wrote: > Infographic > > In this PA, you will be writing a program that ... > Development Strategy > (1) Reading and processing the file > The first step should be... > (2) Counting words > (3) Finding most occurrences > (4) Counting Capitalized > (5) Counting Punctuated (Extra Credit) > (6) Building the bar charts > ...To calculate the height in pixels of each bar, use the formula: > For example,... > Resource Files > Below are some resource files you might find interesting to run your program with. > Examples > Below are several examples, with the input files included. > Submission > Submit this program to Gradescope by Tuesday, 4/21 by 7:00pm. Looks like you got more than enough information to complete the assignment. What would you like us to do? It seems like you just need to start writing code... If you get stuck we can help find the problem. -- 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 savageapple850 at gmail.com Wed Apr 22 07:50:14 2020 From: savageapple850 at gmail.com (Cravan) Date: Wed, 22 Apr 2020 19:50:14 +0800 Subject: [Tutor] Reinforcement learning in pygame Message-ID: Hi does anyone know how to implement reinforcement learning in pygame? I can?t find a suitable tutorial online (have been thinking of using gym but have no idea how to use it in my own environment). Have only learnt python and some sql and am working on a maze game with monsters. Cravan From upwkwd at gmail.com Wed Apr 22 10:44:35 2020 From: upwkwd at gmail.com (shubham sinha) Date: Wed, 22 Apr 2020 20:14:35 +0530 Subject: [Tutor] modification to a list Message-ID: Hi, Q. The skip_elements function returns a list containing every other element from an input list, starting with the first element. Complete this function to do that, using the for loop to iterate through the input list. my code: def skip_elements(elements): new_list = [ ] i = 0 for element in elements: if "element" != "elements(i): new_list.append(element) i += 2 return new_list print(skip_elements(["a", "b", "c", "d", "e", "f", "g"])) # Should be ['a', 'c', 'e', 'g'] print(skip_elements(['Orange', 'Pineapple', 'Strawberry', 'Kiwi', 'Peach'])) # Should be ['Orange', 'Strawberry', 'Peach'] print(skip_elements([ ])) # Should be [ ] my output: ['a', 'b', 'c', 'd', 'e', 'f', 'g'] ['Orange', 'Pineapple', 'Strawberry', 'Kiwi', 'Peach'] [] output should be: ['a', 'c', 'e', 'g'] ['Orange', 'Strawberry', 'Peach'] [] From alan.gauld at yahoo.co.uk Wed Apr 22 11:15:12 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 22 Apr 2020 16:15:12 +0100 Subject: [Tutor] modification to a list In-Reply-To: References: Message-ID: On 22/04/2020 15:44, shubham sinha wrote: Oh dear. This has so much wrong that I'm not sure where to start. > def skip_elements(elements): > new_list = [ ] > i = 0 > for element in elements: > if "element" != "elements(i): Lets ignore the mismatched sting quote for now since the code wouldn't run with it there, so it must be a typo for the email... The line asks if the literal string "element" is different to the return value of a function called elements which you call with the value i. But there is no function elements. So this should give an error too. Lets assume you meant to use square brackets to access the list... Then you compare the string "elements" to each value of the list elements. Since "element" does not appear anywhere in your input data the test will always be false so you will append the element to your new list. That's why you always get all of the elements. > new_list.append(element) I assume what you were trying to write was: for elemet in elements: if element != element[i]: new_list.append(element) > i += 2 Now things get more complicated because you increment the index by 2 but your loop is looking at every item in the list. So your comparison is now with every second item. Lets draw up a table to see what the various values are for "abcdefg": element i element[i] a 0 a b 2 c c 4 e d 6 g e 8 BANG! Should give an error. Only 6 items The result should be only the first item will be ignored all others get added to the list until the index gets too big. Not at all what you want. There are in fact multiple easier ways to do this. It depends on how much you have covered in your course. If you have looked at slicing you can do it in a single line. If not you could try something like: def skip_elements(elements): new_list = [] is_needed = True for element in elements: if is_needed: new_list.append(element) is_needed = not is_needed return new_list Which is a code translation of the requirements. If you really want to fuss with indexes you could do def skip_elements(elements): new_list = [] for i in range(len(elements)): if i % 2 == 0: new_list.append(elements[i]) return new_list But that's pretty horrible Python, even if it is shorter. -- 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 breamoreboy at gmail.com Wed Apr 22 11:11:26 2020 From: breamoreboy at gmail.com (Mark Lawrence) Date: Wed, 22 Apr 2020 16:11:26 +0100 Subject: [Tutor] modification to a list In-Reply-To: References: Message-ID: On 22/04/2020 15:44, shubham sinha wrote: > Hi, > Q. The skip_elements function returns a list containing every other element > from an input list, starting with the first element. Complete this function > to do that, using the for loop to iterate through the input list. > my code: > def skip_elements(elements): > new_list = [ ] > i = 0 > for element in elements: > if "element" != "elements(i): > new_list.append(element) > > i += 2 > return new_list You don't need any of the above code, you can do the entire operation in one hit with the use of slicing as given here https://docs.python.org/3/library/stdtypes.html#common-sequence-operations which I'll leave up to you as an exercise :) > > print(skip_elements(["a", "b", "c", "d", "e", "f", "g"])) # Should be ['a', > 'c', 'e', 'g'] > print(skip_elements(['Orange', 'Pineapple', 'Strawberry', 'Kiwi', > 'Peach'])) # Should be ['Orange', 'Strawberry', 'Peach'] > print(skip_elements([ ])) # Should be [ ] > > my output: > > ['a', 'b', 'c', 'd', 'e', 'f', 'g'] > ['Orange', 'Pineapple', 'Strawberry', 'Kiwi', 'Peach'] > [] > > > output should be: > > ['a', 'c', 'e', 'g'] > > ['Orange', 'Strawberry', 'Peach'] > > [] -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From subhashnunna at hotmail.com Wed Apr 22 11:59:46 2020 From: subhashnunna at hotmail.com (Subhash Nunna) Date: Wed, 22 Apr 2020 15:59:46 +0000 Subject: [Tutor] modification to a list In-Reply-To: References: Message-ID: Hi Shubham, Please try this: def skip_elements(elements): new_list = [ ] a = len(elements)+1 if a==1: return new_list else: for i in range(0, a): if i%2==0: new_list.append(elements[i]) return new_list print(skip_elements(["a", "b", "c", "d", "e", "f", "g"])) print(skip_elements(['Orange', 'Pineapple', 'Strawberry', 'Kiwi','Peach'])) print(skip_elements([ ])) [cid:image002.png at 01D618ED.234A0E60] Regards, Subhash Nunna. Sent from Mail for Windows 10 From: shubham sinha Sent: Wednesday, April 22, 2020 8:17 PM To: tutor at python.org Subject: [Tutor] modification to a list Hi, Q. The skip_elements function returns a list containing every other element from an input list, starting with the first element. Complete this function to do that, using the for loop to iterate through the input list. my code: def skip_elements(elements): new_list = [ ] i = 0 for element in elements: if "element" != "elements(i): new_list.append(element) i += 2 return new_list print(skip_elements(["a", "b", "c", "d", "e", "f", "g"])) # Should be ['a', 'c', 'e', 'g'] print(skip_elements(['Orange', 'Pineapple', 'Strawberry', 'Kiwi', 'Peach'])) # Should be ['Orange', 'Strawberry', 'Peach'] print(skip_elements([ ])) # Should be [ ] my output: ['a', 'b', 'c', 'd', 'e', 'f', 'g'] ['Orange', 'Pineapple', 'Strawberry', 'Kiwi', 'Peach'] [] output should be: ['a', 'c', 'e', 'g'] ['Orange', 'Strawberry', 'Peach'] [] _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From alan.gauld at yahoo.co.uk Wed Apr 22 14:12:17 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 22 Apr 2020 19:12:17 +0100 Subject: [Tutor] modification to a list In-Reply-To: References: Message-ID: On 22/04/2020 16:59, Subhash Nunna wrote: > Please try this: > > def skip_elements(elements): > new_list = [ ] > a = len(elements)+1 You don't want to add one. Just use len() > if a==1: > return new_list a==1 implies an empty list using your code above. > else: > for i in range(0, a): This will push index past the end of the list. If the list is [1,2,3] then len() returns 3 and a is set to 4 Now range(0,4) returns [0,1,2,3] But there is no index 3. > if i%2==0: > new_list.append(elements[i]) > return new_list It is because of the difficulty in getting indexes right that we prefer to use the foreach style of processing in Python: for item in elements And if you really need the index(rare) you can use enumerate: for index,item in enumerate(elements): These guarantee never to over-run your collection. -- 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 emin.kovac at gmail.com Thu Apr 23 15:06:51 2020 From: emin.kovac at gmail.com (Emin Kovac) Date: Thu, 23 Apr 2020 21:06:51 +0200 Subject: [Tutor] diferent between " "(empty string) and None as condition Message-ID: pasword = "" while not pasword: pasword = input ('Pasword: ') username = None while not username: username = input('Username: ') My question is when should I or what is better to use as condition empty string (" ") or None? Anyway, what is different between an empty string and None From alan.gauld at yahoo.co.uk Thu Apr 23 17:45:53 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 23 Apr 2020 22:45:53 +0100 Subject: [Tutor] diferent between " "(empty string) and None as condition In-Reply-To: References: Message-ID: On 23/04/2020 20:06, Emin Kovac wrote: > pasword = "" > while not pasword: > pasword = input ('Pasword: ') > > username = None > while not username: > username = input('Username: ') > My question is when should I or what is better to use as > condition empty string (" ") or None? In this particular context thee is no difference and which you use is largely a matter of taste. But... > Anyway, what is different between an empty string and None They are fundamentally different things. It's like asking what is the difference between 0 and None or even between 0 and '' They all evaluate to false in a boolean context but they mean different things and have different values. >>> '' is None False >>> None == '' False Sticking to strings you can use '' to test for a string that is empty and that's exactly what you get when you read an empty line in a file, for example. None is something else. It is a type in its own right - NoneType. It signifies a non-value. You normally only get a None return from a function (that normally returns a value) if you hit an error. Here is an example that might help. Consider a function: findSmallestSubString(str, start, end) which returns the smallest substring starting with start and ending with end within str. If there are no substrings meeting the criteria you get an empty string back. If there are no occurrences of start in str you get None back. (It would probably be better if it raised a Valueerror, but go with me here) So we call: result = findSmallestSubString("bandana", 'b','n') -> 'ban' result = findSmallestSubString("bandana", 'd','b') -> '' result = findSmallestSubString("bandana", 'c','n') -> None Now we can test the return value and determine what the implications are. If we simply returned '' in the last case we wouldn't know whether there were no substrings or whether we had passed invalid data. But both can be used in an if test with the same outcome. result = findSmallestSubString("bandana", 'b','n') -> 'ban' if result: # process the substring else if result is None: # oops it was bad data else: # handle empty string case Finally None can be used when we don't know what type to expect. For example if a function takes a collection as input but we don't know what kind of collection it is. We can use None as a type neutral marker rather than () when we want a list or [] when we want a tuple. By using none we can examine the data and determine the type required. I can't think of a simple example off hand, hopefully somebody else can... -- 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 PyTutor at danceswithmice.info Thu Apr 23 17:52:08 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Fri, 24 Apr 2020 09:52:08 +1200 Subject: [Tutor] diferent between " "(empty string) and None as condition In-Reply-To: References: Message-ID: <91e2736d-566d-622a-63ce-f326dec870f6@DancesWithMice.info> On 24/04/20 7:06 AM, Emin Kovac wrote: > pasword = "" > while not pasword: > pasword = input ('Pasword: ') > > username = None > while not username: > username = input('Username: ') > My question is when should I or what is better to use as > condition empty string (" ") or None? > Anyway, what is different between an empty string and None Here's an exercise to try: >>> value = input( "what? " ) what? # don't type anything, press the Enter key >>> value '' >>> type(value) # what is the response here? When the 'username' while-loop executes for the first time, what will be the value and type of username? When the 'Enter-key only' value is evaluated, what is its type and value? So, when the 'username' while-loop is executed for the second time, will it have the same type as before? Does that help make your own decision about which is better (in this situation)? NB I like to finish the "input-prompt" with a question-mark (assuming English-language users!) because it 'prompts' the user to understand that (s)he should enter a value... Complicating the issue is the question of which type-value combinations will auto-magically convert to Boolean-type - and whether as True or as False. This you may already understand and is thus part of your enquiry. If not, a recommended reading topic! Beware of either a typo or a misunderstanding (see above): <<<...empty string (" ")>>> what appears within the quotation marks is a "Space" character - we can't see it, but it is very definitely there! Thus, Space is considerably different to "" which 'contains' no characters at all and is known as the Nulstring or "empty string"! With my aging eyes, I rarely use either as "literal constants" inside my active-code, simply because it is so easy to quickly mis-read! Instead, 'at the top' I declare 'constants' (in Python this is a convention rather than a rule), eg NULSTRING = "" SPACE = " " thereafter, my code is easier-on-the-eyes, if long-winded/pedantic, eg pasword = NULSTRING or, if you prefer password = NULL_STRING PS further eye-distractive criticism because the single "L" harks back to even before ASCII code 000 (called "NUL"), but the English word/spelling is "null". My guess is you will want to stop there - people with a desire for technical-precision can really 'go to town' on these distinctions... My preference is to use None when at a stage where the value is completely unknown (or irrelevant), eg an optional parameter for a function. Whereas NULSTRING (or 0, or False, ...) indicates that we 'know' the value and that it has a definite meaning and purpose. -- Regards =dn From upwkwd at gmail.com Fri Apr 24 03:52:39 2020 From: upwkwd at gmail.com (shubham sinha) Date: Fri, 24 Apr 2020 13:22:39 +0530 Subject: [Tutor] getting unknown results Message-ID: Hi, my question: The format_address function separates out parts of the address string into new strings: house_number and street_name, and returns: "house number X on street named Y". The format of the input string is: numeric house number, followed by the street name which may contain numbers, but never by themselves, and could be several words long. For example, "123 Main Street", "1001 1st Ave", or "55 North Center Drive". my code: def format_address(address_string): # Declare variables number = [] place = [] # Separate the address string into parts split_string = address_string.split() # Traverse through the address parts for i in range(0, len(split_string)): # Determine if the address part is the # house number or part of the street name if split_string[i].isnumeric(): # Does anything else need to be done # before returning the result? number.append(split_string[i]) return place.append(split_string[i]) # Return the formatted string place = " ".join(place) return "house number {number} on street named {place}".format(number ,place = " ".join(place) ) print(format_address("123 Main Street")) # Should print: "house number 123 on street named Main Street" print(format_address("1001 1st Ave")) # Should print: "house number 1001 on street named 1st Ave" print(format_address("55 North Center Drive")) # Should print "house number 55 on street named North Center Drive" my output: None None None I am getting result "none" instead of expected result. Please help me through this. Thanks, Shubham K Sinha From PyTutor at danceswithmice.info Fri Apr 24 06:10:12 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Fri, 24 Apr 2020 22:10:12 +1200 Subject: [Tutor] getting unknown results In-Reply-To: References: Message-ID: On 24/04/20 7:52 PM, shubham sinha wrote: > The format_address function separates out parts of the address string into > new strings: house_number and street_name, and returns: "house number X on > street named Y". > The format of the input string is: numeric house number, followed by the > street name which may contain numbers, but never by themselves, and could > be several words long. > For example, "123 Main Street", "1001 1st Ave", or "55 North Center Drive". > > my code: > def format_address(address_string): > # Declare variables > number = [] > place = [] > # Separate the address string into parts > split_string = address_string.split() > # Traverse through the address parts > for i in range(0, len(split_string)): > # Determine if the address part is the > # house number or part of the street name > if split_string[i].isnumeric(): > # Does anything else need to be done > # before returning the result? > number.append(split_string[i]) > return place.append(split_string[i]) > # Return the formatted string > place = " ".join(place) > return "house number {number} on street named {place}".format(number > ,place = " ".join(place) ) > > print(format_address("123 Main Street")) > # Should print: "house number 123 on street named Main Street" > > print(format_address("1001 1st Ave")) > # Should print: "house number 1001 on street named 1st Ave" > > print(format_address("55 North Center Drive")) > # Should print "house number 55 on street named North Center Drive" > > > my output: > > None > None > None > > > I am getting result "none" instead of expected result. > > Please help me through this. Well done! You seem to have the necessary ingredients. The challenge is to look at the detail of Python... Firstly, a really good way to learn and experiment with Python features which are new-learning is the REPL. Fire-up Python from the command-line, and then you can type-in individual statements and have them resolve immediately. For example, to verify that code does what you expect, instead of: split_string = address_string.split() use some sample-data and type the following directly into 'Python': "123 Main Street".split() Is the result exactly as you expected? (hope-so, but if not, you've saved yourself some time and frustration!) So, that's a program-design technique. How about debugging at execution-time? May I suggest copy-pasting this code into a tool such as http://www.pythontutor.com/ which will illustrate how the computer executes code line-by-line? (as do some editor/IDE packages) Rightly, or wrongly, the impression gained from this code is that a couple of functions work differently from the way you seem to expect. One particular problem is that every time the code finds a numeric value within the input, the code-line: return place.append(split_string[i]) is returning None (as you noted). Why is the answer being appended to a list? Should there be two separate statements, if the list is to be returned (ie after being appended)? - both of the above techniques will illustrate such matters. You seem to have used other programming languages. Python has a much (much, much...) easier way of handling loops by completely dropping 'pointers'. Instead of: > split_string = address_string.split() > # Traverse through the address parts > for i in range(0, len(split_string)): > # Determine if the address part is the > # house number or part of the street name > if split_string[i].isnumeric(): try: for token in address_string.split(): if token.isnumeric(): ... What happens here is that the address is split into "tokens" and the for-loop enables consideration of each token in-turn. So much easier! For toy-problems like this and whilst you are learning, it's important to realise that we cannot 'see' what the computer is doing (apart from the illustrative-tool(s) mentioned earlier). Another common technique is to add 'debug print' statements to show what is happening, eg what exactly is the value called "token" 'this time' through the loop? From: for token in address_string.split(): if token.isnumeric(): try: for token in address_string.split(): print( token, token.isnumeric() ) # this is it! if token.isnumeric(): Thus the print() provides a 'window' into the computer, showing you at every cycle of the loop, the token (string) it is considering and whether/not that is a numeric value (boolean)! They are called "debug print" because they are only for fault-finding and you will take them out before handing-in the assignment (or putting code into 'production')! NB there are other ways of doing this, but debug-print is the easiest for beginners to learn/add to practical exercises. Enough? Why don't you try that much, and see how things improve - then revert if other questions arise... -- Regards =dn From alan.gauld at yahoo.co.uk Fri Apr 24 07:48:40 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 24 Apr 2020 12:48:40 +0100 Subject: [Tutor] getting unknown results In-Reply-To: References: Message-ID: On 24/04/2020 08:52, shubham sinha wrote: > my code: > def format_address(address_string): > # Declare variables > number = [] > place = [] > # Separate the address string into parts > split_string = address_string.split() > # Traverse through the address parts > for i in range(0, len(split_string)): > # Determine if the address part is the > # house number or part of the street name > if split_string[i].isnumeric(): > # Does anything else need to be done > # before returning the result? > number.append(split_string[i]) > return place.append(split_string[i]) > # Return the formatted string > place = " ".join(place) > return "house number {number} on street named {place}".format(number > ,place = " ".join(place) ) This code should give you an error so presumably it is not the code you ran. That makes it difficult to give sensible critique. In particular the string formatting at the end is all wrong. I suspect you wanted something like: return "house number {} on street named {}".format(number,place) You had already done the join() on the previous line... That won't give you exactly what you want but it at least prints without errors! Dave has already given you pointers to what else is going wrong. I'd just add that you are printing the result of your function. That means you must look at what your function returns and when. There are two return statements in your code. Which one gets executed first? What does it return? -- 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 mats at wichmann.us Fri Apr 24 08:56:08 2020 From: mats at wichmann.us (Mats Wichmann) Date: Fri, 24 Apr 2020 06:56:08 -0600 Subject: [Tutor] diferent between " "(empty string) and None as condition In-Reply-To: References: Message-ID: On 4/23/20 1:06 PM, Emin Kovac wrote: > pasword = "" > while not pasword: > pasword = input ('Pasword: ') > > username = None > while not username: > username = input('Username: ') > My question is when should I or what is better to use as > condition empty string (" ") or None? > Anyway, what is different between an empty string and None not intending to sound flip: they have different types - one is a string, and one isn't. that matters depending on the circumstances. In general, it's really useful to have a thing that can be used when you need to distinguish expected from unexpected - this is sometimes called a sentinel. If a function returns a string, but it would never return an empty string as a usable value, then you can use the empty string as the sentinel. But consider a function that returns a string, and they're all valid, including the empty string: let's say it returns an operating-system specific file suffix which should be appended to a filename. When called on Windows, the function returns ".exe"; when called on Linux it returns "" - because there is in fact no suffix that needs to be appended. Now we need a way to distinguish between returning that perfectly valid empty string, and failing so badly the caller should take remidial action instead of proceeding with that value - this is a good place to return None, because it's not a string at all, so the caller of the function can detect the difference. === extra credit, no need to go here if you don't want: There are also cases where things are coded in such a way that None is a valid value, and can't be used as the sentinel, and you need yet another value to distinguish that something out-of-band happened. You can do this by calling object() - every Python object instance has a unique identity, and if you save off one and don't free it, nothing else during the run of the program will have that identity so you can check against it (using "is", which compares identity, not "==", which compares values): BADVALUE = object() rv = foo(some, arguments) if rv is BADVALUE: # bail out here, function failed From sbrown106 at yahoo.co.uk Fri Apr 24 08:52:57 2020 From: sbrown106 at yahoo.co.uk (stephen brown) Date: Fri, 24 Apr 2020 12:52:57 +0000 (UTC) Subject: [Tutor] moving an item from one listbox to another in Python Tkinter References: <553467413.494265.1587732777222.ref@mail.yahoo.com> Message-ID: <553467413.494265.1587732777222@mail.yahoo.com> Hi, I am new to python and trying to learn tkinter. Could somebody help me with this 2 problems please Ive been stuck on it for days. I want to move an item from one list box to another but don't want to duplicate the items in the second list box but not sure how to do this. I can move items across but it lets me duplicate as well. Also if somebody could give me some guidance on how I might to this using 'bind' . I have tried this but couldn't understand so ended up using buttons instead. My example code is below. from tkinter import * from tkinter import ttk my_window = Tk()my_listbox_in = Listbox(my_window, height='5') my_listbox_in.grid(row=0, column=0) my_listbox_out = Listbox(my_window, height='5') my_listbox_out.grid(row=0, column=2)my_list = ['1', '2', '4', '6']for item in my_list: ??? my_listbox_in.insert(END, item) def delete(): ??? my_listbox_in.delete(ANCHOR) # delete all??? my_listbox_in.delete(0,END) def select(): #?? my_label.config(text=my_listbox_in.get(ANCHOR)) ??? if my_listbox_out.insert(END, my_listbox_in.get(ANCHOR)) not in my_listbox_out: ??????? my_listbox_out.insert(END, my_listbox_in.get(ANCHOR)) button1 = Button(my_window, text='Delete', command=delete) button1.grid(row=0, column=1)button2 = Button(my_window, text='select', command=select) button2.grid(row=1, column=1) my_label = Label(my_window, text='my_label') my_label.grid(row=2, column=1)#my_listbox_in.bind('<>', select())mainloop() From robertvstepp at gmail.com Sat Apr 25 00:07:01 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Fri, 24 Apr 2020 23:07:01 -0500 Subject: [Tutor] diferent between " "(empty string) and None as condition In-Reply-To: References: Message-ID: On Fri, Apr 24, 2020 at 7:56 AM Mats Wichmann wrote: > === extra credit, no need to go here if you don't want: > > There are also cases where things are coded in such a way that None is a > valid value, and can't be used as the sentinel, and you need yet another > value to distinguish that something out-of-band happened... Would you please show a realistic example where one might do this -- where None can't be used as a sentinel because it is otherwise occupied? -- boB From cs at cskk.id.au Sat Apr 25 03:38:44 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Sat, 25 Apr 2020 17:38:44 +1000 Subject: [Tutor] diferent between " "(empty string) and None as condition In-Reply-To: References: Message-ID: <20200425073844.GA24715@cskk.homeip.net> On 24Apr2020 23:07, boB Stepp wrote: >On Fri, Apr 24, 2020 at 7:56 AM Mats Wichmann wrote: > >> === extra credit, no need to go here if you don't want: >> >> There are also cases where things are coded in such a way that None is a >> valid value, and can't be used as the sentinel, and you need yet another >> value to distinguish that something out-of-band happened... > >Would you please show a realistic example where one might do this -- >where None can't be used as a sentinel because it is otherwise >occupied? Anything where a valid function result might be None. Invented example: from queue import Queue EOF = object() Q = Queue() d = {'a': 0, 'b': 2} for k in 'a', 'b', 'c': Q.put( d.get(k) ) Q.put(EOF) while True: v = Q.get() if v is EOF: break print("v =", v) Here we have a Queue onto which we might want to put _any_ value, including None. The consumer wnats to know when all the values have been received. For this purpose we make a special object instance EOF for the sentinel, which we know will not be used as a value. This kind of "make a special instance of object" is in fact a common idiom for sentinel in Python. Cheers, Cameron Simpson Q: How does a hacker fix a function which doesn't work for all of the elements in its domain? A: He changes the domain. - Rich Wareham From ekesawi at yahoo.com Sat Apr 25 02:11:35 2020 From: ekesawi at yahoo.com (EK Esawi) Date: Sat, 25 Apr 2020 06:11:35 +0000 (UTC) Subject: [Tutor] Rotate 2d Plot References: <1140128913.67496.1587795095255.ref@mail.yahoo.com> Message-ID: <1140128913.67496.1587795095255@mail.yahoo.com> Hi All? I am working on a 2D plot using Matplolib. I am wondering if there is a way to rotate the whole plot; that?s, e.g., if I generate a scatter plot with contouring, labels, etc., Is it possible to rotate the whole plot an x degrees clockwise keeping the same geometry (no distortion)? If so, How?. I was able to rotate the plot by rotating each entity, i.e. each point, but I am not sure if that?s is possible for contouring and other labels. Thanks in advance EK From esawiek at gmail.com Sat Apr 25 00:48:23 2020 From: esawiek at gmail.com (Ek Esawi) Date: Sat, 25 Apr 2020 00:48:23 -0400 Subject: [Tutor] Rotate a 2D plot Message-ID: Hi All? I am working on a 2D plot using Matplolib. I am wondering if there is a way to rotate the whole plot; that?s, e.g., if I generate a scatter plot with contouring, labels, etc., Is it possible to rotate the whole plot an x degrees clockwise keeping the same geometry (no distortion)? If so, How?. I was able to rotate the plot by rotating each entity, i.e. each point, but I am not sure if that?s is possible for contouring and other labels. Thanks in advance EK From saiprani0003 at gmail.com Fri Apr 24 22:49:38 2020 From: saiprani0003 at gmail.com (SuramSrisainath Reddy) Date: Sat, 25 Apr 2020 08:19:38 +0530 Subject: [Tutor] Issue about pyaudiomodule Message-ID: Sir, I have b?en trying to make a desktop assistant project,but i am grtting a problem regarding pyaudio module. Is there any substitute module for pyaudio module or tell me other ways to solve my problem? From subhashnunna at hotmail.com Sat Apr 25 00:03:32 2020 From: subhashnunna at hotmail.com (Subhash Nunna) Date: Sat, 25 Apr 2020 04:03:32 +0000 Subject: [Tutor] modification to a list In-Reply-To: References: Message-ID: Hi Shubham, Here is the code meeting you?re conditions: def skip_elements(elements): # Initialize variables new_list = [] i = 0 # Iterate through the list for i,element in enumerate(elements): # Does this element belong in the resulting list? if elements.index(element)%2==0: # Add this element to the resulting list new_list.append(element) # Increment i i += 1 return new_list print(skip_elements(["a", "b", "c", "d", "e", "f", "g"])) # Should be ['a', 'c', 'e', 'g'] print(skip_elements(['Orange', 'Pineapple', 'Strawberry', 'Kiwi', 'Peach'])) # Should be ['Orange', 'Strawberry', 'Peach'] print(skip_elements([])) # Should be [] Regards, Subhash Nunna Sent from Mail for Windows 10 From: shubham sinha Sent: Wednesday, April 22, 2020 8:17 PM To: tutor at python.org Subject: [Tutor] modification to a list Hi, Q. The skip_elements function returns a list containing every other element from an input list, starting with the first element. Complete this function to do that, using the for loop to iterate through the input list. my code: def skip_elements(elements): new_list = [ ] i = 0 for element in elements: if "element" != "elements(i): new_list.append(element) i += 2 return new_list print(skip_elements(["a", "b", "c", "d", "e", "f", "g"])) # Should be ['a', 'c', 'e', 'g'] print(skip_elements(['Orange', 'Pineapple', 'Strawberry', 'Kiwi', 'Peach'])) # Should be ['Orange', 'Strawberry', 'Peach'] print(skip_elements([ ])) # Should be [ ] my output: ['a', 'b', 'c', 'd', 'e', 'f', 'g'] ['Orange', 'Pineapple', 'Strawberry', 'Kiwi', 'Peach'] [] output should be: ['a', 'c', 'e', 'g'] ['Orange', 'Strawberry', 'Peach'] [] _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From upwkwd at gmail.com Sat Apr 25 03:25:06 2020 From: upwkwd at gmail.com (shubham sinha) Date: Sat, 25 Apr 2020 12:55:06 +0530 Subject: [Tutor] if statement issue Message-ID: question: The City class has the following attributes: name, country (where the city is located), elevation (measured in meters), and population (approximate, according to recent statistics). Fill in the blanks of the max_elevation_city function to return the name of the city and its country (separated by a comma), when comparing the 3 defined instances for a specified minimal population. For example, calling the function for a minimum population of 1 million: max_elevation_city(1000000) should return "Sofia, Bulgaria". code for given question: # define a basic city class class City: name = "" country = "" elevation = 0 population = 0 # create a new instance of the City class and # define each attribute city1 = City() city1.name = "Cusco" city1.country = "Peru" city1.elevation = 3399 city1.population = 358052 # create a new instance of the City class and # define each attribute city2 = City() city2.name = "Sofia" city2.country = "Bulgaria" city2.elevation = 2290 city2.population = 1241675 # create a new instance of the City class and # define each attribute city3 = City() city3.name = "Seoul" city3.country = "South Korea" city3.elevation = 38 city3.population = 9733509 def max_elevation_city(min_population): # Initialize the variable that will hold # the information of the city with # the highest elevation return_city = City() # Evaluate the 1st instance to meet the requirements: # does city #1 have at least min_population and # is its elevation the highest evaluated so far? if city1.population >= min_population and city1.elevation > return_city.elevation: return_city = city1 # Evaluate the 2nd instance to meet the requirements: # does city #2 have at least min_population and # is its elevation the highest evaluated so far? if city2.population >= min_population and city2.elevation > return_city.elevation: return_city = city2 # Evaluate the 3rd instance to meet the requirements: # does city #3 have at least min_population and # is its elevation the highest evaluated so far? if city3.population >= min_population and city3.elevation > return_city.elevation: return_city = city3 #Format the return string if return_city.name: return ("{}, {}".format(return_city.name, return_city.country)) else: return "" print(max_elevation_city(100000)) # Should print "Cusco, Peru" print(max_elevation_city(1000000)) # Should print "Sofia, Bulgaria" print(max_elevation_city(10000000)) # Should print "" output for this code: Cusco, Peru Sofia, Bulgaria my problem: In the "#Format the return string" why we did not call for True statement for if statement and it also gives the correct answer? please help me through the mentioned if statement. Thanks, Shubham Sinha From alan.gauld at yahoo.co.uk Sat Apr 25 10:09:45 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 25 Apr 2020 15:09:45 +0100 Subject: [Tutor] modification to a list In-Reply-To: References: Message-ID: On 25/04/2020 05:03, Subhash Nunna wrote: > def skip_elements(elements): > # Initialize variables > new_list = [] > i = 0 You don't need to initialize i since it is populated by enumerate below. > > # Iterate through the list > for i,element in enumerate(elements): > # Does this element belong in the resulting list? > if elements.index(element)%2==0: You don't need to find the index since you already got i from enumerate. i is the index. So the above line should just be: if i%2 == 0: > # Add this element to the resulting list > new_list.append(element) > # Increment i > i += 1 And you don't need to increment i since enumerate() will overwrite it with the next index anyway. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at yahoo.co.uk Sat Apr 25 10:13:37 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 25 Apr 2020 15:13:37 +0100 Subject: [Tutor] Issue about pyaudiomodule In-Reply-To: References: Message-ID: On 25/04/2020 03:49, SuramSrisainath Reddy wrote: > Sir, > I have b?en trying to make a desktop assistant project,but i am grtting a > problem regarding pyaudio module. > Is there any substitute module for pyaudio module or tell me other ways to > solve my problem? To do that we would have to know what your problem is. pyaudio works as advertised. If you are having problems with it then it means: 1) You are trying to do something that pyaudio can't do or 2) You are using pyaudio wrongly But since you don't tell us what you want to do, how you are trying to do it, or what OS/hardware you are using. It is impossible to help you. -- 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 Sat Apr 25 10:32:22 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 25 Apr 2020 15:32:22 +0100 Subject: [Tutor] if statement issue In-Reply-To: References: Message-ID: On 25/04/2020 08:25, shubham sinha wrote: > question: > The City class has the following attributes: name, country (where the city > is located), elevation (measured in meters), and population (approximate, > according to recent statistics). That's a terrible class definition. But assuming this is a homework and you must use it... Attributes of a class are usually set in its init() method. You should be able to instantiate a city with something like: london = City('London', 'UK', 30, 9000000) > max_elevation_city function to return the name of the city and its country > (separated by a comma), when comparing the 3 defined instances for a > specified minimal population. For example, calling the function for a > minimum population of 1 million: max_elevation_city(1000000) should return > "Sofia, Bulgaria". This is the more interesting part. You effectively need to filter by population and sort by elevation. You can do it either way around but I'd suggest filtering first. > # define a basic city class > class City: > name = "" > country = "" > elevation = 0 > population = 0 You need an init method. And you need to observe proper indentation. Python is very fussy about indentation. > # create a new instance of the City class and > # define each attribute > city1 = City() > city1.name = "Cusco" > city1.country = "Peru" > city1.elevation = 3399 > city1.population = 358052 You really don't want to do that. Create an __init__() method in City. > def max_elevation_city(min_population): > # Initialize the variable that will hold > # the information of the city with > # the highest elevation > return_city = City() You don;t really need this since you already have the city objects and you can just return one of them. But if you must do it this way you art least need to initialize the elevation value. > # Evaluate the 1st instance to meet the requirements: > # does city #1 have at least min_population and > # is its elevation the highest evaluated so far? > if city1.population >= min_population and city1.elevation > > return_city.elevation: You are comparing to return_city.elevation but you never set it anywhere (Because you never created an init() method. > return_city = city1 > # Evaluate the 2nd instance to meet the requirements: > # does city #2 have at least min_population and > # is its elevation the highest evaluated so far? > if city2.population >= min_population and city2.elevation > > return_city.elevation: > return_city = city2 This is duplicate code. You code remove the duplication by using a for loop: for city in [city1,city2,city3]: if city.... return_city = city > #Format the return string > if return_city.name: > return ("{}, {}".format(return_city.name, return_city.country)) > else: > return "" > In the "#Format the return string" why we did not call for True statement > for if statement and it also gives the correct answer? I assume you mean why did you have if return_city.name: instead of if return_city.name != "": Or similar? The answer is that Python treats any value that is zero or empty as False and anything else is True. So in the if statement we effectively check whether the name is not empty. I'm not sure how many of my comments above are down to you and how much is down to the homework template. But it always saddens me when I see students being given bad code as a template to start from! -- 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 mats at wichmann.us Sat Apr 25 11:04:05 2020 From: mats at wichmann.us (Mats Wichmann) Date: Sat, 25 Apr 2020 09:04:05 -0600 Subject: [Tutor] Issue about pyaudiomodule In-Reply-To: References: Message-ID: <969d67d2-283d-09c0-52e3-0ad8ba84baa0@wichmann.us> On 4/24/20 8:49 PM, SuramSrisainath Reddy wrote: > Sir, > I have b?en trying to make a desktop assistant project,but i am grtting a > problem regarding pyaudio module. > Is there any substitute module for pyaudio module or tell me other ways to > solve my problem? Turns out a lot of people are stumbling over pyaudio these days. The "official" pyaudio has not been updated for a long while, and there are no wheels for Windows for 3.7 or 3.8, which means if you're on Windows you can't install it through pip unless you've stayed on an older Python version. I'm assuming you're on Windows (my sympathies to you) since it should work on other platforms. Try here: these are unofficial in the sense they're not produced by the pyaudio project itself, but they are made carefully and will probably work. https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyaudio you'd need to manually select the correct wheel - the "cp" stands for CPython, then the two-digit number is the Python version you have, then the end is to select for a 32-bit (win32) or 64-bit (win_amd64) Python, download it, and then install via py -m pip install /path/to/pyaudiowheel (substituting in the suitable bits of course, and assuming that you are using the Python Launcher, which you should be if you're using the Python distributon from python.org) Hope this helps... From mats at wichmann.us Sat Apr 25 12:33:21 2020 From: mats at wichmann.us (Mats Wichmann) Date: Sat, 25 Apr 2020 10:33:21 -0600 Subject: [Tutor] modification to a list In-Reply-To: References: Message-ID: <2f32c112-cc6a-e9ba-b445-ac3a32c3a077@wichmann.us> On 4/24/20 10:03 PM, Subhash Nunna wrote: > Hi Shubham, > > > Here is the code meeting you?re conditions: > def skip_elements(elements): > # Initialize variables > new_list = [] > i = 0 > > # Iterate through the list > for i,element in enumerate(elements): > # Does this element belong in the resulting list? > if elements.index(element)%2==0: > # Add this element to the resulting list > new_list.append(element) > # Increment i > i += 1 > > > return new_list > > print(skip_elements(["a", "b", "c", "d", "e", "f", "g"])) # Should be ['a', 'c', 'e', 'g'] > print(skip_elements(['Orange', 'Pineapple', 'Strawberry', 'Kiwi', 'Peach'])) # Should be ['Orange', 'Strawberry', 'Peach'] > print(skip_elements([])) # Should be [] This question illustrates a difficulty that faces those of us answering on tutor. In many cases an assignment (homework problem, exercise in a book, etc.) intends you to use something specific because at that moment in time the curriculum wants you to learn about that specific feature. Of course you need to practice how to step through a list in a loop, it's a skill a Pythoneer absolutely must have. But we _also_ want you to learn effective Python, and this problem has, as Mark has already suggested a while ago, a simpler approach available because it's something people need to do often. So in the spirit of the latter (and presumably not the wanted answer in this case), this is a solution to the actual problem: def skip_elements(elements): return elements[::2] In the list "slicing" notation we have starting-index:stop-index:stepsize where for the start and stop indices, and omitted value means "beginning" and "end" respectively. Here is that pasted into an interactive interpreter: >>> def skip_elements(elements): ... return elements[::2] ... >>> print(skip_elements(["a", "b", "c", "d", "e", "f", "g"])) ['a', 'c', 'e', 'g'] >>> print(skip_elements(['Orange', 'Pineapple', 'Strawberry', 'Kiwi', 'Peach'])) ['Orange', 'Strawberry', 'Peach'] >>> print(skip_elements([])) [] >>> From robertvstepp at gmail.com Sat Apr 25 13:01:40 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 25 Apr 2020 12:01:40 -0500 Subject: [Tutor] diferent between " "(empty string) and None as condition In-Reply-To: <20200425073844.GA24715@cskk.homeip.net> References: <20200425073844.GA24715@cskk.homeip.net> Message-ID: On Sat, Apr 25, 2020 at 2:38 AM Cameron Simpson wrote: > > On 24Apr2020 23:07, boB Stepp wrote: > >On Fri, Apr 24, 2020 at 7:56 AM Mats Wichmann wrote: > > > >> === extra credit, no need to go here if you don't want: > >> > >> There are also cases where things are coded in such a way that None is a > >> valid value, and can't be used as the sentinel, and you need yet another > >> value to distinguish that something out-of-band happened... > > > >Would you please show a realistic example where one might do this -- > >where None can't be used as a sentinel because it is otherwise > >occupied? > > Anything where a valid function result might be None. Ah. Just this one sentence made the light bulb glow brightly! > Invented example: > > from queue import Queue > > EOF = object() > Q = Queue() > d = {'a': 0, 'b': 2} > for k in 'a', 'b', 'c': > Q.put( d.get(k) ) > Q.put(EOF) > while True: > v = Q.get() > if v is EOF: > break > print("v =", v) > > Here we have a Queue onto which we might want to put _any_ value, > including None. The consumer wnats to know when all the values have been > received. For this purpose we make a special object instance EOF for the > sentinel, which we know will not be used as a value. > > This kind of "make a special instance of object" is in fact a common > idiom for sentinel in Python. Thanks, Cameron. The example ties it all together for me. OT: Cameron, just for your posts to Tutor where I am being responded to, I find Gmail sending all of your posts to spam. I don't know much about the inner workings of email, but I notice in the details Gmail provides: from:Cameron Simpson reply-to:tutor at python.org, boB Stepp , tutor to:boB Stepp The Tutor list is duplicated. Would this be the cause of straight to spam? If yes, is this something correctable on your end? Not that I want to impose on your valuable time! -- boB From PyTutor at danceswithmice.info Sat Apr 25 17:44:05 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Sun, 26 Apr 2020 09:44:05 +1200 Subject: [Tutor] if statement issue In-Reply-To: References: Message-ID: On 25/04/20 7:25 PM, shubham sinha wrote: > question: > The City class has the following attributes: name, country (where the city > is located), elevation (measured in meters), and population (approximate, > according to recent statistics). Fill in the blanks of the > max_elevation_city function to return the name of the city and its country > (separated by a comma), when comparing the 3 defined instances for a > specified minimal population. For example, calling the function for a > minimum population of 1 million: max_elevation_city(1000000) should return > "Sofia, Bulgaria". However, it is not apparent if this is your first-attempt at code, or if it has been provided for you: > # Evaluate the 1st instance to meet the requirements: > # does city #1 have at least min_population and > # is its elevation the highest evaluated so far? > if city1.population >= min_population and city1.elevation > > return_city.elevation: > return_city = city1 etc Imagine if there were hundreds of cities. @Alan has already mentioned the need for a class definition. Is this code sustainable? The code would require the above set of lines (plus its definition) for every single city. "I don't think so, Tim!" At the very least, "generalise" the above, and put it into a function, in the same way that you will "generalise" the data with a class definition and __init__(). (This idea might also be helpful a little later in this response...) What are we doing here? This is a classic "Database" (now becoming "Data Science") problem. First of all, it is a good idea to visualise the problem - and the data. Whilst easy-enough with 'toy problems', it's not a good idea to dive straight into coding! (I tend to start with 'the data', because that is my background - not just because I like to tease @Alan - mercilessly) Visualising the data: Because there are (apparently) only a few cities with three "dependent" data-items, it is easy to write the whole problem onto a sheet of paper, eg a table with one line/row for each city, and columns for cityNM, countryNM, elevation, and population. (one assumes the elevations all use the same metric, eg feet or meters). Now we can 'see' that a 'solution' should work for our sub-set (or "test-data") AND for a "live" situation involving many more data-items (and possibly, other complications). Now that you are no longer looking at a 'wall of text' in the code-description given by your book/trainer, do you have a 'picture' in your mind? Visualising the problem: If you would like to keep working on-paper, at this time it would be a good idea to either rip your table cross-wise, to that each line/row is an independent 'strip', or transfer each city's data to a 'sticky-note', file-card, or similar - one for each line/row of your pretty table. This is why many dev.team offices have white-boards for many of the walls! The problem becomes one of sequencing the data, filtering-out those with over-large populations, then re-sequencing according to elevation. NB other terms for "sequencing" are "ORDER BY" (in the DB-world) and "sort" (in Python). In the DB-world, we start by reducing the amount of data to be considered by discarding the irrelevant - we call it SELECT, or in English: "selection". @Alan's advice called it "filtering". If you had a data-set of thousands of cities, this would (hopefully) reduce the volume of (applicable) data considerably. (and speed-up the next stage of processing!) So back to our "model", re-assemble your 'strips' as a new 'table', ie in a 'sequence' with the least-populous city at the top, and the most-crowded, at the bottom. Now, starting 'at the top', smile at every strip where the city's population is smaller than the specification and remove all of those that are 'too big'. Hint: once a single city fails to fulfill the criteria, all the others 'below' will too (so you can remove them en-masse - that's why we sequenced them! Thus, we can now move to the second criteria: elevation. Re-sequence the 'strips', this time so that the 'highest' city is at the 'top' and the city with lowest-elevation is at the bottom. (apologies for potentially confusing the sequence of our table's top/bottom, with city-elevation or height!) The required answer is now self-evident, or as my mother used to say when offering me a plate of treats and observing my greedy eyes: "take one"! Coding the solution: So, how do we do this in Python? As @Alan has observed, some of the code as listed is not good style/technique. However, it is not clear what has been provided (which we are not allowed to (even appear to) criticise, are we?) and what is yours; so I shall +1 his comment and ignore from there. Take the data-classes (cities) and assemble them into a list (you can imagine the list as the lines/rows of our illustration (above) and each class's attributes as the columns! Now, if you haven't already, you should study Python's ability to sort data-structures, and sort the list ("in-place") according to each class's population attribute. Once sorted by population, we don't want to continue to consider any cities which are too 'large'. So, create another list, and considering each element in-turn, copy those cities/classes which fulfill the maximum-population criteria. Hint, a "break" in this loop on the first occasion when the criteria fails, will save you/the computer from considering any other list-members. Be careful at this point! What would happen if NO city fulfills the specification? Is there any point in executing further 'calculations'? Moving-on, sort the remaining-list, this time by elevation. "Take one" (learn from me, don't be greedy!) If the 'visualisation' of the data and/or the problem was your difficulty, or if you are new to Python and specifically sort-ing, please ignore the next paragraph! Python lists offer a neat method: .pop(). Normally, (with no parameter) this will return the last ("right-most") element of a list. However, that doesn't suit the visualisation described earlier. We could use list.pop( 0 ) to grab the first/'top' city-class though! > def max_elevation_city(min_population): > # Initialize the variable that will hold > # the information of the city with > # the highest elevation > return_city = City() ... > #Format the return string > if return_city.name: > return ("{}, {}".format(return_city.name, return_city.country)) > else: > return "" I assume this is a 'device' by your teacher/trainer to ensure that assignments can be machine-graded. Using the above, we have decided which city to return as return_city. By the way, you/Python (and many of our fellow list-members!) could code a solution without any sorting operations. I (only) recommended sort() (above), in order to maintain the 'visualisation' developed on-paper! To complete the (DB) picture: SELECTion was mentioned earlier - in our 'paper-computer' this was working with rows of data at a time. The other basic analysis is "projection". This is analysing the table by column(s), eg not bothering with what the city is called, but only being 'interested in it' if its *population* meets a certain criteria. Using Python classes is a good idea. You will gain practice 'pulling' a single "attribute" from the class and analysing/sorting on that, ie "projection". The 'bad news' is that we DB-people could have accomplished the whole assignment (assuming the table) in a single line of SQL - but where's the fun in using SQL and hard-drives, when we could be using Python and working at RAM-speed!? -- Regards =dn From alan.gauld at yahoo.co.uk Sat Apr 25 19:20:17 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 26 Apr 2020 00:20:17 +0100 Subject: [Tutor] if statement issue In-Reply-To: References: Message-ID: On 25/04/2020 22:44, DL Neil via Tutor wrote: > (I tend to start with 'the data', because that is my background - not > just because I like to tease @Alan - mercilessly) Teasing noted, but to be fair if it is a data oriented program (as this clearly is) starting with the data is a good idea. And its how I start most data projects: with a database design using good old ER diagrams. If necessary, I'll later build an object model on top, but the data is the key if that's what the problem requires. Just don't go on to claim it is "Object Oriented"! :-) -- 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 breamoreboy at gmail.com Sat Apr 25 10:48:25 2020 From: breamoreboy at gmail.com (Mark Lawrence) Date: Sat, 25 Apr 2020 15:48:25 +0100 Subject: [Tutor] Rotate 2d Plot In-Reply-To: <1140128913.67496.1587795095255@mail.yahoo.com> References: <1140128913.67496.1587795095255.ref@mail.yahoo.com> <1140128913.67496.1587795095255@mail.yahoo.com> Message-ID: On 25/04/2020 07:11, EK Esawi via Tutor wrote: > Hi All? > > I am working on a 2D plot using Matplolib. I am wondering if there is > a way to rotate the whole plot; that?s, e.g., if I generate a scatter > plot with contouring, labels, etc., Is it possible to rotate the whole > plot an x degrees clockwise keeping the same geometry (no distortion)? > If so, How?. I was able to rotate the plot by rotating each entity, > i.e. each point, but I am not sure if that?s is possible for > contouring and other labels. > > Thanks in advance > > EK Sorry but can't help directly as matplotlib is a specialised third party package whilst this list is aimed at core Python and its libraries. Having said that does this https://stackoverflow.com/questions/22540449/how-can-i-rotate-a-matplotlib-plot-through-90-degrees help? :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From PyTutor at danceswithmice.info Sat Apr 25 19:57:30 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Sun, 26 Apr 2020 11:57:30 +1200 Subject: [Tutor] if statement issue In-Reply-To: References: Message-ID: <621aa5ef-7ff7-6e25-ec8e-e32d479cb9f1@DancesWithMice.info> On 26/04/20 11:20 AM, Alan Gauld via Tutor wrote: > On 25/04/2020 22:44, DL Neil via Tutor wrote: > >> (I tend to start with 'the data', because that is my background - not >> just because I like to tease @Alan - mercilessly) > Teasing noted, but to be fair if it is a data oriented > program (as this clearly is) starting with the data > is a good idea. And its how I start most data projects: > with a database design using good old ER diagrams. > If necessary, I'll later build an object model on top, > but the data is the key if that's what the problem > requires. > > Just don't go on to claim it is "Object Oriented"! :-) Aye, dinna fash yourself laddie! * I wasn't going for OOD or OOP, but by reducing to (almost) functional programming, just-about succeeded in making the whole thing declarative! * have been saving this one for you! Someone phoned me, not to express concern for my COVID-free welfare, but to ask what this phrase means. Apparently there's a new TV series which features Scots/Gaelic characters, and the question caused me to wonder if its ardent-fans are going to end-up like 'Trekkies' speaking Klingon? For those who are also asking: it can be used somewhat humorously (as here) or in a dismissive fashion: do not worry yourself/it is nothing to worry-about/no worries mate/she'll be right/it's above your pay-grade! -- Regards =dn From cs at cskk.id.au Sat Apr 25 19:13:45 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Sun, 26 Apr 2020 09:13:45 +1000 Subject: [Tutor] diferent between " "(empty string) and None as condition In-Reply-To: References: Message-ID: <20200425231345.GA816@cskk.homeip.net> On 25Apr2020 12:01, boB Stepp wrote: >On Sat, Apr 25, 2020 at 2:38 AM Cameron Simpson wrote: >> On 24Apr2020 23:07, boB Stepp wrote: >> >Would you please show a realistic example where one might do this -- >> >where None can't be used as a sentinel because it is otherwise >> >occupied? >> >> Anything where a valid function result might be None. > >Ah. Just this one sentence made the light bulb glow brightly! Aye. A sentinel is by definition a not-in-the-domain value; that is its whole purpose. >OT: Cameron, just for your posts to Tutor where I am being responded >to, I find Gmail sending all of your posts to spam. This is my suspicion as well. Just on the basis of lots of threads where it is like I haven't posted at all (the discussion is like I haven't been seen, versus simply not being helpful). >I don't know much >about the inner workings of email, but I notice in the details Gmail >provides: > >from:Cameron Simpson reply-to:tutor at python.org, >boB Stepp , >tutor >to:boB Stepp > >The Tutor list is duplicated. Would this be the cause of straight to >spam? If yes, is this something correctable on your end? Not that I >want to impose on your valuable time! I often reply to the author as well as the list, but set reply-to to the list to avoid off-list accidents. I don't think this affects GMail's decisions (can't test that). Are there other header on the message at your end indicating what GMail thinks? You may need to view-source on the message to see them. We should take the email/spam side of this discussion off list to personal email. Other things that might affect this is lack of SPF on my domain. I could make one, but since we routinely send via our ISP mail relays rather than through our mail server this there's nothing very useful we can put in the SPF :-( (Think: mobile phone, sending via the phone company's mail relay.) Cheers, Cameron Simpson From robertvstepp at gmail.com Sun Apr 26 00:10:03 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 25 Apr 2020 23:10:03 -0500 Subject: [Tutor] OT (probably): How to change default tab key value to 4 spaces in GNOME Terminal? Message-ID: Linux Mint, Python 3.7.5, GNOME Terminal 3.28.1 A while back I became tired of the default Python interpreter prompt ">>>" and replaced it with the Python version number, e.g., "3.7.5: ". But my original version that I have used for years did not take into account the secondary default prompt "..." and where it put the cursor. For whatever reason my annoyance level with this flaw rose high enough today that I fixed it as follows: """Configure prompt appearance in Python REPL.""" import sys py_version = sys.version.split()[0] sys.ps1 = py_version + ": " # Ensure cursor lines up with previous line of code: sys.ps2 = "..." + " " * (len(sys.ps1) - 3) This does what I want, but now there is a new annoyance: 3.7.5: def f(s): ... print(s) ... 3.7.5: f('Jeremy') Jeremy In the second line as I was typing it I pressed when the cursor was lined up with the "d" in "def". What I see in the terminal is the "p" in "print" lining up under the colon as I have shown above. I understand that the default terminal behavior is that shifts in 8 columns wide tab stops. I would like to change this behavior for when I am in the Python interpreter to have always shift 4 columns from the starting cursor position. Does anyone know how to accomplish this? After some searching online the best advice I could find was to enter at the command prompt "tabs -4". I tried this and as far as I can tell it did not work for me while in the Python interpreter. However, in drafting this email to Tutor when I actually copy and paste what looks like the above code in my terminal window actually pastes into this Gmail message as: 3.7.5: def f(s): ... print(s) ... 3.7.5: f('Jeremy') Jeremy Hmm. That is strange! Pasting what appears different in my terminal shows up in Gmail like I want it to appear in the terminal. That is suggestive of the tab character in the terminal has the value I want, but if this is so, where are the additional 4 spaces/columns coming from? -- boB From robertvstepp at gmail.com Sun Apr 26 00:22:10 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 25 Apr 2020 23:22:10 -0500 Subject: [Tutor] Do you use doctests to show API use even when you normally use unit tests? Message-ID: Amazon delivered a new book to my doorstep today entitled "Practical Programming, Third Edition -- An Introduction to Computer Science Using Python 3.6", c. 2017, by Paul Gries, Jennifer Campbell and Jason Montojo. I am Easter egging through it and so far very much like it. Early on the authors introduce type annotations and inserting doctests into their docstrings. The latter is done for the first part of the book as documentation on how to use the function it exists in, not to run doctests. Later in the book they start actually running the doctests. Near the end of the book they have a chapter on testing and introduce unit tests using Python's unittest. They discuss the question of doctests versus unit tests, and, of course, heavily vote for unit testing as the way to go. However, they never stop inserting doctests into their function and method docstrings. I am assuming that they consider it best practice as to how to document how to use a function or method. My question is: Is this what you would consider to be best documentation practice? -- boB From robertvstepp at gmail.com Sun Apr 26 00:33:56 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 25 Apr 2020 23:33:56 -0500 Subject: [Tutor] OT (probably): How to change default tab key value to 4 spaces in GNOME Terminal? In-Reply-To: References: Message-ID: Oh, joy. I just looked at how my email below looked at mail.python.org/pipermail/tutor and see that my oh so wonderful Gmail has further *adjusted* things. On Sat, Apr 25, 2020 at 11:10 PM boB Stepp wrote: > 3.7.5: def f(s): > ... print(s) What I now see on Tutor is that the "print(s)" lines up several spaces beyond the colon! > After some searching online the best advice I could find was to enter > at the command prompt "tabs -4". I tried this and as far as I can > tell it did not work for me while in the Python interpreter. However, > in drafting this email to Tutor when I actually copy and paste what > looks like the above code in my terminal window actually pastes into > this Gmail message as: > > 3.7.5: def f(s): > ... print(s) And on Tutor the "p" now lines up with the colon!! I have no clue as to what you gentle readers will see!!! -- boB From PyTutor at danceswithmice.info Sun Apr 26 00:53:33 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Sun, 26 Apr 2020 16:53:33 +1200 Subject: [Tutor] OT (probably): How to change default tab key value to 4 spaces in GNOME Terminal? In-Reply-To: References: Message-ID: <142a44ac-2f16-e793-dfd5-700427635207@DancesWithMice.info> On 26/04/20 4:10 PM, boB Stepp wrote: > Linux Mint, Python 3.7.5, GNOME Terminal 3.28.1 > > A while back I became tired of the default Python interpreter prompt > ">>>" and replaced it with the Python version number, e.g., "3.7.5: > ". But my original version that I have used for years did not take > into account the secondary default prompt "..." and where it put the > cursor. For whatever reason my annoyance level with this flaw rose > high enough today that I fixed it as follows: > > """Configure prompt appearance in Python REPL.""" > > import sys > > py_version = sys.version.split()[0] > sys.ps1 = py_version + ": " > > # Ensure cursor lines up with previous line of code: > sys.ps2 = "..." + " " * (len(sys.ps1) - 3) > > This does what I want, but now there is a new annoyance: > > 3.7.5: def f(s): > ... print(s) > ... > 3.7.5: f('Jeremy') > Jeremy > > In the second line as I was typing it I pressed when the cursor > was lined up with the "d" in "def". What I see in the terminal is the > "p" in "print" lining up under the colon as I have shown above. I > understand that the default terminal behavior is that shifts in > 8 columns wide tab stops. I would like to change this behavior for > when I am in the Python interpreter to have always shift 4 > columns from the starting cursor position. Does anyone know how to > accomplish this? > > After some searching online the best advice I could find was to enter > at the command prompt "tabs -4". I tried this and as far as I can > tell it did not work for me while in the Python interpreter. You are not alone! However, the first point to understand is that in the interpreter TAB performs a "completion" function. Indeed (whilst this is definitely in 'do as I say, not as I do' territory) please recall what PEP-8 has to say about TABs! You will find (very little) sympathy in the Python Tutorial: 14. Interactive Input Editing and History Substitution https://docs.python.org/3/tutorial/interactive.html -- Regards =dn From cs at cskk.id.au Sun Apr 26 01:55:59 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Sun, 26 Apr 2020 15:55:59 +1000 Subject: [Tutor] Do you use doctests to show API use even when you normally use unit tests? In-Reply-To: References: Message-ID: <20200426055559.GA5202@cskk.homeip.net> On 25Apr2020 23:22, boB Stepp wrote: >Amazon delivered a new book to my doorstep today entitled "Practical >Programming, Third Edition -- An Introduction to Computer Science >Using Python 3.6", c. 2017, by Paul Gries, Jennifer Campbell and Jason >Montojo. I am Easter egging through it and so far very much like it. >Early on the authors introduce type annotations and inserting doctests > into their docstrings. [...] >[...] They discuss the >question of doctests versus unit tests, and, of course, heavily vote >for unit testing as the way to go. However, they never stop inserting >doctests into their function and method docstrings. I am assuming >that they consider it best practice as to how to document how to use a >function or method. > >My question is: Is this what you would consider to be best >documentation practice? I do this, sometimes, if the function or class is amenable to a doctest which reads nicely. Here's one: https://pypi.org/project/cs.context/ and I intend to adopt this practice more in the future. The nice thing about a doctest is that it is right next to the code. As you say, a nicely written one doubles as a nice example for the docs. Cheers, Cameron Simpson From alan.gauld at yahoo.co.uk Sun Apr 26 02:21:01 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 26 Apr 2020 07:21:01 +0100 Subject: [Tutor] OT (probably): How to change default tab key value to 4 spaces in GNOME Terminal? In-Reply-To: References: Message-ID: On 26/04/2020 05:10, boB Stepp wrote: > > After some searching online the best advice I could find was to enter > at the command prompt "tabs -4". I tried this and as far as I can > tell it did not work for me while in the Python interpreter. tab behaviour is highly problematical within terminals and programs. You may find that changing your terminal emulator works as expected. I seem to recall you use Solaris? If so try switching to the vanilla xterm window rather than Suns console application. (Or on Linux try any of the zillion consoles available: rxvt, xterm, gterm etc) But many apps, especially those using curses will have their own tab behaviour too. (vim is a classic example that ignores/overrides the terminal settings) This is one reason I never use tabs for formatting code! -- 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 Apr 26 02:25:31 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 26 Apr 2020 07:25:31 +0100 Subject: [Tutor] Do you use doctests to show API use even when you normally use unit tests? In-Reply-To: References: Message-ID: On 26/04/2020 05:22, boB Stepp wrote: > for unit testing as the way to go. However, they never stop inserting > doctests into their function and method docstrings. I am assuming > that they consider it best practice as to how to document how to use a > function or method. > > My question is: Is this what you would consider to be best > documentation practice? It's what I do for anything I publish for use by others (not a common thing these days) But it is less ambiguous that a simple textual description, and has the advantage that the user can run the test very quickly to check the code still works. They are not a substitute for a description but they reinforce it, often removing doubts. -- 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 __peter__ at web.de Sun Apr 26 05:02:04 2020 From: __peter__ at web.de (Peter Otten) Date: Sun, 26 Apr 2020 11:02:04 +0200 Subject: [Tutor] OT (probably): How to change default tab key value to 4 spaces in GNOME Terminal? References: Message-ID: boB Stepp wrote: > Linux Mint, Python 3.7.5, GNOME Terminal 3.28.1 > > A while back I became tired of the default Python interpreter prompt > ">>>" and replaced it with the Python version number, e.g., "3.7.5: > ". But my original version that I have used for years did not take > into account the secondary default prompt "..." and where it put the > cursor. For whatever reason my annoyance level with this flaw rose > high enough today that I fixed it as follows: > > """Configure prompt appearance in Python REPL.""" > > import sys > > py_version = sys.version.split()[0] > sys.ps1 = py_version + ": " > > # Ensure cursor lines up with previous line of code: > sys.ps2 = "..." + " " * (len(sys.ps1) - 3) > > This does what I want, but now there is a new annoyance: > > 3.7.5: def f(s): > ... print(s) > ... > 3.7.5: f('Jeremy') > Jeremy > > In the second line as I was typing it I pressed when the cursor > was lined up with the "d" in "def". What I see in the terminal is the > "p" in "print" lining up under the colon as I have shown above. I > understand that the default terminal behavior is that shifts in > 8 columns wide tab stops. I would like to change this behavior for > when I am in the Python interpreter to have always shift 4 > columns from the starting cursor position. Does anyone know how to > accomplish this? > > After some searching online the best advice I could find was to enter > at the command prompt "tabs -4". I tried this and as far as I can > tell it did not work for me while in the Python interpreter. However, > in drafting this email to Tutor when I actually copy and paste what > looks like the above code in my terminal window actually pastes into > this Gmail message as: > > 3.7.5: def f(s): > ... print(s) > ... > 3.7.5: f('Jeremy') > Jeremy > > Hmm. That is strange! Pasting what appears different in my terminal > shows up in Gmail like I want it to appear in the terminal. That is > suggestive of the tab character in the terminal has the value I want, > but if this is so, where are the additional 4 spaces/columns coming > from? With readline you can do import readline readline.parse_and_bind("TAB: ' '") but then you lose tab-completion (which you don't seem to use anyway). An alternative might be to keep autocompletion and bind 4-space indent to another key: readline.parse_and_bind("TAB: complete") readline.parse_and_bind("C-h: ' '") # Control-h From __peter__ at web.de Sun Apr 26 05:18:27 2020 From: __peter__ at web.de (Peter Otten) Date: Sun, 26 Apr 2020 11:18:27 +0200 Subject: [Tutor] OT (probably): How to change default tab key value to 4 spaces in GNOME Terminal? References: Message-ID: Peter Otten wrote: > With readline you can do > > import readline > readline.parse_and_bind("TAB: ' '") The moment I sent that suggestion I had a clever idea (I thought): Change Python's completer to insert 4 spaces if there's no text to complete yet. But then I saw that this is already implemented for interpreters newer than my aging default 3.4: [rlcomplete.py] if not text.strip(): if state == 0: if _readline_available: readline.insert_text('\t') readline.redisplay() return '' else: return '\t' You might try replacing the '\t's with ' ' though. From savageapple850 at gmail.com Sun Apr 26 05:42:37 2020 From: savageapple850 at gmail.com (Cravan) Date: Sun, 26 Apr 2020 17:42:37 +0800 Subject: [Tutor] Pygame environment Message-ID: <9B1AB5E3-8B27-4529-A1E3-C1F947285930@gmail.com> Hi could I ask if I want to implement an ai in my code how should I pass on my current environment to it? Would import (e.g. import * from blah.py) be sufficient? Or do I have to type env = python.learning.environment in order to do so? Cravan From robertvstepp at gmail.com Sun Apr 26 15:17:39 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 26 Apr 2020 14:17:39 -0500 Subject: [Tutor] OT (probably): How to change default tab key value to 4 spaces in GNOME Terminal? In-Reply-To: <142a44ac-2f16-e793-dfd5-700427635207@DancesWithMice.info> References: <142a44ac-2f16-e793-dfd5-700427635207@DancesWithMice.info> Message-ID: On Sat, Apr 25, 2020 at 11:54 PM DL Neil via Tutor wrote: > However, the first point to understand is that in the interpreter TAB > performs a "completion" function. Indeed (whilst this is definitely in > 'do as I say, not as I do' territory) please recall what PEP-8 has to > say about TABs! Well, this is embarrassing! I knew that if I was at the shell prompt (not in the Python interpreter) that did completion. And I knew that if I was in the interpreter in IDLE that did completion. But for whatever reason it never occurred to me that it did the same if I ran the interpreter from the shell! Now, considering other things I have just learned from the other replies, I am going to have to think carefully about things and what I want my shell and interpreter behavior to be. -- boB From robertvstepp at gmail.com Sun Apr 26 15:17:58 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 26 Apr 2020 14:17:58 -0500 Subject: [Tutor] OT (probably): How to change default tab key value to 4 spaces in GNOME Terminal? In-Reply-To: References: Message-ID: On Sun, Apr 26, 2020 at 1:21 AM Alan Gauld via Tutor wrote: > > On 26/04/2020 05:10, boB Stepp wrote: > > > > > After some searching online the best advice I could find was to enter > > at the command prompt "tabs -4". I tried this and as far as I can > > tell it did not work for me while in the Python interpreter. > > tab behaviour is highly problematical within terminals and programs. > You may find that changing your terminal emulator works as expected. > I seem to recall you use Solaris? ... Alan, I only use Solaris at work. I use Linux Mint at home. And I use Windows when I have to in both locations. > But many apps, especially those using curses will have their own tab > behaviour too. (vim is a classic example that ignores/overrides the > terminal settings) I vaguely was aware of this, but until this thread developed I had not realized how much about the terminal that I used to be at least aware of I had forgotten. Of course I know about Vim/vi because I use that all the time. > This is one reason I never use tabs for formatting code! I normally in applications have expand to (usually 4) spaces. But in the interpreter run from the shell I had not given any thought to tabs other than they were annoyingly shifting by 8 columns. So I am curious. Do you normally in the interpreter manually hit the space bar 4 times instead of ? -- boB From robertvstepp at gmail.com Sun Apr 26 15:36:04 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 26 Apr 2020 14:36:04 -0500 Subject: [Tutor] OT (probably): How to change default tab key value to 4 spaces in GNOME Terminal? In-Reply-To: References: Message-ID: On Sun, Apr 26, 2020 at 4:02 AM Peter Otten <__peter__ at web.de> wrote: > With readline you can do > > import readline > readline.parse_and_bind("TAB: ' '") > > but then you lose tab-completion (which you don't seem to use anyway). Hah! Silly boB was not even aware that he had access to it! See my response to Alan. > An alternative might be to keep autocompletion and bind 4-space indent to > another key: > > readline.parse_and_bind("TAB: complete") > readline.parse_and_bind("C-h: ' '") # Control-h Well, Peter, you have opened up quite the educational experience for me last night and today! While looking at the docs for readline I found a link to the GNU Readline Library (https://tiswww.cwru.edu/php/chet/readline/rluserman.html#SEC9). I have no idea why my searching yesterday did not bring up a link to this. I used to be aware of some of the things mentioned, like the Emacs keybindings some of which I routinely used. And I recall (quite vaguely) that there was a way to have the terminal use vi keybindings instead, but I did not know the way ... now I do. And I was totally unaware of the Python readline and rlcompleter libraries and what they do to make the Python interpreter do its stuff. So now I must rethink what I have been doing. An obvious first step would seem to be using vi keybindings in the terminal. I'm not sure yet how the interpreter would then behave. Hopefully it won't mind and give me the behaviors I expect from vi keybindings. But I won't know for sure until I try it (or investigate the source). In vi's insert mode C-t inserts a tab. Now how do I get that to expand to 4 spaces without interfering with tab completion. On to your next response! -- boB From robertvstepp at gmail.com Sun Apr 26 15:40:02 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 26 Apr 2020 14:40:02 -0500 Subject: [Tutor] OT (probably): How to change default tab key value to 4 spaces in GNOME Terminal? In-Reply-To: References: Message-ID: On Sun, Apr 26, 2020 at 4:18 AM Peter Otten <__peter__ at web.de> wrote: > > Peter Otten wrote: > > > With readline you can do > > > > import readline > > readline.parse_and_bind("TAB: ' '") > > The moment I sent that suggestion I had a clever idea (I thought): Change > Python's completer to insert 4 spaces if there's no text to complete yet. > > But then I saw that this is already implemented for interpreters newer than > my aging default 3.4: > > [rlcomplete.py] > if not text.strip(): > if state == 0: > if _readline_available: > readline.insert_text('\t') > readline.redisplay() > return '' > else: > return '\t' > > You might try replacing the '\t's with ' ' though. Do you mean replace "\t" within rlcomplete.py? -- boB From __peter__ at web.de Sun Apr 26 16:02:04 2020 From: __peter__ at web.de (Peter Otten) Date: Sun, 26 Apr 2020 22:02:04 +0200 Subject: [Tutor] OT (probably): How to change default tab key value to 4 spaces in GNOME Terminal? References: Message-ID: boB Stepp wrote: > On Sun, Apr 26, 2020 at 4:18 AM Peter Otten <__peter__ at web.de> wrote: >> >> Peter Otten wrote: >> >> > With readline you can do >> > >> > import readline >> > readline.parse_and_bind("TAB: ' '") >> >> The moment I sent that suggestion I had a clever idea (I thought): Change >> Python's completer to insert 4 spaces if there's no text to complete yet. >> >> But then I saw that this is already implemented for interpreters newer >> than my aging default 3.4: >> >> [rlcomplete.py] >> if not text.strip(): >> if state == 0: >> if _readline_available: >> readline.insert_text('\t') >> readline.redisplay() >> return '' >> else: >> return '\t' >> >> You might try replacing the '\t's with ' ' though. > > Do you mean replace "\t" within rlcomplete.py? Yes. If you are ambitious you can check `text` for the number of spaces and calculate the number of spaces necessary to bring you to the next multiple of four. Keep a copy of the original file in case you mess up, or do the right thing and write your own subclass in a separate module and override the complete() method there. See the bottom of rlcomplete.py to learn how to install your custom Completer. From akleider at sonic.net Sun Apr 26 17:28:15 2020 From: akleider at sonic.net (Alex Kleider) Date: Sun, 26 Apr 2020 14:28:15 -0700 Subject: [Tutor] OT (probably): How to change default tab key value to 4 spaces in GNOME Terminal? In-Reply-To: References: Message-ID: <7b3a616a8a4c447e4b859eb252f47a60@sonic.net> On 2020-04-26 12:36, boB Stepp wrote: > In vi's insert mode C-t inserts a tab. Now how do I get that to > expand to 4 spaces without interfering with tab completion. On to > your next response! What follows are the first few lines in my ~/.vimrc file. They might help you get Vim to give you 4 spaces in response to the tab key at the beginning of a line. set autoindent set shiftwidth=4 set expandtab set tabstop=4 set softtabstop=4 set textwidth=70 From jf_byrnes at comcast.net Sun Apr 26 17:13:40 2020 From: jf_byrnes at comcast.net (Jim) Date: Sun, 26 Apr 2020 16:13:40 -0500 Subject: [Tutor] Parsing email headers Message-ID: OS = linux Mint 18,xx This may be a little OT, as I am as interested in the process leading up to parsing the header as I am in the results of parsing it. What I want to do is figure out where an email came from without actually opening it. We all get possible malicious emails. Some are obvious but some look pretty real. Many times the From line just says "Google" or "Chase", etc. I wrote a little bare bones script that will print out the From:, Return-Path: and the Sender: names from the header. Right now using Thunderbird, I right-click on the email in question. Then I click Save As and give it a name. It is then saved as a .eml file. Then I give the file name to my script and see the header info. I worry about discarding a legitimate email or getting some type infection by opening an email to check if it is legitimate. So am I protecting myself with the above procedure or will the above procedure still subject me to risks of opening a bad email? Right now it is a fairly manual process. If it is worth while I would like to spend the time making it a one click process if possible. Thanks, Jim From upwkwd at gmail.com Sun Apr 26 11:30:40 2020 From: upwkwd at gmail.com (shubham sinha) Date: Sun, 26 Apr 2020 21:00:40 +0530 Subject: [Tutor] positional argument error Message-ID: hello, I am new to python and as a doing excercise I got an error that is mentioned below: please help me through that. q. create a "word cloud" from a text by writing a script. This script needs to process the text, remove punctuation, ignore case and words that do not contain all alphabets, count the frequencies, and ignore uninteresting or irrelevant words. A dictionary is the output of the calculate_frequencies function. my code: def calculate_frequencies(file_contents): # Here is a list of punctuations and uninteresting words you can use to process your text punctuations = '''!()-[]{};:'"\,<>./?@#$%^&*_~''' uninteresting_words = ["the", "a", "to", "if", "is", "it", "of", "and", "or", "an", "as", "i", "me", "my", \ "we", "our", "ours", "you", "your", "yours", "he", "she", "him", "his", "her", "hers", "its", "they", "them", \ "their", "what", "which", "who", "whom", "this", "that", "am", "are", "was", "were", "be", "been", "being", \ "have", "has", "had", "do", "does", "did", "but", "at", "by", "with", "from", "here", "when", "where", "how", \ "all", "any", "both", "each", "few", "more", "some", "such", "no", "nor", "too", "very", "can", "will", "just"] # LEARNER CODE START HERE result = {} contents_split = file_contents.split() def generate_from_frequencies(file_contents): for word in contents_split: if word in uninteresting_words: pass else: for letter in word: if letter in puctuations: letter.replace(punctuations, "") if word not in result.keys(): result[word] = 0 else: result[word] +=1 #wordcloud cloud = wordcloud.WordCloud() cloud.generate_from_frequencies() return cloud.to_array() #wordcloud cloud = wordcloud.WordCloud() cloud.generate_from_frequencies() return cloud.to_array() # Display your wordcloud image myimage = calculate_frequencies(file_contents) plt.imshow(myimage, interpolation = 'nearest') plt.axis('off') plt.show() After executing i am getting an error: ---------------------------------------------------------------------------TypeError Traceback (most recent call last) in 1 # Display your wordcloud image 2 ----> 3 myimage = calculate_frequencies(file_contents) 4 plt.imshow(myimage, interpolation = 'nearest') 5 plt.axis('off') in calculate_frequencies(file_contents) 27 #wordcloud 28 cloud = wordcloud.WordCloud()---> 29 cloud.generate_from_frequencies() 30 return cloud.to_array() TypeError: generate_from_frequencies() missing 1 required positional argument: 'frequencies' Thanks in advance, :) From PyTutor at danceswithmice.info Sun Apr 26 18:42:01 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Mon, 27 Apr 2020 10:42:01 +1200 Subject: [Tutor] OT (probably): How to change default tab key value to 4 spaces in GNOME Terminal? In-Reply-To: References: Message-ID: <6d56b04c-348f-1036-b776-634a546163f4@DancesWithMice.info> On 27/04/20 8:02 AM, Peter Otten wrote: > boB Stepp wrote: >> On Sun, Apr 26, 2020 at 4:18 AM Peter Otten <__peter__ at web.de> wrote: >>> Peter Otten wrote: >>> But then I saw that this is already implemented for interpreters newer >>> than my aging default 3.4: >>> >>> [rlcomplete.py] >>> if not text.strip(): >>> if state == 0: >>> if _readline_available: >>> readline.insert_text('\t') >>> readline.redisplay() >>> return '' >>> else: >>> return '\t' ... > Keep a copy of the original file in case you mess up, or do the right thing > and write your own subclass in a separate module and override the complete() > method there. See the bottom of rlcomplete.py to learn how to install your > custom Completer. Definitely sub-class it! Is there a risk that a Python-update (plus PSL) might over-write? Would it be necessary to place all such code and settings in user-space, and 'point' to it using PYTHONSTARTUP (or similar/better)? This whole area is not something I've looked at, glossing right-over in favor of typing "python3 [file/dirNM]" and enjoying the plain-vanilla flavor. However, the idea of modifying the prompts and improving the tab-spacing would offer considerable advantages when it comes to presenting example-code, eg consistency, auto-magic version-labelling/dating for currency-context, more compact... Keep it going guys! -- Regards =dn From mats at wichmann.us Sun Apr 26 19:08:05 2020 From: mats at wichmann.us (Mats Wichmann) Date: Sun, 26 Apr 2020 17:08:05 -0600 Subject: [Tutor] positional argument error In-Reply-To: References: Message-ID: <1f6ed58f-fd7e-a675-7fe1-c9ac7cbd4301@wichmann.us> On 4/26/20 9:30 AM, shubham sinha wrote: > hello, > I am new to python and as a doing excercise I got an error that is > mentioned below: > please help me through that. > > q. create a "word cloud" from a text by writing a script. This script needs > to process the text, remove punctuation, ignore case and words that do not > contain all alphabets, count the frequencies, and ignore uninteresting or > irrelevant words. A dictionary is the output of the calculate_frequencies > function. > > my code: > > def generate_from_frequencies(file_contents): That function is declared to need an argument. Except: > cloud = wordcloud.WordCloud() > cloud.generate_from_frequencies() you call it without an argument. Further, it looks like it was actually a method in a class, because of the way you call it - but there is no class definition in what you included, so we can't really untangle this for you completely. Even stranger, a thing called file_contents is referenced _outside_ the function, which isn't going to work However the error is pretty clear: > TypeError: generate_from_frequencies() missing 1 required positional > argument: 'frequencies' you needed to call it with an argument and you didn't. From PyTutor at danceswithmice.info Sun Apr 26 19:08:05 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Mon, 27 Apr 2020 11:08:05 +1200 Subject: [Tutor] Parsing email headers In-Reply-To: References: Message-ID: <68f6b494-3298-2d0a-eab8-e3dbe816ed39@DancesWithMice.info> On 27/04/20 9:13 AM, Jim wrote: > What I want to do is figure out where an email came from without > actually opening it. We all get possible malicious emails. Some are > obvious but some look pretty real. Many times the From line just says > "Google" or "Chase", etc.? I wrote a little bare bones script that will > print out the From:, Return-Path: and the Sender: names from the header. > > Right now using Thunderbird, I right-click on the email in question. > Then I click Save As and give it a name. It is then saved as a .eml > file. Then I give the file name to my script and see the header info. > > I worry about discarding a legitimate email or getting some type > infection by opening an email to check if it is legitimate. So am I > protecting myself with the above procedure or will the above procedure > still subject me to risks of opening a bad email? > > Right now it is a fairly manual process. If it is worth while I would > like to spend the time making it a one click process if possible. Have you seen the PSL's imaplib ? IMAP4 protocol client? With appropriate coding, this would save the manual effort by enabling direct access to the server. Sadly, you may need to tangle with whatever security/encryption is used by the email server. It would give the opportunity to move msgs from INBOX to a Junk folder or similar - rather than deleting any false-negatives, per your concern! OT: Yes, be aware (if you are not already) that many headers can be "spoofed" and thus email can be made to come from one place/person but actually originates elsewhere, eg a spammer. So, even if the header says 'whitehouse.gov', it may not be true! Notes: - suggested IMAP rather than POP because you might want to [re]move 'the bad stuff' but not the 'good'. This further implies that either you are using IMAP with Thunderbird, or that the 'filter program' would have to be run before Thunderbird is started (and Tb's regular 'Get messages' function switched off. IMAP stores msg on the server POP downloads msgs and stores them 'in Thunderbird' on the client PSL = Python Standard Library WebRef: https://docs.python.org/3.8/library/imaplib.html -- Regards =dn From alan.gauld at yahoo.co.uk Sun Apr 26 19:21:09 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 27 Apr 2020 00:21:09 +0100 Subject: [Tutor] OT (probably): How to change default tab key value to 4 spaces in GNOME Terminal? In-Reply-To: References: Message-ID: On 26/04/2020 20:17, boB Stepp wrote: > am curious. Do you normally in the interpreter manually hit the space > bar 4 times instead of ? Nope, in a terminal interpreter I use one or two space indentation. The style PEP is intended for written code modules not ad-hoc interpreter sessions. If I'm doing a long interpreter session I use IDLE which takes care of indentation for me in most scenarios. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From cs at cskk.id.au Sun Apr 26 19:24:03 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Mon, 27 Apr 2020 09:24:03 +1000 Subject: [Tutor] Parsing email headers In-Reply-To: References: Message-ID: <20200426232403.GA80286@cskk.homeip.net> On 26Apr2020 16:13, jim wrote: >OS = linux Mint 18,xx > >This may be a little OT, as I am as interested in the process leading >up to parsing the header as I am in the results of parsing it. > >What I want to do is figure out where an email came from without >actually opening it. We all get possible malicious emails. Some are >obvious but some look pretty real. Many times the From line just says >"Google" or "Chase", etc. I wrote a little bare bones script that >will print out the From:, Return-Path: and the Sender: names from the >header. Python has a pretty full email parsing library. Trite example assuming you have the message in a file: import email with open(email_message_file) as f: message = email.Parser.Parser(f) That gets you a Message object in "message", with ready access to the headers and many other facilities. You're probably interesting in the Received: headers (any of which may be forged of course). DL Neil has pointed you at the imap and pop libraries available if you want to write stuff to connect to your mailbox over the net. Cheers, Cameron Simpson From mats at wichmann.us Sun Apr 26 19:25:20 2020 From: mats at wichmann.us (Mats Wichmann) Date: Sun, 26 Apr 2020 17:25:20 -0600 Subject: [Tutor] Parsing email headers In-Reply-To: References: Message-ID: <0ce8dcd2-1ecf-8290-3809-40da929651ac@wichmann.us> On 4/26/20 3:13 PM, Jim wrote: > OS = linux Mint 18,xx > > This may be a little OT, as I am as interested in the process leading up > to parsing the header as I am in the results of parsing it. > > What I want to do is figure out where an email came from without > actually opening it. We all get possible malicious emails. Some are > obvious but some look pretty real. Many times the From line just says > "Google" or "Chase", etc.? I wrote a little bare bones script that will > print out the From:, Return-Path: and the Sender: names from the header. you're going to have to dig deeper than that for reliability... > Right now using Thunderbird, I right-click on the email in question. > Then I click Save As and give it a name. It is then saved as a .eml > file. Then I give the file name to my script and see the header info. > > I worry about discarding a legitimate email or getting some type > infection by opening an email to check if it is legitimate. So am I > protecting myself with the above procedure or will the above procedure > still subject me to risks of opening a bad email? > > Right now it is a fairly manual process. If it is worth while I would > like to spend the time making it a one click process if possible. I'm not sure you can easily do this any longer in a way that integrates with Thunderbird... waiting for a barrage of comments to "use Mutt instead", etc. After Mozilla changed the way plugins are authorized to work, I think the work which let Python integrate with it was lost - at least *I* can't find anything, which doesn't count for much. If you're willing to work outside of Thunderbird, the story improves. From alan.gauld at yahoo.co.uk Sun Apr 26 19:25:58 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 27 Apr 2020 00:25:58 +0100 Subject: [Tutor] OT (probably): How to change default tab key value to 4 spaces in GNOME Terminal? In-Reply-To: <7b3a616a8a4c447e4b859eb252f47a60@sonic.net> References: <7b3a616a8a4c447e4b859eb252f47a60@sonic.net> Message-ID: On 26/04/2020 22:28, Alex Kleider wrote: > On 2020-04-26 12:36, boB Stepp wrote: >> In vi's insert mode C-t inserts a tab. Now how do I get that to >> expand to 4 spaces without interfering with tab completion. On to >> your next response! > > What follows are the first few lines in my ~/.vimrc file. > They might help you get Vim to give you 4 spaces in response to the tab > key at the beginning of a line. > > set autoindent > set shiftwidth=4 > set expandtab > set tabstop=4 > set softtabstop=4 > set textwidth=70 Yes, but those are only read by vim. The readline library/bash shell only provides a vi keystroke emulation, it doesn't read the vimrc file. (At least I'm pretty sure it doesn't!) There may be equivalent settings you can use for readline (in the bashrc file maybe?) -- 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 PyTutor at danceswithmice.info Sun Apr 26 19:33:07 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Mon, 27 Apr 2020 11:33:07 +1200 Subject: [Tutor] Pygame environment In-Reply-To: <9B1AB5E3-8B27-4529-A1E3-C1F947285930@gmail.com> References: <9B1AB5E3-8B27-4529-A1E3-C1F947285930@gmail.com> Message-ID: <4a7701f7-3b95-bf7e-715e-c97299aa1d32@DancesWithMice.info> On 26/04/20 9:42 PM, Cravan wrote: > Hi could I ask if I want to implement an ai in my code how should I pass on my current environment to it? Would import (e.g. import * from blah.py) be sufficient? Or do I have to type env = python.learning.environment in order to do so? Probably insufficient information to offer advice. What do you mean by "current environment"? System, application, command-line configurations, ...??? Python's way of 'combining' modules is import. The usual pattern is to have a 'main' program which "calls" functions and uses classes that have been import-ed from other modules. -- Regards =dn From robertvstepp at gmail.com Sun Apr 26 19:41:41 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 26 Apr 2020 18:41:41 -0500 Subject: [Tutor] OT (probably): How to change default tab key value to 4 spaces in GNOME Terminal? In-Reply-To: References: <7b3a616a8a4c447e4b859eb252f47a60@sonic.net> Message-ID: On Sun, Apr 26, 2020 at 6:30 PM Alan Gauld via Tutor wrote: > > On 26/04/2020 22:28, Alex Kleider wrote: > > On 2020-04-26 12:36, boB Stepp wrote: > >> In vi's insert mode C-t inserts a tab. Now how do I get that to > >> expand to 4 spaces without interfering with tab completion. On to > >> your next response! > > > > What follows are the first few lines in my ~/.vimrc file. > > They might help you get Vim to give you 4 spaces in response to the tab > > key at the beginning of a line. > > > > set autoindent > > set shiftwidth=4 > > set expandtab > > set tabstop=4 > > set softtabstop=4 > > set textwidth=70 > > Yes, but those are only read by vim. > The readline library/bash shell only provides a vi keystroke > emulation, it doesn't read the vimrc file. (At least I'm pretty > sure it doesn't!) > > There may be equivalent settings you can use for readline > (in the bashrc file maybe?) In the GNU Readline Library docs at https://tiswww.cwru.edu/php/chet/readline/rluserman.html#SEC9 it discusses how to set vi-mode and configure a bunch of stuff. I figure this will be the way to go into a vi keybinding direction. Since the default configuration is emacs-mode, last night I played around in the Python interpreter and verified that those Emacs keybindings that are configured for the terminal by default (not all are the docs say) worked fine at the Python prompt. So I have high hopes that if I switch to vi-mode that the same will occur. Anyway GNU Readlines looks for a .inputrc file for these configurations. Like many terminal things it does not exist by default, you have to create and populate it with your desired settings. I have to say one great thing (amongst many) about *nix -- the devs that created all of this are nothing if not *consistent* in how they implement things! -- boB From savageapple850 at gmail.com Sun Apr 26 19:42:20 2020 From: savageapple850 at gmail.com (Cravan) Date: Mon, 27 Apr 2020 07:42:20 +0800 Subject: [Tutor] Pygame environment In-Reply-To: <4a7701f7-3b95-bf7e-715e-c97299aa1d32@DancesWithMice.info> References: <9B1AB5E3-8B27-4529-A1E3-C1F947285930@gmail.com> <4a7701f7-3b95-bf7e-715e-c97299aa1d32@DancesWithMice.info> Message-ID: <26AF7CC5-1925-4FE5-8FE9-CCAA7B668084@gmail.com> Hi DL Neil, In reinforcement learning, the "environment" is typically a set of states the "agent" is attempting to influence via its choice of actions, and the agent is the executer of certain actions which bring about certain rewards/punishments. I'm not sure if the import module will be sufficient to send over these states (partly because I have been reading up on openai Gym documentation which also sets the environment first) Cravan ?On 27/4/20, 7:35 AM, "Tutor on behalf of DL Neil via Tutor" wrote: On 26/04/20 9:42 PM, Cravan wrote: > Hi could I ask if I want to implement an ai in my code how should I pass on my current environment to it? Would import (e.g. import * from blah.py) be sufficient? Or do I have to type env = python.learning.environment in order to do so? Probably insufficient information to offer advice. What do you mean by "current environment"? System, application, command-line configurations, ...??? Python's way of 'combining' modules is import. The usual pattern is to have a 'main' program which "calls" functions and uses classes that have been import-ed from other modules. -- Regards =dn _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From joel.goldstick at gmail.com Sun Apr 26 19:45:50 2020 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Sun, 26 Apr 2020 19:45:50 -0400 Subject: [Tutor] Parsing email headers In-Reply-To: <68f6b494-3298-2d0a-eab8-e3dbe816ed39@DancesWithMice.info> References: <68f6b494-3298-2d0a-eab8-e3dbe816ed39@DancesWithMice.info> Message-ID: On Sun, Apr 26, 2020 at 7:09 PM DL Neil via Tutor wrote: > > On 27/04/20 9:13 AM, Jim wrote: > > What I want to do is figure out where an email came from without > > actually opening it. We all get possible malicious emails. Some are > > obvious but some look pretty real. Many times the From line just says > > "Google" or "Chase", etc. I wrote a little bare bones script that will > > print out the From:, Return-Path: and the Sender: names from the header. > > > > Right now using Thunderbird, I right-click on the email in question. > > Then I click Save As and give it a name. It is then saved as a .eml > > file. Then I give the file name to my script and see the header info. > > > > I worry about discarding a legitimate email or getting some type > > infection by opening an email to check if it is legitimate. So am I > > protecting myself with the above procedure or will the above procedure > > still subject me to risks of opening a bad email? > > > > Right now it is a fairly manual process. If it is worth while I would > > like to spend the time making it a one click process if possible. > > Have you seen the PSL's imaplib ? IMAP4 protocol client? With > appropriate coding, this would save the manual effort by enabling direct > access to the server. > > Sadly, you may need to tangle with whatever security/encryption is used > by the email server. > > It would give the opportunity to move msgs from INBOX to a Junk folder > or similar - rather than deleting any false-negatives, per your concern! > > OT: Yes, be aware (if you are not already) that many headers can be > "spoofed" and thus email can be made to come from one place/person but > actually originates elsewhere, eg a spammer. So, even if the header says > 'whitehouse.gov', it may not be true! totally OT, some might say that anything that comes from 'whitehouse.gov' is never true. Sorry ;) > > > Notes: > - suggested IMAP rather than POP because you might want to [re]move 'the > bad stuff' but not the 'good'. This further implies that either you are > using IMAP with Thunderbird, or that the 'filter program' would have to > be run before Thunderbird is started (and Tb's regular 'Get messages' > function switched off. > > IMAP stores msg on the server > > POP downloads msgs and stores them 'in Thunderbird' on the client > > PSL = Python Standard Library > > > WebRef: > https://docs.python.org/3.8/library/imaplib.html > -- > Regards =dn > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor -- Joel Goldstick http://joelgoldstick.com/blog http://cc-baseballstats.info/stats/birthdays From david at graniteweb.com Sun Apr 26 19:59:13 2020 From: david at graniteweb.com (David Rock) Date: Sun, 26 Apr 2020 18:59:13 -0500 Subject: [Tutor] Parsing email headers In-Reply-To: <0ce8dcd2-1ecf-8290-3809-40da929651ac@wichmann.us> References: <0ce8dcd2-1ecf-8290-3809-40da929651ac@wichmann.us> Message-ID: <20200426235913.GV31606@apple.graniteweb.com> * Mats Wichmann [2020-04-26 17:25]: > > I'm not sure you can easily do this any longer in a way that integrates > with Thunderbird... waiting for a barrage of comments to "use Mutt > instead", etc. After Mozilla changed the way plugins are authorized to Use mutt instead :-) But more seriously, even mutt doesn't magically fix much for you. It does mail reading exceptionally well, but it does NOT do filtering. You'd still have to write something to interface with through the interface. The main benefit you get from a terminal-based email client is it doesn't inherently expose you "accidental opens" the way a GUI program does (most exposures expect an environment in which to run; mutt, pine, elm, etc don't provide that environment). It sounds like what you are really looking for is pre-filter to run through your mail first. It would probably be a better option to look into leveraging something like spamassassin. Purpose-built tools for evaluating spam are almost certainly going to be more robust. -- David Rock david at graniteweb.com From matthew.herzog at gmail.com Sun Apr 26 21:46:11 2020 From: matthew.herzog at gmail.com (Matthew Herzog) Date: Sun, 26 Apr 2020 21:46:11 -0400 Subject: [Tutor] need help writing subprocess output to file(s) Message-ID: Hi all. I have to run a utility (sdptool) that checks the firmware versions on >500 servers. What I pasted below works but the stdout needs to be written to a file, one per IP address. How do I capture the stdout to files? Even a single logfile would work. Thanks. #!/usr/bin/python3 import subprocess with open("ips.txt") as ip_list: ips = ip_list.readlines() for ip in ips: output = subprocess.Popen(["/opt/bin/sdptool", ip, "check"]) From cs at cskk.id.au Sun Apr 26 22:20:56 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Mon, 27 Apr 2020 12:20:56 +1000 Subject: [Tutor] need help writing subprocess output to file(s) In-Reply-To: References: Message-ID: <20200427022056.GA19907@cskk.homeip.net> On 26Apr2020 21:46, Matthew Herzog wrote: >I have to run a utility (sdptool) that checks the firmware versions on >>500 >servers. >What I pasted below works but the stdout needs to be written to a file, one >per IP address. >How do I capture the stdout to files? Even a single logfile would work. >Thanks. > >#!/usr/bin/python3 >import subprocess > >with open("ips.txt") as ip_list: > ips = ip_list.readlines() > >for ip in ips: > output = subprocess.Popen(["/opt/bin/sdptool", ip, "check"]) Something like this: for ip in ips: with open(op + '.out', 'w') as output: output = subprocess.Popen(["/opt/bin/sdptool", ip, "check"], stdout=output) which will open an output file and pass it (still open, important) to Popen for use as stdout. Cheers, Cameron Simpson From robertvstepp at gmail.com Mon Apr 27 00:07:22 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 26 Apr 2020 23:07:22 -0500 Subject: [Tutor] Fwd: OT (probably): How to change default tab key value to 4 spaces in GNOME Terminal? In-Reply-To: References: Message-ID: OK, I believe that I have a solution that I can live with. On 4/26/20 4:02 AM, Peter Otten wrote: > boB Stepp wrote: > With readline you can do > > import readline > readline.parse_and_bind("TAB: ' '") > > but then you lose tab-completion (which you don't seem to use anyway). > An alternative might be to keep autocompletion and bind 4-space indent to > another key: > > readline.parse_and_bind("TAB: complete") > readline.parse_and_bind("C-h: ' '") # Control-h I used Peter's latter thought of binding four spaces to a key. My .pythonstartup file now looks like this: """Configure prompt appearance in Python REPL.""" import readline import sys # Use control-t to insert 4 spaces readline.parse_and_bind("C-t:' '") py_version = sys.version.split()[0] sys.ps1 = py_version + ": " # Ensure cursor lines up with previous line of code: sys.ps2 = "..." + " " * (len(sys.ps1) - 3) In any terminal relying on the GNU Readline Library (again see https://tiswww.cwru.edu/php/chet/readline/rluserman.html#SEC_Top) C-t is bound to the action to transpose two characters. I would hardly ever use this, so I am willing to give up that functionality in the Python interpreter. This now gives me what I want. The earlier (in this thread) example now looks like: 3.7.5: def f(s): ... print(s) ... 3.7.5: f("Jeremy") Jeremy which is exactly how I want it. As a side note if I do the same copy/paste into Google Gmail the "p" in print lines up under the "d" in "def". This is not what is in my terminal and, for me, this is the last straw on using Gmail's web-based email editor. If it won't accurately render a copy/paste operation I am not going to tolerate it any longer. I am currently using Thunderbird to type this as it is already installed on my PC. When I get time I will have to get it configured like I want it after which I will say bye to Google's Gmail editor. And perhaps later I will abandon Gmail altogether. But that is a battle for later, too. I did go ahead and create a .inputrc file in my home directory. Right now it is quite simple: set editing-mode vi As I normally use Neovim/Vim/vi (depending on what computer I am on) as my editor, I think I will like this. Normally in vi C-t when in insert mode would insert a tab character. In my GNOME Terminal C-t still transposes two characters despite otherwise being in vi-mode. There is probably a way to change this, but in the link above they only have the briefest of descriptions of vi-mode. There is probably another docs page somewhere that will give me the information I need to have C-t universally insert 4 spaces, but I will save that battle for another day. To dn: Sorry! No subclassing today. ~(:>)) Cheers! boB -- boB From jf_byrnes at comcast.net Sun Apr 26 20:26:22 2020 From: jf_byrnes at comcast.net (Jim) Date: Sun, 26 Apr 2020 19:26:22 -0500 Subject: [Tutor] Parsing email headers In-Reply-To: <68f6b494-3298-2d0a-eab8-e3dbe816ed39@DancesWithMice.info> References: <68f6b494-3298-2d0a-eab8-e3dbe816ed39@DancesWithMice.info> Message-ID: On 4/26/20 6:08 PM, DL Neil via Tutor wrote: > On 27/04/20 9:13 AM, Jim wrote: >> What I want to do is figure out where an email came from without >> actually opening it. We all get possible malicious emails. Some are >> obvious but some look pretty real. Many times the From line just says >> "Google" or "Chase", etc.? I wrote a little bare bones script that >> will print out the From:, Return-Path: and the Sender: names from the >> header. >> >> Right now using Thunderbird, I right-click on the email in question. >> Then I click Save As and give it a name. It is then saved as a .eml >> file. Then I give the file name to my script and see the header info. >> >> I worry about discarding a legitimate email or getting some type >> infection by opening an email to check if it is legitimate. So am I >> protecting myself with the above procedure or will the above procedure >> still subject me to risks of opening a bad email? >> >> Right now it is a fairly manual process. If it is worth while I would >> like to spend the time making it a one click process if possible. > > Have you seen the PSL's imaplib ? IMAP4 protocol client? With > appropriate coding, this would save the manual effort by enabling direct > access to the server. > > Sadly, you may need to tangle with whatever security/encryption is used > by the email server. > > It would give the opportunity to move msgs from INBOX to a Junk folder > or similar - rather than deleting any false-negatives, per your concern! I didn't know about it. I was focused on the mail sitting in my inbox. > OT: Yes, be aware (if you are not already) that many headers can be > "spoofed" and thus email can be made to come from one place/person but > actually originates elsewhere, eg a spammer. So, even if the header says > 'whitehouse.gov', it may not be true! Yeah I understand that. I am just looking for a safe way to look behind the Comcast Tech Support displayed by Thunderbird and see it is from vadamir at someisp.ru. > > Notes: > - suggested IMAP rather than POP because you might want to [re]move 'the > bad stuff' but not the 'good'. This further implies that either you are > using IMAP with Thunderbird, or that the 'filter program' would have to > be run before Thunderbird is started (and Tb's regular 'Get messages' > function switched off. > > IMAP stores msg on the server > > POP downloads msgs and stores them 'in Thunderbird' on the client > > PSL = Python Standard Library > > > WebRef: > https://docs.python.org/3.8/library/imaplib.html I am using IMAP. Thanks, Jim From jf_byrnes at comcast.net Sun Apr 26 20:36:45 2020 From: jf_byrnes at comcast.net (Jim) Date: Sun, 26 Apr 2020 19:36:45 -0500 Subject: [Tutor] Parsing email headers In-Reply-To: <20200426232403.GA80286@cskk.homeip.net> References: <20200426232403.GA80286@cskk.homeip.net> Message-ID: On 4/26/20 6:24 PM, Cameron Simpson wrote: > On 26Apr2020 16:13, jim wrote: >> OS = linux Mint 18,xx >> >> This may be a little OT, as I am as interested in the process leading >> up to parsing the header as I am in the results of parsing it. >> >> What I want to do is figure out where an email came from without >> actually opening it. We all get possible malicious emails. Some are >> obvious but some look pretty real. Many times the From line just says >> "Google" or "Chase", etc.? I wrote a little bare bones script that >> will print out the From:, Return-Path: and the Sender: names from the >> header. > > Python has a pretty full email parsing library. Trite example assuming > you have the message in a file: > > ?? import email > ?? with open(email_message_file) as f: > ???? message = email.Parser.Parser(f) > > That gets you a Message object in "message", with ready access to the > headers and many other facilities. > > You're probably interesting in the Received: headers (any of which may > be forged of course). > > DL Neil has pointed you at the imap and pop libraries available if you > want to write stuff to connect to your mailbox over the net. I found that library and I found an example in the docs that looked like someone wrote just for my use case. I guess the bigger question for me is, am I being safer doing this or am I just fooling myself. If the email was malicious and it was going to drop a payload on me if I opened would doing what I outlined keep it from happening? Thanks, Jim From jf_byrnes at comcast.net Sun Apr 26 20:43:35 2020 From: jf_byrnes at comcast.net (Jim) Date: Sun, 26 Apr 2020 19:43:35 -0500 Subject: [Tutor] Parsing email headers In-Reply-To: <0ce8dcd2-1ecf-8290-3809-40da929651ac@wichmann.us> References: <0ce8dcd2-1ecf-8290-3809-40da929651ac@wichmann.us> Message-ID: On 4/26/20 6:25 PM, Mats Wichmann wrote: > On 4/26/20 3:13 PM, Jim wrote: >> OS = linux Mint 18,xx >> >> This may be a little OT, as I am as interested in the process leading up >> to parsing the header as I am in the results of parsing it. >> >> What I want to do is figure out where an email came from without >> actually opening it. We all get possible malicious emails. Some are >> obvious but some look pretty real. Many times the From line just says >> "Google" or "Chase", etc.? I wrote a little bare bones script that will >> print out the From:, Return-Path: and the Sender: names from the header. > > you're going to have to dig deeper than that for reliability... I know I can't foil anything really sophisticated but many of them are nothing more than making Thunderbird display a known entity but behind the scenes it's a gmail account. > >> Right now using Thunderbird, I right-click on the email in question. >> Then I click Save As and give it a name. It is then saved as a .eml >> file. Then I give the file name to my script and see the header info. >> >> I worry about discarding a legitimate email or getting some type >> infection by opening an email to check if it is legitimate. So am I >> protecting myself with the above procedure or will the above procedure >> still subject me to risks of opening a bad email? >> >> Right now it is a fairly manual process. If it is worth while I would >> like to spend the time making it a one click process if possible. > > I'm not sure you can easily do this any longer in a way that integrates > with Thunderbird... waiting for a barrage of comments to "use Mutt > instead", etc. After Mozilla changed the way plugins are authorized to > work, I think the work which let Python integrate with it was lost - at > least *I* can't find anything, which doesn't count for much. > > If you're willing to work outside of Thunderbird, the story improves. I haven't given that a lot of thought yet. If I can't hookup a python script to right click menu then maybe I can use PyAutoGUI. Thanks, Jim From jf_byrnes at comcast.net Sun Apr 26 20:50:25 2020 From: jf_byrnes at comcast.net (Jim) Date: Sun, 26 Apr 2020 19:50:25 -0500 Subject: [Tutor] Parsing email headers In-Reply-To: <20200426235913.GV31606@apple.graniteweb.com> References: <0ce8dcd2-1ecf-8290-3809-40da929651ac@wichmann.us> <20200426235913.GV31606@apple.graniteweb.com> Message-ID: On 4/26/20 6:59 PM, David Rock wrote: > * Mats Wichmann [2020-04-26 17:25]: >> >> I'm not sure you can easily do this any longer in a way that integrates >> with Thunderbird... waiting for a barrage of comments to "use Mutt >> instead", etc. After Mozilla changed the way plugins are authorized to > > Use mutt instead :-) > > But more seriously, even mutt doesn't magically fix much for you. It > does mail reading exceptionally well, but it does NOT do filtering. > You'd still have to write something to interface with through the > interface. > The main benefit you get from a terminal-based email client is it > doesn't inherently expose you "accidental opens" the way a GUI program > does (most exposures expect an environment in which to run; mutt, pine, > elm, etc don't provide that environment). No environment, no problem. I hadn't thought of that. I never use html mail so maybe thats an option. I haven't used a terminal email client since I stopped using OS/2. I think it was called alpine. > It sounds like what you are really looking for is pre-filter to > run through your mail first. It would probably be a better option to > look into leveraging something like spamassassin. Purpose-built tools > for evaluating spam are almost certainly going to be more robust. > No I don't think I want a filter. I'm looking for a safe way to say that I don't think Comcast is sending me a support message using gmail. Thanks, Jim From cs at cskk.id.au Mon Apr 27 06:58:13 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Mon, 27 Apr 2020 20:58:13 +1000 Subject: [Tutor] Parsing email headers In-Reply-To: References: Message-ID: <20200427105813.GA61551@cskk.homeip.net> On 26Apr2020 16:13, jim wrote: >Right now using Thunderbird, I right-click on the email in question. >Then I click Save As and give it a name. It is then saved as a .eml >file. Then I give the file name to my script and see the header info. Just looking at this bit. On Thunderbird here (MacOS) selecting a message and hitting Cmd-U shows me the message source, with headers. That is likely Ctrl-U on Linux. Anyway, if you have an index-only view with no message pane, that might get you the headers without "viewing" the whole thing. I would find eyeballing that easier than your ritual to get the message to a script. Cheers, Cameron Simpson From jf_byrnes at comcast.net Mon Apr 27 12:16:48 2020 From: jf_byrnes at comcast.net (Jim) Date: Mon, 27 Apr 2020 11:16:48 -0500 Subject: [Tutor] Parsing email headers In-Reply-To: <20200427105813.GA61551@cskk.homeip.net> References: <20200427105813.GA61551@cskk.homeip.net> Message-ID: On 4/27/20 5:58 AM, Cameron Simpson wrote: > On 26Apr2020 16:13, jim wrote: >> Right now using Thunderbird, I right-click on the email in question. >> Then I click Save As and give it a name. It is then saved as a .eml >> file. Then I give the file name to my script and see the header info. > > Just looking at this bit. On Thunderbird here (MacOS) selecting a > message and hitting Cmd-U shows me the message source, with headers. > That is likely Ctrl-U on Linux. > > Anyway, if you have an index-only view with no message pane, that might > get you the headers without "viewing" the whole thing. I would find > eyeballing that easier than your ritual to get the message to a script. At first I could not figure out how you could click on a message and not have it open. Then I reread your last paragraph and understood. I normally do have the message pane open. So now if I see a suspicious message I can switch to index-only and follow your advice. I think I will continue to work on the script anyway. I think I can use PyAutoGui and PySimpleGUI to come up with a one click solution. It could be a good learning experience. Thanks, Jim From eryksun at gmail.com Mon Apr 27 15:49:18 2020 From: eryksun at gmail.com (Eryk Sun) Date: Mon, 27 Apr 2020 14:49:18 -0500 Subject: [Tutor] need help writing subprocess output to file(s) In-Reply-To: <20200427022056.GA19907@cskk.homeip.net> References: <20200427022056.GA19907@cskk.homeip.net> Message-ID: On 4/26/20, Cameron Simpson wrote: > > Something like this: > > for ip in ips: > with open(op + '.out', 'w') as output: > output = subprocess.Popen(["/opt/bin/sdptool", ip, "check"], > stdout=output) Typo: "op" -> "ip". I'd replace dots and colons (IPv6) with underscores. In particular, using colon in a filename is problematic if the file ever needs to be accessed in Windows. Colon is reserved by most Windows filesystems, and it's used by NTFS to name file streams (e.g. "filename:streamname:$DATA" and "dirname:$I30:$INDEX_ALLOCATION") [1]. [1]: https://docs.microsoft.com/en-us/windows/win32/fileio/file-streams From PyTutor at DancesWithMice.info Mon Apr 27 18:18:25 2020 From: PyTutor at DancesWithMice.info (DL Neil) Date: Tue, 28 Apr 2020 10:18:25 +1200 Subject: [Tutor] Drawing inside the turtle canvas In-Reply-To: References: Message-ID: <1119d439-3d27-e018-8856-348ee8b3cdc9@DancesWithMice.info> On 28/04/20 6:33 AM, Stefan Ram wrote: > The following program will move the turtle > /out of the visible area/: > > from turtle import * > forward( window_width()/ 2 ) Yes, assuming (as the snippet does) that the turtle is in the vertical center of the window, or further to the right/east. > I would like it to move as far as possible while it is > still completly visible. > > . Apparently, one needs to obtain the current width of the > window border and subtract it from the width. This depends upon how you have defined the window and/or "canvas"* Do you understand the difference between these two terms? Are you using them precisely? It may be helpful to distinguish the drawing-surface, within the window-widget, rather than re-using a term like "window" which has specific meaning in other contexts. > How is this done? The turtle is a 2-D object inside a 2-D window. You know the (central?top-left*) position of the turtle. You know how to measure it, and thus find the size of the drawing-surface. (which can thus be re-expressed as the space between two Coordinates: ( 0, 0 ) and ( drawing_width, drawing_height ). IIRC* the size of the turtle is under programmatic control. So, you now need to find its size. Next, ignore the turtle's appearance, and consider it a rectangle. (x-pixels wide, y-pixels high). Now, with reference to what the turtle reports as its (single-pixel) position, we can 'map' it onto the drawing-surface's 2-D Cartesian space by relating its size to its "position", and expressing that as a rectangle - as per the description (above), use two Coordinates representing its top-left and bottom-right pixels! Thus the turtle occupies a portion of space, a rectangle (of pixels) from ( x1, y1 ) to ( x2, y2 )! Now, we can use algebra and consider each of the four sides in-turn (two-sides per dimension!). Do not worry about the turtle's current position (we assume it is on-screen)! Calculate its next position (after direction and speed/rate) - without regard to the drawing-surface/its edges. (However, do not display the turtle in its new position until we've checked it!) The problem re-stated: If the turtle continues to move at its current rate, in its current direction, would the edge of its space start to run 'off' the edge of the drawing-surface? Remember there are four edges (two each, for two dimensions - um, yes, er, ok!) So we don't talk about THE edge of the drawing-surface (as I did, above) but FOUR separate considerations for four edges: 1 consider the turtle's left-edge in relation to the drawing-surface's left-border: assert x1 > 0 (this zero is the x-origin) 2 consider the turtle's right-edge in relation to the drawing-surface's right-border: assert x2 < drawing_width 3 ...top... 4 ...bottom... If one (or two) of the above conditions are false, modify the turtle's trajectory, as appropriate (and calculate such a modification to its next position prior to display). * apologies, I have only used Python's turtle briefly, and in the context of helping a bunch of kids play with the language. Accordingly, some of the finer details may have slipped my memory since - assuming I ever really knew them! The low-level computer graphics calculations have been applicable, across libraries, translated into various languages, and down through the decades, since character (only) terminals. Silver Surfers rule! Today, they are applicable to tkinter, HTML5 Canvas, JavaScript, etc, etc. NB if you are learning Python, you may find the Python-Tutor list helpful. -- Regards =dn From bouncingcats at gmail.com Mon Apr 27 20:32:49 2020 From: bouncingcats at gmail.com (David) Date: Tue, 28 Apr 2020 10:32:49 +1000 Subject: [Tutor] Fwd: OT (probably): How to change default tab key value to 4 spaces in GNOME Terminal? In-Reply-To: References: Message-ID: On Mon, 27 Apr 2020 at 14:08, boB Stepp wrote: > This now gives me what I want. The earlier (in this thread) example now > looks like: > > 3.7.5: def f(s): > ... print(s) > ... > 3.7.5: f("Jeremy") > Jeremy > > which is exactly how I want it. As a side note if I do the same > copy/paste into Google Gmail the "p" in print lines up under the "d" in > "def". This is not what is in my terminal and, for me, this is the last > straw on using Gmail's web-based email editor. If it won't accurately > render a copy/paste operation I am not going to tolerate it any longer. > I am currently using Thunderbird to type this as it is already installed > on my PC. When I get time I will have to get it configured like I want > it after which I will say bye to Google's Gmail editor. And perhaps > later I will abandon Gmail altogether. But that is a battle for later, too. I expect that the explanation for the different vertical alignment of characters that you see in the gmail web interface, compared to your terminal, is that the gmail interface uses a proportional-spaced font, whereas your terminal likely uses a monospaced font. If you are unaware of the difference, here's a short comparison: https://www.techwalla.com/articles/proportional-vs-monospace-fonts If you want every character to be rendered with an identical width, so that every character appears in a specific vertical column that aligns exactly with characters in lines above and below, then a monospace font must be used to view the text. I am not aware of any method that this can be changed in gmail. If I recall correctly, that if the font settings are changed then it will have the undesirable affect of causing messages to be sent html-formatted instead of plain-text. From robertvstepp at gmail.com Mon Apr 27 22:06:37 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Mon, 27 Apr 2020 21:06:37 -0500 Subject: [Tutor] Fwd: OT (probably): How to change default tab key value to 4 spaces in GNOME Terminal? In-Reply-To: References: Message-ID: On Mon, Apr 27, 2020 at 7:33 PM David wrote: > I expect that the explanation for the different vertical alignment of > characters that you see in the gmail web interface, compared to your > terminal, is that the gmail interface uses a proportional-spaced font, > whereas your terminal likely uses a monospaced font... Dang! You're right! > I am not aware of any method that this can be changed in gmail. > If I recall correctly, that if the font settings are changed then it will > have the undesirable affect of causing messages to be sent > html-formatted instead of plain-text. When I shifted from Chrome to Firefox I did not pay a whole lot of attention and set the default text style to "fixed width" not realizing that this would only be used in non-plaintext mode. Which causes me to remember that when I was still in Windows and Chrome I had installed a plugin/add-on, Stylish or some such, that provided the desired plaintext monospaced functionality. But that plugin had some issues with security or some such. Ah well. I want to get away from Googleland anyway, so this will be another step in that direction. -- boB From alan.gauld at yahoo.co.uk Tue Apr 28 08:16:00 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 28 Apr 2020 13:16:00 +0100 Subject: [Tutor] [OT] Cool vim feature Message-ID: I've been using vi/vim since 1986. Today I learned a cool new feature that has been there for at least 10 years and I never knew. When in insert mode if you hit Ctrl-N it brings up a list of completions - IDE style. Repeated Ctlr-N steps through them. Ctrl-U cancels. There are other related strokes such as C-X C-F for file completion too. :help ins-comp will get you the details. How could that be there for so long and I not know?! (I knew there were plugins could do it, but I don't like using plugins because it makes the editor inconsistent between machines.) Probably all the other vim users are saying, "of course..." but just in case anyone else is missing out ... Anyways, not really Python related but I thought I'd share. -- 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 jarkmx at gmail.com Tue Apr 28 11:59:01 2020 From: jarkmx at gmail.com (jark AJ) Date: Tue, 28 Apr 2020 11:59:01 -0400 Subject: [Tutor] Iterate over the list Message-ID: Hi All, I want to iterate over the list and save the values Is there a better approach than the one below? Each of the names is unique and do not follow a pattern names = ["name1","name2","name3","name4"] for s in names: resp = requests.get( "https://{0}/APIendpoint".format(s) ) From mats at wichmann.us Tue Apr 28 12:11:42 2020 From: mats at wichmann.us (Mats Wichmann) Date: Tue, 28 Apr 2020 10:11:42 -0600 Subject: [Tutor] Iterate over the list In-Reply-To: References: Message-ID: On 4/28/20 9:59 AM, jark AJ wrote: > Hi All, > > I want to iterate over the list and save the values > Is there a better approach than the one below? > Each of the names is unique and do not follow a pattern > > names = ["name1","name2","name3","name4"] > > for s in names: > resp = requests.get( > "https://{0}/APIendpoint".format(s) > ) Your iterating is just fine. But you are not saving the result values. One approach (without optimizing) might be this, which will leave you with a dictionary of name/value pairs. names = ["name1","name2","name3","name4"] values = {} for s in names: values[s] = requests.get("https://{0}/APIendpoint".format(s)) From mats at wichmann.us Tue Apr 28 12:56:43 2020 From: mats at wichmann.us (Mats Wichmann) Date: Tue, 28 Apr 2020 10:56:43 -0600 Subject: [Tutor] [OT] Cool vim feature In-Reply-To: References: Message-ID: <0e5d3dae-8158-c668-2e5b-4c82d14b90f4@wichmann.us> On 4/28/20 6:16 AM, Alan Gauld via Tutor wrote: > I've been using vi/vim since 1986. > Today I learned a cool new feature that has been there for at least 10 > years and I never knew. > > When in insert mode if you hit Ctrl-N it brings up a list of completions > - IDE style. Repeated Ctlr-N steps through them. Ctrl-U cancels. > > There are other related strokes such as C-X C-F for file completion too. > :help ins-comp will get you the details. > > How could that be there for so long and I not know?! (I knew there were > plugins could do it, but I don't like using plugins because it makes the > editor inconsistent between machines.) > > Probably all the other vim users are saying, "of course..." but just in > case anyone else is missing out ... I didn't know these either. vim has been a lot more proactive than the old vi was in adding features. Those of us who have been with vi for a very long time (I date back to the very beginning, I was attending UC Berkeley while it was being developed), and found vim did everything we were used to probably don't have a lot of incentive to keep exploring new stuff... at least that's been the case for me, I've discovered new stuff quite slowly. From jarkmx at gmail.com Tue Apr 28 13:20:43 2020 From: jarkmx at gmail.com (jark AJ) Date: Tue, 28 Apr 2020 13:20:43 -0400 Subject: [Tutor] Iterate over the list In-Reply-To: References: Message-ID: excellent, thank you. I will try this On Tue, Apr 28, 2020 at 12:12 PM Mats Wichmann wrote: > On 4/28/20 9:59 AM, jark AJ wrote: > > Hi All, > > > > I want to iterate over the list and save the values > > Is there a better approach than the one below? > > Each of the names is unique and do not follow a pattern > > > > names = ["name1","name2","name3","name4"] > > > > for s in names: > > resp = requests.get( > > "https://{0}/APIendpoint".format(s) > > ) > > Your iterating is just fine. > > But you are not saving the result values. One approach (without > optimizing) might be this, which will leave you with a dictionary of > name/value pairs. > > > > names = ["name1","name2","name3","name4"] > values = {} > > for s in names: > values[s] = requests.get("https://{0}/APIendpoint".format(s)) > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From mats at wichmann.us Tue Apr 28 15:42:51 2020 From: mats at wichmann.us (Mats Wichmann) Date: Tue, 28 Apr 2020 13:42:51 -0600 Subject: [Tutor] need help writing subprocess output to file(s) In-Reply-To: References: Message-ID: On 4/26/20 7:46 PM, Matthew Herzog wrote: > Hi all. > I have to run a utility (sdptool) that checks the firmware versions on >500 > servers. > What I pasted below works but the stdout needs to be written to a file, one > per IP address. > How do I capture the stdout to files? Even a single logfile would work. > Thanks. > > #!/usr/bin/python3 > import subprocess > > with open("ips.txt") as ip_list: > ips = ip_list.readlines() > > for ip in ips: > output = subprocess.Popen(["/opt/bin/sdptool", ip, "check"]) you really need to do something to let the above "finish" (with Popen, that's usually a wait() or a communicate() ) you've gotten other answers, here's some of how I'd attack it which is probably less efficient than just sending stdout directly to the file in the subprocess call... with open("log", "a") as f: for ip in ips: cp = subprocess.run(["/opt/bin/sdptool", ip, "check"], stdout=subprocess.PIPE) if cp.returncode: continue # do something if it failed f.write(cp.stdout) From zachary.ware+pytut at gmail.com Tue Apr 28 16:52:53 2020 From: zachary.ware+pytut at gmail.com (Zachary Ware) Date: Tue, 28 Apr 2020 15:52:53 -0500 Subject: [Tutor] [OT] Cool vim feature In-Reply-To: References: Message-ID: On Tue, Apr 28, 2020 at 7:16 AM Alan Gauld via Tutor wrote: > I've been using vi/vim since 1986. > Today I learned a cool new feature that has been there for at least 10 > years and I never knew. > > When in insert mode if you hit Ctrl-N it brings up a list of completions > - IDE style. Repeated Ctlr-N steps through them. Ctrl-U cancels. I'm a more recent convert (somewhere around 2015, I think), but didn't know this either. I was basically in the same boat; I knew people did have completion in vim, but assumed it to be a plugin or something I would have to configure and never took the time to look into it. Now that I know about it, I can foresee this being a very frequently used feature once it makes it into muscle memory. Thanks for bringing it up! -- Zach From blakeblaze15 at gmail.com Tue Apr 28 15:00:46 2020 From: blakeblaze15 at gmail.com (Blake Blaze) Date: Tue, 28 Apr 2020 15:00:46 -0400 Subject: [Tutor] Modules, sys.path Message-ID: Hello, I've really enjoyed learning Python so far, and am appreciative of the robust online help available. I've come across a question that I haven't found a solid answer for though, which is likely due to my inexperience. I've downloaded Anaconda so that I can use scipy.py. When trying to import scipy I was getting a ModuleNotFoundError, and then figuring it was because Anaconda may not yet work with Python3.8 I downloaded 3.7. After doing so last night, I was able to use the functions in scipy just fine. Today, though, I'm getting the same ModuleNotFoundError. I've read a little bit about sys.path and PYTHONPATH. The sys.path is does not include the opt folder where Anaconda and all the packages are stored. Should I be able to move Anaconda into the Python.frameworks directory? Or should I append the opt file path for Anaconda to sys.path? Really confused by what I may have done last night that allowed me to successfully import scipy. Thank you for any advice! Best, Blake From alan.gauld at yahoo.co.uk Tue Apr 28 19:19:28 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 29 Apr 2020 00:19:28 +0100 Subject: [Tutor] Modules, sys.path In-Reply-To: References: Message-ID: On 28/04/2020 20:00, Blake Blaze wrote: > I've downloaded Anaconda so that I can use scipy.py. When trying to import > scipy I was getting a ModuleNotFoundError, and then figuring it was because > Anaconda may not yet work with Python3.8 I downloaded 3.7. After doing so > last night, I was able to use the functions in scipy just fine. Today, > though, I'm getting the same ModuleNotFoundError. Normally with Anaconda I'd say just use the interpreter that comes with it. The whole point of Anaconda as a package is that everything has been built to be compatible. The minute you start trying to use its packages with other modules/interpreters you are inviting pain. > I've read a little bit about sys.path and PYTHONPATH. The sys.path is does > not include the opt folder where Anaconda and all the packages are stored. > Should I be able to move Anaconda into the Python.frameworks directory? I'd avoid that if at all possible. Rather try adding the opt folder to your PYTHONPATH environment variable. sys.path uses that on setup. But the simplest solution is just to use he Anaconda interpreter. Don't worry if its a version or two behind current, Python doesn't really change that much in releases. -- 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 abhishekmarupaka123 at gmail.com Wed Apr 29 07:46:59 2020 From: abhishekmarupaka123 at gmail.com (Abhishek M) Date: Wed, 29 Apr 2020 17:16:59 +0530 Subject: [Tutor] When to use __new__ vs. __init__ ? Message-ID: From mats at wichmann.us Wed Apr 29 10:37:43 2020 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 29 Apr 2020 08:37:43 -0600 Subject: [Tutor] When to use __new__ vs. __init__ ? In-Reply-To: References: Message-ID: On 4/29/20 5:46 AM, Abhishek M wrote: Is that a question? Both are used during instantiation of a class instance, but they are different things: one is used to create the object and the other to initialize it. It's pretty rare that you need to override __new__, while it is quite common to set up a custom initialization function __init__ (which may of course call up to the parent class __init__ using super()). From alan.gauld at yahoo.co.uk Wed Apr 29 12:07:28 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 29 Apr 2020 17:07:28 +0100 Subject: [Tutor] When to use __new__ vs. __init__ ? In-Reply-To: References: Message-ID: On 29/04/2020 12:46, Abhishek M wrote: As ats said you use both of them every time you create an instance of a class. But in practice you normally override __init__() to initialize any class attributes that you have introduced. It is much less common to override __new__(). The main use case for overrriding __new__() is when you are subclassing one of the built-in types such as int or list. An example would be class Integer(int): # do some fancy integer type things... def __new__(cls,n): # whatever... return super().__new__(cls, n) Remember that the first parameter in __init__(), traditionally spelled self, represents the new instance of the class and returns None. Whereas, the first parameter of __new__(), traditionally spelled cls, represents the class itself and it return an instance of the class. -- 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 PyTutor at DancesWithMice.info Wed Apr 29 15:38:28 2020 From: PyTutor at DancesWithMice.info (DL Neil) Date: Thu, 30 Apr 2020 07:38:28 +1200 Subject: [Tutor] [OT] Cool vim feature In-Reply-To: <0e5d3dae-8158-c668-2e5b-4c82d14b90f4@wichmann.us> References: <0e5d3dae-8158-c668-2e5b-4c82d14b90f4@wichmann.us> Message-ID: <6662800b-a61a-10bf-dba8-21e673640501@DancesWithMice.info> On 29/04/20 4:56 AM, Mats Wichmann wrote: > On 4/28/20 6:16 AM, Alan Gauld via Tutor wrote: >> I've been using vi/vim since 1986. >> Today I learned a cool new feature that has been there for at least 10 >> years and I never knew. >> >> When in insert mode if you hit Ctrl-N it brings up a list of completions >> - IDE style. Repeated Ctlr-N steps through them. Ctrl-U cancels. >> >> There are other related strokes such as C-X C-F for file completion too. >> :help ins-comp will get you the details. >> >> How could that be there for so long and I not know?! (I knew there were >> plugins could do it, but I don't like using plugins because it makes the >> editor inconsistent between machines.) >> >> Probably all the other vim users are saying, "of course..." but just in >> case anyone else is missing out ... > > I didn't know these either. > > vim has been a lot more proactive than the old vi was in adding > features. Those of us who have been with vi for a very long time (I > date back to the very beginning, I was attending UC Berkeley while it > was being developed), and found vim did everything we were used to > probably don't have a lot of incentive to keep exploring new stuff... at > least that's been the case for me, I've discovered new stuff quite slowly. Are Release Notes largely treated in the same manner as License Agreements? (that's a bit long, I'm not going to read that/will come back to it later?) Do we imagine that we (IT folk) are any more accepting of change than are our users? -- Regards =dn From mats at wichmann.us Wed Apr 29 16:02:25 2020 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 29 Apr 2020 14:02:25 -0600 Subject: [Tutor] [OT] Cool vim feature In-Reply-To: <6662800b-a61a-10bf-dba8-21e673640501@DancesWithMice.info> References: <0e5d3dae-8158-c668-2e5b-4c82d14b90f4@wichmann.us> <6662800b-a61a-10bf-dba8-21e673640501@DancesWithMice.info> Message-ID: <6747a199-82b1-0812-0e99-c62dcd93a631@wichmann.us> On 4/29/20 1:38 PM, DL Neil via Tutor wrote: >> probably don't have a lot of incentive to keep exploring new stuff... at >> least that's been the case for me, I've discovered new stuff quite >> slowly. > Are Release Notes largely treated in the same manner as License Agreements? > (that's a bit long, I'm not going to read that/will come back to it later?) In my case, I get updates through a package manager... dnf or apt on Linux, and chocolatey on Windows. So new versions "just install", I would have to go looking for release notes, and if there's not a reason you know you need to, why? From akleider at sonic.net Wed Apr 29 18:27:59 2020 From: akleider at sonic.net (Alex Kleider) Date: Wed, 29 Apr 2020 15:27:59 -0700 Subject: [Tutor] Fwd: OT (probably): How to change default tab key value to 4 spaces in GNOME Terminal? In-Reply-To: References: Message-ID: On 2020-04-26 21:07, boB Stepp wrote: > OK, I believe that I have a solution that I can live with. > > On 4/26/20 4:02 AM, Peter Otten wrote: >> boB Stepp wrote: > >> With readline you can do >> >> import readline >> readline.parse_and_bind("TAB: ' '") >> >> but then you lose tab-completion (which you don't seem to use anyway). >> An alternative might be to keep autocompletion and bind 4-space indent >> to >> another key: >> >> readline.parse_and_bind("TAB: complete") >> readline.parse_and_bind("C-h: ' '") # Control-h > > I used Peter's latter thought of binding four spaces to a key. My > .pythonstartup file now looks like this: Bob, (or do you prefer 'boB'?) I didn't know there was such a thing as a .pythonstartup file (although I see there is a .python_history file in my ~ directory.) (I'm using Debian Stable (10 I believe it is.)) A little research took me here: https://www.assertnotmagic.com/2018/06/30/python-startup-file/ and indicates that such a file can be called anything one would like: $ export PYTHONSTARTUP="~/.config/pythonrc.py" So thanks for the tip! I'm curious to know if it is run every time the interpreter starts, even if one is working within a virtualenv? From wescpy at gmail.com Wed Apr 29 19:52:33 2020 From: wescpy at gmail.com (wesley chun) Date: Wed, 29 Apr 2020 16:52:33 -0700 Subject: [Tutor] When to use __new__ vs. __init__ ? In-Reply-To: References: Message-ID: I concur with both Mats' and Alan's responses, and add that more explicitly, __new__() is really only used for subclassing existing (user or built-in) *immutable* types, not all Python built-in types. (If you subclass dict or list, you don't need __new__() ). (Although, subclassing mutable types have their own issues .) With traditional object-oriented languages, you have constructors (and destructors) whose job it is to allocate/create (and deallocate/destroy) objects. Python works differently in that the *Python interpreter* manages your memory, i.e., it does the creation (and destruction) of regular objects. That's why __init__() is named as an "initializer" more than a constructor. For immutables, it's different because you need to be able to specify what you want in such an object *before* it's created, so __new__() serves that purpose... to specify its setup and then let Python create that object. For normal/mutable objects, Python creates the object first, then lets you initialize/customize it with __init__() before it's returned to be used by your application. You'd only pick one (normal/mutable/__init__ or immutable/ __new__) and never both. Cheers, --Wesley On Wed, Apr 29, 2020 at 9:07 AM Alan Gauld via Tutor wrote: > On 29/04/2020 12:46, Abhishek M wrote: > > As ats said you use both of them every time you create an instance of a > class. > > But in practice you normally override __init__() to initialize > any class attributes that you have introduced. It is much less common to > override __new__(). > > The main use case for overrriding __new__() is when you are subclassing > one of the built-in types such as int or list. An example would be > > class Integer(int): > # do some fancy integer type things... > def __new__(cls,n): > # whatever... > return super().__new__(cls, n) > > Remember that the first parameter in __init__(), traditionally spelled > self, represents the new instance of the class and returns None. > Whereas, the first parameter of __new__(), traditionally spelled cls, > represents the class itself and it return an instance of the class. > > -- > 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 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "A computer never does what you want... only what you tell it." +wesley chun : wescpy at gmail : @wescpy Python training & consulting : http://CyberwebConsulting.com "Core Python" books : http://CorePython.com Python blog: http://wescpy.blogspot.com From robertvstepp at gmail.com Wed Apr 29 21:21:12 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Wed, 29 Apr 2020 20:21:12 -0500 Subject: [Tutor] Fwd: OT (probably): How to change default tab key value to 4 spaces in GNOME Terminal? In-Reply-To: References: Message-ID: On Wed, Apr 29, 2020 at 5:28 PM Alex Kleider wrote: > Bob, (or do you prefer 'boB'?) boB please! > I didn't know there was such a thing as a .pythonstartup file > (although I see there is a .python_history file in my ~ directory.) > (I'm using Debian Stable (10 I believe it is.)) > A little research took me here: > https://www.assertnotmagic.com/2018/06/30/python-startup-file/ > and indicates that such a file can be called anything one would like: > $ export PYTHONSTARTUP="~/.config/pythonrc.py" > > So thanks for the tip! > > I'm curious to know if it is run every time the interpreter starts, even > if one is working within a virtualenv? I haven't delved into virtual environments much yet, though I am using pyenv to manage my Python versions per a suggestion by Mats a while back. Anyway I added the following to the end of my .bashrc file: # Set default text editor: export EDITOR='nvim' # Load pyenv automatically by adding # the following to ~/.bash_profile: export PATH="~/.pyenv/bin:$PATH" eval "$(pyenv init -)" eval "$(pyenv virtualenv-init -)" # Set Python 3 custom prompt: export PYTHONSTARTUP=$HOME/.pythonstartup Note that the .pythonstartup (Or whatever you choose to call it.) does not exist until you create it. So this works for me, one environment boB. -- boB From tsaib at bc.edu Thu Apr 30 20:11:06 2020 From: tsaib at bc.edu (Benjamin Tsai) Date: Thu, 30 Apr 2020 17:11:06 -0700 Subject: [Tutor] Help with Pygame Message-ID: Hi there, I just recently bought a new computer back in december and installed python on my computer. However, for some reason, I can't run pygame successfully. I am using Pycharm and using my system interpreter of python 3.7, which I installed using homebrew in the terminal. I've installed the pygame module and the code runs fine (the message "Hello from the pygame community" pops up in the console). In addition, a pop-up window called "pygame window" opens, but nothing in my test code after my for loop works. I've tried looking for a lot of solutions online and deleted and redownloaded python a few times and I'm quite new to Pycharm so I'm not sure if this is a pycharm or python problem. Any help would be appreciated. Sidenote: is there an easy way I can get back to "square one" with python without damaging the python that inherently comes with my computer? Thank you! - Ben Tsai