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: <CAFvq9EKeo1o2xq78opCAKd2FCO_8ZYN-zmOOqqzdUm8CrmOXAA@mail.gmail.com>
 <9ce8306447a1a36279947ed0e514c3ad@sonic.net>
 <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info>
 <79f2d4c9bda941b781d87e96a735703b@sonic.net> <r5vaqb$2gm2$1@ciao.gmane.io>
 <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: <CAFvq9EKeo1o2xq78opCAKd2FCO_8ZYN-zmOOqqzdUm8CrmOXAA@mail.gmail.com>
 <9ce8306447a1a36279947ed0e514c3ad@sonic.net>
 <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info>
 <79f2d4c9bda941b781d87e96a735703b@sonic.net> <r5vaqb$2gm2$1@ciao.gmane.io>
 <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info>
 <80ee8ede-e998-9001-5d74-011b2d856829@wichmann.us>
Message-ID: <af46f51a-a979-9c94-9e9a-755c71f46bff@DancesWithMice.info>

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: <af46f51a-a979-9c94-9e9a-755c71f46bff@DancesWithMice.info>
References: <CAFvq9EKeo1o2xq78opCAKd2FCO_8ZYN-zmOOqqzdUm8CrmOXAA@mail.gmail.com>
 <9ce8306447a1a36279947ed0e514c3ad@sonic.net>
 <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info>
 <79f2d4c9bda941b781d87e96a735703b@sonic.net> <r5vaqb$2gm2$1@ciao.gmane.io>
 <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info>
 <80ee8ede-e998-9001-5d74-011b2d856829@wichmann.us>
 <af46f51a-a979-9c94-9e9a-755c71f46bff@DancesWithMice.info>
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: <r5244q$7c8$2@ciao.gmane.io>
References: <CAAShjMAqXhzZAjP5-wwTfT1Tko+-SuExWMYeQNqJ614R3DYUUQ@mail.gmail.com>
 <r4ssek$qu2$1@ciao.gmane.io>
 <CANDiX9Jq-QQX2HP=3yQUT2z5PQhG3tsZM21FgEnLrCkm3m_z1A@mail.gmail.com>
 <75d8dc0f-4e06-b6d7-a18f-2bfc36ee3311@DancesWithMice.info>
 <r5244q$7c8$2@ciao.gmane.io>
Message-ID: <CAB6eaA7ED0E4mUC43Ke8etCeBYW2ciDiNzyhEnZHm3PrfC9=1w@mail.gmail.com>

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
<http://goo.gl/i4u0R> 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 <tutor at python.org>
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: <r64c96$v7j$1@ciao.gmane.io>

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: <r64d4g$2t74$1@ciao.gmane.io>

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: <r64d4g$2t74$1@ciao.gmane.io>
References: <2B393A04-947C-4F1C-AD1C-0535999EF009@gmail.com>
 <r64d4g$2t74$1@ciao.gmane.io>
Message-ID: <r64gcf$2iv8$1@ciao.gmane.io>

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: <r64c96$v7j$1@ciao.gmane.io>
References: <5e844daf.1c69fb81.f9fd5.3eb1@mx.google.com>
 <r64c96$v7j$1@ciao.gmane.io>
Message-ID: <r64r9p$v23$1@ciao.gmane.io>

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: <CAFvq9EKeo1o2xq78opCAKd2FCO_8ZYN-zmOOqqzdUm8CrmOXAA@mail.gmail.com>
 <9ce8306447a1a36279947ed0e514c3ad@sonic.net>
 <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info>
 <79f2d4c9bda941b781d87e96a735703b@sonic.net> <r5vaqb$2gm2$1@ciao.gmane.io>
 <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info>
Message-ID: <r66v3o$1jpl$1@ciao.gmane.io>

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: <r66v3o$1jpl$1@ciao.gmane.io>
References: <CAFvq9EKeo1o2xq78opCAKd2FCO_8ZYN-zmOOqqzdUm8CrmOXAA@mail.gmail.com>
 <9ce8306447a1a36279947ed0e514c3ad@sonic.net>
 <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info>
 <79f2d4c9bda941b781d87e96a735703b@sonic.net> <r5vaqb$2gm2$1@ciao.gmane.io>
 <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info>
 <r66v3o$1jpl$1@ciao.gmane.io>
Message-ID: <r67713$fg5$1@ciao.gmane.io>

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: <r67713$fg5$1@ciao.gmane.io>
References: <CAFvq9EKeo1o2xq78opCAKd2FCO_8ZYN-zmOOqqzdUm8CrmOXAA@mail.gmail.com>
 <9ce8306447a1a36279947ed0e514c3ad@sonic.net>
 <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info>
 <79f2d4c9bda941b781d87e96a735703b@sonic.net> <r5vaqb$2gm2$1@ciao.gmane.io>
 <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info>
 <r66v3o$1jpl$1@ciao.gmane.io> <r67713$fg5$1@ciao.gmane.io>
Message-ID: <CANDiX9+3CtEkXRGwU1MTAQHwRsodmWp6CTz8NYKvh-Q_F_wPFg@mail.gmail.com>

On Fri, Apr 3, 2020 at 6:35 AM Alan Gauld via Tutor <tutor at python.org> 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: <CANDiX9+3CtEkXRGwU1MTAQHwRsodmWp6CTz8NYKvh-Q_F_wPFg@mail.gmail.com>
References: <CAFvq9EKeo1o2xq78opCAKd2FCO_8ZYN-zmOOqqzdUm8CrmOXAA@mail.gmail.com>
 <9ce8306447a1a36279947ed0e514c3ad@sonic.net>
 <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info>
 <79f2d4c9bda941b781d87e96a735703b@sonic.net> <r5vaqb$2gm2$1@ciao.gmane.io>
 <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info>
 <r66v3o$1jpl$1@ciao.gmane.io> <r67713$fg5$1@ciao.gmane.io>
 <CANDiX9+3CtEkXRGwU1MTAQHwRsodmWp6CTz8NYKvh-Q_F_wPFg@mail.gmail.com>
Message-ID: <r698q2$3hnl$1@ciao.gmane.io>

On 04/04/2020 00:19, boB Stepp wrote:
> On Fri, Apr 3, 2020 at 6:35 AM Alan Gauld via Tutor <tutor at python.org> 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: <CANDiX9+3CtEkXRGwU1MTAQHwRsodmWp6CTz8NYKvh-Q_F_wPFg@mail.gmail.com>
References: <CANDiX9+3CtEkXRGwU1MTAQHwRsodmWp6CTz8NYKvh-Q_F_wPFg@mail.gmail.com>
Message-ID: <20200404082755.GA31207@cskk.homeip.net>

On 03Apr2020 18:19, boB Stepp <robertvstepp at gmail.com> wrote:
>On Fri, Apr 3, 2020 at 6:35 AM Alan Gauld via Tutor <tutor at python.org> 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 <cs at cskk.id.au>

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: <CANDiX9+3CtEkXRGwU1MTAQHwRsodmWp6CTz8NYKvh-Q_F_wPFg@mail.gmail.com>
References: <CAFvq9EKeo1o2xq78opCAKd2FCO_8ZYN-zmOOqqzdUm8CrmOXAA@mail.gmail.com>
 <9ce8306447a1a36279947ed0e514c3ad@sonic.net>
 <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info>
 <79f2d4c9bda941b781d87e96a735703b@sonic.net> <r5vaqb$2gm2$1@ciao.gmane.io>
 <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info>
 <r66v3o$1jpl$1@ciao.gmane.io> <r67713$fg5$1@ciao.gmane.io>
 <CANDiX9+3CtEkXRGwU1MTAQHwRsodmWp6CTz8NYKvh-Q_F_wPFg@mail.gmail.com>
Message-ID: <e530237c-a04c-9d6c-339b-6e4fcf8514e6@wichmann.us>

On 4/3/20 5:19 PM, boB Stepp wrote:
> On Fri, Apr 3, 2020 at 6:35 AM Alan Gauld via Tutor <tutor at python.org> 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: <r6b6gt$3ur6$1@ciao.gmane.io>

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: <e530237c-a04c-9d6c-339b-6e4fcf8514e6@wichmann.us>
References: <CAFvq9EKeo1o2xq78opCAKd2FCO_8ZYN-zmOOqqzdUm8CrmOXAA@mail.gmail.com>
 <9ce8306447a1a36279947ed0e514c3ad@sonic.net>
 <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info>
 <79f2d4c9bda941b781d87e96a735703b@sonic.net> <r5vaqb$2gm2$1@ciao.gmane.io>
 <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info>
 <r66v3o$1jpl$1@ciao.gmane.io> <r67713$fg5$1@ciao.gmane.io>
 <CANDiX9+3CtEkXRGwU1MTAQHwRsodmWp6CTz8NYKvh-Q_F_wPFg@mail.gmail.com>
 <e530237c-a04c-9d6c-339b-6e4fcf8514e6@wichmann.us>
Message-ID: <c42862625d68afbb4fd45da194084531@sonic.net>


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: <c42862625d68afbb4fd45da194084531@sonic.net>
References: <CAFvq9EKeo1o2xq78opCAKd2FCO_8ZYN-zmOOqqzdUm8CrmOXAA@mail.gmail.com>
 <9ce8306447a1a36279947ed0e514c3ad@sonic.net>
 <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info>
 <79f2d4c9bda941b781d87e96a735703b@sonic.net> <r5vaqb$2gm2$1@ciao.gmane.io>
 <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info>
 <r66v3o$1jpl$1@ciao.gmane.io> <r67713$fg5$1@ciao.gmane.io>
 <CANDiX9+3CtEkXRGwU1MTAQHwRsodmWp6CTz8NYKvh-Q_F_wPFg@mail.gmail.com>
 <e530237c-a04c-9d6c-339b-6e4fcf8514e6@wichmann.us>
 <c42862625d68afbb4fd45da194084531@sonic.net>
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: <CAFvq9EKeo1o2xq78opCAKd2FCO_8ZYN-zmOOqqzdUm8CrmOXAA@mail.gmail.com>
 <9ce8306447a1a36279947ed0e514c3ad@sonic.net>
 <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info>
 <79f2d4c9bda941b781d87e96a735703b@sonic.net> <r5vaqb$2gm2$1@ciao.gmane.io>
 <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info>
 <r66v3o$1jpl$1@ciao.gmane.io> <r67713$fg5$1@ciao.gmane.io>
 <CANDiX9+3CtEkXRGwU1MTAQHwRsodmWp6CTz8NYKvh-Q_F_wPFg@mail.gmail.com>
 <e530237c-a04c-9d6c-339b-6e4fcf8514e6@wichmann.us>
 <c42862625d68afbb4fd45da194084531@sonic.net>
 <2d23e677-4647-c1ea-db01-0112b2639418@DancesWithMice.info>
Message-ID: <r6c89d$11g2$1@ciao.gmane.io>

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: <c42862625d68afbb4fd45da194084531@sonic.net>
References: <CAFvq9EKeo1o2xq78opCAKd2FCO_8ZYN-zmOOqqzdUm8CrmOXAA@mail.gmail.com>
 <9ce8306447a1a36279947ed0e514c3ad@sonic.net>
 <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info>
 <79f2d4c9bda941b781d87e96a735703b@sonic.net> <r5vaqb$2gm2$1@ciao.gmane.io>
 <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info>
 <r66v3o$1jpl$1@ciao.gmane.io> <r67713$fg5$1@ciao.gmane.io>
 <CANDiX9+3CtEkXRGwU1MTAQHwRsodmWp6CTz8NYKvh-Q_F_wPFg@mail.gmail.com>
 <e530237c-a04c-9d6c-339b-6e4fcf8514e6@wichmann.us>
 <c42862625d68afbb4fd45da194084531@sonic.net>
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())
<class 'dict'>
>>> greet = "Hello"
>>> locals()
{'__name__': '__main__', '__doc__': None, '__package__': None,
'__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__':
None, '__annotations__': {}, '__builtins__': <module 'builtins'
(built-in)>, '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: <CAFvq9EKeo1o2xq78opCAKd2FCO_8ZYN-zmOOqqzdUm8CrmOXAA@mail.gmail.com>
 <9ce8306447a1a36279947ed0e514c3ad@sonic.net>
 <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info>
 <79f2d4c9bda941b781d87e96a735703b@sonic.net> <r5vaqb$2gm2$1@ciao.gmane.io>
 <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info>
 <r66v3o$1jpl$1@ciao.gmane.io> <r67713$fg5$1@ciao.gmane.io>
 <CANDiX9+3CtEkXRGwU1MTAQHwRsodmWp6CTz8NYKvh-Q_F_wPFg@mail.gmail.com>
 <e530237c-a04c-9d6c-339b-6e4fcf8514e6@wichmann.us>
 <c42862625d68afbb4fd45da194084531@sonic.net>
 <2d23e677-4647-c1ea-db01-0112b2639418@DancesWithMice.info>
Message-ID: <r6d58j$3k9s$1@ciao.gmane.io>

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: <CAFvq9EKeo1o2xq78opCAKd2FCO_8ZYN-zmOOqqzdUm8CrmOXAA@mail.gmail.com>
 <9ce8306447a1a36279947ed0e514c3ad@sonic.net>
 <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info>
 <79f2d4c9bda941b781d87e96a735703b@sonic.net> <r5vaqb$2gm2$1@ciao.gmane.io>
 <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info>
 <r66v3o$1jpl$1@ciao.gmane.io> <r67713$fg5$1@ciao.gmane.io>
 <CANDiX9+3CtEkXRGwU1MTAQHwRsodmWp6CTz8NYKvh-Q_F_wPFg@mail.gmail.com>
 <e530237c-a04c-9d6c-339b-6e4fcf8514e6@wichmann.us>
 <c42862625d68afbb4fd45da194084531@sonic.net>
 <2d23e677-4647-c1ea-db01-0112b2639418@DancesWithMice.info>
 <r6d58j$3k9s$1@ciao.gmane.io>
Message-ID: <r6dbvm$3858$1@ciao.gmane.io>

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: <CA+z96MJRmKvuOW4iLVb=Eq_odoa-su2ScF=7gJ2=qzWDhvK7XA@mail.gmail.com>

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: <r6dbvm$3858$1@ciao.gmane.io>
References: <CAFvq9EKeo1o2xq78opCAKd2FCO_8ZYN-zmOOqqzdUm8CrmOXAA@mail.gmail.com>
 <9ce8306447a1a36279947ed0e514c3ad@sonic.net>
 <54af6ab0-936c-0e63-38e6-1d7b6130645f@DancesWithMice.info>
 <79f2d4c9bda941b781d87e96a735703b@sonic.net> <r5vaqb$2gm2$1@ciao.gmane.io>
 <30e589e2-626e-0ce2-6688-dbbefcf52f52@DancesWithMice.info>
 <r66v3o$1jpl$1@ciao.gmane.io> <r67713$fg5$1@ciao.gmane.io>
 <CANDiX9+3CtEkXRGwU1MTAQHwRsodmWp6CTz8NYKvh-Q_F_wPFg@mail.gmail.com>
 <e530237c-a04c-9d6c-339b-6e4fcf8514e6@wichmann.us>
 <c42862625d68afbb4fd45da194084531@sonic.net>
 <2d23e677-4647-c1ea-db01-0112b2639418@DancesWithMice.info>
 <r6d58j$3k9s$1@ciao.gmane.io> <r6dbvm$3858$1@ciao.gmane.io>
Message-ID: <r6dnav$p6p$1@ciao.gmane.io>

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: <r6dpih$1mau$1@ciao.gmane.io>

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: <r6dpih$1mau$1@ciao.gmane.io>
References: <r6dpih$1mau$1@ciao.gmane.io>
Message-ID: <a1bc3c5a-9823-65c7-c206-780329933724@DancesWithMice.info>

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: <a1bc3c5a-9823-65c7-c206-780329933724@DancesWithMice.info>
References: <r6dpih$1mau$1@ciao.gmane.io>
 <a1bc3c5a-9823-65c7-c206-780329933724@DancesWithMice.info>
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: <r6dnav$p6p$1@ciao.gmane.io>
References: <r6dnav$p6p$1@ciao.gmane.io>
Message-ID: <20200406055219.GA96163@cskk.homeip.net>

On 05Apr2020 23:50, Alan Gauld <alan.gauld at yahoo.co.uk> 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 <cs at cskk.id.au>

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: <r6dnav$p6p$1@ciao.gmane.io>
 <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 <alan.gauld at yahoo.co.uk> 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 <cs at cskk.id.au>
_______________________________________________
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: <r6dnav$p6p$1@ciao.gmane.io>
 <20200406055219.GA96163@cskk.homeip.net>
Message-ID: <r6etfu$17tl$1@ciao.gmane.io>

On 06/04/2020 06:52, Cameron Simpson wrote:
> On 05Apr2020 23:50, Alan Gauld <alan.gauld at yahoo.co.uk> 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: <r6etfu$17tl$1@ciao.gmane.io>
References: <r6dnav$p6p$1@ciao.gmane.io>
 <20200406055219.GA96163@cskk.homeip.net> <r6etfu$17tl$1@ciao.gmane.io>
Message-ID: <r6f2mg$1k9b$1@ciao.gmane.io>

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: <r6f2mg$1k9b$1@ciao.gmane.io>
References: <r6dnav$p6p$1@ciao.gmane.io>
 <20200406055219.GA96163@cskk.homeip.net> <r6etfu$17tl$1@ciao.gmane.io>
 <r6f2mg$1k9b$1@ciao.gmane.io>
Message-ID: <r6f5sq$qov$1@ciao.gmane.io>

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: <CA+z96MJRmKvuOW4iLVb=Eq_odoa-su2ScF=7gJ2=qzWDhvK7XA@mail.gmail.com>
References: <CA+z96MJRmKvuOW4iLVb=Eq_odoa-su2ScF=7gJ2=qzWDhvK7XA@mail.gmail.com>
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" <mambafrutty at gmail.com> 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)
<ipython-input-1-2e15c1951be1> in <module>()
      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: <r6kkjs$3db9$1@ciao.gmane.io>

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)
> <ipython-input-1-2e15c1951be1> in <module>()
>       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: <r6kru7$j7l$1@ciao.gmane.io>

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) <ipython-input-1-2e15c1951be1> in <module>()
>       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: <r6l6h0$v9a$1@ciao.gmane.io>

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: <r6l8le$1o01$1@ciao.gmane.io>

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: <r6l8le$1o01$1@ciao.gmane.io>
References: <r6l8le$1o01$1@ciao.gmane.io>
Message-ID: <a7ecf0cc-d4de-3030-9be6-89b504571dbf@DancesWithMice.info>

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: <a7ecf0cc-d4de-3030-9be6-89b504571dbf@DancesWithMice.info>
References: <r6l8le$1o01$1@ciao.gmane.io>
 <a7ecf0cc-d4de-3030-9be6-89b504571dbf@DancesWithMice.info>
Message-ID: <r6lqqh$1hnf$1@ciao.gmane.io>

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: <CAPM-O+zoYW2FdRAoZXKUjGw35hbB=aoENrqhhxtgiUOm3QQmAA@mail.gmail.com>

On Thu, Apr 9, 2020 at 4:06 AM Peter Jennings
<peterjennings1999 at gmail.com> 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: <r6mn80$1d1e$1@ciao.gmane.io>

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: <r6mnbn$1d1e$2@ciao.gmane.io>

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: <http://mail.python.org/pipermail/tutor/attachments/20200409/df8d8ab1/attachment.txt>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: mdf.txt
URL: <http://mail.python.org/pipermail/tutor/attachments/20200409/df8d8ab1/attachment-0001.txt>

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: <r6nji8$248s$1@ciao.gmane.io>

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: <CAPdnPmzGBQV_qDHQ8L4nAcWbvVSvof3TxZ23vyv+6cEeN=7kUg@mail.gmail.com>

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: <r6pi3r$24tk$1@ciao.gmane.io>

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: <CAPdnPmzGBQV_qDHQ8L4nAcWbvVSvof3TxZ23vyv+6cEeN=7kUg@mail.gmail.com>
References: <CAPdnPmzGBQV_qDHQ8L4nAcWbvVSvof3TxZ23vyv+6cEeN=7kUg@mail.gmail.com>
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: <CAPdnPmzGBQV_qDHQ8L4nAcWbvVSvof3TxZ23vyv+6cEeN=7kUg@mail.gmail.com>
References: <CAPdnPmzGBQV_qDHQ8L4nAcWbvVSvof3TxZ23vyv+6cEeN=7kUg@mail.gmail.com>
Message-ID: <53C4E968-97AC-44BD-B72C-D709BA25A64E@wichmann.us>

On April 10, 2020 3:10:34 AM MDT, Zulfadli Azhar <zulfadli.azh at gmail.com> 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: <DB7PR01MB53707AF41BD55FBF15FC043AACDE0@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>

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: <CANyKM1gLGnnX5AOv1F1d49rtXa_yJ_0M918EDBXBjcXZ5+5gZw@mail.gmail.com>

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: <CANyKM1gLGnnX5AOv1F1d49rtXa_yJ_0M918EDBXBjcXZ5+5gZw@mail.gmail.com>
References: <CANyKM1gLGnnX5AOv1F1d49rtXa_yJ_0M918EDBXBjcXZ5+5gZw@mail.gmail.com>
Message-ID: <r6quos$lin$1@ciao.gmane.io>

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: <DB7PR01MB53707AF41BD55FBF15FC043AACDE0@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
References: <DB7PR01MB53707AF41BD55FBF15FC043AACDE0@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
Message-ID: <r6qut4$lin$2@ciao.gmane.io>

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: <r6quos$lin$1@ciao.gmane.io>
References: <CANyKM1gLGnnX5AOv1F1d49rtXa_yJ_0M918EDBXBjcXZ5+5gZw@mail.gmail.com>
 <r6quos$lin$1@ciao.gmane.io>
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: <CANDiX9+TLyiDYik4g8p=kFfo627TRK4OUR7SXwmz=_5+XpGNJg@mail.gmail.com>

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 <module>
    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: <CANDiX9+TLyiDYik4g8p=kFfo627TRK4OUR7SXwmz=_5+XpGNJg@mail.gmail.com>
References: <CANDiX9+TLyiDYik4g8p=kFfo627TRK4OUR7SXwmz=_5+XpGNJg@mail.gmail.com>
Message-ID: <CANDiX9JzmWOJAS8fJM3NwcHyAeC3K+es7ON6xWakJujMdEN6sw@mail.gmail.com>

On Sat, Apr 11, 2020 at 12:57 AM boB Stepp <robertvstepp at gmail.com> 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 <module>
>     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: <DB7PR01MB53707AF41BD55FBF15FC043AACDE0@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
References: <DB7PR01MB53707AF41BD55FBF15FC043AACDE0@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
Message-ID: <DB7PR01MB537044B747A2811C84C5D7AEACDF0@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>

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 <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: <DB7PR01MB537044B747A2811C84C5D7AEACDF0@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
References: <DB7PR01MB53707AF41BD55FBF15FC043AACDE0@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>,
 <DB7PR01MB537044B747A2811C84C5D7AEACDF0@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
Message-ID: <DB7PR01MB5370DCA2224F9F9CC6879A6AACDF0@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>

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 <jon_davies17 at hotmail.co.uk>
Sent: 11 April 2020 10:54
To: tutor at python.org <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 <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: <r6quos$lin$1@ciao.gmane.io>
References: <CANyKM1gLGnnX5AOv1F1d49rtXa_yJ_0M918EDBXBjcXZ5+5gZw@mail.gmail.com>
 <r6quos$lin$1@ciao.gmane.io>
Message-ID: <CANyKM1gb+itO7EKJ1JJXqyWgS78Q8p=Cg3Cwzqr9aiqk04j0eQ@mail.gmail.com>

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 <tutor at python.org>
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: <CANyKM1gb+itO7EKJ1JJXqyWgS78Q8p=Cg3Cwzqr9aiqk04j0eQ@mail.gmail.com>
References: <CANyKM1gLGnnX5AOv1F1d49rtXa_yJ_0M918EDBXBjcXZ5+5gZw@mail.gmail.com>
 <r6quos$lin$1@ciao.gmane.io>
 <CANyKM1gb+itO7EKJ1JJXqyWgS78Q8p=Cg3Cwzqr9aiqk04j0eQ@mail.gmail.com>
Message-ID: <CANyKM1gz_wn0vhCKx70xb9+GBMMyMVavDhsu55PG4Hni_zL0Kw@mail.gmail.com>

how about


while msvcrt.getch() != 'F2':
    time.sleep(1)

On Fri, Apr 10, 2020 at 4:31 PM Chris C <mysecretrobotfactory at gmail.com>
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 <tutor at python.org>
> 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: <DEFA60CA-84AD-44D4-98CD-C35BED089CAF@gmail.com>

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 <tutor at python.org> 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: <CANyKM1gz_wn0vhCKx70xb9+GBMMyMVavDhsu55PG4Hni_zL0Kw@mail.gmail.com>
References: <CANyKM1gLGnnX5AOv1F1d49rtXa_yJ_0M918EDBXBjcXZ5+5gZw@mail.gmail.com>
 <r6quos$lin$1@ciao.gmane.io>
 <CANyKM1gb+itO7EKJ1JJXqyWgS78Q8p=Cg3Cwzqr9aiqk04j0eQ@mail.gmail.com>
 <CANyKM1gz_wn0vhCKx70xb9+GBMMyMVavDhsu55PG4Hni_zL0Kw@mail.gmail.com>
Message-ID: <af517b55-7355-f6b0-98d3-39ffebe209cc@yahoo.co.uk>

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: <CANyKM1gz_wn0vhCKx70xb9+GBMMyMVavDhsu55PG4Hni_zL0Kw@mail.gmail.com>
References: <CANyKM1gLGnnX5AOv1F1d49rtXa_yJ_0M918EDBXBjcXZ5+5gZw@mail.gmail.com>
 <r6quos$lin$1@ciao.gmane.io>
 <CANyKM1gb+itO7EKJ1JJXqyWgS78Q8p=Cg3Cwzqr9aiqk04j0eQ@mail.gmail.com>
 <CANyKM1gz_wn0vhCKx70xb9+GBMMyMVavDhsu55PG4Hni_zL0Kw@mail.gmail.com>
Message-ID: <af517b55-7355-f6b0-98d3-39ffebe209cc@yahoo.co.uk>

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: <CANDiX9+TLyiDYik4g8p=kFfo627TRK4OUR7SXwmz=_5+XpGNJg@mail.gmail.com>
 <CANDiX9JzmWOJAS8fJM3NwcHyAeC3K+es7ON6xWakJujMdEN6sw@mail.gmail.com>
Message-ID: <r6sgk2$3vji$1@ciao.gmane.io>

boB Stepp wrote:

> On Sat, Apr 11, 2020 at 12:57 AM boB Stepp <robertvstepp at gmail.com> 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 <module>
>>     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: <r6umbb$2348$1@ciao.gmane.io>

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: <CAByHNXWwbyZF58aEOxn_VcEfvCLH20eiz+3EtG7gdB0T-sdzdg@mail.gmail.com>

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: <CAByHNXWwbyZF58aEOxn_VcEfvCLH20eiz+3EtG7gdB0T-sdzdg@mail.gmail.com>
References: <CAByHNXWwbyZF58aEOxn_VcEfvCLH20eiz+3EtG7gdB0T-sdzdg@mail.gmail.com>
Message-ID: <r6v7hs$2gck$1@ciao.gmane.io>

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: <r6v88h$1di$1@ciao.gmane.io>

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: <r6v7hs$2gck$1@ciao.gmane.io>
References: <CAByHNXWwbyZF58aEOxn_VcEfvCLH20eiz+3EtG7gdB0T-sdzdg@mail.gmail.com>
 <r6v7hs$2gck$1@ciao.gmane.io>
Message-ID: <CAPStRW-KTsyADLp3VYU9FORXRvqjow+uhaYn-ZZY9NXeOjdy+A@mail.gmail.com>

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 <tutor at python.org>
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
>

<https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail&utm_term=icon>
Virus-free.
www.avast.com
<https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail&utm_term=link>
<#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: <CAByHNXWwbyZF58aEOxn_VcEfvCLH20eiz+3EtG7gdB0T-sdzdg@mail.gmail.com>
References: <CAByHNXWwbyZF58aEOxn_VcEfvCLH20eiz+3EtG7gdB0T-sdzdg@mail.gmail.com>
Message-ID: <CAHVvXxSPp3fatz+yDNGCrwZKt0P4ZPh=f30dvvq-10VLTqCBAQ@mail.gmail.com>

On Sun, 12 Apr 2020 at 14:04, mixipilixi . <mixipilixi at gmail.com> 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: <CANDiX9+TLyiDYik4g8p=kFfo627TRK4OUR7SXwmz=_5+XpGNJg@mail.gmail.com>
References: <CANDiX9+TLyiDYik4g8p=kFfo627TRK4OUR7SXwmz=_5+XpGNJg@mail.gmail.com>
Message-ID: <20200412235927.GA68584@cskk.homeip.net>

On 11Apr2020 00:57, boB Stepp <robertvstepp at gmail.com> 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 <cs at cskk.id.au>

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: <CAHVvXxSPp3fatz+yDNGCrwZKt0P4ZPh=f30dvvq-10VLTqCBAQ@mail.gmail.com>
References: <CAByHNXWwbyZF58aEOxn_VcEfvCLH20eiz+3EtG7gdB0T-sdzdg@mail.gmail.com>
 <CAHVvXxSPp3fatz+yDNGCrwZKt0P4ZPh=f30dvvq-10VLTqCBAQ@mail.gmail.com>
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: <CAKDb_j7qR=U6qggbaH3ZReF2BwELrwuOftJDSnAguiUXyaGH_A@mail.gmail.com>

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: <CACN=rDRbSjOtMeUvjK73WpXdO_HkYYu57DhTd1MgUJskiioUzA@mail.gmail.com>

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 "<stdin>", 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: <CACN=rDRbSjOtMeUvjK73WpXdO_HkYYu57DhTd1MgUJskiioUzA@mail.gmail.com>
References: <CACN=rDRbSjOtMeUvjK73WpXdO_HkYYu57DhTd1MgUJskiioUzA@mail.gmail.com>
Message-ID: <9BF964BB-009C-4B3D-97CF-E714E7002DF7@wichmann.us>

On April 13, 2020 2:14:12 PM MDT, Owen Davies <owendavies00 at gmail.com> 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 "<stdin>", 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: <CAKDb_j7qR=U6qggbaH3ZReF2BwELrwuOftJDSnAguiUXyaGH_A@mail.gmail.com>
Message-ID: <r74lam$10vj$1@ciao.gmane.io>

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: <CAByHNXWwbyZF58aEOxn_VcEfvCLH20eiz+3EtG7gdB0T-sdzdg@mail.gmail.com>
 <CAHVvXxSPp3fatz+yDNGCrwZKt0P4ZPh=f30dvvq-10VLTqCBAQ@mail.gmail.com>
 <11d22a04-fcc8-605b-eec1-7a330c5878c4@btinternet.com>
Message-ID: <CAHVvXxSwAjeXUsb-9cyu=RHA26pASDPCgaq1cTqg1+GoTWLvDg@mail.gmail.com>

On Mon, 13 Apr 2020 at 01:53, Alan Gauld via Tutor <tutor at python.org> 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: <CAON5Gn0QKQrWqBq5G0ojr4O1Ku9zFgx10HBt0Z7Ui76UfpSLLQ@mail.gmail.com>

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: <CAON5Gn0QKQrWqBq5G0ojr4O1Ku9zFgx10HBt0Z7Ui76UfpSLLQ@mail.gmail.com>
References: <CAON5Gn0QKQrWqBq5G0ojr4O1Ku9zFgx10HBt0Z7Ui76UfpSLLQ@mail.gmail.com>
Message-ID: <CAMPXz=rr4+F86v9r-QsG3d4-cVNZ7OdBBGqvSbhvnfpKYvqjhQ@mail.gmail.com>

On Wed, 15 Apr 2020 at 23:25, Cranky Frankie <cranky.frankie at gmail.com> 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: <CAON5Gn0QKQrWqBq5G0ojr4O1Ku9zFgx10HBt0Z7Ui76UfpSLLQ@mail.gmail.com>
References: <CAON5Gn0QKQrWqBq5G0ojr4O1Ku9zFgx10HBt0Z7Ui76UfpSLLQ@mail.gmail.com>
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: <CAON5Gn0QKQrWqBq5G0ojr4O1Ku9zFgx10HBt0Z7Ui76UfpSLLQ@mail.gmail.com>
References: <CAON5Gn0QKQrWqBq5G0ojr4O1Ku9zFgx10HBt0Z7Ui76UfpSLLQ@mail.gmail.com>
Message-ID: <57FB3EA5-0A9E-4768-9CDC-EC84C2144AD3@graniteweb.com>


> On Apr 15, 2020, at 08:24, Cranky Frankie <cranky.frankie at gmail.com> 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: <CAON5Gn0QKQrWqBq5G0ojr4O1Ku9zFgx10HBt0Z7Ui76UfpSLLQ@mail.gmail.com>
 <3a7bef42-60dd-e1ef-273b-a8e80b523edc@wichmann.us>
Message-ID: <CAON5Gn1a7v3-J_OTvC6UCa2Vxm2TS+7EQUDpwyOgDLL9sCYzoA@mail.gmail.com>

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 <mats at wichmann.us> 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: <CAON5Gn1a7v3-J_OTvC6UCa2Vxm2TS+7EQUDpwyOgDLL9sCYzoA@mail.gmail.com>
References: <CAON5Gn0QKQrWqBq5G0ojr4O1Ku9zFgx10HBt0Z7Ui76UfpSLLQ@mail.gmail.com>
 <3a7bef42-60dd-e1ef-273b-a8e80b523edc@wichmann.us>
 <CAON5Gn1a7v3-J_OTvC6UCa2Vxm2TS+7EQUDpwyOgDLL9sCYzoA@mail.gmail.com>
Message-ID: <3B006350-DDF9-439A-8326-64A83D5805E1@graniteweb.com>


> On Apr 15, 2020, at 09:08, Cranky Frankie <cranky.frankie at gmail.com> 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: <CAON5Gn0QKQrWqBq5G0ojr4O1Ku9zFgx10HBt0Z7Ui76UfpSLLQ@mail.gmail.com>
 <57FB3EA5-0A9E-4768-9CDC-EC84C2144AD3@graniteweb.com>
Message-ID: <CAON5Gn2fmMRgUic6r5KisLiLDGsJrB-wWqaJF21hxBy1NDsvFQ@mail.gmail.com>

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 <david at graniteweb.com> wrote:

>
> > On Apr 15, 2020, at 08:24, Cranky Frankie <cranky.frankie at gmail.com>
> 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: <CAON5Gn0QKQrWqBq5G0ojr4O1Ku9zFgx10HBt0Z7Ui76UfpSLLQ@mail.gmail.com>
References: <CAON5Gn0QKQrWqBq5G0ojr4O1Ku9zFgx10HBt0Z7Ui76UfpSLLQ@mail.gmail.com>
Message-ID: <r784hm$1pn6$1@ciao.gmane.io>

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: <DB7PR01MB5370725C0D8CD3AB25567211ACDB0@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>

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: <df3dc5a35bf0fd564ac46c96e217c3fe@sonic.net>
References: <CAON5Gn0QKQrWqBq5G0ojr4O1Ku9zFgx10HBt0Z7Ui76UfpSLLQ@mail.gmail.com>
 <df3dc5a35bf0fd564ac46c96e217c3fe@sonic.net>
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 <akleider at sonic.net>
To: Cranky Frankie <cranky.frankie at gmail.com>

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: <DB7PR01MB5370725C0D8CD3AB25567211ACDB0@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
References: <DB7PR01MB5370725C0D8CD3AB25567211ACDB0@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
Message-ID: <r798gg$2nkg$1@ciao.gmane.io>

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 <ButtonPressed-1> and <ButtonRelease-1> 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(<ButtonPressed-1>, self.beginFuelling)
       self.fuelbutton.bind(<ButtonRelease-1>, 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: <DB7PR01MB5370725C0D8CD3AB25567211ACDB0@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
References: <DB7PR01MB5370725C0D8CD3AB25567211ACDB0@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
Message-ID: <r79h0d$20rp$1@ciao.gmane.io>

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('<Button-1>', self.press)
         self.btn.bind("<ButtonRelease-1>", 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: <CAGTz3vRX4pmxhS4gRR8FmRwmpkG_rtd2u1k2U8yye22rM3RvKg@mail.gmail.com>



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: <CAGTz3vRX4pmxhS4gRR8FmRwmpkG_rtd2u1k2U8yye22rM3RvKg@mail.gmail.com>
References: <CAGTz3vRX4pmxhS4gRR8FmRwmpkG_rtd2u1k2U8yye22rM3RvKg@mail.gmail.com>
Message-ID: <r7bmvj$2dii$1@ciao.gmane.io>

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: <CALC_W0vRis8GVXd84JV3rfsnd9-5mrR8qOjwZ-sV4ftL_T8cZQ@mail.gmail.com>

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 <module>
    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()
 <<line 350


# set the Engine class and define it.
class Engine(object):

    def __init__(self, scene_map):
        self.scene_map = scene_map

    def play(self):
        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)

        # be sure to print out the last scene
        current_scene.enter()

Thanks!

Alan

From mats at wichmann.us  Fri Apr 17 12:24:45 2020
From: mats at wichmann.us (Mats Wichmann)
Date: Fri, 17 Apr 2020 10:24:45 -0600
Subject: [Tutor] Attribution Error
In-Reply-To: <CALC_W0vRis8GVXd84JV3rfsnd9-5mrR8qOjwZ-sV4ftL_T8cZQ@mail.gmail.com>
References: <CALC_W0vRis8GVXd84JV3rfsnd9-5mrR8qOjwZ-sV4ftL_T8cZQ@mail.gmail.com>
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 <module>
>     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: <CALC_W0vRis8GVXd84JV3rfsnd9-5mrR8qOjwZ-sV4ftL_T8cZQ@mail.gmail.com>
References: <CALC_W0vRis8GVXd84JV3rfsnd9-5mrR8qOjwZ-sV4ftL_T8cZQ@mail.gmail.com>
Message-ID: <r7cli1$1omg$1@ciao.gmane.io>

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 <module>
>     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: <r7cli1$1omg$1@ciao.gmane.io>
References: <CALC_W0vRis8GVXd84JV3rfsnd9-5mrR8qOjwZ-sV4ftL_T8cZQ@mail.gmail.com>
 <r7cli1$1omg$1@ciao.gmane.io>
Message-ID: <CALC_W0s_j4L2r7OPZemdA3N3oVW+_C5grimJDa8QVyRMz0v6CA@mail.gmail.com>

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 <tutor at python.org>
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 <module>
> >     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: <CALC_W0s_j4L2r7OPZemdA3N3oVW+_C5grimJDa8QVyRMz0v6CA@mail.gmail.com>
References: <CALC_W0vRis8GVXd84JV3rfsnd9-5mrR8qOjwZ-sV4ftL_T8cZQ@mail.gmail.com>
 <r7cli1$1omg$1@ciao.gmane.io>
 <CALC_W0s_j4L2r7OPZemdA3N3oVW+_C5grimJDa8QVyRMz0v6CA@mail.gmail.com>
Message-ID: <r7dfum$ese$1@ciao.gmane.io>

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: <r7dfum$ese$1@ciao.gmane.io>
References: <CALC_W0vRis8GVXd84JV3rfsnd9-5mrR8qOjwZ-sV4ftL_T8cZQ@mail.gmail.com>
 <r7cli1$1omg$1@ciao.gmane.io>
 <CALC_W0s_j4L2r7OPZemdA3N3oVW+_C5grimJDa8QVyRMz0v6CA@mail.gmail.com>
 <r7dfum$ese$1@ciao.gmane.io>
Message-ID: <CALC_W0vk8+noJOe930BfRZLvtPqCaPVBo14qY2qsrFPJbGOGMg@mail.gmail.com>

My apologies. I can't see how I missed that.

Alan

On Fri, Apr 17, 2020 at 8:00 PM Alan Gauld via Tutor <tutor at python.org>
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: <r79h0d$20rp$1@ciao.gmane.io>
References: <DB7PR01MB5370725C0D8CD3AB25567211ACDB0@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>,
 <r79h0d$20rp$1@ciao.gmane.io>
Message-ID: <DB7PR01MB537059556CC7984F5B8A0F0BACD60@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>

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 <tutor-bounces+jon_davies17=hotmail.co.uk at python.org> on behalf of Alan Gauld via Tutor <tutor at python.org>
Sent: 16 April 2020 12:53
To: tutor at python.org <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('<Button-1>', self.press)
         self.btn.bind("<ButtonRelease-1>", 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 <tutor-bounces+jon_davies17=hotmail.co.uk at python.org> on behalf of Alan Gauld via Tutor <tutor at python.org>
Sent: 16 April 2020 10:28
To: tutor at python.org <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 <ButtonPressed-1> and <ButtonRelease-1> 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(<ButtonPressed-1>, self.beginFuelling)
       self.fuelbutton.bind(<ButtonRelease-1>, 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: <DB7PR01MB5370725C0D8CD3AB25567211ACDB0@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
 <r79h0d$20rp$1@ciao.gmane.io>
 <DB7PR01MB537059556CC7984F5B8A0F0BACD60@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
Message-ID: <r7f7o9$2mks$1@ciao.gmane.io>

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: <r7g2oq$11q7$1@ciao.gmane.io>

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: <DB7PR01MB537059556CC7984F5B8A0F0BACD60@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
References: <DB7PR01MB5370725C0D8CD3AB25567211ACDB0@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
 <r79h0d$20rp$1@ciao.gmane.io>
 <DB7PR01MB537059556CC7984F5B8A0F0BACD60@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
Message-ID: <r7hbg0$1t0h$1@ciao.gmane.io>

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: <LOYP265MB1936A5C4FDDF4C5CD5EB1E0FA3D70@LOYP265MB1936.GBRP265.PROD.OUTLOOK.COM>

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: <http://mail.python.org/pipermail/tutor/attachments/20200419/64ba5e13/attachment.ksh>

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: <LOYP265MB1936A5C4FDDF4C5CD5EB1E0FA3D70@LOYP265MB1936.GBRP265.PROD.OUTLOOK.COM>
References: <LOYP265MB1936A5C4FDDF4C5CD5EB1E0FA3D70@LOYP265MB1936.GBRP265.PROD.OUTLOOK.COM>
Message-ID: <r7hiue$1sl9$1@ciao.gmane.io>

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: <DB7PR01MB5370032037322C48B81528A8ACD70@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
References: <DB7PR01MB5370032037322C48B81528A8ACD70@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
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 <jon_davies17 at hotmail.co.uk>
To: 	Alan Gauld <alan.gauld at yahoo.co.uk>, 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 <tutor-bounces+jon_davies17=hotmail.co.uk at python.org> on
behalf of Alan Gauld via Tutor <tutor at python.org>
*Sent:* 19 April 2020 12:08
*To:* tutor at python.org <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 <tutor-bounces+jon_davies17=hotmail.co.uk at python.org> on
behalf of Peter Otten <__peter__ at web.de>
*Sent:*?18 April 2020 16:52
*To:*?tutor at python.org <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: <DB7PR01MB5370032037322C48B81528A8ACD70@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
 <9ac4284b-dcab-09cb-7d87-6e3f6b71f709@yahoo.co.uk>
Message-ID: <r7hmpk$2cph$1@ciao.gmane.io>

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: <DB7PR01MB5370032037322C48B81528A8ACD70@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
 <9ac4284b-dcab-09cb-7d87-6e3f6b71f709@yahoo.co.uk>
Message-ID: <r7hoor$2mck$1@ciao.gmane.io>

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: <r7hmpk$2cph$1@ciao.gmane.io>
References: <DB7PR01MB5370032037322C48B81528A8ACD70@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
 <9ac4284b-dcab-09cb-7d87-6e3f6b71f709@yahoo.co.uk>,
 <r7hmpk$2cph$1@ciao.gmane.io>
Message-ID: <DB7PR01MB5370C4BBB0619B9B8DB9FFF9ACD70@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>

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('<Button-1>', self.press)
        self.lever_btn.bind("<ButtonRelease-1>", 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 <tutor-bounces+jon_davies17=hotmail.co.uk at python.org> on behalf of Alan Gauld via Tutor <tutor at python.org>
Sent: 19 April 2020 15:21
To: tutor at python.org <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: <DB7PR01MB5370C4BBB0619B9B8DB9FFF9ACD70@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
References: <DB7PR01MB5370032037322C48B81528A8ACD70@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
 <9ac4284b-dcab-09cb-7d87-6e3f6b71f709@yahoo.co.uk>
 <r7hmpk$2cph$1@ciao.gmane.io>
 <DB7PR01MB5370C4BBB0619B9B8DB9FFF9ACD70@DB7PR01MB5370.eurprd01.prod.exchangelabs.com>
Message-ID: <r7hskh$34ao$1@ciao.gmane.io>

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: <b1884337-6383-dbc2-90c0-e0b7709bdcbd@DancesWithMice.info>

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 <http://benjdd.com/courses/cs110/spring-2020/pas/infographic/res/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 <http://benjdd.com/courses/cs110/spring-2020/pas/infographic/res/files/poem.txt>
Bible.txt <http://benjdd.com/courses/cs110/spring-2020/pas/infographic/res/files/Bible.txt>
Cat_in_the_Hat.txt <http://benjdd.com/courses/cs110/spring-2020/pas/infographic/res/files/Cat_in_the_Hat.txt>
If you?d like to try the program on other books, you can visit www.gutenberg.org <http://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 <http://benjdd.com/courses/cs110/spring-2020/pas/infographic/res/files/words.txt>
	Cat_in_the_Hat.txt <http://benjdd.com/courses/cs110/spring-2020/pas/infographic/res/files/Cat_in_the_Hat.txt>
	Poetics.txt <http://benjdd.com/courses/cs110/spring-2020/pas/infographic/res/files/Poetics.txt>
	values.txt <http://benjdd.com/courses/cs110/spring-2020/pas/infographic/res/files/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: <CAPM-O+z8cZz35T6azxF0Q53Mof-RU2fp=Q2BVNYfy5S6YoFaFQ@mail.gmail.com>

On Tue, Apr 21, 2020 at 1:32 PM thuhinesh reddy
<thuhineshreddy2002 at gmail.com> 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 <http://benjdd.com/courses/cs110/spring-2020/pas/infographic/res/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 <http://benjdd.com/courses/cs110/spring-2020/pas/infographic/res/files/poem.txt>
> Bible.txt <http://benjdd.com/courses/cs110/spring-2020/pas/infographic/res/files/Bible.txt>
> Cat_in_the_Hat.txt <http://benjdd.com/courses/cs110/spring-2020/pas/infographic/res/files/Cat_in_the_Hat.txt>
> If you?d like to try the program on other books, you can visit www.gutenberg.org <http://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 <http://benjdd.com/courses/cs110/spring-2020/pas/infographic/res/files/words.txt>
>         Cat_in_the_Hat.txt <http://benjdd.com/courses/cs110/spring-2020/pas/infographic/res/files/Cat_in_the_Hat.txt>
>         Poetics.txt <http://benjdd.com/courses/cs110/spring-2020/pas/infographic/res/files/Poetics.txt>
>         values.txt <http://benjdd.com/courses/cs110/spring-2020/pas/infographic/res/files/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: <r7ncfd$2hpu$1@ciao.gmane.io>

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: <A6670A8D-0C29-48AC-9801-A3CEF8588AB9@gmail.com>

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: <CAEEsdtObfRQHsvv5Nuj5miHx0mGwetG0Yx6eddq3Jf24YtAq8w@mail.gmail.com>

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: <CAEEsdtObfRQHsvv5Nuj5miHx0mGwetG0Yx6eddq3Jf24YtAq8w@mail.gmail.com>
References: <CAEEsdtObfRQHsvv5Nuj5miHx0mGwetG0Yx6eddq3Jf24YtAq8w@mail.gmail.com>
Message-ID: <r7pn20$1ikh$1@ciao.gmane.io>

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: <CAEEsdtObfRQHsvv5Nuj5miHx0mGwetG0Yx6eddq3Jf24YtAq8w@mail.gmail.com>
References: <CAEEsdtObfRQHsvv5Nuj5miHx0mGwetG0Yx6eddq3Jf24YtAq8w@mail.gmail.com>
Message-ID: <r7pmqu$12j4$1@ciao.gmane.io>

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: <CAEEsdtObfRQHsvv5Nuj5miHx0mGwetG0Yx6eddq3Jf24YtAq8w@mail.gmail.com>
References: <CAEEsdtObfRQHsvv5Nuj5miHx0mGwetG0Yx6eddq3Jf24YtAq8w@mail.gmail.com>
Message-ID: <CH2PR15MB3560EDDA31BE3721FF6A61CEC3D20@CH2PR15MB3560.namprd15.prod.outlook.com>

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<https://go.microsoft.com/fwlink/?LinkId=550986> for Windows 10

From: shubham sinha<mailto:upwkwd at gmail.com>
Sent: Wednesday, April 22, 2020 8:17 PM
To: tutor at python.org<mailto: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: <CH2PR15MB3560EDDA31BE3721FF6A61CEC3D20@CH2PR15MB3560.namprd15.prod.outlook.com>
References: <CAEEsdtObfRQHsvv5Nuj5miHx0mGwetG0Yx6eddq3Jf24YtAq8w@mail.gmail.com>
 <CH2PR15MB3560EDDA31BE3721FF6A61CEC3D20@CH2PR15MB3560.namprd15.prod.outlook.com>
Message-ID: <r7q1e1$21h4$1@ciao.gmane.io>

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: <CACX3BSg-dkKFTDPEgQ+Fc36Z254obTCjBz7Sc0ByNbbHGV68BA@mail.gmail.com>

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: <CACX3BSg-dkKFTDPEgQ+Fc36Z254obTCjBz7Sc0ByNbbHGV68BA@mail.gmail.com>
References: <CACX3BSg-dkKFTDPEgQ+Fc36Z254obTCjBz7Sc0ByNbbHGV68BA@mail.gmail.com>
Message-ID: <r7t2ah$3hf7$1@ciao.gmane.io>

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: <CACX3BSg-dkKFTDPEgQ+Fc36Z254obTCjBz7Sc0ByNbbHGV68BA@mail.gmail.com>
References: <CACX3BSg-dkKFTDPEgQ+Fc36Z254obTCjBz7Sc0ByNbbHGV68BA@mail.gmail.com>
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: <CAEEsdtM99UtcxgAZcAc=tVptXrX2y+2gUs448Z1UrviVy_Q8eA@mail.gmail.com>

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: <CAEEsdtM99UtcxgAZcAc=tVptXrX2y+2gUs448Z1UrviVy_Q8eA@mail.gmail.com>
References: <CAEEsdtM99UtcxgAZcAc=tVptXrX2y+2gUs448Z1UrviVy_Q8eA@mail.gmail.com>
Message-ID: <ba2d32a9-ad50-d68d-ccfe-778347220d9d@DancesWithMice.info>

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: <CAEEsdtM99UtcxgAZcAc=tVptXrX2y+2gUs448Z1UrviVy_Q8eA@mail.gmail.com>
References: <CAEEsdtM99UtcxgAZcAc=tVptXrX2y+2gUs448Z1UrviVy_Q8eA@mail.gmail.com>
Message-ID: <r7ujmo$3g9o$1@ciao.gmane.io>

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: <CACX3BSg-dkKFTDPEgQ+Fc36Z254obTCjBz7Sc0ByNbbHGV68BA@mail.gmail.com>
References: <CACX3BSg-dkKFTDPEgQ+Fc36Z254obTCjBz7Sc0ByNbbHGV68BA@mail.gmail.com>
Message-ID: <c0bda42a-bbd5-49a4-53e0-bb5f3a7153cc@wichmann.us>

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('<<ListboxSelect>>', 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: <c0bda42a-bbd5-49a4-53e0-bb5f3a7153cc@wichmann.us>
References: <CACX3BSg-dkKFTDPEgQ+Fc36Z254obTCjBz7Sc0ByNbbHGV68BA@mail.gmail.com>
 <c0bda42a-bbd5-49a4-53e0-bb5f3a7153cc@wichmann.us>
Message-ID: <CANDiX9JWkAn1JsK9zUspLSzmyB+bMW+qjjQf6fF43Fy9CKG4tg@mail.gmail.com>

On Fri, Apr 24, 2020 at 7:56 AM Mats Wichmann <mats at wichmann.us> 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: <CANDiX9JWkAn1JsK9zUspLSzmyB+bMW+qjjQf6fF43Fy9CKG4tg@mail.gmail.com>
References: <CANDiX9JWkAn1JsK9zUspLSzmyB+bMW+qjjQf6fF43Fy9CKG4tg@mail.gmail.com>
Message-ID: <20200425073844.GA24715@cskk.homeip.net>

On 24Apr2020 23:07, boB Stepp <robertvstepp at gmail.com> wrote:
>On Fri, Apr 24, 2020 at 7:56 AM Mats Wichmann <mats at wichmann.us> 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 <cs at cskk.id.au>

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 <rjw57 at hermes.cam.ac.uk>

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: <CA+ZkTxvdgHpHrB-v5tn19qa+ZEZu5sWboA9MNtN9fYBzOZ3Tog@mail.gmail.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 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: <CABE1JJ3d3PEHtPx=s5S-3vDNxD0B4HpcGUA3p_vM7mt-K4GQPg@mail.gmail.com>

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: <CAEEsdtObfRQHsvv5Nuj5miHx0mGwetG0Yx6eddq3Jf24YtAq8w@mail.gmail.com>
References: <CAEEsdtObfRQHsvv5Nuj5miHx0mGwetG0Yx6eddq3Jf24YtAq8w@mail.gmail.com>
Message-ID: <CH2PR15MB35601366E5BA252178E327A5C3D10@CH2PR15MB3560.namprd15.prod.outlook.com>

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<https://go.microsoft.com/fwlink/?LinkId=550986> for Windows 10

From: shubham sinha<mailto:upwkwd at gmail.com>
Sent: Wednesday, April 22, 2020 8:17 PM
To: tutor at python.org<mailto: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: <CAEEsdtN38aHnr_RjYJc0t6Hz7myE_2Br637=nKuOuWKoKd4nRw@mail.gmail.com>

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: <CH2PR15MB35601366E5BA252178E327A5C3D10@CH2PR15MB3560.namprd15.prod.outlook.com>
References: <CAEEsdtObfRQHsvv5Nuj5miHx0mGwetG0Yx6eddq3Jf24YtAq8w@mail.gmail.com>
 <CH2PR15MB35601366E5BA252178E327A5C3D10@CH2PR15MB3560.namprd15.prod.outlook.com>
Message-ID: <r81gb9$213b$1@ciao.gmane.io>

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: <CABE1JJ3d3PEHtPx=s5S-3vDNxD0B4HpcGUA3p_vM7mt-K4GQPg@mail.gmail.com>
References: <CABE1JJ3d3PEHtPx=s5S-3vDNxD0B4HpcGUA3p_vM7mt-K4GQPg@mail.gmail.com>
Message-ID: <r81gii$2g6b$1@ciao.gmane.io>

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: <CAEEsdtN38aHnr_RjYJc0t6Hz7myE_2Br637=nKuOuWKoKd4nRw@mail.gmail.com>
References: <CAEEsdtN38aHnr_RjYJc0t6Hz7myE_2Br637=nKuOuWKoKd4nRw@mail.gmail.com>
Message-ID: <r81hln$ued$1@ciao.gmane.io>

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: <CABE1JJ3d3PEHtPx=s5S-3vDNxD0B4HpcGUA3p_vM7mt-K4GQPg@mail.gmail.com>
References: <CABE1JJ3d3PEHtPx=s5S-3vDNxD0B4HpcGUA3p_vM7mt-K4GQPg@mail.gmail.com>
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: <CH2PR15MB35601366E5BA252178E327A5C3D10@CH2PR15MB3560.namprd15.prod.outlook.com>
References: <CAEEsdtObfRQHsvv5Nuj5miHx0mGwetG0Yx6eddq3Jf24YtAq8w@mail.gmail.com>
 <CH2PR15MB35601366E5BA252178E327A5C3D10@CH2PR15MB3560.namprd15.prod.outlook.com>
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: <CANDiX9JWkAn1JsK9zUspLSzmyB+bMW+qjjQf6fF43Fy9CKG4tg@mail.gmail.com>
 <20200425073844.GA24715@cskk.homeip.net>
Message-ID: <CANDiX9+sgzHnKVqubgVKiH=9Kc6j-uYJp0zpJJHHrj6HeMUasA@mail.gmail.com>

On Sat, Apr 25, 2020 at 2:38 AM Cameron Simpson <cs at cskk.id.au> wrote:
>
> On 24Apr2020 23:07, boB Stepp <robertvstepp at gmail.com> wrote:
> >On Fri, Apr 24, 2020 at 7:56 AM Mats Wichmann <mats at wichmann.us> 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 <cs at cskk.id.au> reply-to:tutor at python.org,
boB Stepp <robertvstepp at gmail.com>,
tutor <tutor at python.org>
to:boB Stepp <robertvstepp at gmail.com>

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: <CAEEsdtN38aHnr_RjYJc0t6Hz7myE_2Br637=nKuOuWKoKd4nRw@mail.gmail.com>
References: <CAEEsdtN38aHnr_RjYJc0t6Hz7myE_2Br637=nKuOuWKoKd4nRw@mail.gmail.com>
Message-ID: <e46c03af-0bd1-3f3e-78e6-f6086d16c608@DancesWithMice.info>

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: <e46c03af-0bd1-3f3e-78e6-f6086d16c608@DancesWithMice.info>
References: <CAEEsdtN38aHnr_RjYJc0t6Hz7myE_2Br637=nKuOuWKoKd4nRw@mail.gmail.com>
 <e46c03af-0bd1-3f3e-78e6-f6086d16c608@DancesWithMice.info>
Message-ID: <r82gjh$3f5a$1@ciao.gmane.io>

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: <r81ijp$2vtq$1@ciao.gmane.io>

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: <r82gjh$3f5a$1@ciao.gmane.io>
References: <CAEEsdtN38aHnr_RjYJc0t6Hz7myE_2Br637=nKuOuWKoKd4nRw@mail.gmail.com>
 <e46c03af-0bd1-3f3e-78e6-f6086d16c608@DancesWithMice.info>
 <r82gjh$3f5a$1@ciao.gmane.io>
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: <CANDiX9+sgzHnKVqubgVKiH=9Kc6j-uYJp0zpJJHHrj6HeMUasA@mail.gmail.com>
References: <CANDiX9+sgzHnKVqubgVKiH=9Kc6j-uYJp0zpJJHHrj6HeMUasA@mail.gmail.com>
Message-ID: <20200425231345.GA816@cskk.homeip.net>

On 25Apr2020 12:01, boB Stepp <robertvstepp at gmail.com> wrote:
>On Sat, Apr 25, 2020 at 2:38 AM Cameron Simpson <cs at cskk.id.au> wrote:
>> On 24Apr2020 23:07, boB Stepp <robertvstepp at gmail.com> 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 <cs at cskk.id.au> reply-to:tutor at python.org,
>boB Stepp <robertvstepp at gmail.com>,
>tutor <tutor at python.org>
>to:boB Stepp <robertvstepp at gmail.com>
>
>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 <cs at cskk.id.au>

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: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>

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 <tab> 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 <tab> shifts in
8 columns wide tab stops.  I would like to change this behavior for
when I am in the Python interpreter to have <tab> 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: <CANDiX9Jc8NsQ+Lt6j4JC5=Aw4TMxB1FzCdHDHE8wdat4=c4Esg@mail.gmail.com>

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: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
References: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
Message-ID: <CANDiX9KyNPORpSKyk4iEfen1hLe8BV1c31tyZH_NEmq4nVW0RA@mail.gmail.com>

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 <robertvstepp at gmail.com> 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: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
References: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
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 <tab> 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 <tab> shifts in
> 8 columns wide tab stops.  I would like to change this behavior for
> when I am in the Python interpreter to have <tab> 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: <CANDiX9Jc8NsQ+Lt6j4JC5=Aw4TMxB1FzCdHDHE8wdat4=c4Esg@mail.gmail.com>
References: <CANDiX9Jc8NsQ+Lt6j4JC5=Aw4TMxB1FzCdHDHE8wdat4=c4Esg@mail.gmail.com>
Message-ID: <20200426055559.GA5202@cskk.homeip.net>

On 25Apr2020 23:22, boB Stepp <robertvstepp at gmail.com> 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 <cs at cskk.id.au>

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: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
References: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
Message-ID: <r8398d$1ni8$1@ciao.gmane.io>

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: <CANDiX9Jc8NsQ+Lt6j4JC5=Aw4TMxB1FzCdHDHE8wdat4=c4Esg@mail.gmail.com>
References: <CANDiX9Jc8NsQ+Lt6j4JC5=Aw4TMxB1FzCdHDHE8wdat4=c4Esg@mail.gmail.com>
Message-ID: <r839gr$28tl$1@ciao.gmane.io>

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: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
Message-ID: <r83imc$1bld$1@ciao.gmane.io>

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 <tab> 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 <tab> shifts in
> 8 columns wide tab stops.  I would like to change this behavior for
> when I am in the Python interpreter to have <tab> 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: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
 <r83imc$1bld$1@ciao.gmane.io>
Message-ID: <r83jl4$3cmf$1@ciao.gmane.io>

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: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
 <142a44ac-2f16-e793-dfd5-700427635207@DancesWithMice.info>
Message-ID: <CANDiX9+NM1Q3VmFRCJN7KW=hcr9Dj2cuvrd1spaZtJB-mBJyzg@mail.gmail.com>

On Sat, Apr 25, 2020 at 11:54 PM DL Neil via Tutor <tutor at python.org> 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 <tab> did completion.  And I knew
that if I was in the interpreter in IDLE that <tab> 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: <r8398d$1ni8$1@ciao.gmane.io>
References: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
 <r8398d$1ni8$1@ciao.gmane.io>
Message-ID: <CANDiX9+v1fd5u+Pxn5=Qiu-SYeXTA8S+fD5r5mZfS5Yy=N2Lyg@mail.gmail.com>

On Sun, Apr 26, 2020 at 1:21 AM Alan Gauld via Tutor <tutor at python.org> 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 <tab> 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 <tab>?


--
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: <r83imc$1bld$1@ciao.gmane.io>
References: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
 <r83imc$1bld$1@ciao.gmane.io>
Message-ID: <CANDiX9+G4=Gsm9PeGxh_ph2dF5s4q4s77gaECd=7tzrkdPUerQ@mail.gmail.com>

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: <r83jl4$3cmf$1@ciao.gmane.io>
References: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
 <r83imc$1bld$1@ciao.gmane.io> <r83jl4$3cmf$1@ciao.gmane.io>
Message-ID: <CANDiX9+E5OhXL-_kB1d9Ray+y_ehM7u+PfDn-3naPQ-Z2yXPiQ@mail.gmail.com>

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: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
 <r83imc$1bld$1@ciao.gmane.io> <r83jl4$3cmf$1@ciao.gmane.io>
 <CANDiX9+E5OhXL-_kB1d9Ray+y_ehM7u+PfDn-3naPQ-Z2yXPiQ@mail.gmail.com>
Message-ID: <r84pbt$tnc$1@ciao.gmane.io>

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: <CANDiX9+G4=Gsm9PeGxh_ph2dF5s4q4s77gaECd=7tzrkdPUerQ@mail.gmail.com>
References: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
 <r83imc$1bld$1@ciao.gmane.io>
 <CANDiX9+G4=Gsm9PeGxh_ph2dF5s4q4s77gaECd=7tzrkdPUerQ@mail.gmail.com>
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: <r84ti5$1usb$1@ciao.gmane.io>

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: <CAEEsdtOeT9aymSkH+opNOzz28jU5tmxSQzS=HeWPV8OkJAoWwQ@mail.gmail.com>

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)<ipython-input-75-fd0f708f372c> in <module>      1 # Display your
wordcloud image      2 ----> 3 myimage =
calculate_frequencies(file_contents)      4 plt.imshow(myimage,
interpolation = 'nearest')      5 plt.axis('off')
<ipython-input-74-960d677d987a> 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: <r84pbt$tnc$1@ciao.gmane.io>
References: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
 <r83imc$1bld$1@ciao.gmane.io> <r83jl4$3cmf$1@ciao.gmane.io>
 <CANDiX9+E5OhXL-_kB1d9Ray+y_ehM7u+PfDn-3naPQ-Z2yXPiQ@mail.gmail.com>
 <r84pbt$tnc$1@ciao.gmane.io>
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: <CAEEsdtOeT9aymSkH+opNOzz28jU5tmxSQzS=HeWPV8OkJAoWwQ@mail.gmail.com>
References: <CAEEsdtOeT9aymSkH+opNOzz28jU5tmxSQzS=HeWPV8OkJAoWwQ@mail.gmail.com>
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: <r84ti5$1usb$1@ciao.gmane.io>
References: <r84ti5$1usb$1@ciao.gmane.io>
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: <CANDiX9+v1fd5u+Pxn5=Qiu-SYeXTA8S+fD5r5mZfS5Yy=N2Lyg@mail.gmail.com>
References: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
 <r8398d$1ni8$1@ciao.gmane.io>
 <CANDiX9+v1fd5u+Pxn5=Qiu-SYeXTA8S+fD5r5mZfS5Yy=N2Lyg@mail.gmail.com>
Message-ID: <r85515$1lso$1@ciao.gmane.io>

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 <tab>?

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: <r84ti5$1usb$1@ciao.gmane.io>
References: <r84ti5$1usb$1@ciao.gmane.io>
Message-ID: <20200426232403.GA80286@cskk.homeip.net>

On 26Apr2020 16:13, jim <jf_byrnes at comcast.net> 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 <cs at cskk.id.au>

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: <r84ti5$1usb$1@ciao.gmane.io>
References: <r84ti5$1usb$1@ciao.gmane.io>
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: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
 <r83imc$1bld$1@ciao.gmane.io>
 <CANDiX9+G4=Gsm9PeGxh_ph2dF5s4q4s77gaECd=7tzrkdPUerQ@mail.gmail.com>
 <7b3a616a8a4c447e4b859eb252f47a60@sonic.net>
Message-ID: <r855a6$1lso$2@ciao.gmane.io>

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: <r855a6$1lso$2@ciao.gmane.io>
References: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
 <r83imc$1bld$1@ciao.gmane.io>
 <CANDiX9+G4=Gsm9PeGxh_ph2dF5s4q4s77gaECd=7tzrkdPUerQ@mail.gmail.com>
 <7b3a616a8a4c447e4b859eb252f47a60@sonic.net> <r855a6$1lso$2@ciao.gmane.io>
Message-ID: <CANDiX9+Aq+9jB=7KAJaiT2okQmfnfzSQqjhzpfmMPeONJEEGVw@mail.gmail.com>

On Sun, Apr 26, 2020 at 6:30 PM Alan Gauld via Tutor <tutor at python.org> 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" <tutor-bounces+savageapple850=gmail.com at python.org on behalf of tutor at python.org> 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: <r84ti5$1usb$1@ciao.gmane.io>
 <68f6b494-3298-2d0a-eab8-e3dbe816ed39@DancesWithMice.info>
Message-ID: <CAPM-O+x-TZz1_c2AarGJS9M9ErLNdgT3bVytOuWSpNgHoqq00g@mail.gmail.com>

On Sun, Apr 26, 2020 at 7:09 PM DL Neil via Tutor <tutor at python.org> 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: <r84ti5$1usb$1@ciao.gmane.io>
 <0ce8dcd2-1ecf-8290-3809-40da929651ac@wichmann.us>
Message-ID: <20200426235913.GV31606@apple.graniteweb.com>

* Mats Wichmann <mats at wichmann.us> [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: <CABhyZ36whcvwK5scvpV7FKB_OxAbDf7yar4zbV4Run0-MdUY=g@mail.gmail.com>

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: <CABhyZ36whcvwK5scvpV7FKB_OxAbDf7yar4zbV4Run0-MdUY=g@mail.gmail.com>
References: <CABhyZ36whcvwK5scvpV7FKB_OxAbDf7yar4zbV4Run0-MdUY=g@mail.gmail.com>
Message-ID: <20200427022056.GA19907@cskk.homeip.net>

On 26Apr2020 21:46, Matthew Herzog <matthew.herzog at gmail.com> 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 <cs at cskk.id.au>

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: <dcac9175-c206-a0fb-f9a5-b7c9e545464f@gmail.com>
References: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
 <r83imc$1bld$1@ciao.gmane.io> <dcac9175-c206-a0fb-f9a5-b7c9e545464f@gmail.com>
Message-ID: <CANDiX9JqE=B0wYfmYtaTQkHhjUKXqziXc45CaTo4ojseV=QSPQ@mail.gmail.com>

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: <r84ti5$1usb$1@ciao.gmane.io>
 <68f6b494-3298-2d0a-eab8-e3dbe816ed39@DancesWithMice.info>
Message-ID: <r858rf$1i79$1@ciao.gmane.io>

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: <r84ti5$1usb$1@ciao.gmane.io>
 <20200426232403.GA80286@cskk.homeip.net>
Message-ID: <r859et$2pjo$1@ciao.gmane.io>

On 4/26/20 6:24 PM, Cameron Simpson wrote:
> On 26Apr2020 16:13, jim <jf_byrnes at comcast.net> 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: <r84ti5$1usb$1@ciao.gmane.io>
 <0ce8dcd2-1ecf-8290-3809-40da929651ac@wichmann.us>
Message-ID: <r859ro$3ibk$1@ciao.gmane.io>

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: <r84ti5$1usb$1@ciao.gmane.io>
 <0ce8dcd2-1ecf-8290-3809-40da929651ac@wichmann.us>
 <20200426235913.GV31606@apple.graniteweb.com>
Message-ID: <r85a8h$edl$1@ciao.gmane.io>

On 4/26/20 6:59 PM, David Rock wrote:
> * Mats Wichmann <mats at wichmann.us> [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: <r84ti5$1usb$1@ciao.gmane.io>
References: <r84ti5$1usb$1@ciao.gmane.io>
Message-ID: <20200427105813.GA61551@cskk.homeip.net>

On 26Apr2020 16:13, jim <jf_byrnes at comcast.net> 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 <cs at cskk.id.au>

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: <r84ti5$1usb$1@ciao.gmane.io>
 <20200427105813.GA61551@cskk.homeip.net>
Message-ID: <r870hh$34rl$1@ciao.gmane.io>

On 4/27/20 5:58 AM, Cameron Simpson wrote:
> On 26Apr2020 16:13, jim <jf_byrnes at comcast.net> 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: <CABhyZ36whcvwK5scvpV7FKB_OxAbDf7yar4zbV4Run0-MdUY=g@mail.gmail.com>
 <20200427022056.GA19907@cskk.homeip.net>
Message-ID: <CACL+1as85=CYMGMzUF8aa+nzhnBA_nmv5CY-yu76Tyq4OKj8Cw@mail.gmail.com>

On 4/26/20, Cameron Simpson <cs at cskk.id.au> 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: <drawing-20200427192129@ram.dialup.fu-berlin.de>
References: <drawing-20200427192129@ram.dialup.fu-berlin.de>
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: <CANDiX9JqE=B0wYfmYtaTQkHhjUKXqziXc45CaTo4ojseV=QSPQ@mail.gmail.com>
References: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
 <r83imc$1bld$1@ciao.gmane.io> <dcac9175-c206-a0fb-f9a5-b7c9e545464f@gmail.com>
 <CANDiX9JqE=B0wYfmYtaTQkHhjUKXqziXc45CaTo4ojseV=QSPQ@mail.gmail.com>
Message-ID: <CAMPXz=q79-8wvvZ=AMW9m25eYVkYjeFqyUku8pZ4yO8SkP3Wig@mail.gmail.com>

On Mon, 27 Apr 2020 at 14:08, boB Stepp <robertvstepp at gmail.com> 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: <CAMPXz=q79-8wvvZ=AMW9m25eYVkYjeFqyUku8pZ4yO8SkP3Wig@mail.gmail.com>
References: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
 <r83imc$1bld$1@ciao.gmane.io> <dcac9175-c206-a0fb-f9a5-b7c9e545464f@gmail.com>
 <CANDiX9JqE=B0wYfmYtaTQkHhjUKXqziXc45CaTo4ojseV=QSPQ@mail.gmail.com>
 <CAMPXz=q79-8wvvZ=AMW9m25eYVkYjeFqyUku8pZ4yO8SkP3Wig@mail.gmail.com>
Message-ID: <CANDiX9JcoiDybFAsPF9bKc2gSiGUQS8zmnAuZgeCt1cpiD_WJg@mail.gmail.com>

On Mon, Apr 27, 2020 at 7:33 PM David <bouncingcats at gmail.com> 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: <r896q0$2mln$1@ciao.gmane.io>

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: <CAAaDumQyhJT=WqhbEJyvpXnXpKFdAfiGVGi2E8kYTf5peDXN7w@mail.gmail.com>

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: <CAAaDumQyhJT=WqhbEJyvpXnXpKFdAfiGVGi2E8kYTf5peDXN7w@mail.gmail.com>
References: <CAAaDumQyhJT=WqhbEJyvpXnXpKFdAfiGVGi2E8kYTf5peDXN7w@mail.gmail.com>
Message-ID: <b6351f28-0f09-3865-0511-5bc6deb41929@wichmann.us>

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: <r896q0$2mln$1@ciao.gmane.io>
References: <r896q0$2mln$1@ciao.gmane.io>
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: <b6351f28-0f09-3865-0511-5bc6deb41929@wichmann.us>
References: <CAAaDumQyhJT=WqhbEJyvpXnXpKFdAfiGVGi2E8kYTf5peDXN7w@mail.gmail.com>
 <b6351f28-0f09-3865-0511-5bc6deb41929@wichmann.us>
Message-ID: <CAAaDumRr=E75toLbvSHz5NDdPw1A72NY+5P-Q0=f=JCz6QGP3A@mail.gmail.com>

excellent, thank you.
I will try this

On Tue, Apr 28, 2020 at 12:12 PM Mats Wichmann <mats at wichmann.us> 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: <CABhyZ36whcvwK5scvpV7FKB_OxAbDf7yar4zbV4Run0-MdUY=g@mail.gmail.com>
References: <CABhyZ36whcvwK5scvpV7FKB_OxAbDf7yar4zbV4Run0-MdUY=g@mail.gmail.com>
Message-ID: <c92254b6-0d0d-58d9-2426-23d90bb21da3@wichmann.us>

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: <r896q0$2mln$1@ciao.gmane.io>
References: <r896q0$2mln$1@ciao.gmane.io>
Message-ID: <CAKJDb-OP1S-iW7LOAhgiJzU-y4dmuDCMsjnmztgQfH0ojy3JUQ@mail.gmail.com>

On Tue, Apr 28, 2020 at 7:16 AM Alan Gauld via Tutor <tutor at python.org> 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: <CAOk6yMU_==YEnid=M6+akE1zOeOzFAZ03aTaF-vRBAQJ1rpyuw@mail.gmail.com>

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: <CAOk6yMU_==YEnid=M6+akE1zOeOzFAZ03aTaF-vRBAQJ1rpyuw@mail.gmail.com>
References: <CAOk6yMU_==YEnid=M6+akE1zOeOzFAZ03aTaF-vRBAQJ1rpyuw@mail.gmail.com>
Message-ID: <r8adm0$1qds$1@ciao.gmane.io>

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: <CAOOWgcE_CUH+7QO6wuk=O1jRN9S0ZT6mFaFynRwFWPrfBMSj4w@mail.gmail.com>



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: <CAOOWgcE_CUH+7QO6wuk=O1jRN9S0ZT6mFaFynRwFWPrfBMSj4w@mail.gmail.com>
References: <CAOOWgcE_CUH+7QO6wuk=O1jRN9S0ZT6mFaFynRwFWPrfBMSj4w@mail.gmail.com>
Message-ID: <a50d160e-4161-755d-b276-00e40aba8e41@wichmann.us>

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: <CAOOWgcE_CUH+7QO6wuk=O1jRN9S0ZT6mFaFynRwFWPrfBMSj4w@mail.gmail.com>
References: <CAOOWgcE_CUH+7QO6wuk=O1jRN9S0ZT6mFaFynRwFWPrfBMSj4w@mail.gmail.com>
Message-ID: <r8c8o1$1k41$1@ciao.gmane.io>

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: <r896q0$2mln$1@ciao.gmane.io>
 <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: <r896q0$2mln$1@ciao.gmane.io>
 <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: <CANDiX9JqE=B0wYfmYtaTQkHhjUKXqziXc45CaTo4ojseV=QSPQ@mail.gmail.com>
References: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
 <r83imc$1bld$1@ciao.gmane.io>
 <dcac9175-c206-a0fb-f9a5-b7c9e545464f@gmail.com>
 <CANDiX9JqE=B0wYfmYtaTQkHhjUKXqziXc45CaTo4ojseV=QSPQ@mail.gmail.com>
Message-ID: <ef810b91542204020f8608c3f24eaba8@sonic.net>

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: <r8c8o1$1k41$1@ciao.gmane.io>
References: <CAOOWgcE_CUH+7QO6wuk=O1jRN9S0ZT6mFaFynRwFWPrfBMSj4w@mail.gmail.com>
 <r8c8o1$1k41$1@ciao.gmane.io>
Message-ID: <CAB6eaA6p5_oLN8b1=kra_cWcM9w7wBn7bGp0fUZXV=qU6q0UjA@mail.gmail.com>

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
<https://treyhunner.com/2019/04/why-you-shouldnt-inherit-from-list-and-dict-in-python/>
.)

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 <tutor at python.org>
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: <ef810b91542204020f8608c3f24eaba8@sonic.net>
References: <CANDiX9+UKA7tx1e=3HB29W8iFMKSoGuR0q5s9tZmSyLMWJYB8Q@mail.gmail.com>
 <r83imc$1bld$1@ciao.gmane.io> <dcac9175-c206-a0fb-f9a5-b7c9e545464f@gmail.com>
 <CANDiX9JqE=B0wYfmYtaTQkHhjUKXqziXc45CaTo4ojseV=QSPQ@mail.gmail.com>
 <ef810b91542204020f8608c3f24eaba8@sonic.net>
Message-ID: <CANDiX9Js7x2Xwa_8o3N+kxsUbZqToDi7+qci1K9vZw7Te6_g_A@mail.gmail.com>

On Wed, Apr 29, 2020 at 5:28 PM Alex Kleider <akleider at sonic.net> 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: <CA+pzcezHP9RuF+ABH=2gaJ52CkqZ1NsKbn8vyqeQHYpe=eb=WQ@mail.gmail.com>

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