From learn2program at gmail.com  Fri Oct  1 06:30:53 2021
From: learn2program at gmail.com (Alan Gauld)
Date: Fri, 1 Oct 2021 11:30:53 +0100
Subject: [Tutor] precision handling
In-Reply-To: <CAOacnXnS0mxH2zjmd97GCodQkOZQZq0Y5p55TsTVGAVEF4dxTA@mail.gmail.com>
References: <CAOacnXkVY0kgceuyU=Kcvat6c+wJvWXqWzWWHGyqeiFZDQWLRA@mail.gmail.com>
 <sj566q$16n3$1@ciao.gmane.io>
 <CAOacnXnS0mxH2zjmd97GCodQkOZQZq0Y5p55TsTVGAVEF4dxTA@mail.gmail.com>
Message-ID: <21f94f80-e335-30fa-4fbd-85de063ae02c@yahoo.co.uk>


On 01/10/2021 09:30, Msd De wrote:
> Thank you for your email.
>
> Part of my code
> M = [[1,0],[0,1]]
> for k in range(Nslice,1,-1):
> ? WFjAFjB = F_jA[k]*DF_jB[k] - ?F_jB[k]*DF_jA[k]
> ? Mj11 = (DF_jB[k]*F_jm1A[k]- F_jB[k]*DF_jm1A[k])/WFjAFjB
> ? Mj12 = (DF_jB[k]*F_jm1B[k] - F_jB[k]*DF_jm1B[k])/WFjAFjB
> ? Mj21 = (F_jA[k]*DF_jm1A[k] - DF_jA[k]*F_jm1A[k])/WFjAFjB
> ? Mj22 = (F_jA[k]*DF_jm1B[k] - DF_jA[k]*F_jm1B[k])/WFjAFjB
> ? Mj = [[Mj11,Mj12],[Mj21,Mj22]]
> ? test1 = DF_jB[k]*F_jm1B[k]
> ? test2= - F_jB[k]*DF_jm1B[k]
> ? print round(Decimal(test1),10),round(Decimal(test2),10)
> ? M = np.dot(M,Mj)
>
OK, So you are not actually comparing 2 constants but rather the results
of calculations.

Those calculations will almost inevitably result in slight differences
in the results even
if they should result in the same answer.

OUTPUT:
> -36027335809.8 36027335809.8
> -3.77786532033e+11 3.77786532033e+11
> -4.23206814691e+12 4.23206814691e+12
> -5.05577734264e+13 5.05577734264e+13
> -6.43053645277e+14 6.43053645277e+14
> -8.69512959787e+15 8.69512959787e+15
> -1.24814507298e+17 1.24814507298e+17
> -1.89952420024e+18 1.89952420024e+18
> -3.06113023909e+19 3.06113023909e+19
>
And looking at these outputs they are not actually the same number.
One is negative, the other positive. That could make a difference too.

BTW. Converting to Decimal for the print stage is not going to
help the calculation precision

Sometimes modifying the order of the operations can make a difference too.

For example:

a/b + c/b

can sometimes give a better result than

(a+c)/b

because the two numbers may be closer in magnitudes.
But at other times it may be worse!

Working with floats is a precarious pastime.

-- 
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 Oct  1 06:50:07 2021
From: PyTutor at DancesWithMice.info (dn)
Date: Fri, 1 Oct 2021 23:50:07 +1300
Subject: [Tutor] precision handling
In-Reply-To: <21f94f80-e335-30fa-4fbd-85de063ae02c@yahoo.co.uk>
References: <CAOacnXkVY0kgceuyU=Kcvat6c+wJvWXqWzWWHGyqeiFZDQWLRA@mail.gmail.com>
 <sj566q$16n3$1@ciao.gmane.io>
 <CAOacnXnS0mxH2zjmd97GCodQkOZQZq0Y5p55TsTVGAVEF4dxTA@mail.gmail.com>
 <21f94f80-e335-30fa-4fbd-85de063ae02c@yahoo.co.uk>
Message-ID: <747a70ce-40b0-f954-2760-5f492f9d24ea@DancesWithMice.info>

On 01/10/2021 23.30, Alan Gauld wrote:
> On 01/10/2021 09:30, Msd De wrote:
...

> Sometimes modifying the order of the operations can make a difference too.
> 
> For example:
> 
> a/b + c/b
> 
> can sometimes give a better result than
> 
> (a+c)/b
> 
> because the two numbers may be closer in magnitudes.
> But at other times it may be worse!
> 
> Working with floats is a precarious pastime.

Perhaps the NA-entry applies?
https://xkcd.com/2520/ (Symbols and what they mean)
-- 
Regards,
=dn

From wlfraed at ix.netcom.com  Fri Oct  1 13:20:23 2021
From: wlfraed at ix.netcom.com (Dennis Lee Bieber)
Date: Fri, 01 Oct 2021 13:20:23 -0400
Subject: [Tutor] precision handling
References: <CAOacnXkVY0kgceuyU=Kcvat6c+wJvWXqWzWWHGyqeiFZDQWLRA@mail.gmail.com>
 <sj566q$16n3$1@ciao.gmane.io>
 <CAOacnXnS0mxH2zjmd97GCodQkOZQZq0Y5p55TsTVGAVEF4dxTA@mail.gmail.com>
 <21f94f80-e335-30fa-4fbd-85de063ae02c@yahoo.co.uk>
 <747a70ce-40b0-f954-2760-5f492f9d24ea@DancesWithMice.info>
Message-ID: <jagelg9jue6uakuuth7jpa51da2m646uun@4ax.com>

On Fri, 1 Oct 2021 23:50:07 +1300, dn via Tutor <tutor at python.org>
declaimed the following:


>Perhaps the NA-entry applies?
>https://xkcd.com/2520/ (Symbols and what they mean)

	I'd have recommended a copy of
https://www.amazon.com/Real-Computing-Made-Engineering-Calculations/dp/0486442217/


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


From marcus.luetolf at bluewin.ch  Fri Oct  1 14:23:24 2021
From: marcus.luetolf at bluewin.ch (marcus.luetolf at bluewin.ch)
Date: Fri, 1 Oct 2021 20:23:24 +0200
Subject: [Tutor] infinite while loop
Message-ID: <003201d7b6f1$6bf80970$43e81c50$@bluewin.ch>

Hello Experts,

I'm stuck with not beeig able to stop the while loop in the script below
which should

yield the  minimumFixedMonthlyPayment (in steps of 10) to payoff a balance
in 12 months

according to the variables set.

 

The script below creates an indefinite loop and I don't understand why the
the loop

does not stop when the variable "previousBalance > yields negative values
despite

the condition set for the while loop.

Where is my mistake ?

 

>balance = 1000

>previousBalance = balance

 

>minimumFixedMonthlyPayment = 10

>annualInterestRate = 0.2

>monthlyInterestRate = (annualInterestRate) / 12.0

 

>while previousBalance > 0.0:

 

        >for i in range(12):

            >monthlyPaidBalance = (previousBalance) -
(minimumFixedMonthlyPayment)

            >updatedBalanceEachMonth = (monthlyPaidBalance) +
(monthlyInterestRate * monthlyPaidBalance)

            >previousBalance = updatedBalanceEachMonth

            >print('previousBalance:', round(previousBalance,2))

            >print('minimumFixedMonthlyPayment:',
minimumFixedMonthlyPayment)

        >previousBalance = balance

        >minimumFixedMonthlyPayment += 10

>print(previousBalance, minimumFixedMonthlyPayment)

 

 


From wlfraed at ix.netcom.com  Fri Oct  1 14:48:22 2021
From: wlfraed at ix.netcom.com (Dennis Lee Bieber)
Date: Fri, 01 Oct 2021 14:48:22 -0400
Subject: [Tutor] infinite while loop
References: <003201d7b6f1$6bf80970$43e81c50$@bluewin.ch>
Message-ID: <3rlelg5eaeousi0mrlhbjs2nlc7gc3nq4i@4ax.com>

On Fri, 1 Oct 2021 20:23:24 +0200, <marcus.luetolf at bluewin.ch> declaimed
the following:

>
>Where is my mistake ?
>
> 
>
>>balance = 1000

>        >previousBalance = balance
>

	balance never changes, so you are setting previousBalance back to +1000
each time the loop processes.



-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


From PyTutor at DancesWithMice.info  Fri Oct  1 15:06:20 2021
From: PyTutor at DancesWithMice.info (dn)
Date: Sat, 2 Oct 2021 08:06:20 +1300
Subject: [Tutor] precision handling
In-Reply-To: <jagelg9jue6uakuuth7jpa51da2m646uun@4ax.com>
References: <CAOacnXkVY0kgceuyU=Kcvat6c+wJvWXqWzWWHGyqeiFZDQWLRA@mail.gmail.com>
 <sj566q$16n3$1@ciao.gmane.io>
 <CAOacnXnS0mxH2zjmd97GCodQkOZQZq0Y5p55TsTVGAVEF4dxTA@mail.gmail.com>
 <21f94f80-e335-30fa-4fbd-85de063ae02c@yahoo.co.uk>
 <747a70ce-40b0-f954-2760-5f492f9d24ea@DancesWithMice.info>
 <jagelg9jue6uakuuth7jpa51da2m646uun@4ax.com>
Message-ID: <208a9207-efbe-9d77-9f4d-2b7599585108@DancesWithMice.info>

On 02/10/2021 06.20, Dennis Lee Bieber wrote:
> On Fri, 1 Oct 2021 23:50:07 +1300, dn via Tutor <tutor at python.org>
> declaimed the following:
> 
> 
>> Perhaps the NA-entry applies?
>> https://xkcd.com/2520/ (Symbols and what they mean)
> 
> 	I'd have recommended a copy of
> https://www.amazon.com/Real-Computing-Made-Engineering-Calculations/dp/0486442217/

Not only do few institutions teach Numerical Programming these days, but
I've noticed numbers of programmers 'coming through' who don't have
knowledge of, or even a decent mental model of, how a CPU works - up to
and including a failure to have anything more than an understanding of
how a chart of binary and decimal numbers 'line up'.

Which is why we see questions like this one (no reflection on the OP),
and wonder "why?", given that we (dinosaurs) were trained to cope with
the limitations of floating-point without a second-thought.
-- 
Regards,
=dn

From wlfraed at ix.netcom.com  Fri Oct  1 17:28:05 2021
From: wlfraed at ix.netcom.com (Dennis Lee Bieber)
Date: Fri, 01 Oct 2021 17:28:05 -0400
Subject: [Tutor] precision handling
References: <CAOacnXkVY0kgceuyU=Kcvat6c+wJvWXqWzWWHGyqeiFZDQWLRA@mail.gmail.com>
 <sj566q$16n3$1@ciao.gmane.io>
 <CAOacnXnS0mxH2zjmd97GCodQkOZQZq0Y5p55TsTVGAVEF4dxTA@mail.gmail.com>
 <21f94f80-e335-30fa-4fbd-85de063ae02c@yahoo.co.uk>
 <747a70ce-40b0-f954-2760-5f492f9d24ea@DancesWithMice.info>
 <jagelg9jue6uakuuth7jpa51da2m646uun@4ax.com>
 <208a9207-efbe-9d77-9f4d-2b7599585108@DancesWithMice.info>
Message-ID: <62velgdpldbo9j9o0spg2vmq9uv1trmfuu@4ax.com>

On Sat, 2 Oct 2021 08:06:20 +1300, dn via Tutor <tutor at python.org>
declaimed the following:

>
>Not only do few institutions teach Numerical Programming these days, but
>I've noticed numbers of programmers 'coming through' who don't have
>knowledge of, or even a decent mental model of, how a CPU works - up to
>and including a failure to have anything more than an understanding of
>how a chart of binary and decimal numbers 'line up'.
>
	Whereas I recall (vaguely -- it has been near 45 years) an assignment
to implement single precision floating point +-*/ using 32-bit integer
operations (even though the campus mainframe had integer, float, and BCD
arithmetic modules -- the BCD board failed one term, which essentially
killed all COBOL courses until a replacement BCD unit could be obtained).


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


From marcus.luetolf at bluewin.ch  Sat Oct  2 05:13:53 2021
From: marcus.luetolf at bluewin.ch (=?utf-8?Q?Marcus_L=C3=BCtolf?=)
Date: Sat, 2 Oct 2021 11:13:53 +0200
Subject: [Tutor] infinite while loop
In-Reply-To: <20211001184659.GA22451@huginn>
References: <003201d7b6f1$6bf80970$43e81c50$@bluewin.ch>
 <20211001184659.GA22451@huginn>
Message-ID: <000a01d7b76d$d2584f00$7708ed00$@bluewin.ch>

Thank you. 
The previousBalance is set back to 1000 after each run oft he for loop intentionally for the
following for loops should run with minimumFixedMonthlyPayment each time increased by 10
til previousBalance get's negative.

The while loop  should then stop, when   previousBalance  gets smaller than 0 but it doesn't.
Might it be a problem of scope ?


-----Urspr?ngliche Nachricht-----
Von: Susana <lists at linguarum.net> 
Gesendet: Freitag, 1. Oktober 2021 20:47
An: marcus.luetolf at bluewin.ch
Cc: tutor at python.org
Betreff: Re: [Tutor] infinite while loop

Hi,

"previousBalance" reaches while condition (< 0.0) inside the for loop, but then it is set to the value of "balance" in the line:

previousBalance = balance

So I think that "previousBalance" is always 1000 when the while condition is checked.

Hope this helps.

Cheers,
-- 
Susana Sotelo Doc?o                                  gpg-id: 0E9BEDA4


marcus.luetolf at bluewin.ch escreveu:
> Hello Experts,
> 
> I'm stuck with not beeig able to stop the while loop in the script 
> below which should
> 
> yield the  minimumFixedMonthlyPayment (in steps of 10) to payoff a 
> balance in 12 months
> 
> according to the variables set.
> 
>  
> 
> The script below creates an indefinite loop and I don't understand why 
> the the loop
> 
> does not stop when the variable "previousBalance > yields negative 
> values despite
> 
> the condition set for the while loop.
> 
> Where is my mistake ?
> 
>  
> 
> >balance = 1000
> 
> >previousBalance = balance
> 
>  
> 
> >minimumFixedMonthlyPayment = 10
> 
> >annualInterestRate = 0.2
> 
> >monthlyInterestRate = (annualInterestRate) / 12.0
> 
>  
> 
> >while previousBalance > 0.0:
> 
>  
> 
>         >for i in range(12):
> 
>             >monthlyPaidBalance = (previousBalance) -
> (minimumFixedMonthlyPayment)
> 
>             >updatedBalanceEachMonth = (monthlyPaidBalance) + 
> (monthlyInterestRate * monthlyPaidBalance)
> 
>             >previousBalance = updatedBalanceEachMonth
> 
>             >print('previousBalance:', round(previousBalance,2))
> 
>             >print('minimumFixedMonthlyPayment:',
> minimumFixedMonthlyPayment)
> 
>         >previousBalance = balance
> 
>         >minimumFixedMonthlyPayment += 10
> 
> >print(previousBalance, minimumFixedMonthlyPayment)
> 
>  
> 
>  
> 
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https:



From leamhall at gmail.com  Sat Oct  2 06:14:52 2021
From: leamhall at gmail.com (Leam Hall)
Date: Sat, 2 Oct 2021 05:14:52 -0500
Subject: [Tutor] infinite while loop
In-Reply-To: <000a01d7b76d$d2584f00$7708ed00$@bluewin.ch>
References: <003201d7b6f1$6bf80970$43e81c50$@bluewin.ch>
 <20211001184659.GA22451@huginn> <000a01d7b76d$d2584f00$7708ed00$@bluewin.ch>
Message-ID: <d635a0f1-eb7f-3bc0-396d-4a7f5b13764a@gmail.com>

I put the following line right under the while loop, and at the same indentation as the for loop:

	print("In while, the previous balance is: {}.".format(previousBalance))

Maybe give that a try and see what it tells you?

Leam

On 10/2/21 4:13 AM, Marcus L?tolf wrote:
> Thank you.
> The previousBalance is set back to 1000 after each run oft he for loop intentionally for the
> following for loops should run with minimumFixedMonthlyPayment each time increased by 10
> til previousBalance get's negative.
> 
> The while loop  should then stop, when   previousBalance  gets smaller than 0 but it doesn't.
> Might it be a problem of scope ?
> 
> 
> -----Urspr?ngliche Nachricht-----
> Von: Susana <lists at linguarum.net>
> Gesendet: Freitag, 1. Oktober 2021 20:47
> An: marcus.luetolf at bluewin.ch
> Cc: tutor at python.org
> Betreff: Re: [Tutor] infinite while loop
> 
> Hi,
> 
> "previousBalance" reaches while condition (< 0.0) inside the for loop, but then it is set to the value of "balance" in the line:
> 
> previousBalance = balance
> 
> So I think that "previousBalance" is always 1000 when the while condition is checked.
> 
> Hope this helps.
> 
> Cheers,
> 

-- 
Systems Programmer         (reuel.net/resume)
Scribe: The Domici War     (domiciwar.net)
General Ne'er-do-well      (github.com/LeamHall)


From alan.gauld at yahoo.co.uk  Sat Oct  2 08:05:06 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 2 Oct 2021 13:05:06 +0100
Subject: [Tutor] infinite while loop
In-Reply-To: <000a01d7b76d$d2584f00$7708ed00$@bluewin.ch>
References: <003201d7b6f1$6bf80970$43e81c50$@bluewin.ch>
 <20211001184659.GA22451@huginn> <000a01d7b76d$d2584f00$7708ed00$@bluewin.ch>
Message-ID: <sj9hti$124b$1@ciao.gmane.io>

On 02/10/2021 10:13, Marcus L?tolf wrote:
> Thank you. 
> The previousBalance is set back to 1000 after each run oft he for loop intentionally for the
> following for loops should run with minimumFixedMonthlyPayment each time increased by 10
> til previousBalance get's negative.

but you do that insie the while loop, so at the end of the loop it is
always 1000. So the loop never ends.

Try setting it at the top of the while loop, before entering the for loop.

> The while loop  should then stop, when   previousBalance  gets smaller than 0 but it doesn't.

The while loop only tests the value at the end of the loop block,
it does not detect changes inside the loop. So you need to ensure that
the value at the end of the loop is the one you want to be tested.


-- 
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 rajeshkoot190 at gmail.com  Sat Oct  2 08:11:00 2021
From: rajeshkoot190 at gmail.com (Rajesh Koot)
Date: Sat, 2 Oct 2021 17:41:00 +0530
Subject: [Tutor] Code correction
Message-ID: <CAMDWJkkO6qwtbkAXd_RJ7di0WmaMOcobQY6i58bCF+8hT4zwZQ@mail.gmail.com>

below is a code attached to scrape videos from instagram groups we are
following
Can you please tell me which all fields are needed to fill other than
username and password

# scrape_videos.py scrapes all the videos from pages we are following
def scrapeVideos(username = "",
                 password = "",
                 output_folder = "",
                 days = 1):

    print("Starting Scraping")

    L = instaloader.Instaloader()

    # Login or load session for loader
    L.login(username, password)
    profile = instaloader.Profile.from_username(L.context, username)
    following = profile.get_followees()
    print(following)

    for profile in following:
        acc = profile.username
        looter = ProfileLooter(acc, videos_only=True,
template="{id}-{username}-{width}-{height}")
        if not looter.logged_in():
            looter.login(username, password)
        print("Scraping From Account: " + acc)

        today = datetime.date.today()
        timeframe = (today, today -
dateutil.relativedelta.relativedelta(days=days))
        numDowloaded = looter.download(output_folder, media_count=30,
timeframe=timeframe)
        print("Downloaded " + str(numDowloaded) + " videos successfully")
        print("")

From alan.gauld at yahoo.co.uk  Sat Oct  2 12:44:47 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 2 Oct 2021 17:44:47 +0100
Subject: [Tutor] Code correction
In-Reply-To: <CAMDWJkkO6qwtbkAXd_RJ7di0WmaMOcobQY6i58bCF+8hT4zwZQ@mail.gmail.com>
References: <CAMDWJkkO6qwtbkAXd_RJ7di0WmaMOcobQY6i58bCF+8hT4zwZQ@mail.gmail.com>
Message-ID: <sja29v$rlg$1@ciao.gmane.io>

On 02/10/2021 13:11, Rajesh Koot wrote:
> below is a code attached to scrape videos from instagram groups we are
> following
> Can you please tell me which all fields are needed to fill other than
> username and password
> 
> # scrape_videos.py scrapes all the videos from pages we are following
> def scrapeVideos(username = "",
>                  password = "",
>                  output_folder = "",
>                  days = 1):
> 
>     print("Starting Scraping")
> 
>     L = instaloader.Instaloader()

This list is for questions about the Python language and its
standard libraries.

Questions about third party libraries should really be directed to their
support forum or the library author.

However, in this case, I suspect the question is not even about the
library but more about how instagram itself works. For that you may
need to do some testing/experimenting. Thats all part of programming...


-- 
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 wlfraed at ix.netcom.com  Sat Oct  2 13:22:52 2021
From: wlfraed at ix.netcom.com (Dennis Lee Bieber)
Date: Sat, 02 Oct 2021 13:22:52 -0400
Subject: [Tutor] infinite while loop
References: <003201d7b6f1$6bf80970$43e81c50$@bluewin.ch>
 <20211001184659.GA22451@huginn> <000a01d7b76d$d2584f00$7708ed00$@bluewin.ch>
Message-ID: <1uvglgt4q8533d7db19rgg2nru53ckd4hu@4ax.com>


	Please ensure you reply to the LIST -- not to individuals.

On Sat, 2 Oct 2021 11:13:53 +0200, Marcus L?tolf
<marcus.luetolf at bluewin.ch> declaimed the following:

	What, exactly, are you attempting to calculate? The minimum payment
that will pay off a loan in 12 months?


>Thank you. 
>The previousBalance is set back to 1000 after each run oft he for loop intentionally for the
>following for loops should run with minimumFixedMonthlyPayment each time increased by 10
>til previousBalance get's negative.
>

	The for loop is, I presume, supposed to span 12 months -- one year. BUT
you are resetting "previousBalance" (which is a poor name, as it really is
the /remainingBalance/) to 1000 at the END of EACH MONTH -- so the
remaining balance never decreases inside the for loop. Furthermore, you are
ALSO changing (incrementing) the monthly payment EACH MONTH -- you do not
have a "fixed monthly payment" inside the for loop.


	BOTH the "fixed payment" and the initial balance need to be set BETWEEN
the "while" and the "for" loops. The for loop should only adjust the
remaining balance by applying the fixed payment (deduction) for the month
and interest (addition) for that month. The order you do those could
differentiate between interest before payment, or interest after payment.

set payment to 0.0
while True:
	set remaining balance to initial balance
	increment payment to next value
	for _ in range(12):
		apply payment to remaining balance
		apply interest to remaining balance
		if remaining balance <= 0.0: break
	if remaining balance <= 0.0: break

NOTE: I'm using the "while True" with an "if ...: break" to avoid the need
to "prime" the while loop with...

set remaining balance to initial balance
while remaining balance > 0.0:
	set remaining balance to initial balance

... however it requires the two if/break lines as the first exits the month
loop, and the second exits the while loop.

	I'm not going to show the code, but will show the last cycle of running
my implementation of this iterative approach...

period: 11	balance: 14.934028775505954	payment: 90.0
current payment: 100.0
period: 0	balance: 915.0	payment: 100.0
period: 1	balance: 828.5833333333333	payment: 100.0
period: 2	balance: 740.7263888888888	payment: 100.0
period: 3	balance: 651.4051620370369	payment: 100.0
period: 4	balance: 560.5952480709875	payment: 100.0
period: 5	balance: 468.27183553883725	payment: 100.0
period: 6	balance: 374.4096994644845	payment: 100.0
period: 7	balance: 278.9831944555592	payment: 100.0
period: 8	balance: 181.9662476964852	payment: 100.0
period: 9	balance: 83.33235182475994	payment: 100.0
period: 10	balance: -16.94544231149406	payment: 100.0
>>> 

	With your payment incrementing by 10, my solution case only runs 11
periods (months) on payment 100. Payment 90 still owes ~15 on the 12th
period.

NOTE: that this (minimum payment to pay off a loan in n-periods) is just
one variant of "time value of money" equations, and all of those have
solutions that do NOT require a loop.

http://www.frickcpa.com/tvom/tvom_amort.asp

Not a loop in sight -- just a straight up exponential equation.

>>> initialBalance = 1000
>>> annualRate = 0.2
>>> numberYears = 1
>>> periodYear = 12
>>> numberPeriods = numberYears * periodYear
>>> periodRate = annualRate / periodYear
>>> 
>>> payment = initialBalance * (periodRate / 
... 		(1.0 - (1.0 + periodRate) ** (-numberPeriods)))
>>> payment
92.63450589708033
>>> 

	Note: If you round down (92.63) that payment you will owe a residual of
a few cents at the end of the year. Rounding up (92.64) will result in the
last payment being a touch smaller.


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


From marcus.luetolf at bluewin.ch  Sat Oct  2 18:14:01 2021
From: marcus.luetolf at bluewin.ch (marcus.luetolf at bluewin.ch)
Date: Sun, 3 Oct 2021 00:14:01 +0200
Subject: [Tutor] infinite while loop
In-Reply-To: <1uvglgt4q8533d7db19rgg2nru53ckd4hu@4ax.com>
References: <003201d7b6f1$6bf80970$43e81c50$@bluewin.ch>
 <20211001184659.GA22451@huginn> <000a01d7b76d$d2584f00$7708ed00$@bluewin.ch>
 <1uvglgt4q8533d7db19rgg2nru53ckd4hu@4ax.com>
Message-ID: <002301d7b7da$cdbe8e10$693baa30$@bluewin.ch>

Many thanks.
I've applied your comments to my script and put it into a function as part
of a problem set of the edx 6.00.1x course.
Therefore, I'm bound to use the prescribed variable names etc. and can't use
the equation from http://www.frickcpa.com/tvom/tvom_amort.asp.
The function payOff(...) works well, but has to be refined as it takes to
many calculations/time.

def payOff(balance):
    annualInterestRate = 0.2
    minimumFixedMonthlyPayment  = 0

    while True:
        previousBalance = balance
        minimumFixedMonthlyPayment += 10

        for dummy_i in range(12):
            previousBalance = previousBalance - minimumFixedMonthlyPayment
            newBalance = round(previousBalance +
(previousBalance*(annualInterestRate/12)),2)
            previousBalance = newBalance
            if newBalance <= 0:
                break
        if newBalance <= 0:
            break
            
    return( minimumFixedMonthlyPayment)
print(payOff(1000))

-----Urspr?ngliche Nachricht-----
Von: Tutor <tutor-bounces+marcus.luetolf=bluewin.ch at python.org> Im Auftrag
von Dennis Lee Bieber
Gesendet: Samstag, 2. Oktober 2021 19:23
An: tutor at python.org
Betreff: Re: [Tutor] infinite while loop


	Please ensure you reply to the LIST -- not to individuals.

On Sat, 2 Oct 2021 11:13:53 +0200, Marcus L?tolf <marcus.luetolf at bluewin.ch>
declaimed the following:

	What, exactly, are you attempting to calculate? The minimum payment
that will pay off a loan in 12 months?


>Thank you. 
>The previousBalance is set back to 1000 after each run oft he for loop 
>intentionally for the following for loops should run with 
>minimumFixedMonthlyPayment each time increased by 10 til previousBalance
get's negative.
>

	The for loop is, I presume, supposed to span 12 months -- one year.
BUT you are resetting "previousBalance" (which is a poor name, as it really
is the /remainingBalance/) to 1000 at the END of EACH MONTH -- so the
remaining balance never decreases inside the for loop. Furthermore, you are
ALSO changing (incrementing) the monthly payment EACH MONTH -- you do not
have a "fixed monthly payment" inside the for loop.


	BOTH the "fixed payment" and the initial balance need to be set
BETWEEN the "while" and the "for" loops. The for loop should only adjust the
remaining balance by applying the fixed payment (deduction) for the month
and interest (addition) for that month. The order you do those could
differentiate between interest before payment, or interest after payment.

set payment to 0.0
while True:
	set remaining balance to initial balance
	increment payment to next value
	for _ in range(12):
		apply payment to remaining balance
		apply interest to remaining balance
		if remaining balance <= 0.0: break
	if remaining balance <= 0.0: break

NOTE: I'm using the "while True" with an "if ...: break" to avoid the need
to "prime" the while loop with...

set remaining balance to initial balance while remaining balance > 0.0:
	set remaining balance to initial balance

... however it requires the two if/break lines as the first exits the month
loop, and the second exits the while loop.

	I'm not going to show the code, but will show the last cycle of
running my implementation of this iterative approach...

period: 11	balance: 14.934028775505954	payment: 90.0
current payment: 100.0
period: 0	balance: 915.0	payment: 100.0
period: 1	balance: 828.5833333333333	payment: 100.0
period: 2	balance: 740.7263888888888	payment: 100.0
period: 3	balance: 651.4051620370369	payment: 100.0
period: 4	balance: 560.5952480709875	payment: 100.0
period: 5	balance: 468.27183553883725	payment: 100.0
period: 6	balance: 374.4096994644845	payment: 100.0
period: 7	balance: 278.9831944555592	payment: 100.0
period: 8	balance: 181.9662476964852	payment: 100.0
period: 9	balance: 83.33235182475994	payment: 100.0
period: 10	balance: -16.94544231149406	payment: 100.0
>>> 

	With your payment incrementing by 10, my solution case only runs 11
periods (months) on payment 100. Payment 90 still owes ~15 on the 12th
period.

NOTE: that this (minimum payment to pay off a loan in n-periods) is just one
variant of "time value of money" equations, and all of those have solutions
that do NOT require a loop.

http://www.frickcpa.com/tvom/tvom_amort.asp

Not a loop in sight -- just a straight up exponential equation.

>>> initialBalance = 1000
>>> annualRate = 0.2
>>> numberYears = 1
>>> periodYear = 12
>>> numberPeriods = numberYears * periodYear periodRate = annualRate / 
>>> periodYear
>>> 
>>> payment = initialBalance * (periodRate /
... 		(1.0 - (1.0 + periodRate) ** (-numberPeriods)))
>>> payment
92.63450589708033
>>> 

	Note: If you round down (92.63) that payment you will owe a residual
of a few cents at the end of the year. Rounding up (92.64) will result in
the last payment being a touch smaller.


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/

_______________________________________________
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 Oct  2 19:32:51 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 3 Oct 2021 00:32:51 +0100
Subject: [Tutor] infinite while loop
In-Reply-To: <002301d7b7da$cdbe8e10$693baa30$@bluewin.ch>
References: <003201d7b6f1$6bf80970$43e81c50$@bluewin.ch>
 <20211001184659.GA22451@huginn> <000a01d7b76d$d2584f00$7708ed00$@bluewin.ch>
 <1uvglgt4q8533d7db19rgg2nru53ckd4hu@4ax.com>
 <002301d7b7da$cdbe8e10$693baa30$@bluewin.ch>
Message-ID: <sjaq73$v3e$1@ciao.gmane.io>

On 02/10/2021 23:14, marcus.luetolf at bluewin.ch wrote:

> def payOff(balance):
>     annualInterestRate = 0.2
>     minimumFixedMonthlyPayment  = 0
> 
>     while True:
>         previousBalance = balance
>         minimumFixedMonthlyPayment += 10
> 
>         for dummy_i in range(12):
>             previousBalance = previousBalance - minimumFixedMonthlyPayment
>             newBalance = round(previousBalance +
> (previousBalance*(annualInterestRate/12)),2)
>             previousBalance = newBalance
>             if newBalance <= 0:
>                 break
>         if newBalance <= 0:
>             break
>             
>     return( minimumFixedMonthlyPayment)

The double break is a bit ugly since they both test the same
condition(albeit under different circumstances). You could
eliminate the second break test and move the return
statement inside the for loop, replacing the first break.
Then as soon as the value drops to/below zero you will end
the function and return the chosen 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 juliushamilton100 at gmail.com  Sat Oct  2 14:48:31 2021
From: juliushamilton100 at gmail.com (Julius Hamilton)
Date: Sat, 2 Oct 2021 20:48:31 +0200
Subject: [Tutor] See execution of script live from command line
Message-ID: <CAEsMKX3LV-ecrcc73AE=TaRm1fYhobeAk7-yjWxL=DO0d6DHpQ@mail.gmail.com>

Hey,

I am running a script with some user input and I?d like to see the script
being executed at the same time, in split screen at the command line (for
example, with tmux or GNU screen).

What are my options for printing out what the computer is doing as it
executes the code?

What levels are there? Can we see which line of the program it?s currently
executing in both Python and assembly language, for example?

Thank you,
Julius

From juliushamilton100 at gmail.com  Sat Oct  2 16:22:35 2021
From: juliushamilton100 at gmail.com (Julius Hamilton)
Date: Sat, 2 Oct 2021 22:22:35 +0200
Subject: [Tutor] Edit program while executing
Message-ID: <CAEsMKX0kqTvNTk92J9tzatu7nwV++DsQS+YbBE5bG07WvECrFw@mail.gmail.com>

Hey,

Is there any way to edit a computer program while it is running?

For example, with Python - when the script is executed, what happens next?
Does it get compiled into assembly language and sent to the computer?s
circuits? In that case, if the computer allowed it, if you edited the
program, and the computer knew where in the program it was, it might in
theory be possible to pass the new instructions after the point where the
execution is.

On the other hand, if this is impossible with Python, is there any other
computer language where the computer is reading the program and executing
it step by step immediately, without a step beforehand where the whole
program is compiled? In that case it would surely be possible to change the
program in the middle of execution, I believe?

Thank you,
Julius

From juliushamilton100 at gmail.com  Sat Oct  2 17:27:34 2021
From: juliushamilton100 at gmail.com (Julius Hamilton)
Date: Sat, 2 Oct 2021 23:27:34 +0200
Subject: [Tutor] =?utf-8?q?Condition_for_variable_which_doesn=E2=80=99t_e?=
 =?utf-8?q?xist_yet?=
Message-ID: <CAEsMKX0jn3naMas7MPwkVeNrXAFCw49c99n5P-dqQzCw6B6b1Q@mail.gmail.com>

Hey,

I?d like to make a while-loop stop on a condition related to an equivalence
statement on a variable (while L != ??). However, I?d prefer to not declare
this variable before the while loop, for the sake of elegance.

Is there any syntax or idea that comes to mind that would allow me to say ?
while L!=?? ? and for the program to understand, ?L doesn?t exist yet so
this is fine, the only issue is if it exists and it?s a blank string??

Another idea I have is just using a different loop type. Maybe a syntax
like:

do:
  l = input()
  if l == ?? break
  g.append(l)

What would be the Python for this?

But I can picture a more elegant way I?d love to see, something like this:

do (if l == ?? break):
  g.append(l = input())

This hopefully says to check at all times if l is ever ??. If it ever
happens, break the loop. Meanwhile, the input is getting passed to the
variable l, and then appended straight to the list g, in one line of code.

Is this possible in Python or a different language?

Thank you very much,
Julius

From wlfraed at ix.netcom.com  Sat Oct  2 20:11:48 2021
From: wlfraed at ix.netcom.com (Dennis Lee Bieber)
Date: Sat, 02 Oct 2021 20:11:48 -0400
Subject: [Tutor] See execution of script live from command line
References: <CAEsMKX3LV-ecrcc73AE=TaRm1fYhobeAk7-yjWxL=DO0d6DHpQ@mail.gmail.com>
Message-ID: <58thlg1vsasjsbnl2oh9n0a5pbi98d5da0@4ax.com>

On Sat, 2 Oct 2021 20:48:31 +0200, Julius Hamilton
<juliushamilton100 at gmail.com> declaimed the following:

>Hey,
>
>I am running a script with some user input and I?d like to see the script
>being executed at the same time, in split screen at the command line (for
>example, with tmux or GNU screen).
>
>What are my options for printing out what the computer is doing as it
>executes the code?
>
	Python debugger in single step mode.

>What levels are there? Can we see which line of the program it?s currently
>executing in both Python and assembly language, for example?
>
	Python is a BYTE CODE interpreter -- it does not generate "assembly
language" per se.


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


From wlfraed at ix.netcom.com  Sat Oct  2 20:18:33 2021
From: wlfraed at ix.netcom.com (Dennis Lee Bieber)
Date: Sat, 02 Oct 2021 20:18:33 -0400
Subject: [Tutor] Edit program while executing
References: <CAEsMKX0kqTvNTk92J9tzatu7nwV++DsQS+YbBE5bG07WvECrFw@mail.gmail.com>
Message-ID: <cbthlghbplij2gmbp2d0scccgkvvop1nh9@4ax.com>

On Sat, 2 Oct 2021 22:22:35 +0200, Julius Hamilton
<juliushamilton100 at gmail.com> declaimed the following:

>
>For example, with Python - when the script is executed, what happens next?

	Imported modules get compiled into Python byte-code (.pyc files) to
speed processing the next time the module is imported by a program.

	The main file gets compiled to byte-code, but does not get saved as a
.pyc file.

>Does it get compiled into assembly language and sent to the computer?s

	Only if you consider the byte-code to be "assembly' -- but it is really
interpreted at run time.

>
>On the other hand, if this is impossible with Python, is there any other
>computer language where the computer is reading the program and executing
>it step by step immediately, without a step beforehand where the whole
>program is compiled? In that case it would surely be possible to change the
>program in the middle of execution, I believe?

	LISP, FORTH, and maybe APL, can programatically modify their own code.
But I don't know of any system that allows external editing /while/ a
program is running.


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


From wlfraed at ix.netcom.com  Sat Oct  2 20:21:56 2021
From: wlfraed at ix.netcom.com (Dennis Lee Bieber)
Date: Sat, 02 Oct 2021 20:21:56 -0400
Subject: [Tutor] 
 =?utf-8?q?Condition_for_variable_which_doesn=E2=80=99t_e?=
 =?utf-8?q?xist_yet?=
References: <CAEsMKX0jn3naMas7MPwkVeNrXAFCw49c99n5P-dqQzCw6B6b1Q@mail.gmail.com>
Message-ID: <unthlgh3skuimc1qcrqagqo08k7d3jimdd@4ax.com>

On Sat, 2 Oct 2021 23:27:34 +0200, Julius Hamilton
<juliushamilton100 at gmail.com> declaimed the following:

>Another idea I have is just using a different loop type. Maybe a syntax
>like:
>
>do:
>  l = input()
>  if l == ?? break
>  g.append(l)
>
	g = []
	while True:
		l = input()
		if not l: break	#empty strings, 0, empty lists are all "false"
		g.append(l)



-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


From PyTutor at DancesWithMice.info  Sat Oct  2 22:46:22 2021
From: PyTutor at DancesWithMice.info (dn)
Date: Sun, 3 Oct 2021 15:46:22 +1300
Subject: [Tutor] 
 =?utf-8?q?Condition_for_variable_which_doesn=E2=80=99t_e?=
 =?utf-8?q?xist_yet?=
In-Reply-To: <CAEsMKX0jn3naMas7MPwkVeNrXAFCw49c99n5P-dqQzCw6B6b1Q@mail.gmail.com>
References: <CAEsMKX0jn3naMas7MPwkVeNrXAFCw49c99n5P-dqQzCw6B6b1Q@mail.gmail.com>
Message-ID: <6046803e-4009-e1e7-8a54-a2931eb62453@DancesWithMice.info>

On 03/10/2021 10.27, Julius Hamilton wrote:
> Hey,
> 
> I?d like to make a while-loop stop on a condition related to an equivalence
> statement on a variable (while L != ??). However, I?d prefer to not declare
> this variable before the while loop, for the sake of elegance.
> 
> Is there any syntax or idea that comes to mind that would allow me to say ?
> while L!=?? ? and for the program to understand, ?L doesn?t exist yet so
> this is fine, the only issue is if it exists and it?s a blank string??
> 
> Another idea I have is just using a different loop type. Maybe a syntax
> like:
> 
> do:
>   l = input()
>   if l == ?? break
>   g.append(l)
> 
> What would be the Python for this?
> 
> But I can picture a more elegant way I?d love to see, something like this:
> 
> do (if l == ?? break):
>   g.append(l = input())
> 
> This hopefully says to check at all times if l is ever ??. If it ever
> happens, break the loop. Meanwhile, the input is getting passed to the
> variable l, and then appended straight to the list g, in one line of code.
> 
> Is this possible in Python or a different language?
I started a thread about the repeat ... until condition construct, for
"elegance" and because I consider the while+forever...break construct be
(a) ugly, (b) higher complexity, and (c) contrary to the Zen of Python,
over on the [main] Python List, a few weeks back.

In this case you might be able to sneak under-the-wire with:

>>> l = list()
>>> while i := input( "? " ):
...     l.append( i )
...
? a
? b
? c
? d
?
>>> l
['a', 'b', 'c', 'd']

-- 
Regards,
=dn

From PyTutor at DancesWithMice.info  Sat Oct  2 22:50:17 2021
From: PyTutor at DancesWithMice.info (dn)
Date: Sun, 3 Oct 2021 15:50:17 +1300
Subject: [Tutor] See execution of script live from command line
In-Reply-To: <CAEsMKX3LV-ecrcc73AE=TaRm1fYhobeAk7-yjWxL=DO0d6DHpQ@mail.gmail.com>
References: <CAEsMKX3LV-ecrcc73AE=TaRm1fYhobeAk7-yjWxL=DO0d6DHpQ@mail.gmail.com>
Message-ID: <e6f5a259-2371-1e41-6517-af7b65eca3d1@DancesWithMice.info>

On 03/10/2021 07.48, Julius Hamilton wrote:
> Hey,
> 
> I am running a script with some user input and I?d like to see the script
> being executed at the same time, in split screen at the command line (for
> example, with tmux or GNU screen).
> 
> What are my options for printing out what the computer is doing as it
> executes the code?
> 
> What levels are there? Can we see which line of the program it?s currently
> executing in both Python and assembly language, for example?

https://pythontutor.com/visualize.html

At least one of the editors has similar facility built-in, but I can't
remember which (ie please research for yourself): Idle, Wing, Thony,
and/or Spyder. eg https://hackr.io/blog/best-python-ide
-- 
Regards,
=dn

From manpritsinghece at gmail.com  Sun Oct  3 03:05:55 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Sun, 3 Oct 2021 12:35:55 +0530
Subject: [Tutor] Trying to write a class based iterator
Message-ID: <CAO1OCwbk+9xh1JeN6G6oRitUR7RRrb-VZcVDBO7T1d+LEohZsg@mail.gmail.com>

Dear sir ,

I have written a class based iterator for integers, as given below:

class Intiter:
    """Iterator for looping over digits of integer"""
    def __init__(self, data, Rev):
        self.data = data if Rev else int(str(data)[::-1])

    def __iter__(self):
        return self

    def __next__(self):
        if self.data == 0:
            raise StopIteration
        self.data, rem = divmod(self.data, 10)
        return rem

doing this :
rev = Intiter(309, Rev=True)   Returns an iterator
for num in rev:     # applying for loop
    print(num)

prints the digits in reverse order (Due to Rev = True when calling  the
class)
9
0
3

doing this :
forward = Intiter(309, Rev=False)

for num in forward:
    print(num)

Prints the digits in right order (Due to Rev=False when calling the class)
3
0
9

So this is basically implementation of an iterator (both Forward & Rev)
based on the input given by user Rev=True or False.
Is my implementation ok ?
Need your comments

Regards
Manprit Singh

From alan.gauld at yahoo.co.uk  Sun Oct  3 04:22:43 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 3 Oct 2021 09:22:43 +0100
Subject: [Tutor] Trying to write a class based iterator
In-Reply-To: <CAO1OCwbk+9xh1JeN6G6oRitUR7RRrb-VZcVDBO7T1d+LEohZsg@mail.gmail.com>
References: <CAO1OCwbk+9xh1JeN6G6oRitUR7RRrb-VZcVDBO7T1d+LEohZsg@mail.gmail.com>
Message-ID: <sjbp8j$m0d$1@ciao.gmane.io>

On 03/10/2021 08:05, Manprit Singh wrote:

> class Intiter:
>     """Iterator for looping over digits of integer"""
>     def __init__(self, data, Rev):
>         self.data = data if Rev else int(str(data)[::-1])
> 
>     def __iter__(self):
>         return self
> 
>     def __next__(self):
>         if self.data == 0:
>             raise StopIteration
>         self.data, rem = divmod(self.data, 10)
>         return rem

> Is my implementation ok ?
> Need your comments

Its OK but it might be simpler to just store the number
as a string and return the characters. That would remove
the need for one of the conversions in the init() as well
as the divmod calculation.

Of course if the user wanted to use the numbers they would
need to convert to int() later.

-- 
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 Oct  3 07:55:19 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 3 Oct 2021 12:55:19 +0100
Subject: [Tutor] See execution of script live from command line
In-Reply-To: <CAEsMKX3LV-ecrcc73AE=TaRm1fYhobeAk7-yjWxL=DO0d6DHpQ@mail.gmail.com>
References: <CAEsMKX3LV-ecrcc73AE=TaRm1fYhobeAk7-yjWxL=DO0d6DHpQ@mail.gmail.com>
Message-ID: <sjc5nb$nda$1@ciao.gmane.io>

On 02/10/2021 19:48, Julius Hamilton wrote:

> I am running a script with some user input and I?d like to see the script
> being executed at the same time, in split screen at the command line (for
> example, with tmux or GNU screen).
> 
> What are my options for printing out what the computer is doing as it
> executes the code?

That is usually a function of the debugger.
Some debuggers have a trace option that will print out
the line of code being executed or, more commonly, selected
lines of code each time they are executed. (Printing every
line of a non-trivial program generates huge amounts of
output very quickly!)

But be aware that debuggers will slow your code down
massively - often by 100 times or more. Its not really
a practical option for anything non-trivial. And if
its trivial why would you need it - just insert a few
print statements!

-- 
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 Oct  3 08:21:07 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 3 Oct 2021 13:21:07 +0100
Subject: [Tutor] Edit program while executing
In-Reply-To: <CAEsMKX0kqTvNTk92J9tzatu7nwV++DsQS+YbBE5bG07WvECrFw@mail.gmail.com>
References: <CAEsMKX0kqTvNTk92J9tzatu7nwV++DsQS+YbBE5bG07WvECrFw@mail.gmail.com>
Message-ID: <sjc77k$ivr$1@ciao.gmane.io>

On 02/10/2021 21:22, Julius Hamilton wrote:
> Is there any way to edit a computer program while it is running?

There are a few sophisticated IDE/debugging tools that allow this.
For example Borland C++ used to have a debugger that allowed you
to stop the code, step back a few steps, modify the code and then
rerun those steps again (using JIT compilation). (I say "used to"
because I haven't used Borland software for years. It's probably
still a feature today, but I don't know.)

But it is an inherently difficult feat to make work as it's a bit
like cutting off the branch of a tree while you are sitting on it!
It's OK for minor tweaks like changing a constant value or the loop
variable name but any significant change is likely to send your
code spinning off into a black hole.

Part of the reason for this is that the source code is always one
step away from the machine code that the CPU executes, so changing
the source even slightly can make a huge difference to the machine code.
It's much easier to use an assembly debugger to trace the execution of
assembler code than to trace high level code like C++ or Python.

> For example, with Python - when the script is executed, what happens next?
> Does it get compiled into assembly language and sent to the computer?s
> circuits? 

No. Programs never get sent to the computer's circuits. (Except in
real-time controllers and embedded devices) The Operating system loads
the code into an executable section of memory and monitors it as it
runs. Loading libraries etc as needed. That's the primary job of an
operating system - to load and execute programs while managing the
resources and peripherals of the computer.

In the case of Python the program code never even reaches the operating
system. It is executed by the Python interpreter. The interpreter is
loaded by the OS and the interpreter then loads the script and executes
it. The code that is executed is not the code you type however. That
source code is first compiled into Python "byte code" which is like
assembly code in traditional programming. The interpreter then executes
the byte code line by line. (You can use Python tools to inspect the
Python byte code if that's of interest to you.)

> In that case, if the computer allowed it, if you edited the
> program, and the computer knew where in the program it was, it might in
> theory be possible to pass the new instructions after the point where the
> execution is.

In theory yes. In practice it's extremely difficult both for the
human to edit safely and for the computer to process, for all
the reasons discussed above. You can certainly do it at the executable
machine code level and most of us who have been around for long enough,
will have experience of stopping a running program and going into the
executable image and poking new hex or octal values in before restarting
the program. But it's highly risky and only possible for very trivial
changes.

> On the other hand, if this is impossible with Python, is there any other
> computer language where the computer is reading the program and executing
> it step by step immediately, without a step beforehand where the whole
> program is compiled? 

There are pure interpreted languages. Early BASICs come to mind, where
each instruction had a line number. You could stop the interpreter and
replace a line of code anywhere in the program and resume execution and
the new line would be used the next time it was called (For example if
it was part of a loop)

Also Lisp and similar languages(Scheme, Logo etc) store their code as a
data structure within the program. As such it is accessible and with a
debugger or even from within the code itself, you can change the program
code. But again this is mind meltingly difficult and error prone.

> In that case it would surely be possible to change the
> program in the middle of execution, I believe?

Possible yes, practical no. And of very little real-world use.
It's like reprogramming the gears of your car while driving.
Suddenly, changing to 3rd gear makes the headlights come
on! Clever, but potentially dangerous and very confusing to
the driver.


-- 
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 Oct  3 08:40:40 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 3 Oct 2021 13:40:40 +0100
Subject: [Tutor] 
 =?utf-8?q?Condition_for_variable_which_doesn=E2=80=99t_e?=
 =?utf-8?q?xist_yet?=
In-Reply-To: <CAEsMKX0jn3naMas7MPwkVeNrXAFCw49c99n5P-dqQzCw6B6b1Q@mail.gmail.com>
References: <CAEsMKX0jn3naMas7MPwkVeNrXAFCw49c99n5P-dqQzCw6B6b1Q@mail.gmail.com>
Message-ID: <sjc8cb$ta8$1@ciao.gmane.io>

On 02/10/2021 22:27, Julius Hamilton wrote:

> I?d like to make a while-loop stop on a condition related to an equivalence
> statement on a variable (while L != ??). However, I?d prefer to not declare
> this variable before the while loop, for the sake of elegance.

That's one idea of elegance. It's also a maintainers nightmare!
There is a reason that text books recommend listing and
initializing variables at the top of a program/function - it
makes them easy to find. Python allows you to create variables
as the program runs but from a maintainers point of view that
makes finding them a pain (although modern IDEs can help with
that.)

In short, using or referencing variables before they exist
is a very, very bad idea!

> Is there any syntax or idea that comes to mind that would allow me to say ?
> while L!=?? ? and for the program to understand, ?L doesn?t exist yet so
> this is fine, the only issue is if it exists and it?s a blank string??

The new walrus operator kind of allows this by creating L at the
point of the test but you still need to create a value. If the
code relies on something that does not yet exist that suggests
a flawed design. Or maybe even a non-existent design!? Poke-and-hope
programming often results in these kinds of scenarios. But
poke-and-hope never produces elegant or maintainable code!

> Another idea I have is just using a different loop type. Maybe a syntax
> like:
> 
> do:
>   l = input()
>   if l == ?? break
>   g.append(l)

That is basically the common 'while True' idiom.
It's one of, if not the, most common forms of while loop in Python.
But you still need the tested variable to exist before it is tested!

> But I can picture a more elegant way I?d love to see, something like this:
> 
> do (if l == ?? break):
>   g.append(l = input())

Some languages support a repeat loop construct for these
types of scenarios. For example in Pascal:

repeat
   L := readln()
   if L <> "" then g.append(L)
until L = ""

In Python we make do with

while True:
   L = input()
   if not L: break
   g.append(input())

> This hopefully says to check at all times if l is ever ??. If it ever
> happens, break the loop. Meanwhile, the input is getting passed to the
> variable l, and then appended straight to the list g, in one line of code.

Putting it all on one line makes it nearly impossible to debug.
Single lines of code are not usually good practice when dealing
with I/O.

> Is this possible in Python or a different language?

There are hundreds of languages, I'm sure several do what you want.
Fortunately, Python is not one of them.

-- 
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  Sun Oct  3 09:38:14 2021
From: mats at wichmann.us (Mats Wichmann)
Date: Sun, 3 Oct 2021 07:38:14 -0600
Subject: [Tutor] Edit program while executing
In-Reply-To: <CAEsMKX0kqTvNTk92J9tzatu7nwV++DsQS+YbBE5bG07WvECrFw@mail.gmail.com>
References: <CAEsMKX0kqTvNTk92J9tzatu7nwV++DsQS+YbBE5bG07WvECrFw@mail.gmail.com>
Message-ID: <e6c413b0-39d8-e0b8-ec81-b2f231c12678@wichmann.us>

On 10/2/21 14:22, Julius Hamilton wrote:
> Hey,
> 
> Is there any way to edit a computer program while it is running?
> 
> For example, with Python - when the script is executed, what happens next?
> Does it get compiled into assembly language and sent to the computer?s
> circuits? In that case, if the computer allowed it, if you edited the
> program, and the computer knew where in the program it was, it might in
> theory be possible to pass the new instructions after the point where the
> execution is.

If you want gory details there are some good descriptions here:

https://tenthousandmeters.com/

You can actually "compile" new code on the fly - as has already been 
mentioned this happens on imports, and the compile() built-in function 
can be called to compile a bit of code passed as a string into a code 
object.  But there's a bit more to it than that, and doesn't really 
sound like what you are asking about.



From wlfraed at ix.netcom.com  Sun Oct  3 10:27:23 2021
From: wlfraed at ix.netcom.com (Dennis Lee Bieber)
Date: Sun, 03 Oct 2021 10:27:23 -0400
Subject: [Tutor] 
 =?utf-8?q?Condition_for_variable_which_doesn=E2=80=99t_e?=
 =?utf-8?q?xist_yet?=
References: <CAEsMKX0jn3naMas7MPwkVeNrXAFCw49c99n5P-dqQzCw6B6b1Q@mail.gmail.com>
 <sjc8cb$ta8$1@ciao.gmane.io>
Message-ID: <m0fjlgh4vepe9uo6mkipku3c9s86llpmpo@4ax.com>

On Sun, 3 Oct 2021 13:40:40 +0100, Alan Gauld via Tutor <tutor at python.org>
declaimed the following:


>
>There are hundreds of languages, I'm sure several do what you want.
>Fortunately, Python is not one of them.

	REXX probably wouldn't produce an error in the test -- but that's
because names that have not been assigned a value have the name itself as
value.

C:\Users\Wulfraed>rexx
say aName
b = anotherName
say b
^Z
ANAME
ANOTHERNAME

C:\Users\Wulfraed>regina
say aName
aName = anotherName
say aName
^Z
ANAME
ANOTHERNAME

C:\Users\Wulfraed>

	The IBM influence is probably obvious -- as it converts everything to
upper case <G>

{Regina installs two executables: REXX is statically linked, REGINA is
dynamically linked -- Regina allows run-time configuration of external
function libraries}



-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


From manpritsinghece at gmail.com  Sun Oct  3 11:41:59 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Sun, 3 Oct 2021 21:11:59 +0530
Subject: [Tutor] classmethod - need to know what exactly it can do
Message-ID: <CAO1OCwa6=0t4r6Bp7s_x6rWeCeNoGDS=T1YQ-Jc_OjBz+UV0zQ@mail.gmail.com>

Dear Sir ,

Consider an example of class that contains a class method, given below:

class StudentDetails:
    """Class for details of students"""
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    @classmethod
    def fromstring(cls, details):
        det = details.split(",")
        return cls(det[0], int(det[1]), det[2])

    def __str__(self):
        return f'Name = {self.name} Age = {self.age} Sex = {self.sex}'

The class is written to store Name, age and sex of students of a class . As
far
as i have gone through texts, it clearly says, classmethod is a method in
which the first argument is the class itself, I have made a classmethod
fromstring
that has a first argument as cls. cls represents the class.

Now if have to make a record of student Rama i can do like this :

Rama = StudentDetails("Rama Singh", 21, "F")
Where "Rama Singh" is name, age is 21 and sex is "F"

For getting the details of student rama i can write

print(Rama)

Which will print :

Name = Rama Singh Age = 21 Sex = F

Now if the details of a student Ajit are given in a single string:
"Ajit Singh,21,M"  where name age and sex is separated with comma, here the

classmethod fromstring is utilized, first the string is splitted with comma
 as a separator which separates name age and sex then these separated details

are passed as arguments in the class, that creates new record for student

Ajit as given below:

Classmethod fromstring is called for making record of student Ajit .

Ajit = StudentDetails.fromstring("Ajit Singh,21,M")

print(Ajit)  #  will print the details of Ajit as given below:

Name = Ajit Singh Age = 21 Sex = M


My question is, The way i have used the classmethod is its appropriate use ?

What are other uses of class method ?

Regards

Manprit Singh

From alan.gauld at yahoo.co.uk  Sun Oct  3 14:32:35 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 3 Oct 2021 19:32:35 +0100
Subject: [Tutor] classmethod - need to know what exactly it can do
In-Reply-To: <CAO1OCwa6=0t4r6Bp7s_x6rWeCeNoGDS=T1YQ-Jc_OjBz+UV0zQ@mail.gmail.com>
References: <CAO1OCwa6=0t4r6Bp7s_x6rWeCeNoGDS=T1YQ-Jc_OjBz+UV0zQ@mail.gmail.com>
Message-ID: <sjct04$c4n$1@ciao.gmane.io>

On 03/10/2021 16:41, Manprit Singh wrote:

> class StudentDetails:
>     """Class for details of students"""
>     def __init__(self, name, age, sex):
>         self.name = name
>         self.age = age
>         self.sex = sex
> 
>     @classmethod
>     def fromstring(cls, details):
>         det = details.split(",")
>         return cls(det[0], int(det[1]), det[2])

In practice you'd need to add a lot of validation code otherwise your
new instance could be full of garbage. As it is it requires the string
to be very precisely defined. But lets ignore those niceties for now...

> as i have gone through texts, it clearly says, classmethod is a method in
> which the first argument is the class itself, I have made a classmethod
> fromstring
> that has a first argument as cls. cls represents the class.

That's correct although its looking at it from a syntactic definition.
If you look at wider OOP books you will find out what the conceptual
use of a class method is. ie. one which operates on the class rather
than on a single instance.

> Now if the details of a student Ajit are given in a single string:
> "Ajit Singh,21,M"  where name age and sex is separated with comma, here the
> 
> classmethod fromstring is utilized, first the string is splitted with comma
>  as a separator which separates name age and sex then these separated details
> are passed as arguments in the class, that creates new record for student
...
> My question is, The way i have used the classmethod is its
> appropriate use ?
> What are other uses of class method ?

Yes, one common use of classmethods in Python is to create factory
methods that replicate the use of overloaded constructors in other
languages. fromString() is a common operation for constructing
instances from data received over a network for example.
Another common one is load(id) where the instance is created
from a database table.

Other uses include keeping a record of all instances. Class methods
can then be used to find an existing instance given some id or key,
or to provide a count of instances. Or you can ensure only unique
valued instances are created (by finding existing instances with
the same values) This approach is often used when working with
scarce resources such as network connections for example where
a pool of connection objects is created and reused when possible.

Most large scale applications will have classmethods somewhere
in the design. Smaller apps often don't need them.

-- 
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 juliushamilton100 at gmail.com  Sun Oct  3 11:21:21 2021
From: juliushamilton100 at gmail.com (Julius Hamilton)
Date: Sun, 3 Oct 2021 17:21:21 +0200
Subject: [Tutor] Alternative to importing
Message-ID: <CAEsMKX0UnpUzk84p6ZPyOWiwJ+GCcznRqYSBWWU2zV60+eXb1g@mail.gmail.com>

Hey,

Is there any alternative to importing a Python script in another script for
the methods defined in it, where Python when executing one script will just
automatically look in the enclosing folder for any other Python scripts,
and check them for methods? Perhaps there could be a Python option, like
python -?importall? runscript.py? Or some other way of eliminating import
statements?

Thanks very much,
Julius

From PyTutor at DancesWithMice.info  Sun Oct  3 16:51:51 2021
From: PyTutor at DancesWithMice.info (dn)
Date: Mon, 4 Oct 2021 09:51:51 +1300
Subject: [Tutor] Alternative to importing
In-Reply-To: <CAEsMKX0UnpUzk84p6ZPyOWiwJ+GCcznRqYSBWWU2zV60+eXb1g@mail.gmail.com>
References: <CAEsMKX0UnpUzk84p6ZPyOWiwJ+GCcznRqYSBWWU2zV60+eXb1g@mail.gmail.com>
Message-ID: <90558188-e50f-a9c8-794e-2c4193343286@DancesWithMice.info>

On 04/10/2021 04.21, Julius Hamilton wrote:
> Hey,
> 
> Is there any alternative to importing a Python script in another script for
> the methods defined in it, where Python when executing one script will just
> automatically look in the enclosing folder for any other Python scripts,
> and check them for methods? Perhaps there could be a Python option, like
> python -?importall? runscript.py? Or some other way of eliminating import
> statements?

Python's import system is discussed at
https://docs.python.org/3/reference/import.html including the idea of
"packages" which consist of more than one module.

(Judging from previous questions, you may also like to peruse the
previous chapter of that manual: Python's "Execution Model")

More of the actual machinery for handling imports, and the various
sub-components available to advanced-users at
https://docs.python.org/3/library/modules.html which also includes the
various file formats which may be handled.
-- 
Regards,
=dn

From mats at wichmann.us  Sun Oct  3 17:24:40 2021
From: mats at wichmann.us (Mats Wichmann)
Date: Sun, 3 Oct 2021 15:24:40 -0600
Subject: [Tutor] Alternative to importing
In-Reply-To: <CAEsMKX0UnpUzk84p6ZPyOWiwJ+GCcznRqYSBWWU2zV60+eXb1g@mail.gmail.com>
References: <CAEsMKX0UnpUzk84p6ZPyOWiwJ+GCcznRqYSBWWU2zV60+eXb1g@mail.gmail.com>
Message-ID: <1729adb2-95e7-c4fa-40ce-0513c1e22ddc@wichmann.us>

On 10/3/21 09:21, Julius Hamilton wrote:
> Hey,
> 
> Is there any alternative to importing a Python script in another script for
> the methods defined in it, where Python when executing one script will just
> automatically look in the enclosing folder for any other Python scripts,
> and check them for methods? Perhaps there could be a Python option, like
> python -?importall? runscript.py? Or some other way of eliminating import
> statements?

so... @dn gave you some ideas.

but it's really hard not to ask: what is it you're trying to accomplish?

importing is an absolutely fundamental part of Python.  when somebody 
wants to avoid import statements it seems fair to try and look behind 
the curtain: there's some reason you're asking this question, right?


oh, one more fun resource for you:

https://tenthousandmeters.com/blog/python-behind-the-scenes-11-how-the-python-import-system-works/


From alan.gauld at yahoo.co.uk  Sun Oct  3 18:45:39 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 3 Oct 2021 23:45:39 +0100
Subject: [Tutor] Alternative to importing
In-Reply-To: <CAEsMKX0UnpUzk84p6ZPyOWiwJ+GCcznRqYSBWWU2zV60+eXb1g@mail.gmail.com>
References: <CAEsMKX0UnpUzk84p6ZPyOWiwJ+GCcznRqYSBWWU2zV60+eXb1g@mail.gmail.com>
Message-ID: <sjdbqj$eec$1@ciao.gmane.io>

On 03/10/2021 16:21, Julius Hamilton wrote:

> Is there any alternative to importing a Python script in another script for
> the methods defined in it, where Python when executing one script will just
> automatically look in the enclosing folder for any other Python scripts,
> and check them for methods? 

That would be a really, really bad idea! Imagine the folder full of
scripts, potentially many of them with functions of the same name.
Which one does python decide to executer? The first one it finds?
Then a week or two later the same program runs but a few new scripts
have been added. Now it runs a completely different function!

And having picked a function what happens if that function calls
another function in a different module. Does Python now search
all the scripts to see if it can find that new function?
And what about global variables. If it just runs a random function
what happens to the names imported by that functions module?
Does it run the whole module or just the function?

It would rapidly descend into utter chaos. That's why we use
imported modules, to control the namespaces and make sure that
every function has the environment it needs to work properly.

You could argue that we could create a folder for the project
and only have the scripts swe need. But then we need to ensure
that function names are unique within, not just a file, but
the whole folder. And how would reuse work? You'd need to copy
the reused modules into every project folder. And what happens
when you fix a bug? You need to find every copy and fix it
in every one! That completely defeats the purpose of reusable
modules.

> python -?importall? runscript.py? Or some other way of eliminating import
> statements?

Why would you want to? imports and modules are one of the
most important tools for controlling the complexity of
Python projects. By removing that you have code anarchy.
Almost everything we do in software engineering is designed
to limit and control access to code and hide the details
away, inside packages, modules, classes, functions and
data structures. We don't want to expose things, we
want to hide them and only expose the things we really
need. It's what keeps us sane and our code maintainable!

-- 
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  Mon Oct  4 14:14:00 2021
From: PyTutor at DancesWithMice.info (dn)
Date: Tue, 5 Oct 2021 07:14:00 +1300
Subject: [Tutor] JetBrains Academy
Message-ID: <2707f247-57d3-a050-3f3d-85205b316c84@DancesWithMice.info>

Have you tried the Python courses ($free and/or chargeable) offered
through the "JetBrains Academy" (https://www.jetbrains.com/academy/)?

Any and all feedback would be welcome...
-- 
Regards,
=dn

From manpritsinghece at gmail.com  Mon Oct  4 20:12:44 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Tue, 5 Oct 2021 05:42:44 +0530
Subject: [Tutor] cases with single if and an else clause
Message-ID: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>

Dear Sir,

Take an example of finding absolute value of a number without using builtin
abs()
it will be written simply as :

num = int(input("Enter a number"))
if num < 0:
    print(-num)
else:
    print(num)

This example involves an if clause and an else clause.
So when i am going to write a function that returns the absolute value, i
feel writing the function in the below given way is perfectly fine:

def absolutevalue(num):
    if num < 0:
        return -num
    return num

Here the else clause is not used:
1) because when the number is negative then only return -num inside the  if
clause of the function will execute and it will return a positive number,
after that return num will not execute.
2) If the number is a positive number then return -num inside the if clause
will not execute because num < 0 is False. return num will return the same
number.

Need your suggestions
Regards
Manprit Singh

From bouncingcats at gmail.com  Mon Oct  4 20:28:54 2021
From: bouncingcats at gmail.com (David)
Date: Tue, 5 Oct 2021 11:28:54 +1100
Subject: [Tutor] cases with single if and an else clause
In-Reply-To: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
References: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
Message-ID: <CAMPXz=pLF2htjQ5OmqWY11WKnLL0OK+WiPJTbp-Z7m1CEDqmpA@mail.gmail.com>

On Tue, 5 Oct 2021 at 11:14, Manprit Singh <manpritsinghece at gmail.com> wrote:

> So when i am going to write a function that returns the absolute value, i
> feel writing the function in the below given way is perfectly fine:
>
> def absolutevalue(num):
>     if num < 0:
>         return -num
>     return num
>
> Need your suggestions

I used to use this style because it feels like it does simplify and
perhaps makes the code more elegant.

However I have recently stopped doing this.

Functions and methods with more than one return statement
are harder to debug when used. They are more likely to need
external testing.

If there is just one return statement, then the return value can be
easily checked inside the function just before it returns.

If the function has more than one return statement then that
approach to debugging is not so easy.

In that situation, the return value would need to  be checked outside
the function in every place that the function is called, or checked
at more than one place inside the function.

From leamhall at gmail.com  Mon Oct  4 20:37:28 2021
From: leamhall at gmail.com (Leam Hall)
Date: Mon, 4 Oct 2021 19:37:28 -0500
Subject: [Tutor] cases with single if and an else clause
In-Reply-To: <CAMPXz=pLF2htjQ5OmqWY11WKnLL0OK+WiPJTbp-Z7m1CEDqmpA@mail.gmail.com>
References: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
 <CAMPXz=pLF2htjQ5OmqWY11WKnLL0OK+WiPJTbp-Z7m1CEDqmpA@mail.gmail.com>
Message-ID: <9472ab0e-f794-0dcd-0375-c329a8e2894f@gmail.com>

On 10/4/21 7:28 PM, David wrote:
> On Tue, 5 Oct 2021 at 11:14, Manprit Singh <manpritsinghece at gmail.com> wrote:
> 
>> So when i am going to write a function that returns the absolute value, i
>> feel writing the function in the below given way is perfectly fine:
>>
>> def absolutevalue(num):
>>      if num < 0:
>>          return -num
>>      return num
>>
>> Need your suggestions
> 
> I used to use this style because it feels like it does simplify and
> perhaps makes the code more elegant.
> 
> However I have recently stopped doing this.
> 
> Functions and methods with more than one return statement
> are harder to debug when used. They are more likely to need
> external testing.
> 
> If there is just one return statement, then the return value can be
> easily checked inside the function just before it returns.
> 
> If the function has more than one return statement then that
> approach to debugging is not so easy.
> 
> In that situation, the return value would need to  be checked outside
> the function in every place that the function is called, or checked
> at more than one place inside the function.

You could also use a ternary statement. They can be easy-ish to read for simple cases.

-- 
Systems Programmer         (reuel.net/resume)
Scribe: The Domici War     (domiciwar.net)
General Ne'er-do-well      (github.com/LeamHall)

From manpritsinghece at gmail.com  Mon Oct  4 21:13:02 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Tue, 5 Oct 2021 06:43:02 +0530
Subject: [Tutor] cases with single if and an else clause
In-Reply-To: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
References: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
Message-ID: <CAO1OCwaW7PgdSX35eUmCAf-h89idJTz6H2yXCwaQw7YZ+a+WxQ@mail.gmail.com>

Dear sir,

Yes I too feel a single return instead of multiple return statements should
be preferred :
I will not talk about using conditional expression a if c else b because it
can be used in simple cases only . When I have an if clause with multiple
statements I can't use it .
Regards
Manprit Singh




On Tue, Oct 5, 2021 at 5:42 AM Manprit Singh <manpritsinghece at gmail.com>
wrote:

> Dear Sir,
>
> Take an example of finding absolute value of a number without using
> builtin abs()
> it will be written simply as :
>
> num = int(input("Enter a number"))
> if num < 0:
>     print(-num)
> else:
>     print(num)
>
> This example involves an if clause and an else clause.
> So when i am going to write a function that returns the absolute value, i
> feel writing the function in the below given way is perfectly fine:
>
> def absolutevalue(num):
>     if num < 0:
>         return -num
>     return num
>
> Here the else clause is not used:
> 1) because when the number is negative then only return -num inside the
> if clause of the function will execute and it will return a positive
> number, after that return num will not execute.
> 2) If the number is a positive number then return -num inside the if
> clause will not execute because num < 0 is False. return num will return
> the same number.
>
> Need your suggestions
> Regards
> Manprit Singh
>
>

From manpritsinghece at gmail.com  Mon Oct  4 21:52:24 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Tue, 5 Oct 2021 07:22:24 +0530
Subject: [Tutor] cases with single if and an else clause
In-Reply-To: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
References: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
Message-ID: <CAO1OCwZR5b2SmccR0=NndjoAVqC0-013=CJZYWLkBpV6OS80_g@mail.gmail.com>

Dear sir,

Now there is one more problem ,  Kindly loom at below written functions :

def grade(percent):
    if percent < 0 or percent > 100:
        ans = "Invalid Input"
    elif percent >= 90:
        ans = "A"
    elif percent >= 70:
        ans = "B"
    elif percent >= 60:
        ans = "C"
    else:
        ans =  "Fail"
    return ans

ans = grade(71)
print(ans)    # that returns "B" which is the right answer
This is a function that returns the grade of the student according to marks
. In this function i have made a single return statement,  This can be
written with multiple return statements as below:

def grade(percent):
    if percent < 0 or percent > 100:    # By combining with or, expression
will be true if any subexpression is true
        return "Invalid Input"
    elif percent >= 90:
        return  "A"
    elif percent >= 70:
        return "B"
    elif percent >= 60:
        return "C"
    else:
        return "Fail"

ans = grade(71)
print(ans)   # that prints "B" the right answer.

Which way should be preferred ?
kindly guide

Regards
Manprit Singh


On Tue, Oct 5, 2021 at 5:42 AM Manprit Singh <manpritsinghece at gmail.com>
wrote:

> Dear Sir,
>
> Take an example of finding absolute value of a number without using
> builtin abs()
> it will be written simply as :
>
> num = int(input("Enter a number"))
> if num < 0:
>     print(-num)
> else:
>     print(num)
>
> This example involves an if clause and an else clause.
> So when i am going to write a function that returns the absolute value, i
> feel writing the function in the below given way is perfectly fine:
>
> def absolutevalue(num):
>     if num < 0:
>         return -num
>     return num
>
> Here the else clause is not used:
> 1) because when the number is negative then only return -num inside the
> if clause of the function will execute and it will return a positive
> number, after that return num will not execute.
> 2) If the number is a positive number then return -num inside the if
> clause will not execute because num < 0 is False. return num will return
> the same number.
>
> Need your suggestions
> Regards
> Manprit Singh
>
>

From alan.gauld at yahoo.co.uk  Tue Oct  5 03:34:04 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 5 Oct 2021 08:34:04 +0100
Subject: [Tutor] cases with single if and an else clause
In-Reply-To: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
References: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
Message-ID: <sjgv5d$15lm$1@ciao.gmane.io>

On 05/10/2021 01:12, Manprit Singh wrote:

> def absolutevalue(num):
>     if num < 0:
>         return -num
>     return num
> 
> Here the else clause is not used:

Strict structural programming rules say there should
be a single return statement from a function. So
setting a value in the if/else and returning that
at the end is "better"

In practice there can be valid arguments for returning
as soon as possible, especially in a complex function.
The alternative often requires setting flags and
adding lots of unnecessary if/else tests which
complicate an already complex function further.
In that case it's easier for everyone if you just
exit as soon as possible.

As ever there are no hard and fast rules, use what
makes the code easiest to read, test and debug.

-- 
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 wlfraed at ix.netcom.com  Tue Oct  5 14:39:17 2021
From: wlfraed at ix.netcom.com (Dennis Lee Bieber)
Date: Tue, 05 Oct 2021 14:39:17 -0400
Subject: [Tutor] cases with single if and an else clause
References: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
 <CAO1OCwZR5b2SmccR0=NndjoAVqC0-013=CJZYWLkBpV6OS80_g@mail.gmail.com>
Message-ID: <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com>

On Tue, 5 Oct 2021 07:22:24 +0530, Manprit Singh
<manpritsinghece at gmail.com> declaimed the following:

>Dear sir,
>
>Now there is one more problem ,  Kindly loom at below written functions :
>
>def grade(percent):
>    if percent < 0 or percent > 100:
>        ans = "Invalid Input"
>    elif percent >= 90:
>        ans = "A"
>    elif percent >= 70:
>        ans = "B"
>    elif percent >= 60:
>        ans = "C"
>    else:
>        ans =  "Fail"
>    return ans
>

	My biggest concern is that you are using the same "ans" return to
indicate invalid input, letter grades (you have a big gap between A and B
-- at least in US you'd commonly have breakpoints A:90, B:80, C:70, D:60,
and E (or F) at 50). 

	Presuming the numeric grade is being entered by the user of some
program (say a teacher's electronic grade book) the input should have been
validated at the place it was entered, NOT in a function that just
translates number ranges into a letter grade.

	If you really need to validate /in/ this function, you should be
raising an exception... and the caller needs to catch this exception and do
whatever is needed to correct the data before retrying the operation. As
is, the caller is forced to test every return from the function for a
SPECIFIC string...

aGrade = grade(score)
if aGrade == "Invalid Input":
	#do something to correct the input and retry the call to grade()
else:
	#record the returned letter grade



	There are multiple ways to avoid a chain of if/elif/else comparisons...
But for that you need to study /data structures/ and the algorithms using
them rather than just playing around with simple examples that would seldom
be used in actual applications. Especially examples that are mostly
concerned with /coding style/ than on flexibility (algorithm reuse). If the
code runs, it is technically correct -- but may look ugly and locked in to
just the one application. Coding style, these days, tends to be defined by
the company one works at, and one has to follow some guide book that
already exists at that company. If you want to follow the One-In/One-Out of
Structured Programming -- try to lay out your code using
https://en.wikipedia.org/wiki/Nassi%E2%80%93Shneiderman_diagram
(even in OOP, once one gets down to coding class methods, one should be
back to structured programming)

-=-=-=-
C:\Users\Wulfraed\Documents\_Hg-Repositories\Python Progs>letterGrade.py
Enter percentage grade for Abigail: -5
Invalid numeric grade
Please try again
Enter percentage grade for Abigail: 45

Letter grade for Abigail is F


Enter percentage grade for Bertram: 110
Invalid numeric grade
Please try again
Enter percentage grade for Bertram: 99

Letter grade for Bertram is A


Enter percentage grade for Charlie: xyz
invalid literal for int() with base 10: 'xyz'
Please try again
Enter percentage grade for Charlie: 68.5
invalid literal for int() with base 10: '68.5'
Please try again
Enter percentage grade for Charlie: 68

Letter grade for Charlie is D


Enter percentage grade for Edith: 77

Letter grade for Edith is C


Enter percentage grade for Francisca: 81

Letter grade for Francisca is B



C:\Users\Wulfraed\Documents\_Hg-Repositories\Python Progs>
-=-=-=-
STUDENTS = [    "Abigail",
                "Bertram",
                "Charlie",
                "Edith",
                "Francisca" ]

GRADES = [ (60, "F"),
           (70, "D"),
           (80, "C"),
           (90, "B"),
           (100, "A") ]	#ordered list of break points

def grade(percent):
    if percent < 0 or percent > 100:
        raise ValueError("Invalid numeric grade")
    for pc, ltr in GRADES:
        if percent <= pc: return ltr

for st in STUDENTS:
    while True:
        try:
            pcent = input("Enter percentage grade for %s: " % st)
            pcent = int(pcent)
            ltrGrade = grade(pcent)
            print("\nLetter grade for %s is %s\n\n"
                  % (st, ltrGrade))
            break
        except ValueError as ve:
            print(str(ve))
            print("Please try again")
    
-=-=-=-

	For the example, I've left GRADES as a read-only "global". For reuse
purposes, it should be passed as an argument to the grade() function.

	This is easily modifiable for use when grading "by the curve".
Simplified version: "C" is the mean of the scores, and one then works
outwards; all that needs to be changed is the GRADES list; so if the mean
came in at 60 then GRADES would look like:

GRADES = [ (45, "F"),
           (55, "D"),
           (65, "C"),		#allow 5 below to 5 above
           (75, "B"),
           (100, "A") ]	#don't change to catch outliers

If you input the scores per student first, you can have the program
calculate the mean and modify GRADES as needed.. Granted, this simplified
version will have problems if the scores are near the extremes... mean of
85 makes GRADES look like

GRADES = [ (70, "F"),
           (80, "D"),
           (90, "C"),		#allow 5 below to 5 above
           (100, "B"),
           (100, "A") ]	#no one gets a "A"

The more complex version would compute %iles using mean&std.dev. and use
those to set the break points for letter grades.


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


From PyTutor at DancesWithMice.info  Tue Oct  5 15:08:56 2021
From: PyTutor at DancesWithMice.info (dn)
Date: Wed, 6 Oct 2021 08:08:56 +1300
Subject: [Tutor] cases with single if and an else clause
In-Reply-To: <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com>
References: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
 <CAO1OCwZR5b2SmccR0=NndjoAVqC0-013=CJZYWLkBpV6OS80_g@mail.gmail.com>
 <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com>
Message-ID: <c971812c-7761-c1de-48e9-46a55a12edcb@DancesWithMice.info>

On 06/10/2021 07.39, Dennis Lee Bieber wrote:
> On Tue, 5 Oct 2021 07:22:24 +0530, Manprit Singh
> <manpritsinghece at gmail.com> declaimed the following:
> 
>> Dear sir,
>>
>> Now there is one more problem ,  Kindly loom at below written functions :
>>
>> def grade(percent):
>>    if percent < 0 or percent > 100:
>>        ans = "Invalid Input"
>>    elif percent >= 90:
>>        ans = "A"
>>    elif percent >= 70:
>>        ans = "B"
>>    elif percent >= 60:
>>        ans = "C"
>>    else:
>>        ans =  "Fail"
>>    return ans
>>
> 
> 	My biggest concern is that you are using the same "ans" return to
> indicate invalid input, letter grades (you have a big gap between A and B
> -- at least in US you'd commonly have breakpoints A:90, B:80, C:70, D:60,
> and E (or F) at 50). 
> 
> 	Presuming the numeric grade is being entered by the user of some
> program (say a teacher's electronic grade book) the input should have been
> validated at the place it was entered, NOT in a function that just
> translates number ranges into a letter grade.
> 
> 	If you really need to validate /in/ this function, you should be
> raising an exception... and the caller needs to catch this exception and do
> whatever is needed to correct the data before retrying the operation. As
> is, the caller is forced to test every return from the function for a
> SPECIFIC string...
> 
> aGrade = grade(score)
> if aGrade == "Invalid Input":
> 	#do something to correct the input and retry the call to grade()
> else:
> 	#record the returned letter grade
> 
> 
> 
> 	There are multiple ways to avoid a chain of if/elif/else comparisons...
> But for that you need to study /data structures/ and the algorithms using
> them rather than just playing around with simple examples that would seldom
> be used in actual applications. Especially examples that are mostly
> concerned with /coding style/ than on flexibility (algorithm reuse). If the
> code runs, it is technically correct -- but may look ugly and locked in to
> just the one application. Coding style, these days, tends to be defined by
> the company one works at, and one has to follow some guide book that
> already exists at that company. If you want to follow the One-In/One-Out of
> Structured Programming -- try to lay out your code using
> https://en.wikipedia.org/wiki/Nassi%E2%80%93Shneiderman_diagram
> (even in OOP, once one gets down to coding class methods, one should be
> back to structured programming)
> 
> -=-=-=-
> C:\Users\Wulfraed\Documents\_Hg-Repositories\Python Progs>letterGrade.py
> Enter percentage grade for Abigail: -5
> Invalid numeric grade
> Please try again
> Enter percentage grade for Abigail: 45
> 
> Letter grade for Abigail is F
> 
> 
> Enter percentage grade for Bertram: 110
> Invalid numeric grade
> Please try again
> Enter percentage grade for Bertram: 99
> 
> Letter grade for Bertram is A
> 
> 
> Enter percentage grade for Charlie: xyz
> invalid literal for int() with base 10: 'xyz'
> Please try again
> Enter percentage grade for Charlie: 68.5
> invalid literal for int() with base 10: '68.5'
> Please try again
> Enter percentage grade for Charlie: 68
> 
> Letter grade for Charlie is D
> 
> 
> Enter percentage grade for Edith: 77
> 
> Letter grade for Edith is C
> 
> 
> Enter percentage grade for Francisca: 81
> 
> Letter grade for Francisca is B
> 
> 
> 
> C:\Users\Wulfraed\Documents\_Hg-Repositories\Python Progs>
> -=-=-=-
> STUDENTS = [    "Abigail",
>                 "Bertram",
>                 "Charlie",
>                 "Edith",
>                 "Francisca" ]
> 
> GRADES = [ (60, "F"),
>            (70, "D"),
>            (80, "C"),
>            (90, "B"),
>            (100, "A") ]	#ordered list of break points
> 
> def grade(percent):
>     if percent < 0 or percent > 100:
>         raise ValueError("Invalid numeric grade")
>     for pc, ltr in GRADES:
>         if percent <= pc: return ltr
> 
> for st in STUDENTS:
>     while True:
>         try:
>             pcent = input("Enter percentage grade for %s: " % st)
>             pcent = int(pcent)
>             ltrGrade = grade(pcent)
>             print("\nLetter grade for %s is %s\n\n"
>                   % (st, ltrGrade))
>             break
>         except ValueError as ve:
>             print(str(ve))
>             print("Please try again")
>     
> -=-=-=-
> 
> 	For the example, I've left GRADES as a read-only "global". For reuse
> purposes, it should be passed as an argument to the grade() function.
> 
> 	This is easily modifiable for use when grading "by the curve".
> Simplified version: "C" is the mean of the scores, and one then works
> outwards; all that needs to be changed is the GRADES list; so if the mean
> came in at 60 then GRADES would look like:
> 
> GRADES = [ (45, "F"),
>            (55, "D"),
>            (65, "C"),		#allow 5 below to 5 above
>            (75, "B"),
>            (100, "A") ]	#don't change to catch outliers
> 
> If you input the scores per student first, you can have the program
> calculate the mean and modify GRADES as needed.. Granted, this simplified
> version will have problems if the scores are near the extremes... mean of
> 85 makes GRADES look like
> 
> GRADES = [ (70, "F"),
>            (80, "D"),
>            (90, "C"),		#allow 5 below to 5 above
>            (100, "B"),
>            (100, "A") ]	#no one gets a "A"
> 
> The more complex version would compute %iles using mean&std.dev. and use
> those to set the break points for letter grades.


+1

Those of us who learned "Structured Programming" when it was 'new'
probably still think of it as a 'thing'. (I'm not sure how often such is
mentioned in 'today's training', and haven't seen anyone under thirty
using a Nassi-Schneiderman chart for ages) We also take quite-naturally
to the SRP (Single Responsibility Principle)!

The OP named the function "grade" - in a conversation about 'style'.
Choosing names is important. It's also a matter of style - a weak name
requires a strong comment/docstring! In this case, the function lacks a
descriptive name.

As soon as one describes the (original) functionality as 'check validity
of numeric grade input AND convert to a letter-grade, if possible' the
problem @wulfraed illustrates becomes starkly-evident.

Secondly, we refer to successive mutually-exclusive if-statements as a
"ladder". It is logical that the conditions proceed systematically from
low-to-high, or vice-versa. Certainly "method" is better than "madness",
and testing becomes more methodical. (easier?) Accordingly, the first
if-statement is discordant because it can't make up its mind - is it the
'top' of the ladder, or the bottom? Such is NOT as readable as it
(easily) could/should be!

If the function includes an if-statement (to trap invalid data), won't
the calling code also have to cope with the same possibility? Does this
mean that there will be two if-statements which ask essentially the same
question, in two different scopes? Is that a good idea?

Instead of over-loading a data-object (see earlier post), is it time to
look at using Exceptions to convey meaning and handle unwanted
'edge-cases'?
(however, I'd prefer the 'solution' mooted above)
-- 
Regards,
=dn

From alan.gauld at yahoo.co.uk  Tue Oct  5 18:48:48 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 5 Oct 2021 23:48:48 +0100
Subject: [Tutor] cases with single if and an else clause
In-Reply-To: <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com>
References: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
 <CAO1OCwZR5b2SmccR0=NndjoAVqC0-013=CJZYWLkBpV6OS80_g@mail.gmail.com>
 <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com>
Message-ID: <sjikog$e12$1@ciao.gmane.io>

On 05/10/2021 19:39, Dennis Lee Bieber wrote:

> (even in OOP, once one gets down to coding class methods, one should be
> back to structured programming)

Kind of, except...

Structured programming says to pass the state values in as
parameters.

In OOP we tend to rely on using instance attributes to hold
state and its perfectly OK for methods to access that state
directly. But that nuance aside, the structure of the methods
follows SP principles.

-- 
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  Tue Oct  5 19:23:08 2021
From: PyTutor at DancesWithMice.info (dn)
Date: Wed, 6 Oct 2021 12:23:08 +1300
Subject: [Tutor] cases with single if and an else clause
In-Reply-To: <sjikog$e12$1@ciao.gmane.io>
References: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
 <CAO1OCwZR5b2SmccR0=NndjoAVqC0-013=CJZYWLkBpV6OS80_g@mail.gmail.com>
 <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com> <sjikog$e12$1@ciao.gmane.io>
Message-ID: <2a6795d3-bca8-ee38-5b0f-ae1e9510a6cc@DancesWithMice.info>

On 06/10/2021 11.48, Alan Gauld via Tutor wrote:
> On 05/10/2021 19:39, Dennis Lee Bieber wrote:
> 
>> (even in OOP, once one gets down to coding class methods, one should be
>> back to structured programming)
> 
> Kind of, except...
> 
> Structured programming says to pass the state values in as
> parameters.
> 
> In OOP we tend to rely on using instance attributes to hold
> state and its perfectly OK for methods to access that state
> directly. But that nuance aside, the structure of the methods
> follows SP principles.

Yes, adjusting to that gave me shades of an existential crisis too.

If the object has its own (dict of) self, and there's no need to pass-in
(or receive back) any values which are attributes - isn't this a new
form of 'global danger' and how do I test, keep control ...

It's all down to one's "state" of mind. Hah!


However, the important (and v.helpful) point being made was SP's 'one
way in, one way out' (of a "structure") mantra.
-- 
Regards,
=dn

From alan.gauld at yahoo.co.uk  Tue Oct  5 19:48:21 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 6 Oct 2021 00:48:21 +0100
Subject: [Tutor] cases with single if and an else clause
In-Reply-To: <2a6795d3-bca8-ee38-5b0f-ae1e9510a6cc@DancesWithMice.info>
References: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
 <CAO1OCwZR5b2SmccR0=NndjoAVqC0-013=CJZYWLkBpV6OS80_g@mail.gmail.com>
 <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com> <sjikog$e12$1@ciao.gmane.io>
 <2a6795d3-bca8-ee38-5b0f-ae1e9510a6cc@DancesWithMice.info>
Message-ID: <sjio86$6uj$1@ciao.gmane.io>

On 06/10/2021 00:23, dn via Tutor wrote:

>> In OOP we tend to rely on using instance attributes to hold
>> state and its perfectly OK for methods to access that state

> If the object has its own (dict of) self, and there's no need to pass-in
> (or receive back) any values which are attributes - isn't this a new
> form of 'global danger' and how do I test, keep control ...

It can initially seem like that, except that the attributes are
encapsulated in an instance - an object. And in OOP all variables are -
or should be - objects, so you pass the objects around and changes to
the state are controlled by the object (via the methods). So the evils
of globals are greatly reduced.

For example, methods can only be reused in the context of an
instance so the dependant "external" state is guaranteed to exist.
And provided the objects are single threaded (or created thread safe)
only one  method can be changing the attributes at once. And the
class as a namespace avoids name collisions.

-- 
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 wlfraed at ix.netcom.com  Tue Oct  5 21:21:35 2021
From: wlfraed at ix.netcom.com (Dennis Lee Bieber)
Date: Tue, 05 Oct 2021 21:21:35 -0400
Subject: [Tutor] Sidetrack history: Re: cases with single if and an else
 clause
References: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
 <CAO1OCwZR5b2SmccR0=NndjoAVqC0-013=CJZYWLkBpV6OS80_g@mail.gmail.com>
 <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com>
 <c971812c-7761-c1de-48e9-46a55a12edcb@DancesWithMice.info>
Message-ID: <msrplglnh91f1okaelhobrn5k963fa1a78@4ax.com>

On Wed, 6 Oct 2021 08:08:56 +1300, dn via Tutor <tutor at python.org>
declaimed the following:


>
>Those of us who learned "Structured Programming" when it was 'new'
>probably still think of it as a 'thing'. (I'm not sure how often such is
>mentioned in 'today's training', and haven't seen anyone under thirty
>using a Nassi-Schneiderman chart for ages) We also take quite-naturally
>to the SRP (Single Responsibility Principle)!
>
	I don't think I've touched one since around 1985. At the time, the
company tended to load up on new-hires, and /then/ shop them around to
department managers to determine final placement^1.  In the meantime we
were all in an "icebox" and provided general (ie: unclassified) work
assignments. ^2

	Company was trying to develop a suite of programs for software
engineering (N-square charts^3, the "Chapin" variant of N-S charts,
requirements traceability^4, etc.). An effort with continuously changing
environments -- it started with non-graphical systems, then moved to
high-end graphical documentation workstations, then started adding OOAD
features, and maybe ended up with COTS software.


*1	I was shanghaied -- had two department interviews, told I would have a
few more before having to choose, was one of a small group sent to a 4-day
course in Ada [mil-std 1815 had only been released a few weeks before and
the Ada/Ed translator even more recently], returned and was told management
decided I'd be in the second interview (the first one had been summarized
by the manager as "after a long study, the Navy had concluded high-speed
aircraft posed a threat" -- I think that was supposed to turn into some
scheme with satellites and/or loitering AWACS descendents relaying
targetting information to ships).

*2	Even after being assigned to a department, one still had to await
proper clearances. My DoD Secret came through in something like two months
(at the time, the average time for a Secret ran 6+ months -- I used to joke
that my paperwork must have gotten stuck into the stack for Reagan's new
staff). My black program access, though, did take over a year.

*3	On an early 48K CP/M machine using M$ FORTRAN (F80). The machine was
limited to 48K as it had some weird ROM and a custom CP/M (needed as the
normal interrupt vector used for OS services was buried in the ROM and
couldn't be modified)

*4	With some effort, I always thought the "Automated Requirements
Traceability System" could have been developed into an RDBM using
relational algebra. It already had operations similar to those of SELECT
and PROJECT -- the weakness was that one had to predefine the "table"
layouts, and specify the format (by numeric ID) on most operations; rather
than incorporating some means of having PROJECT extract the field
specifications and dynamically generating a new format definition. Porting
that application to a CDC MP-60 [in a militarized "drop container" -- the
paint was sturdy enough to chip concrete] was "fun". Minimal FORTRAN-IV
meant all the subroutine calls that incorporated operations
			call xyz(n-1, n+1)
had to be changed to 
			jinx = n-1
			minx = n+1
			call xyq(jinx, minx)
AND, since it lacked direct access I/O via F-IV statements, we had to use
an OS system service call to seek file sectors. Only to discover that while
a sector was 512 bytes, some sort of overhead only allowed F-IV to
read/write 480 bytes.


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


From manpritsinghece at gmail.com  Wed Oct  6 05:25:03 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Wed, 6 Oct 2021 14:55:03 +0530
Subject: [Tutor] cases with single if and an else clause
In-Reply-To: <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com>
References: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
 <CAO1OCwZR5b2SmccR0=NndjoAVqC0-013=CJZYWLkBpV6OS80_g@mail.gmail.com>
 <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com>
Message-ID: <CAO1OCwZemBq1gaPD3E=RWJSRt3ZPVEC_s9ssHnD_EVsYoBsA9w@mail.gmail.com>

Many Many thanks to Dennis Lee Bieber for the mail.

Regards
Manprit Singh


On Wed, Oct 6, 2021 at 12:10 AM Dennis Lee Bieber <wlfraed at ix.netcom.com>
wrote:

> On Tue, 5 Oct 2021 07:22:24 +0530, Manprit Singh
> <manpritsinghece at gmail.com> declaimed the following:
>
> >Dear sir,
> >
> >Now there is one more problem ,  Kindly loom at below written functions :
> >
> >def grade(percent):
> >    if percent < 0 or percent > 100:
> >        ans = "Invalid Input"
> >    elif percent >= 90:
> >        ans = "A"
> >    elif percent >= 70:
> >        ans = "B"
> >    elif percent >= 60:
> >        ans = "C"
> >    else:
> >        ans =  "Fail"
> >    return ans
> >
>
>         My biggest concern is that you are using the same "ans" return to
> indicate invalid input, letter grades (you have a big gap between A and B
> -- at least in US you'd commonly have breakpoints A:90, B:80, C:70, D:60,
> and E (or F) at 50).
>
>         Presuming the numeric grade is being entered by the user of some
> program (say a teacher's electronic grade book) the input should have been
> validated at the place it was entered, NOT in a function that just
> translates number ranges into a letter grade.
>
>         If you really need to validate /in/ this function, you should be
> raising an exception... and the caller needs to catch this exception and do
> whatever is needed to correct the data before retrying the operation. As
> is, the caller is forced to test every return from the function for a
> SPECIFIC string...
>
> aGrade = grade(score)
> if aGrade == "Invalid Input":
>         #do something to correct the input and retry the call to grade()
> else:
>         #record the returned letter grade
>
>
>
>         There are multiple ways to avoid a chain of if/elif/else
> comparisons...
> But for that you need to study /data structures/ and the algorithms using
> them rather than just playing around with simple examples that would seldom
> be used in actual applications. Especially examples that are mostly
> concerned with /coding style/ than on flexibility (algorithm reuse). If the
> code runs, it is technically correct -- but may look ugly and locked in to
> just the one application. Coding style, these days, tends to be defined by
> the company one works at, and one has to follow some guide book that
> already exists at that company. If you want to follow the One-In/One-Out of
> Structured Programming -- try to lay out your code using
> https://en.wikipedia.org/wiki/Nassi%E2%80%93Shneiderman_diagram
> (even in OOP, once one gets down to coding class methods, one should be
> back to structured programming)
>
> -=-=-=-
> C:\Users\Wulfraed\Documents\_Hg-Repositories\Python Progs>letterGrade.py
> Enter percentage grade for Abigail: -5
> Invalid numeric grade
> Please try again
> Enter percentage grade for Abigail: 45
>
> Letter grade for Abigail is F
>
>
> Enter percentage grade for Bertram: 110
> Invalid numeric grade
> Please try again
> Enter percentage grade for Bertram: 99
>
> Letter grade for Bertram is A
>
>
> Enter percentage grade for Charlie: xyz
> invalid literal for int() with base 10: 'xyz'
> Please try again
> Enter percentage grade for Charlie: 68.5
> invalid literal for int() with base 10: '68.5'
> Please try again
> Enter percentage grade for Charlie: 68
>
> Letter grade for Charlie is D
>
>
> Enter percentage grade for Edith: 77
>
> Letter grade for Edith is C
>
>
> Enter percentage grade for Francisca: 81
>
> Letter grade for Francisca is B
>
>
>
> C:\Users\Wulfraed\Documents\_Hg-Repositories\Python Progs>
> -=-=-=-
> STUDENTS = [    "Abigail",
>                 "Bertram",
>                 "Charlie",
>                 "Edith",
>                 "Francisca" ]
>
> GRADES = [ (60, "F"),
>            (70, "D"),
>            (80, "C"),
>            (90, "B"),
>            (100, "A") ] #ordered list of break points
>
> def grade(percent):
>     if percent < 0 or percent > 100:
>         raise ValueError("Invalid numeric grade")
>     for pc, ltr in GRADES:
>         if percent <= pc: return ltr
>
> for st in STUDENTS:
>     while True:
>         try:
>             pcent = input("Enter percentage grade for %s: " % st)
>             pcent = int(pcent)
>             ltrGrade = grade(pcent)
>             print("\nLetter grade for %s is %s\n\n"
>                   % (st, ltrGrade))
>             break
>         except ValueError as ve:
>             print(str(ve))
>             print("Please try again")
>
> -=-=-=-
>
>         For the example, I've left GRADES as a read-only "global". For
> reuse
> purposes, it should be passed as an argument to the grade() function.
>
>         This is easily modifiable for use when grading "by the curve".
> Simplified version: "C" is the mean of the scores, and one then works
> outwards; all that needs to be changed is the GRADES list; so if the mean
> came in at 60 then GRADES would look like:
>
> GRADES = [ (45, "F"),
>            (55, "D"),
>            (65, "C"),           #allow 5 below to 5 above
>            (75, "B"),
>            (100, "A") ] #don't change to catch outliers
>
> If you input the scores per student first, you can have the program
> calculate the mean and modify GRADES as needed.. Granted, this simplified
> version will have problems if the scores are near the extremes... mean of
> 85 makes GRADES look like
>
> GRADES = [ (70, "F"),
>            (80, "D"),
>            (90, "C"),           #allow 5 below to 5 above
>            (100, "B"),
>            (100, "A") ] #no one gets a "A"
>
> The more complex version would compute %iles using mean&std.dev. and use
> those to set the break points for letter grades.
>
>
> --
>         Wulfraed                 Dennis Lee Bieber         AF6VN
>         wlfraed at ix.netcom.com
> http://wlfraed.microdiversity.freeddns.org/
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From manpritsinghece at gmail.com  Wed Oct  6 07:04:43 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Wed, 6 Oct 2021 16:34:43 +0530
Subject: [Tutor] cases with single if and an else clause
In-Reply-To: <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com>
References: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
 <CAO1OCwZR5b2SmccR0=NndjoAVqC0-013=CJZYWLkBpV6OS80_g@mail.gmail.com>
 <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com>
Message-ID: <CAO1OCwbGBQetD_Ufykz4rX7yxAnEAdmq46PUohevYsN8Wt7=ow@mail.gmail.com>

Dear Dennis Lee Bieber,

I  saw your explanation about my question :
GRADES = [ (60, "F"),
           (70, "D"),
           (80, "C"),
           (90, "B"),
           (100, "A") ] #ordered list of breakpoints

These were the grades you have used, There is a problem, See if the marks
are 60 That should not be classified as F . The pattern must be like as
follows :

if marks >=90   and  <= 100  ---- "A" Grade
else marks >= 80 and  < 90  ----  "B" Grade
else marks >= 70 and  < 80  ----  "C" Grade
else marks >= 60 and <  70  ----  "D" Grade
else marks below 60 ---- "F" or Fail
and if marks are less than  0 or greater than 100 then the program must
display "Invalid value entered":
The way i have implemented it given below:

def grades(glist, score):
    if score < 0 or score > 100:
        raise ValueError
    for ch, rg in glist:
        if score in rg:
            return ch

lst = [("F", range(0, 60)),
       ("D", range(60, 70)),
       ("C", range(70, 80)),
       ("B", range(80, 90)),
       ("A", range(90, 101))]

try:
    marks= int(input("Enter marks"))
    grade = grades(lst, marks)

except ValueError:
    print("Invalid Value Entered")

else:
    print(f'for {marks} marks the grade is {grade}')

Can I make such a  program without using range ?

The program is giving correct output as below :

Enter marks59
for 59 marks the grade is F

Enter marks60
for 60 marks the grade is D

Enter marks70
for 70 marks the grade is C

Enter marks79
for 79 marks the grade is C

Enter marks-3
Invalid Value Entered

Enter marks104
Invalid Value Entered



On Wed, Oct 6, 2021 at 12:10 AM Dennis Lee Bieber <wlfraed at ix.netcom.com>
wrote:

> On Tue, 5 Oct 2021 07:22:24 +0530, Manprit Singh
> <manpritsinghece at gmail.com> declaimed the following:
>
> >Dear sir,
> >
> >Now there is one more problem ,  Kindly loom at below written functions :
> >
> >def grade(percent):
> >    if percent < 0 or percent > 100:
> >        ans = "Invalid Input"
> >    elif percent >= 90:
> >        ans = "A"
> >    elif percent >= 70:
> >        ans = "B"
> >    elif percent >= 60:
> >        ans = "C"
> >    else:
> >        ans =  "Fail"
> >    return ans
> >
>
>         My biggest concern is that you are using the same "ans" return to
> indicate invalid input, letter grades (you have a big gap between A and B
> -- at least in US you'd commonly have breakpoints A:90, B:80, C:70, D:60,
> and E (or F) at 50).
>
>         Presuming the numeric grade is being entered by the user of some
> program (say a teacher's electronic grade book) the input should have been
> validated at the place it was entered, NOT in a function that just
> translates number ranges into a letter grade.
>
>         If you really need to validate /in/ this function, you should be
> raising an exception... and the caller needs to catch this exception and do
> whatever is needed to correct the data before retrying the operation. As
> is, the caller is forced to test every return from the function for a
> SPECIFIC string...
>
> aGrade = grade(score)
> if aGrade == "Invalid Input":
>         #do something to correct the input and retry the call to grade()
> else:
>         #record the returned letter grade
>
>
>
>         There are multiple ways to avoid a chain of if/elif/else
> comparisons...
> But for that you need to study /data structures/ and the algorithms using
> them rather than just playing around with simple examples that would seldom
> be used in actual applications. Especially examples that are mostly
> concerned with /coding style/ than on flexibility (algorithm reuse). If the
> code runs, it is technically correct -- but may look ugly and locked in to
> just the one application. Coding style, these days, tends to be defined by
> the company one works at, and one has to follow some guide book that
> already exists at that company. If you want to follow the One-In/One-Out of
> Structured Programming -- try to lay out your code using
> https://en.wikipedia.org/wiki/Nassi%E2%80%93Shneiderman_diagram
> (even in OOP, once one gets down to coding class methods, one should be
> back to structured programming)
>
> -=-=-=-
> C:\Users\Wulfraed\Documents\_Hg-Repositories\Python Progs>letterGrade.py
> Enter percentage grade for Abigail: -5
> Invalid numeric grade
> Please try again
> Enter percentage grade for Abigail: 45
>
> Letter grade for Abigail is F
>
>
> Enter percentage grade for Bertram: 110
> Invalid numeric grade
> Please try again
> Enter percentage grade for Bertram: 99
>
> Letter grade for Bertram is A
>
>
> Enter percentage grade for Charlie: xyz
> invalid literal for int() with base 10: 'xyz'
> Please try again
> Enter percentage grade for Charlie: 68.5
> invalid literal for int() with base 10: '68.5'
> Please try again
> Enter percentage grade for Charlie: 68
>
> Letter grade for Charlie is D
>
>
> Enter percentage grade for Edith: 77
>
> Letter grade for Edith is C
>
>
> Enter percentage grade for Francisca: 81
>
> Letter grade for Francisca is B
>
>
>
> C:\Users\Wulfraed\Documents\_Hg-Repositories\Python Progs>
> -=-=-=-
> STUDENTS = [    "Abigail",
>                 "Bertram",
>                 "Charlie",
>                 "Edith",
>                 "Francisca" ]
>
> GRADES = [ (60, "F"),
>            (70, "D"),
>            (80, "C"),
>            (90, "B"),
>            (100, "A") ] #ordered list of break points
>
> def grade(percent):
>     if percent < 0 or percent > 100:
>         raise ValueError("Invalid numeric grade")
>     for pc, ltr in GRADES:
>         if percent <= pc: return ltr
>
> for st in STUDENTS:
>     while True:
>         try:
>             pcent = input("Enter percentage grade for %s: " % st)
>             pcent = int(pcent)
>             ltrGrade = grade(pcent)
>             print("\nLetter grade for %s is %s\n\n"
>                   % (st, ltrGrade))
>             break
>         except ValueError as ve:
>             print(str(ve))
>             print("Please try again")
>
> -=-=-=-
>
>         For the example, I've left GRADES as a read-only "global". For
> reuse
> purposes, it should be passed as an argument to the grade() function.
>
>         This is easily modifiable for use when grading "by the curve".
> Simplified version: "C" is the mean of the scores, and one then works
> outwards; all that needs to be changed is the GRADES list; so if the mean
> came in at 60 then GRADES would look like:
>
> GRADES = [ (45, "F"),
>            (55, "D"),
>            (65, "C"),           #allow 5 below to 5 above
>            (75, "B"),
>            (100, "A") ] #don't change to catch outliers
>
> If you input the scores per student first, you can have the program
> calculate the mean and modify GRADES as needed.. Granted, this simplified
> version will have problems if the scores are near the extremes... mean of
> 85 makes GRADES look like
>
> GRADES = [ (70, "F"),
>            (80, "D"),
>            (90, "C"),           #allow 5 below to 5 above
>            (100, "B"),
>            (100, "A") ] #no one gets a "A"
>
> The more complex version would compute %iles using mean&std.dev. and use
> those to set the break points for letter grades.
>
>
> --
>         Wulfraed                 Dennis Lee Bieber         AF6VN
>         wlfraed at ix.netcom.com
> http://wlfraed.microdiversity.freeddns.org/
>
> _______________________________________________
> 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 Oct  6 07:30:36 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 6 Oct 2021 12:30:36 +0100
Subject: [Tutor] cases with single if and an else clause
In-Reply-To: <CAO1OCwbGBQetD_Ufykz4rX7yxAnEAdmq46PUohevYsN8Wt7=ow@mail.gmail.com>
References: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
 <CAO1OCwZR5b2SmccR0=NndjoAVqC0-013=CJZYWLkBpV6OS80_g@mail.gmail.com>
 <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com>
 <CAO1OCwbGBQetD_Ufykz4rX7yxAnEAdmq46PUohevYsN8Wt7=ow@mail.gmail.com>
Message-ID: <sjk1ct$fmb$1@ciao.gmane.io>

On 06/10/2021 12:04, Manprit Singh wrote:
> Dear Dennis Lee Bieber,
> 
> I  saw your explanation about my question :
> GRADES = [ (60, "F"),
>            (70, "D"),
>            (80, "C"),
>            (90, "B"),
>            (100, "A") ] #ordered list of breakpoints
> 
> These were the grades you have used, There is a problem, See if the marks
> are 60 That should not be classified as F . 

All you need to do is change the comparison from <= to <
(You also need to change the 100 to 101 for an "A" grade.)
Alternatively, change all the test values to the highest vale
for the grade: 59,69,...100 and keep the <= test

> The way i have implemented it given below:
> 
> def grades(glist, score):
>     if score < 0 or score > 100:
>         raise ValueError
>     for ch, rg in glist:
>         if score in rg:
>             return ch
> 
> lst = [("F", range(0, 60)),
>        ("D", range(60, 70)),
>        ("C", range(70, 80)),
>        ("B", range(80, 90)),
>        ("A", range(90, 101))]

But now there is much more work generating ranges and using
the in operation which implicitly loops over the values.
A simple comparison is much cheaper. Although your version
does exit as soon as it finds the correct range which will
compensate somewhat. But 5 comparisons should be cheaper than
an average of 3 'in' checks over 10 values(60 for the first!)
even though the 'in' is written in C.

> try:
>     marks= int(input("Enter marks"))
>     grade = grades(lst, marks)
> 
> except ValueError:
>     print("Invalid Value Entered")
> 
> else:
>     print(f'for {marks} marks the grade is {grade}')
> 
> Can I make such a  program without using range ?

Just change the comparison operator in Dennis' example.

-- 
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 nathan-tech at hotmail.com  Wed Oct  6 10:20:43 2021
From: nathan-tech at hotmail.com (Nathan Smith)
Date: Wed, 6 Oct 2021 15:20:43 +0100
Subject: [Tutor] getting past an ssl issue
Message-ID: <DB7PR07MB509390B888B0F199F3A114A6E4B09@DB7PR07MB5093.eurprd07.prod.outlook.com>

Hi List,


I wonder if someone could help me here.

Since a few days ago I've been getting the following error with requests:

requests.exceptions.SSLError: HTTPSConnectionPool(host='google.co.uk', 
port=443): Max retries exceeded with url: / (Caused by 
SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] 
certificate verify failed: self signed certificate in certificate chain 
(_ssl.c:1124)')))


I recently had to add a cert to my trusted list for windows because the 
place I work at is an educational establishment that has an extra https 
firewall or some such, so wonder if this could be related?

This happens with any URI running:

import requests

r=requests.get(any_uri)


I've tried:

pip install --upgrad certifii


But it says I am up to date.


thanks

nathan


From wlfraed at ix.netcom.com  Wed Oct  6 11:43:38 2021
From: wlfraed at ix.netcom.com (Dennis Lee Bieber)
Date: Wed, 06 Oct 2021 11:43:38 -0400
Subject: [Tutor] cases with single if and an else clause
References: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
 <CAO1OCwZR5b2SmccR0=NndjoAVqC0-013=CJZYWLkBpV6OS80_g@mail.gmail.com>
 <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com>
 <CAO1OCwbGBQetD_Ufykz4rX7yxAnEAdmq46PUohevYsN8Wt7=ow@mail.gmail.com>
Message-ID: <kkfrlgpjb6cu72hjqcm85h2kv0vqe4aij8@4ax.com>

On Wed, 6 Oct 2021 16:34:43 +0530, Manprit Singh
<manpritsinghece at gmail.com> declaimed the following:

>
>I  saw your explanation about my question :
>GRADES = [ (60, "F"),
>           (70, "D"),
>           (80, "C"),
>           (90, "B"),
>           (100, "A") ] #ordered list of breakpoints
>
>These were the grades you have used, There is a problem, See if the marks
>are 60 That should not be classified as F . The pattern must be like as
>follows :
>
>if marks >=90   and  <= 100  ---- "A" Grade
>else marks >= 80 and  < 90  ----  "B" Grade
>else marks >= 70 and  < 80  ----  "C" Grade
>else marks >= 60 and <  70  ----  "D" Grade
>else marks below 60 ---- "F" or Fail

	Using those ranges means that "A" is achieved for 11 scores, but "B",
"C", and "D" are only achieved for 10 scores each -- an imbalance (or bias)
in distributing letter grades. 

A	90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100
B	80, 81, 82, 83, 84, 85, 86, 87, 88, 89
(with the B pattern applied to C and D)

	The break points I used mean that each letter grade A..D has only 10
matching scores -- with F absorbing everything below (including the fact
that 0..100 spans 101 distinct scores; logically one might expect 0..99 or
1..100 <G>).
. 


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


From manpritsinghece at gmail.com  Wed Oct  6 12:01:04 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Wed, 6 Oct 2021 21:31:04 +0530
Subject: [Tutor] cases with single if and an else clause
In-Reply-To: <kkfrlgpjb6cu72hjqcm85h2kv0vqe4aij8@4ax.com>
References: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
 <CAO1OCwZR5b2SmccR0=NndjoAVqC0-013=CJZYWLkBpV6OS80_g@mail.gmail.com>
 <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com>
 <CAO1OCwbGBQetD_Ufykz4rX7yxAnEAdmq46PUohevYsN8Wt7=ow@mail.gmail.com>
 <kkfrlgpjb6cu72hjqcm85h2kv0vqe4aij8@4ax.com>
Message-ID: <CAO1OCwb6em1KA+Lg1F90KqVNcbKtEEkss-ZruZu4iGy3aJiLHA@mail.gmail.com>

So...once again ...many many thanks to Dennis ....and Alan sir .

Today .it was something ..that made me to think...differently ..

Upto this ..point ...I was habitual of writing longer if else inside
functions ..but today's...mail of Dennis...has taught me so many things...

And...I am not a programmer ..python ...is just my hobby...just...to
say...I am glad...I am learning it day by day.


Regards
Manprit Singh

On Wed, 6 Oct, 2021, 21:13 Dennis Lee Bieber, <wlfraed at ix.netcom.com> wrote:

> On Wed, 6 Oct 2021 16:34:43 +0530, Manprit Singh
> <manpritsinghece at gmail.com> declaimed the following:
>
> >
> >I  saw your explanation about my question :
> >GRADES = [ (60, "F"),
> >           (70, "D"),
> >           (80, "C"),
> >           (90, "B"),
> >           (100, "A") ] #ordered list of breakpoints
> >
> >These were the grades you have used, There is a problem, See if the marks
> >are 60 That should not be classified as F . The pattern must be like as
> >follows :
> >
> >if marks >=90   and  <= 100  ---- "A" Grade
> >else marks >= 80 and  < 90  ----  "B" Grade
> >else marks >= 70 and  < 80  ----  "C" Grade
> >else marks >= 60 and <  70  ----  "D" Grade
> >else marks below 60 ---- "F" or Fail
>
>         Using those ranges means that "A" is achieved for 11 scores, but
> "B",
> "C", and "D" are only achieved for 10 scores each -- an imbalance (or bias)
> in distributing letter grades.
>
> A       90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100
> B       80, 81, 82, 83, 84, 85, 86, 87, 88, 89
> (with the B pattern applied to C and D)
>
>         The break points I used mean that each letter grade A..D has only
> 10
> matching scores -- with F absorbing everything below (including the fact
> that 0..100 spans 101 distinct scores; logically one might expect 0..99 or
> 1..100 <G>).
> .
>
>
> --
>         Wulfraed                 Dennis Lee Bieber         AF6VN
>         wlfraed at ix.netcom.com
> http://wlfraed.microdiversity.freeddns.org/
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From manpritsinghece at gmail.com  Wed Oct  6 18:23:11 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Thu, 7 Oct 2021 03:53:11 +0530
Subject: [Tutor] cases with single if and an else clause
In-Reply-To: <sjk1ct$fmb$1@ciao.gmane.io>
References: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
 <CAO1OCwZR5b2SmccR0=NndjoAVqC0-013=CJZYWLkBpV6OS80_g@mail.gmail.com>
 <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com>
 <CAO1OCwbGBQetD_Ufykz4rX7yxAnEAdmq46PUohevYsN8Wt7=ow@mail.gmail.com>
 <sjk1ct$fmb$1@ciao.gmane.io>
Message-ID: <CAO1OCwZ57Ygtod0uaJuYQKSFM2dPEOh-vq17JDSOwvpzQy4GOA@mail.gmail.com>

I would continue my discussion on this topic regarding the function written
and the way it is implemented, So finally it is done this way :

def grades(glist, score):
    if score < 0 or score > 100:
        raise ValueError
    for ch, rg in glist:
        if score < rg:
            return ch

lst = [("F", 60),
       ("D", 70),
       ("C", 80),
       ("B", 90),
       ("A", 101)]

try:
    marks= int(input("Enter marks"))
    grade = grades(lst, marks)

except ValueError:
    print("Invalid Value Entered")

else:
    print(f'for {marks} marks the grade is {grade}')

My Next question is, in this particular scenario, where keeping the
variable lst (which contains grade Characters and marks limits) as global
and passing it as an argument to the function grades. So when this function
is called, a copy of lst is created and it is destroyed upon exit from
function.

As the variable lst serves no other purpose, why not keep this lst as a
local variable inside the function grades .
Need some light on it .

Regards
Manprit Singh





On Wed, Oct 6, 2021 at 5:02 PM Alan Gauld via Tutor <tutor at python.org>
wrote:

> On 06/10/2021 12:04, Manprit Singh wrote:
> > Dear Dennis Lee Bieber,
> >
> > I  saw your explanation about my question :
> > GRADES = [ (60, "F"),
> >            (70, "D"),
> >            (80, "C"),
> >            (90, "B"),
> >            (100, "A") ] #ordered list of breakpoints
> >
> > These were the grades you have used, There is a problem, See if the marks
> > are 60 That should not be classified as F .
>
> All you need to do is change the comparison from <= to <
> (You also need to change the 100 to 101 for an "A" grade.)
> Alternatively, change all the test values to the highest vale
> for the grade: 59,69,...100 and keep the <= test
>
> > The way i have implemented it given below:
> >
> > def grades(glist, score):
> >     if score < 0 or score > 100:
> >         raise ValueError
> >     for ch, rg in glist:
> >         if score in rg:
> >             return ch
> >
> > lst = [("F", range(0, 60)),
> >        ("D", range(60, 70)),
> >        ("C", range(70, 80)),
> >        ("B", range(80, 90)),
> >        ("A", range(90, 101))]
>
> But now there is much more work generating ranges and using
> the in operation which implicitly loops over the values.
> A simple comparison is much cheaper. Although your version
> does exit as soon as it finds the correct range which will
> compensate somewhat. But 5 comparisons should be cheaper than
> an average of 3 'in' checks over 10 values(60 for the first!)
> even though the 'in' is written in C.
>
> > try:
> >     marks= int(input("Enter marks"))
> >     grade = grades(lst, marks)
> >
> > except ValueError:
> >     print("Invalid Value Entered")
> >
> > else:
> >     print(f'for {marks} marks the grade is {grade}')
> >
> > Can I make such a  program without using range ?
>
> Just change the comparison operator in Dennis' example.
>
> --
> 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  Wed Oct  6 19:15:26 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 7 Oct 2021 00:15:26 +0100
Subject: [Tutor] cases with single if and an else clause
In-Reply-To: <CAO1OCwZ57Ygtod0uaJuYQKSFM2dPEOh-vq17JDSOwvpzQy4GOA@mail.gmail.com>
References: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
 <CAO1OCwZR5b2SmccR0=NndjoAVqC0-013=CJZYWLkBpV6OS80_g@mail.gmail.com>
 <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com>
 <CAO1OCwbGBQetD_Ufykz4rX7yxAnEAdmq46PUohevYsN8Wt7=ow@mail.gmail.com>
 <sjk1ct$fmb$1@ciao.gmane.io>
 <CAO1OCwZ57Ygtod0uaJuYQKSFM2dPEOh-vq17JDSOwvpzQy4GOA@mail.gmail.com>
Message-ID: <sjlamh$gd4$1@ciao.gmane.io>

On 06/10/2021 23:23, Manprit Singh wrote:

> def grades(glist, score):
>     if score < 0 or score > 100:
>         raise ValueError
>     for ch, rg in glist:
>         if score < rg:
>             return ch
> 
> lst = [("F", 60),
>        ("D", 70),
>        ("C", 80),
>        ("B", 90),
>        ("A", 101)]

> My Next question is, in this particular scenario, where keeping the
> variable lst (which contains grade Characters and marks limits) as global
> and passing it as an argument to the function grades. So when this function
> is called, a copy of lst is created and it is destroyed upon exit from
> function.

Nope. When you pass the list to the function you pass a reference to it.
There is no copy made. The original list is still there in its global
space and the function parameter refers out to it.

> As the variable lst serves no other purpose, why not keep this lst as a
> local variable inside the function grades.

If you are sure that you won't want to refer to the list anywhere else
that would be fine. But what if you want to write some reports that map
grades to scores? You need to duplicate the data and then have a
maintenance headache.

Also what if you want to use the grades() function in anther program
that uses a different set of grades:

lst2 = [('fail':5),('pass',7)('credit":10)]

[ These were actually the scores used on my practical exams
during my apprenticeship. Theory exams used the more usual
A-F grades but practicals had this simpler fail/pass/credit
scheme based on the number of successful tasks out of 10.]

By keeping it as a parameter you have more options for reuse.

Of course you could make a default value for the glist parameter
and if it's None use your default set of values inside the function.
Best of both worlds? But you would need to make glist the second
parameter...

def grades(score,glist=None):
    if glist is None:
       glist = {("F",60),....]
    if score <...
etc

-- 
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 wlfraed at ix.netcom.com  Wed Oct  6 19:35:33 2021
From: wlfraed at ix.netcom.com (Dennis Lee Bieber)
Date: Wed, 06 Oct 2021 19:35:33 -0400
Subject: [Tutor] cases with single if and an else clause
References: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
 <CAO1OCwZR5b2SmccR0=NndjoAVqC0-013=CJZYWLkBpV6OS80_g@mail.gmail.com>
 <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com>
 <CAO1OCwbGBQetD_Ufykz4rX7yxAnEAdmq46PUohevYsN8Wt7=ow@mail.gmail.com>
 <sjk1ct$fmb$1@ciao.gmane.io>
 <CAO1OCwZ57Ygtod0uaJuYQKSFM2dPEOh-vq17JDSOwvpzQy4GOA@mail.gmail.com>
Message-ID: <86bslgde9v3dc5abfu8jjcdh615o50k5bv@4ax.com>

On Thu, 7 Oct 2021 03:53:11 +0530, Manprit Singh
<manpritsinghece at gmail.com> declaimed the following:


>def grades(glist, score):

>
>lst = [("F", 60),
>       ("D", 70),
>       ("C", 80),
>       ("B", 90),
>       ("A", 101)]
>
>try:
>    marks= int(input("Enter marks"))
>    grade = grades(lst, marks)
>

>
>My Next question is, in this particular scenario, where keeping the
>variable lst (which contains grade Characters and marks limits) as global
>and passing it as an argument to the function grades. So when this function
>is called, a copy of lst is created and it is destroyed upon exit from
>function.

	There is NO COPY... The parameter NAME "glist" is bound to the actual
list.

>>> lst = []
>>> def aFunc(lst):
... 	lst.append(len(lst))
... 	
>>> lst
[]
>>> aFunc(lst)
>>> lst
[0]
>>> 

	Names in Python are bound (connected) to objects. Python does NOT use
the "post office box" model where the names are fixed memory locations and
assignment copies the contents of the source box to the destination box.
Instead, in a somewhat simplified representation, Python uses "Post-It"
notes attached to strings which themselves connect to objects laying on the
floor. "Assignment" (binding) grabs a Post-It, writes the destination name
on it, finds a free string, attaches the Post-It (name) to the string, then
finds the source name's Post-It, follows its string to the relevant object,
and attaches the destination's string to the same object.

>>> aFunc(lst[:])
>>> lst
[0]
>>> 

	The use of [:] is what MAKES A (shallow) COPY of a list.

>
>As the variable lst serves no other purpose, why not keep this lst as a
>local variable inside the function grades .

	Python is byte-code interpreted at run time. Putting the list creation
inside the function means that the list is created each time the function
is executed, and deleted when the function exits. If the list (or other
structure) is large, creating it each time could be a significant slow-down
on the program.

>>> def bFunc():
... 	lst = [a]
... 	lst.append(len(lst))
... 	return lst
... 
>>> a = 1
>>> bFunc()
[1, 1]
>>> a = 3
>>> bFunc()
[3, 1]
>>> 

	If the list were not built at run time, the "def bFunc" compile (to
byte code) would fail since at the time, "a" does not exist.

	I used all capitals as a convention in Python that this name represents
a CONSTANT and should not be rebound or modified by code; code should only
access (read) the contents. I also treated it as a global (within the file)
constant to avoid passing it. 

	I would pass it if I were generating the score<>letter break points
dynamically (my example of "grading by the curve") as then it is not a
constant..



-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


From manpritsinghece at gmail.com  Fri Oct  8 05:28:34 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Fri, 8 Oct 2021 14:58:34 +0530
Subject: [Tutor] cases with single if and an else clause
In-Reply-To: <86bslgde9v3dc5abfu8jjcdh615o50k5bv@4ax.com>
References: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
 <CAO1OCwZR5b2SmccR0=NndjoAVqC0-013=CJZYWLkBpV6OS80_g@mail.gmail.com>
 <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com>
 <CAO1OCwbGBQetD_Ufykz4rX7yxAnEAdmq46PUohevYsN8Wt7=ow@mail.gmail.com>
 <sjk1ct$fmb$1@ciao.gmane.io>
 <CAO1OCwZ57Ygtod0uaJuYQKSFM2dPEOh-vq17JDSOwvpzQy4GOA@mail.gmail.com>
 <86bslgde9v3dc5abfu8jjcdh615o50k5bv@4ax.com>
Message-ID: <CAO1OCwbged8+pHjfbu8UK2__f3WoUMyBx5iCD+o02qVN1_qvKA@mail.gmail.com>

Once again a big thanks to Dennis for a very very informative email , That
made me to do some experiments with the python interpreter as given below:

>>> a = 1
>>> b = a
>>> b
1
>>> a
1
>>> id(a)
140287237945648
>>> id(b)
140287237945648
>>>
Here in this example above due to the assignment in the second line ,
variables a and b are now references to the same object .  Which is proved
by their id, id(a) is the same as id(b).

>>> a = [3, 6, 7]
>>> b= a
>>> id(a), id(b)
(140287234775168, 140287234775168)
>>> a[0] = 7
>>> a
[7, 6, 7]
>>> b
[7, 6, 7]
>>>
In this example again a & b variables are references to the same object ,
Since lists are mutable doing a[0] = 7  makes changes in a & b
Second thing is arguments are passed by assignment in Python  in functions.

  def increment(x):
      return x+1

num = 9
ans = increment(num)
When we execute it , the value of num will be passed to formal parameter x
by assignment, so obviously no copy is made, x is reference to num , the
function will return a value incremented by one . One point written in
Dennis' email I do feel is correct is if we place a bulky data structure
inside the function, everytime the function is called, there will be an
overhead of creation and destruction of this data structure.

So placing the data structure outside the function is obviously good :
1) First to avoid overheads as given above
2) If we need to use that data structure in the program, we would not be
able to use it if it was placed locally inside the function as mentioned by
Alan's sir email.

Hopefully my points are correct now
Need comments

Regards

Manprit Singh


On Thu, Oct 7, 2021 at 5:05 AM Dennis Lee Bieber <wlfraed at ix.netcom.com>
wrote:

> On Thu, 7 Oct 2021 03:53:11 +0530, Manprit Singh
> <manpritsinghece at gmail.com> declaimed the following:
>
>
> >def grades(glist, score):
>
> >
> >lst = [("F", 60),
> >       ("D", 70),
> >       ("C", 80),
> >       ("B", 90),
> >       ("A", 101)]
> >
> >try:
> >    marks= int(input("Enter marks"))
> >    grade = grades(lst, marks)
> >
>
> >
> >My Next question is, in this particular scenario, where keeping the
> >variable lst (which contains grade Characters and marks limits) as global
> >and passing it as an argument to the function grades. So when this
> function
> >is called, a copy of lst is created and it is destroyed upon exit from
> >function.
>
>         There is NO COPY... The parameter NAME "glist" is bound to the
> actual
> list.
>
> >>> lst = []
> >>> def aFunc(lst):
> ...     lst.append(len(lst))
> ...
> >>> lst
> []
> >>> aFunc(lst)
> >>> lst
> [0]
> >>>
>
>         Names in Python are bound (connected) to objects. Python does NOT
> use
> the "post office box" model where the names are fixed memory locations and
> assignment copies the contents of the source box to the destination box.
> Instead, in a somewhat simplified representation, Python uses "Post-It"
> notes attached to strings which themselves connect to objects laying on the
> floor. "Assignment" (binding) grabs a Post-It, writes the destination name
> on it, finds a free string, attaches the Post-It (name) to the string, then
> finds the source name's Post-It, follows its string to the relevant object,
> and attaches the destination's string to the same object.
>
> >>> aFunc(lst[:])
> >>> lst
> [0]
> >>>
>
>         The use of [:] is what MAKES A (shallow) COPY of a list.
>
> >
> >As the variable lst serves no other purpose, why not keep this lst as a
> >local variable inside the function grades .
>
>         Python is byte-code interpreted at run time. Putting the list
> creation
> inside the function means that the list is created each time the function
> is executed, and deleted when the function exits. If the list (or other
> structure) is large, creating it each time could be a significant slow-down
> on the program.
>
> >>> def bFunc():
> ...     lst = [a]
> ...     lst.append(len(lst))
> ...     return lst
> ...
> >>> a = 1
> >>> bFunc()
> [1, 1]
> >>> a = 3
> >>> bFunc()
> [3, 1]
> >>>
>
>         If the list were not built at run time, the "def bFunc" compile (to
> byte code) would fail since at the time, "a" does not exist.
>
>         I used all capitals as a convention in Python that this name
> represents
> a CONSTANT and should not be rebound or modified by code; code should only
> access (read) the contents. I also treated it as a global (within the file)
> constant to avoid passing it.
>
>         I would pass it if I were generating the score<>letter break points
> dynamically (my example of "grading by the curve") as then it is not a
> constant..
>
>
>
> --
>         Wulfraed                 Dennis Lee Bieber         AF6VN
>         wlfraed at ix.netcom.com
> http://wlfraed.microdiversity.freeddns.org/
>
> _______________________________________________
> 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 Oct  8 06:30:53 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 8 Oct 2021 11:30:53 +0100
Subject: [Tutor] cases with single if and an else clause
In-Reply-To: <CAO1OCwbged8+pHjfbu8UK2__f3WoUMyBx5iCD+o02qVN1_qvKA@mail.gmail.com>
References: <CAO1OCwZsr_scDO7cQ-0Om7Xe3ThucpwD-em+TwBYudVbbejhaw@mail.gmail.com>
 <CAO1OCwZR5b2SmccR0=NndjoAVqC0-013=CJZYWLkBpV6OS80_g@mail.gmail.com>
 <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com>
 <CAO1OCwbGBQetD_Ufykz4rX7yxAnEAdmq46PUohevYsN8Wt7=ow@mail.gmail.com>
 <sjk1ct$fmb$1@ciao.gmane.io>
 <CAO1OCwZ57Ygtod0uaJuYQKSFM2dPEOh-vq17JDSOwvpzQy4GOA@mail.gmail.com>
 <86bslgde9v3dc5abfu8jjcdh615o50k5bv@4ax.com>
 <CAO1OCwbged8+pHjfbu8UK2__f3WoUMyBx5iCD+o02qVN1_qvKA@mail.gmail.com>
Message-ID: <sjp6kt$tsm$1@ciao.gmane.io>

On 08/10/2021 10:28, Manprit Singh wrote:
> Once again a big thanks to Dennis for a very very informative email , That
> made me to do some experiments with the python interpreter as given below:

> 
> Hopefully my points are correct now
> Need comments
Yes, you seem to have grasped the points.


-- 
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 edwinconnell at gmail.com  Fri Oct  8 15:37:54 2021
From: edwinconnell at gmail.com (Ed Connell)
Date: Fri, 8 Oct 2021 14:37:54 -0500
Subject: [Tutor] returning from 2 functions at once
Message-ID: <CADmpvFGnRiydREVCn4h=mJep0SjgWDDeBMVqkG_7eWi=HrP8Pg@mail.gmail.com>

Hello,

Is there a way to return from a function because of the return of a
subfunction.  Don't know if I said that right, so I'll give an example.

Say you have function f1 and f2,

def f1( *args )



-- 
I have a right and a left brain, but there is nothing right in the left one
and there is nothing left in the right one!

From mats at wichmann.us  Fri Oct  8 18:11:03 2021
From: mats at wichmann.us (Mats Wichmann)
Date: Fri, 8 Oct 2021 16:11:03 -0600
Subject: [Tutor] returning from 2 functions at once
In-Reply-To: <CADmpvFGnRiydREVCn4h=mJep0SjgWDDeBMVqkG_7eWi=HrP8Pg@mail.gmail.com>
References: <CADmpvFGnRiydREVCn4h=mJep0SjgWDDeBMVqkG_7eWi=HrP8Pg@mail.gmail.com>
Message-ID: <ab706c73-7b56-c6db-fb7a-d942862f5822@wichmann.us>

On 10/8/21 13:37, Ed Connell wrote:
> Hello,
> 
> Is there a way to return from a function because of the return of a
> subfunction.  Don't know if I said that right, so I'll give an example.
> 
> Say you have function f1 and f2,
> 
> def f1( *args )

looks like this got truncated, or sent before it was done?



From breamoreboy at gmail.com  Fri Oct  8 17:18:20 2021
From: breamoreboy at gmail.com (Mark Lawrence)
Date: Fri, 8 Oct 2021 22:18:20 +0100
Subject: [Tutor] returning from 2 functions at once
In-Reply-To: <CADmpvFGnRiydREVCn4h=mJep0SjgWDDeBMVqkG_7eWi=HrP8Pg@mail.gmail.com>
References: <CADmpvFGnRiydREVCn4h=mJep0SjgWDDeBMVqkG_7eWi=HrP8Pg@mail.gmail.com>
Message-ID: <7f3da9be-77d7-b150-e7c1-914da522fe65@gmail.com>

On 08/10/2021 20:37, Ed Connell wrote:
> Hello,
> 
> Is there a way to return from a function because of the return of a
> subfunction.  Don't know if I said that right, so I'll give an example.
> 
> Say you have function f1 and f2,
> 
> def f1( *args )
> 

f2 is conspicuous by its absence :)

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From learn2program at gmail.com  Fri Oct  8 19:44:10 2021
From: learn2program at gmail.com (Alan Gauld)
Date: Sat, 9 Oct 2021 00:44:10 +0100
Subject: [Tutor] returning from 2 functions at once
In-Reply-To: <CADmpvFGnRiydREVCn4h=mJep0SjgWDDeBMVqkG_7eWi=HrP8Pg@mail.gmail.com>
References: <CADmpvFGnRiydREVCn4h=mJep0SjgWDDeBMVqkG_7eWi=HrP8Pg@mail.gmail.com>
Message-ID: <1473cc08-e6ef-26c9-b521-812d1e3b8ba5@yahoo.co.uk>


On 08/10/2021 20:37, Ed Connell wrote:
> Hello,
>
> Is there a way to return from a function because of the return of a
> subfunction.  Don't know if I said that right, so I'll give an example.
>
> Say you have function f1 and f2,
>
> def f1( *args )

The example got lost. But if I understand you correctly the answer is
no, not easily.
Or maybe yes, that's the default....

That's because when you call a function from inside another function the
outer
function stops executing and waits for the inner function to complete.
So when
the inner function returns you have the option of exiting the outer
function
if you want. Or you can test the return value and only exit under certain
conditions, or you can just ignore the inner function's return and continue
with the outer function. It's up to you.

But the important point is that the outer function stops while the inner
executes.
You can get round that with threading and concurrency but that's a way
more complex scenario.

If that's not what you meant you need to repost with a more complete
example.

-- 

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 learn2program at gmail.com  Sat Oct  9 13:51:30 2021
From: learn2program at gmail.com (Alan Gauld)
Date: Sat, 9 Oct 2021 18:51:30 +0100
Subject: [Tutor] returning from 2 functions at once
In-Reply-To: <CADmpvFGdrUHtkq+iiEm3JjBuZYsoSvFZDhTbr4O9ZvtQAB8xWA@mail.gmail.com>
References: <CADmpvFGnRiydREVCn4h=mJep0SjgWDDeBMVqkG_7eWi=HrP8Pg@mail.gmail.com>
 <1473cc08-e6ef-26c9-b521-812d1e3b8ba5@yahoo.co.uk>
 <CADmpvFGdrUHtkq+iiEm3JjBuZYsoSvFZDhTbr4O9ZvtQAB8xWA@mail.gmail.com>
Message-ID: <0bbf726e-84ba-3962-b1cc-bc1631cc8fa0@yahoo.co.uk>

CCing to tutor.

Please use replyAll when respo ding to tutor list mails.


On 09/10/2021 15:13, Ed Connell wrote:
>
> Actually I am trying to learn to work with tkinter but I don't think
> y'all do tkinter.? Is there a list for that?
>
There is a dedicated tkinter list but since its part of the standard
library we cover the basics here too.

If its complicated stuff the tkinter list is better.


> def pickFromList(( thelist ):
> ? ? stuff...
> ? ? return choice
>
> I can do that easily in Python, but I want to use the ttk.Listbox( ...?
>
I can't find any reference to a ttk.Listbox widget. There is however a
tkinter Listbox
so I'll assume you mean ghat.

As I'm sure you know tkinter is event driven so a function like the
above only makes
sense when we know which events you are attaching it to? For example the
tkinter.Listbox
widget often has the mouse button actions bound to events and these
often call the curselection()
method to get the list of currently selected items (or their indices at
least.)?

But you need to explain with a bit more detail what exactly you are
trying to do.
Its not obvious.

> -- 

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 juliushamilton100 at gmail.com  Sat Oct  9 17:58:34 2021
From: juliushamilton100 at gmail.com (Julius Hamilton)
Date: Sat, 9 Oct 2021 23:58:34 +0200
Subject: [Tutor] Input to correct data type
Message-ID: <CAEsMKX21iJcDPg4mUw+broaQoNZDNkC3sTEg-peSxWL_DWc2nA@mail.gmail.com>

Hey,

Is there any built-in function which guesses the data type of input or a
variable? For example, it would take integer input as an integer, and
anything non-numerical as a string, perhaps?

Thanks,
Julius

From wlfraed at ix.netcom.com  Sat Oct  9 20:39:11 2021
From: wlfraed at ix.netcom.com (Dennis Lee Bieber)
Date: Sat, 09 Oct 2021 20:39:11 -0400
Subject: [Tutor] Input to correct data type
References: <CAEsMKX21iJcDPg4mUw+broaQoNZDNkC3sTEg-peSxWL_DWc2nA@mail.gmail.com>
Message-ID: <5mc4mghk9320f90kco4fs3bsccuk4h5ml6@4ax.com>

On Sat, 9 Oct 2021 23:58:34 +0200, Julius Hamilton
<juliushamilton100 at gmail.com> declaimed the following:

>Hey,
>
>Is there any built-in function which guesses the data type of input or a
>variable? For example, it would take integer input as an integer, and
>anything non-numerical as a string, perhaps?
>
	That description is a bit vague... after all...

>>> def stupidExample(a, b):
... 	return a + b
... 
>>> stupidExample(5.25, 123)
128.25
>>> stupidExample("hello ", "goodbye [pump out the septic tank]")
'hello goodbye [pump out the septic tank]'
>>> 

	If you mean the use of input() to obtain interactive values, it is up
to you to determine what is expected at that point -- input() itself
returns a string.

>>> "123.5".isdecimal()
False
>>> "123".isdecimal()
True
>>> 

	For floats you'll have to use a try/except block

>>> x = "123.75"
>>> try:
... 	xval = int(x)
... except ValueError:
... 	try:
... 		xval = float(x)
... 	except ValueError:
... 		xval = x
... 		
>>> xval
123.75
>>> x = 123
>>> try:
... 	xval = int(x)
... except ValueError:
... 	try:
... 		xval = float(x)
... 	except ValueError:
... 		xval = x
... 
>>> xval
123
>>> x = "123"
>>> try:
... 	xval = int(x)
... except ValueError:
... 	try:
... 		xval = float(x)
... 	except ValueError:
... 		xval = x
... 
>>> xval
123
>>> x = "something wicked this way comes"
>>> try:
... 	xval = int(x)
... except ValueError:
... 	try:
... 		xval = float(x)
... 	except ValueError:
... 		xval = x
... 
>>> xval
'something wicked this way comes'
>>> 


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


From edwinconnell at gmail.com  Sun Oct 10 15:14:55 2021
From: edwinconnell at gmail.com (Ed Connell)
Date: Sun, 10 Oct 2021 14:14:55 -0500
Subject: [Tutor] returning from 2 functions at once
In-Reply-To: <0bbf726e-84ba-3962-b1cc-bc1631cc8fa0@yahoo.co.uk>
References: <CADmpvFGnRiydREVCn4h=mJep0SjgWDDeBMVqkG_7eWi=HrP8Pg@mail.gmail.com>
 <1473cc08-e6ef-26c9-b521-812d1e3b8ba5@yahoo.co.uk>
 <CADmpvFGdrUHtkq+iiEm3JjBuZYsoSvFZDhTbr4O9ZvtQAB8xWA@mail.gmail.com>
 <0bbf726e-84ba-3962-b1cc-bc1631cc8fa0@yahoo.co.uk>
Message-ID: <CADmpvFH_3r6WdfwbV7GpU+DGU0EWM7DbwvH4YxEvHyQovf6pPA@mail.gmail.com>

Hi again.

You hit the nail square on the head.  It is the event-driven mode that has
me flustered.  I have consulted many examples and they ALL have one thing
in common.  No matter the triggering event (change in selection,
double-clicking, or responding to a button-click) they ALL print the choice
from within the call-back function.  I have made choice
a global variable, but this seems mickey-mouse to me. The choice is ALWAYS
identified within the call-back function.

Probably there is an easy way to communicate the choice to the rest of the
program, but it escapes me.

What I want is to be able to pass, from a program section, a candidate list
(counties to visit, files to open, teams to watch) to the function and have
it tell (return) my choice.

If this is not something you want to mess with, please tell me the
help-list to annoy.

Thanks,

Ed
On Sat, Oct 9, 2021 at 12:51 PM Alan Gauld <learn2program at gmail.com> wrote:

> CCing to tutor.
>
> Please use replyAll when respo ding to tutor list mails.
>
>
> On 09/10/2021 15:13, Ed Connell wrote:
> >
> > Actually I am trying to learn to work with tkinter but I don't think
> > y'all do tkinter.  Is there a list for that?
> >
> There is a dedicated tkinter list but since its part of the standard
> library we cover the basics here too.
>
> If its complicated stuff the tkinter list is better.
>
>
> > def pickFromList(( thelist ):
> >     stuff...
> >     return choice
> >
> > I can do that easily in Python, but I want to use the ttk.Listbox( ...
> >
> I can't find any reference to a ttk.Listbox widget. There is however a
> tkinter Listbox
> so I'll assume you mean ghat.
>
> As I'm sure you know tkinter is event driven so a function like the
> above only makes
> sense when we know which events you are attaching it to? For example the
> tkinter.Listbox
> widget often has the mouse button actions bound to events and these
> often call the curselection()
> method to get the list of currently selected items (or their indices at
> least.)
>
> But you need to explain with a bit more detail what exactly you are
> trying to do.
> Its not obvious.
>
> > --
>
> 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
>
>

-- 
I have a right and a left brain, but there is nothing right in the left one
and there is nothing left in the right one!

From alan.gauld at yahoo.co.uk  Sun Oct 10 19:07:14 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 11 Oct 2021 00:07:14 +0100
Subject: [Tutor] returning from 2 functions at once
In-Reply-To: <CADmpvFH_3r6WdfwbV7GpU+DGU0EWM7DbwvH4YxEvHyQovf6pPA@mail.gmail.com>
References: <CADmpvFGnRiydREVCn4h=mJep0SjgWDDeBMVqkG_7eWi=HrP8Pg@mail.gmail.com>
 <1473cc08-e6ef-26c9-b521-812d1e3b8ba5@yahoo.co.uk>
 <CADmpvFGdrUHtkq+iiEm3JjBuZYsoSvFZDhTbr4O9ZvtQAB8xWA@mail.gmail.com>
 <0bbf726e-84ba-3962-b1cc-bc1631cc8fa0@yahoo.co.uk>
 <CADmpvFH_3r6WdfwbV7GpU+DGU0EWM7DbwvH4YxEvHyQovf6pPA@mail.gmail.com>
Message-ID: <sjvrn2$cjt$1@ciao.gmane.io>

On 10/10/2021 20:14, Ed Connell wrote:

> You hit the nail square on the head.  It is the event-driven mode that has
> me flustered.  I have consulted many examples and they ALL have one thing
> in common.  No matter the triggering event (change in selection,
> double-clicking, or responding to a button-click) they ALL print the choice
> from within the call-back function.  I have made choice
> a global variable, but this seems mickey-mouse to me. 

Not at all. if you are not using an OOP architecture then global
variables are the only way to communicate the choice between functionds
i an event driven architecture. If you don;t like having a lot of
globals you could create a single dict and store the values there, but
that's really just disguising the global not removing it.

This is why OOP techniques are so popular for GUI programs. You can
store the choice as an attribute of an object representing that
window/screen/form. Then any time the Window with the list is
visible the choice is available.

> Probably there is an easy way to communicate the choice to the rest of the
> program, but it escapes me.

A global variable or an attribute of the Window object.
Those are the most common options.

> What I want is to be able to pass, from a program section, a candidate list
> (counties to visit, files to open, teams to watch) to the function and have
> it tell (return) my choice.

But that I don't understand. I think you need to describe it
in much more detail using example values. Describe what you mean
by passing "from a program section", where the list of counties
comes from. Which function are you passing it to? Hoe do you
make "your choice"? And when?

Maybe avoid terms like "you" or "I" or even the "function"
and instead describe the interaction in terms of user roles
and the application. eg.

1. The app displays <what? describe the UI>

2. The user <does what??? which buttons, fields, lists do
   they interact with What values do they choose of input?>

3. The program responds by <what? How does the display or data change?>

And so on. This kind of dialog between users and the system is
called a use case and  is commonly used to define the requirements
of a system in unambiguous terms.


> If this is not something you want to mess with, please tell me the
> help-list to annoy

This level of tkinter is entirely appropriate for the tutor list.
We are very far away from advanced features here. These are the
fundamentals of GUI programming, in fact not even tkinter specific
but applicable to most GUI toolkits.

-- 
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 manpritsinghece at gmail.com  Mon Oct 11 22:43:09 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Tue, 12 Oct 2021 08:13:09 +0530
Subject: [Tutor] array module
Message-ID: <CAO1OCwZPGrTjMoq7eeBSPsd5U3GEWYRUFRo+rR7mBRQmUoLkvA@mail.gmail.com>

Dear Sir,
While doing some experiments with array module in python standard library ,
which are given below :
lst = list(range(100))

import array
arr = array.array("h", range(100))

sys.getsizeof(lst)
returns 856

sys.getsizeof(arr)
returns 268

Shows that the list lst and array arr both are having same data, but there
is huge difference in size bytes.  so for storing homogenous 1 D data
arrays are more good ,  Why they are not widely used ?
What are the specific use cases of this array module ?

Regards
Manprit Singh

From sjeik_appie at hotmail.com  Tue Oct 12 03:58:09 2021
From: sjeik_appie at hotmail.com (Albert-Jan Roskam)
Date: Tue, 12 Oct 2021 09:58:09 +0200
Subject: [Tutor] Order of unittests
Message-ID: <DB6PR01MB38954AAABFFEDC672D18874883B69@DB6PR01MB3895.eurprd01.prod.exchangelabs.com>

   Hi,
   How can I write a unittest where tge tesrs are run in the order in which
   they are defined? I tried the code below. I prefer not to change the names
   of the tests.
   Thank you in advance!
   Albert-Jan
   (base) albertjan at debian:~/Downloads$ cat sometest.py
   import unittest

   unittest.defaultTestLoader.sortTestMethodsUsing = lambda *args: -1

   print("wanted order: import, mutate, export, delete")

   class SomeTest(unittest.TestCase):
       def test_import(self):
           pass
       def test_mutate(self):
          pass
       def test_export(self):
           pass
       def test_delete(self):
           pass

   if __name__ == "__main__":
       unittest.main(verbosity=2)

   (base) albertjan at debian:~/Downloads$ python sometest.py
   wanted order: import, mutate, export, delete
   test_mutate (__main__.SomeTest) ... ok
   test_import (__main__.SomeTest) ... ok
   test_export (__main__.SomeTest) ... ok
   test_delete (__main__.SomeTest) ... ok

From sjeik_appie at hotmail.com  Tue Oct 12 05:33:14 2021
From: sjeik_appie at hotmail.com (Albert-Jan Roskam)
Date: Tue, 12 Oct 2021 11:33:14 +0200
Subject: [Tutor] Order of unittests
In-Reply-To: <DB6PR01MB38954AAABFFEDC672D18874883B69@DB6PR01MB3895.eurprd01.prod.exchangelabs.com>
Message-ID: <DB6PR01MB38953665EFD1FAC4C3ED18A983B69@DB6PR01MB3895.eurprd01.prod.exchangelabs.com>

   Hmmmm, this works, though it does not look pretty.
   import unittest

   print("wanted order: import, mutate, export, delete")

   class SomeTest(unittest.TestCase):
       def test_import(self):
           print("*import")
       def test_mutate(self):
           print("*mutate")
       def test_export(self):
           print("*export")
       def test_delete(self):
           print("*delete")

   suite = unittest.TestSuite()
   [suite.addTest(SomeTest(t)) for t in SomeTest.__dict__  if
   t.startswith("test_")]
   runner = unittest.TextTestRunner()

   if __name__ == "__main__":
       runner.run(suite)

From oscar.j.benjamin at gmail.com  Tue Oct 12 05:44:07 2021
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Tue, 12 Oct 2021 10:44:07 +0100
Subject: [Tutor] Order of unittests
In-Reply-To: <DB6PR01MB38953665EFD1FAC4C3ED18A983B69@DB6PR01MB3895.eurprd01.prod.exchangelabs.com>
References: <DB6PR01MB38954AAABFFEDC672D18874883B69@DB6PR01MB3895.eurprd01.prod.exchangelabs.com>
 <DB6PR01MB38953665EFD1FAC4C3ED18A983B69@DB6PR01MB3895.eurprd01.prod.exchangelabs.com>
Message-ID: <CAHVvXxR4s-CaquhrMSTtobvzbezxAZPEpNgU_mrcjdsSR9f5-w@mail.gmail.com>

On Tue, 12 Oct 2021 at 10:34, Albert-Jan Roskam <sjeik_appie at hotmail.com>
wrote:

>    Hmmmm, this works, though it does not look pretty.
>    import unittest
>

Outside of the stdlib I would just use pytest rather than unittest. I
always found unittest awkward because it is designed around Java idioms
that don't come naturally to me. I don't think that unittest is as widely
used as pytest in the wider python ecosystem mostly for this reason.

--
Oscar

From sjeik_appie at hotmail.com  Tue Oct 12 05:39:32 2021
From: sjeik_appie at hotmail.com (Albert-Jan Roskam)
Date: Tue, 12 Oct 2021 11:39:32 +0200
Subject: [Tutor] Order of unittests
Message-ID: <DB6PR01MB38954FFF7EAE74196A5A4ED283B69@DB6PR01MB3895.eurprd01.prod.exchangelabs.com>

   On 12 Oct 2021 11:38, Albert-Jan Roskam <sjeik_appie at hotmail.com> wrote:

     On 12 Oct 2021 11:18, Sarfraaz Ahmed <sarfraaz at gmail.com> wrote:

       Hello Albert-Jan,
       Try using pytest. That works fine with unittest test cases. And it
       executes the test cases in the order you define them.
       ==>>> Hi, thank you for your reply. I will try pytest. Do you happen
       to know if this works similarly with nose?

From sarfraaz at gmail.com  Tue Oct 12 07:12:31 2021
From: sarfraaz at gmail.com (Sarfraaz Ahmed)
Date: Tue, 12 Oct 2021 16:42:31 +0530
Subject: [Tutor] Order of unittests
In-Reply-To: <DB6PR01MB38954FFF7EAE74196A5A4ED283B69@DB6PR01MB3895.eurprd01.prod.exchangelabs.com>
References: <DB6PR01MB38954FFF7EAE74196A5A4ED283B69@DB6PR01MB3895.eurprd01.prod.exchangelabs.com>
Message-ID: <CAKvdLD74xP-ZutdWWXLHHL8BXpV84nUEyaWPLXMRyZzTDOGAFQ@mail.gmail.com>

Please see my reply inline.

On Tue, Oct 12, 2021 at 3:25 PM Albert-Jan Roskam <sjeik_appie at hotmail.com>
wrote:

>    On 12 Oct 2021 11:38, Albert-Jan Roskam <sjeik_appie at hotmail.com>
> wrote:
>
>      On 12 Oct 2021 11:18, Sarfraaz Ahmed <sarfraaz at gmail.com> wrote:
>
>        Hello Albert-Jan,
>        Try using pytest. That works fine with unittest test cases. And it
>        executes the test cases in the order you define them.
>        ==>>> Hi, thank you for your reply. I will try pytest. Do you happen
>        to know if this works similarly with nose?
>

Sorry. Not much familiar with nose. May be others could help.

I found this on stackoverflow that might come in handy for you :
https://stackoverflow.com/questions/22856638/nose-vs-pytest-what-are-the-subjective-differences-that-should-make-me-pick




> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>


-- 
        Jazaak Allahu Khair
               -- Sarfraaz Ahmed

From wlfraed at ix.netcom.com  Tue Oct 12 07:24:17 2021
From: wlfraed at ix.netcom.com (Dennis Lee Bieber)
Date: Tue, 12 Oct 2021 07:24:17 -0400
Subject: [Tutor] array module
References: <CAO1OCwZPGrTjMoq7eeBSPsd5U3GEWYRUFRo+rR7mBRQmUoLkvA@mail.gmail.com>
Message-ID: <s0ramg5of058si5okhti9ntao5j9m4aqp6@4ax.com>

On Tue, 12 Oct 2021 08:13:09 +0530, Manprit Singh
<manpritsinghece at gmail.com> declaimed the following:

>lst = list(range(100))
>
>import array
>arr = array.array("h", range(100))
>
>sys.getsizeof(lst)
>returns 856
>
>sys.getsizeof(arr)
>returns 268
>
>Shows that the list lst and array arr both are having same data, but there
>is huge difference in size bytes.  so for storing homogenous 1 D data
>arrays are more good ,  Why they are not widely used ?
>What are the specific use cases of this array module ?

	 They work with machine native NUMERIC data types, not Python objects.
Unless you use only the methods documented
https://docs.python.org/3/library/array.html you will require a C-extension
to really take advantage of array.array() -- otherwise you are continuously
converting between Python objects and processor native types. That is, you
will be creating an object header, storage space, copying the native type
into the new object (which includes conversion for short/long etc. to
Python integers, for example); operating on the object, then converting it
back to the array data size, copying the native value into the array, and
disposing of the object header.

	This is one of the problems with just focusing on one aspect of Python
at a time with minimalistic examples.

	Try running some moderately complex arithmetic using values contained
in a list vs the same values contained in an array -- TIMING both. Heck,
even computing squares of integers may be sufficient to show it:

nlst = [x*x for x in olst]

vs

oarr = array.array("suitableCode", olst)
narr = array.array("sameCode", (x*x for x in oarr))	#generator, not list
comprehension, to avoid creating a list only to throw it away

or

oarr = array.array("suitableCode", olst)
narr = array.array("sameCode")
for itm in oarr:
	narr.append(itm*itm)


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


From mattlester1 at u.boisestate.edu  Wed Oct 13 11:40:42 2021
From: mattlester1 at u.boisestate.edu (Matt Lester)
Date: Wed, 13 Oct 2021 09:40:42 -0600
Subject: [Tutor] Fsolve and CSV help
Message-ID: <22E145BF-DFFD-4551-A41A-E7D40ACA0F89@u.boisestate.edu>

Hi everyone,

I am trying to use the fsolve function to solve two equations for two variables (theta1 and theta2). The rest of the variables in the equation are either constants or are given in a CSV file. I have tried the code several ways, but can?t seem to get it right (the most recent code is below). I am struggling with:

	? Where do i read in and update the CSV data? Inside or outside the function?
	? Where to place the fsolve? Again, inside or outside the function?
	? I am having some issues with the array sizes, I?m assuming this has to do with the CSV data being larger than the array of the function, but I?m not sure how to fix that.

I am new to python, and coding in general, so I apologize if I?m using incorrect terminology or my code is totally off base.

I?ve added a sample of the data given in the CSV, for this problem I am only using the ?x? and ?y? columns.

Thanks for any help or advice you can give me!!!

Matt



-------------- next part --------------


import pandas as pd
import numpy as np
from scipy.optimize import fsolve


def Ik(thetas):
    df = pd.read_csv("ik_question.csv")         # reads in the CSV file info

    x = df['x'].values
    y = df['y'].values
    L1 = 1
    L2 = 1
    L3 = 0.5
    theta1 = thetas[0]
    theta2 = thetas[1]
    theta3 = np.pi/3

# equations for theta 1 and theta2
    thetaEQ = np.array([2,11], dtype=np.float64)
    
    thetaEQ[0] = L3*np.cos(theta1 + theta2 + theta3) + L2*np.cos(theta1 + theta2) + L1*np.cos(theta1) - x
    thetaEQ[1] = L3*np.sin(theta1 + theta2 + theta3) + L2*np.sin(theta1 + theta2) + L1*np.sin(theta1) - y
    
    thetas = fsolve(Ik, (0,0))
    df.insert(2,"th1",theta1)
    df.insert(3,"th2",theta2)
    df.insert(4,"th2",theta3)
    df.to_csv('ik_questions1.csv')
  
    
    return thetaEQ

From alan.gauld at yahoo.co.uk  Wed Oct 13 15:02:07 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 13 Oct 2021 20:02:07 +0100
Subject: [Tutor] Fsolve and CSV help
In-Reply-To: <22E145BF-DFFD-4551-A41A-E7D40ACA0F89@u.boisestate.edu>
References: <22E145BF-DFFD-4551-A41A-E7D40ACA0F89@u.boisestate.edu>
Message-ID: <sk7aff$nrd$1@ciao.gmane.io>

On 13/10/2021 16:40, Matt Lester wrote:

> I am trying to use the fsolve function

This group is for python language and standard library issues
so the Scipy modules are a wee bit out of our scope. There
are some users who might be able to help though. but you might
like to try on the SciPy forums too because there will be a
lot more users there.

> 	? Where do i read in and update the CSV data? Inside or outside the function?

Probably outside. Otherwise you are reading and writing to the same file
every time you call the function. That will make it slow and probably
overwrite all of your data each time too. Imagine using it inside a
loop. You'd end up with only the last iteration of the loop stored in
the file all the earlier calls would be lost!

> 	? Where to place the fsolve? Again, inside or outside the function?

I'm assuming inside for this one. Yu want your function to set up the
data then call fsolve then present back the results filtered or
formatted in some way. I assume...

> 	? I am having some issues with the array sizes, I?m assuming 
> this has to do with the CSV data being larger than the array of the 
> function, but I?m not sure how to fix that.

This is the kind of thing that's probably better answered on the
Scipy forum(s)

> I am new to python, and coding in general, 

We can help with those areas, but not so much with svcipy
module specific type issues.

-- 
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 finnjavier08 at gmail.com  Wed Oct 13 19:06:09 2021
From: finnjavier08 at gmail.com (Finn Mason)
Date: Wed, 13 Oct 2021 17:06:09 -0600
Subject: [Tutor] array module
In-Reply-To: <s0ramg5of058si5okhti9ntao5j9m4aqp6@4ax.com>
References: <CAO1OCwZPGrTjMoq7eeBSPsd5U3GEWYRUFRo+rR7mBRQmUoLkvA@mail.gmail.com>
 <s0ramg5of058si5okhti9ntao5j9m4aqp6@4ax.com>
Message-ID: <CAJ3a0+2OO=0-3eaegA2OrkUKJodN1zeW0UkpZ1gD0TkPMiHkcQ@mail.gmail.com>

array.array() is very limited in what it can do. Honestly, I'm not sure why
it's in the standard library when NumPy is so popular it can practically be
considered a core library.
Check out NumPy for arrays of numbers.


--
Finn Mason

On Tue, Oct 12, 2021, 5:24 AM Dennis Lee Bieber <wlfraed at ix.netcom.com>
wrote:

> On Tue, 12 Oct 2021 08:13:09 +0530, Manprit Singh
> <manpritsinghece at gmail.com> declaimed the following:
>
> >lst = list(range(100))
> >
> >import array
> >arr = array.array("h", range(100))
> >
> >sys.getsizeof(lst)
> >returns 856
> >
> >sys.getsizeof(arr)
> >returns 268
> >
> >Shows that the list lst and array arr both are having same data, but there
> >is huge difference in size bytes.  so for storing homogenous 1 D data
> >arrays are more good ,  Why they are not widely used ?
> >What are the specific use cases of this array module ?
>
>          They work with machine native NUMERIC data types, not Python
> objects.
> Unless you use only the methods documented
> https://docs.python.org/3/library/array.html you will require a
> C-extension
> to really take advantage of array.array() -- otherwise you are continuously
> converting between Python objects and processor native types. That is, you
> will be creating an object header, storage space, copying the native type
> into the new object (which includes conversion for short/long etc. to
> Python integers, for example); operating on the object, then converting it
> back to the array data size, copying the native value into the array, and
> disposing of the object header.
>
>         This is one of the problems with just focusing on one aspect of
> Python
> at a time with minimalistic examples.
>
>         Try running some moderately complex arithmetic using values
> contained
> in a list vs the same values contained in an array -- TIMING both. Heck,
> even computing squares of integers may be sufficient to show it:
>
> nlst = [x*x for x in olst]
>
> vs
>
> oarr = array.array("suitableCode", olst)
> narr = array.array("sameCode", (x*x for x in oarr))     #generator, not
> list
> comprehension, to avoid creating a list only to throw it away
>
> or
>
> oarr = array.array("suitableCode", olst)
> narr = array.array("sameCode")
> for itm in oarr:
>         narr.append(itm*itm)
>
>
> --
>         Wulfraed                 Dennis Lee Bieber         AF6VN
>         wlfraed at ix.netcom.com
> http://wlfraed.microdiversity.freeddns.org/
>
> _______________________________________________
> 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  Thu Oct 14 04:22:27 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 14 Oct 2021 09:22:27 +0100
Subject: [Tutor] array module
In-Reply-To: <CAJ3a0+2OO=0-3eaegA2OrkUKJodN1zeW0UkpZ1gD0TkPMiHkcQ@mail.gmail.com>
References: <CAO1OCwZPGrTjMoq7eeBSPsd5U3GEWYRUFRo+rR7mBRQmUoLkvA@mail.gmail.com>
 <s0ramg5of058si5okhti9ntao5j9m4aqp6@4ax.com>
 <CAJ3a0+2OO=0-3eaegA2OrkUKJodN1zeW0UkpZ1gD0TkPMiHkcQ@mail.gmail.com>
Message-ID: <sk8pc3$6ub$1@ciao.gmane.io>

On 14/10/2021 00:06, Finn Mason wrote:
> array.array() is very limited in what it can do. Honestly, I'm not sure why
> it's in the standard library when NumPy is so popular it can practically be
> considered a core library.
> Check out NumPy for arrays of numbers.

Because array has been around forever, much longer than numpy.

Also numpy is huge. If you just want an array, using numpy would
be like buying a swiss army knife because you wanted a nail file.

But personally, I've only used array once, mostly a regular
Python list does all that I need.

-- 
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 leamhall at gmail.com  Thu Oct 14 09:39:56 2021
From: leamhall at gmail.com (Leam Hall)
Date: Thu, 14 Oct 2021 08:39:56 -0500
Subject: [Tutor] array module
In-Reply-To: <sk8pc3$6ub$1@ciao.gmane.io>
References: <CAO1OCwZPGrTjMoq7eeBSPsd5U3GEWYRUFRo+rR7mBRQmUoLkvA@mail.gmail.com>
 <s0ramg5of058si5okhti9ntao5j9m4aqp6@4ax.com>
 <CAJ3a0+2OO=0-3eaegA2OrkUKJodN1zeW0UkpZ1gD0TkPMiHkcQ@mail.gmail.com>
 <sk8pc3$6ub$1@ciao.gmane.io>
Message-ID: <502d6c5c-51bb-6054-bb96-5e98326e8fd4@gmail.com>

On 10/14/21 3:22 AM, Alan Gauld via Tutor wrote:

> But personally, I've only used array once, mostly a regular
> Python list does all that I need.

Sorry for being dense, but I'm still moving between languages. How are a Python list and an array different?

Leam

-- 
Systems Programmer         (reuel.net/resume)
Scribe: The Domici War     (domiciwar.net)
General Ne'er-do-well      (github.com/LeamHall)

From alan.gauld at yahoo.co.uk  Thu Oct 14 11:27:41 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 14 Oct 2021 16:27:41 +0100
Subject: [Tutor] array module
In-Reply-To: <502d6c5c-51bb-6054-bb96-5e98326e8fd4@gmail.com>
References: <CAO1OCwZPGrTjMoq7eeBSPsd5U3GEWYRUFRo+rR7mBRQmUoLkvA@mail.gmail.com>
 <s0ramg5of058si5okhti9ntao5j9m4aqp6@4ax.com>
 <CAJ3a0+2OO=0-3eaegA2OrkUKJodN1zeW0UkpZ1gD0TkPMiHkcQ@mail.gmail.com>
 <sk8pc3$6ub$1@ciao.gmane.io> <502d6c5c-51bb-6054-bb96-5e98326e8fd4@gmail.com>
Message-ID: <sk9i9e$rho$1@ciao.gmane.io>

On 14/10/2021 14:39, Leam Hall wrote:
> On 10/14/21 3:22 AM, Alan Gauld via Tutor wrote:
> 
>> But personally, I've only used array once, mostly a regular
>> Python list does all that I need.
> 
> Sorry for being dense, but I'm still moving between languages. 
> How are a Python list and an array different?

A list is a built in data type, array is implemented as a module.

Arrays are homogenous, they only hold one type of data.

As the docs state:

"...compactly represent an array of basic values: characters,
integers, floating point numbers. Arrays are sequence types
and behave very much like lists, except that the type of
objects stored in them is constrained. The type is specified
at object creation time by using a type code, which is a
single character. "

They are therefore more resource efficient and allegedly faster to
access, although I've not seen much difference in that regard.

They have a few extra tricks compared to lists, such as the ability
to load values from strings or files.

On the downside they are limited to basic types and and the int
types are those supported by the C compiler not native Python
integers.

Useful if you have a lot of homogenous data to store/process.
I'm not sure what other use-cases exist.

For heavy processing or where top speed is required numpy
arrays are probably a better bet, but then you need to
install and import numpy...

-- 
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  Thu Oct 14 10:05:10 2021
From: breamoreboy at gmail.com (Mark Lawrence)
Date: Thu, 14 Oct 2021 15:05:10 +0100
Subject: [Tutor] array module
In-Reply-To: <502d6c5c-51bb-6054-bb96-5e98326e8fd4@gmail.com>
References: <CAO1OCwZPGrTjMoq7eeBSPsd5U3GEWYRUFRo+rR7mBRQmUoLkvA@mail.gmail.com>
 <s0ramg5of058si5okhti9ntao5j9m4aqp6@4ax.com>
 <CAJ3a0+2OO=0-3eaegA2OrkUKJodN1zeW0UkpZ1gD0TkPMiHkcQ@mail.gmail.com>
 <sk8pc3$6ub$1@ciao.gmane.io> <502d6c5c-51bb-6054-bb96-5e98326e8fd4@gmail.com>
Message-ID: <09a96fd3-8a9c-e518-ce47-c824671e9032@gmail.com>

On 14/10/2021 14:39, Leam Hall wrote:
> On 10/14/21 3:22 AM, Alan Gauld via Tutor wrote:
> 
>> But personally, I've only used array once, mostly a regular
>> Python list does all that I need.
> 
> Sorry for being dense, but I'm still moving between languages. How are a 
> Python list and an array different?
> 
> Leam
> 

Explained here https://learnpython.com/blog/python-array-vs-list/

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From manpritsinghece at gmail.com  Fri Oct 15 03:03:40 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Fri, 15 Oct 2021 12:33:40 +0530
Subject: [Tutor] User defined exceptions
Message-ID: <CAO1OCwZdPbtcZNDu73JVZXeYLCfX4+nytqJ+sWzYxrojWC_WFg@mail.gmail.com>

Dear Sir,

I have written an example on user defined exceptions, just to check if my
understanding is correct, I request you to read the points and  let me know
if those are correct or not


class MarksError(Exception):   # A simple user defined exception
    pass

def grades(glist, score):
    if score < 0 or score > 100:
        raise MarksError("Invalid Score")    # Argument to raise is an
exception instance
    for ch, rg in glist:
        if score < rg:
            return ch

lst = [("F", 60),
       ("D", 70),
       ("C", 80),
       ("B", 90),
       ("A", 101)]


try:
    marks= int(input("Enter marks"))
    grade = grades(lst, marks)

except MarksError as err:
    print(err)

else:
    print(f'for {marks} marks the grade is {grade}')

This program is for printing the grade of a student  based on marks .

1) In the starting, I have written a very simple user-defined Exception
class- MarksError, simply placing a pass inside this class causes no extra
addition, this class inherits everything from the Exception class.

2) Inside the function def grades, i have  used raise keyword to raise an
exception . Just besides the raise keyword I have written
MarksError("Invalid Score"), which is basically an instance of the
exception class MarksError with the argument "Invalid Score".

3) In the except block given below:
except MarksError as err:
    print(err)
variable err is bound to the exception instance written with raise keyword,
hence print(err)  will print the argument "Invalid Score", when exception
is handled.

Kindly comment

Regards
Manprit Singh

From alan.gauld at yahoo.co.uk  Fri Oct 15 07:14:52 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 15 Oct 2021 12:14:52 +0100
Subject: [Tutor] User defined exceptions
In-Reply-To: <CAO1OCwZdPbtcZNDu73JVZXeYLCfX4+nytqJ+sWzYxrojWC_WFg@mail.gmail.com>
References: <CAO1OCwZdPbtcZNDu73JVZXeYLCfX4+nytqJ+sWzYxrojWC_WFg@mail.gmail.com>
Message-ID: <skbnrd$vcs$1@ciao.gmane.io>

On 15/10/2021 08:03, Manprit Singh wrote:

> I have written an example on user defined exceptions, just to check if my
> understanding is correct, 

The understanding is correct in terms of how to write the code
and how the mechanism works.

However, in general, it is best to use a built in exception
wherever possible, then pass a unique message when it is raised.
In this case a ValueError would seem to be entirely appropriate.

Even if you did have a reason to define your own, it might be better to
derive it from ValueError rather than Exception, since then it could be
caught by an "except ValueError" clause as well as a specific "except
MarksError"

Part of the reason for adopting a general approach is that you may
have a function that gets used by another user in a different context.
Possibly even as part of a collection of functions. In that case the
user will possibly put try/except around the function call
but it becomes tedious to have an except for every possible
exception type from every possible function. So, writing

for f in functions:
   try:
      result = f()
      # do something with result
   except ValueError:  #...
   except TypeError:   #...
   except:  # catch all maybe???

Would catch the most common cases with a generic handler for the rest.
By deriving your error from ValueError it will be caught by the
first except rather than falling through to the default handler.
Or better still just use a ValueError directly.

The other pint about using a custom error is that it adds to the
documentation. If you raise a standard exception there is no real
need to describe it in the documentation but if you define your own
error then the user as to know all about it, what it signifies,
and so on. More work for you as author and more effort for the user.

> 
> class MarksError(Exception):   # A simple user defined exception
>     pass
> 
> def grades(glist, score):
>     if score < 0 or score > 100:
>         raise MarksError("Invalid Score")    # Argument to raise is an
> exception instance
>     for ch, rg in glist:
>         if score < rg:
>             return ch
> 
> lst = [("F", 60),
>        ("D", 70),
>        ("C", 80),
>        ("B", 90),
>        ("A", 101)]
> 
> 
> try:
>     marks= int(input("Enter marks"))
>     grade = grades(lst, marks)
> 
> except MarksError as err:
>     print(err)
> 
> else:
>     print(f'for {marks} marks the grade is {grade}')

-- 
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 Oct 15 07:43:04 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 15 Oct 2021 12:43:04 +0100
Subject: [Tutor] User defined exceptions
In-Reply-To: <CAO1OCwZdPbtcZNDu73JVZXeYLCfX4+nytqJ+sWzYxrojWC_WFg@mail.gmail.com>
References: <CAO1OCwZdPbtcZNDu73JVZXeYLCfX4+nytqJ+sWzYxrojWC_WFg@mail.gmail.com>
Message-ID: <skbpgc$f12$1@ciao.gmane.io>

On 15/10/2021 08:03, Manprit Singh wrote:


>     if score < 0 or score > 100:
>         raise MarksError("Invalid Score")    # Argument to raise is an

One other oint I meant to make is that it would be better to be more
specific in the message that is passed. tell the user what was wrong,
and how to put it right, not just that it was invalid.

For example:

raise MarksError("Score must be between 0 and 100")

tells the user what kind of score they should use.
You could go further and include a format string that inserts
the actual value received. That would also speed up debugging:

raise MarksError("Score of %d does not lie between 0 and 100" % score)

-- 
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  Fri Oct 15 08:53:44 2021
From: __peter__ at web.de (Peter Otten)
Date: Fri, 15 Oct 2021 14:53:44 +0200
Subject: [Tutor] Order of unittests
In-Reply-To: <DB6PR01MB38954AAABFFEDC672D18874883B69@DB6PR01MB3895.eurprd01.prod.exchangelabs.com>
References: <DB6PR01MB38954AAABFFEDC672D18874883B69@DB6PR01MB3895.eurprd01.prod.exchangelabs.com>
Message-ID: <255a6e9f-36e9-500e-0ef9-b89c8179a418@web.de>

On 12/10/2021 09:58, Albert-Jan Roskam wrote:
>     Hi,
>     How can I write a unittest where tge tesrs are run in the order in which
>     they are defined? I tried the code below. I prefer not to change the names
>     of the tests.

The following monkey patch seems to work:

# shadow the dir() built-in with an order-preserving analogue
def my_dir(obj):
     return list(vars(obj))
unittest.loader.dir = my_dir

# disable sorting
unittest.defaultTestLoader.sortTestMethodsUsing = None

>     Thank you in advance!
>     Albert-Jan
>     (base) albertjan at debian:~/Downloads$ cat sometest.py
>     import unittest
> 
>     unittest.defaultTestLoader.sortTestMethodsUsing = lambda *args: -1
> 
>     print("wanted order: import, mutate, export, delete")
> 
>     class SomeTest(unittest.TestCase):
>         def test_import(self):
>             pass
>         def test_mutate(self):
>            pass
>         def test_export(self):
>             pass
>         def test_delete(self):
>             pass
> 
>     if __name__ == "__main__":
>         unittest.main(verbosity=2)
> 
>     (base) albertjan at debian:~/Downloads$ python sometest.py
>     wanted order: import, mutate, export, delete
>     test_mutate (__main__.SomeTest) ... ok
>     test_import (__main__.SomeTest) ... ok
>     test_export (__main__.SomeTest) ... ok
>     test_delete (__main__.SomeTest) ... ok
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
> 



From wlfraed at ix.netcom.com  Fri Oct 15 11:51:18 2021
From: wlfraed at ix.netcom.com (Dennis Lee Bieber)
Date: Fri, 15 Oct 2021 11:51:18 -0400
Subject: [Tutor] User defined exceptions
References: <CAO1OCwZdPbtcZNDu73JVZXeYLCfX4+nytqJ+sWzYxrojWC_WFg@mail.gmail.com>
 <skbpgc$f12$1@ciao.gmane.io>
Message-ID: <fp8jmg1lnvkup9501rv0pnd832hacrf298@4ax.com>

On Fri, 15 Oct 2021 12:43:04 +0100, Alan Gauld via Tutor <tutor at python.org>
declaimed the following:

>On 15/10/2021 08:03, Manprit Singh wrote:

>>     if score < 0 or score > 100:

>
>raise MarksError("Score must be between 0 and 100")
>

	.... Inclusive

	"between 0 and 100" can be interpreted as 1 to 99.


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


From roel at roelschroeven.net  Fri Oct 15 11:29:32 2021
From: roel at roelschroeven.net (Roel Schroeven)
Date: Fri, 15 Oct 2021 17:29:32 +0200
Subject: [Tutor] User defined exceptions
In-Reply-To: <skbpgc$f12$1@ciao.gmane.io>
References: <CAO1OCwZdPbtcZNDu73JVZXeYLCfX4+nytqJ+sWzYxrojWC_WFg@mail.gmail.com>
 <skbpgc$f12$1@ciao.gmane.io>
Message-ID: <740be346-85c5-72e8-3779-29abbb3c5853@roelschroeven.net>


Op 15/10/2021 om 13:43 schreef Alan Gauld via Tutor:
> You could go further and include a format string that inserts
> the actual value received. That would also speed up debugging:
>
> raise MarksError("Score of %d does not lie between 0 and 100" % score)
Yes! This is not done very often, and it often feels a bit like a chore. 
But it's so very useful in case of errors! IMO that advantage more than 
compensates for the extra effort.

-- 
"This planet has - or rather had - a problem, which was this: most of the
people living on it were unhappy for pretty much of the time. Many solutions
were suggested for this problem, but most of these were largely concerned with
the movement of small green pieces of paper, which was odd because on the whole
it wasn't the small green pieces of paper that were unhappy."
         -- Douglas Adams


From juliushamilton100 at gmail.com  Fri Oct 15 15:42:56 2021
From: juliushamilton100 at gmail.com (Julius Hamilton)
Date: Fri, 15 Oct 2021 21:42:56 +0200
Subject: [Tutor] Python IMAP library
Message-ID: <CAEsMKX1fY-J+oGa=ZJR4G1XHWSiK0xpzhfXdST6ES7-QKK7RTQ@mail.gmail.com>

Hey,

Is there any support community for this Python library? I don?t see any
mention of it at the documentation:
https://docs.python.org/3/library/imaplib.html

Could someone please help me understand the following?


IMAP4.authenticate(*mechanism*, *authobject*)?
<https://docs.python.org/3/library/imaplib.html#imaplib.IMAP4.authenticate>

Authenticate command ? requires response processing.

*mechanism* specifies which authentication mechanism is to be used - it
should appear in the instance variable capabilities in the form
AUTH=mechanism.


When I create an IMAP4() object, I have to edit the capabilities variable
with ?AUTH=mechanism?? What mechanisms are permitted or expected?


*authobject* must be a callable object:

data = authobject(response)


Is this another method from the library? What does it do?


It will be called to process server continuation responses; the
*response* argument
it is passed will be bytes. It should return bytes *data* that will be
base64 encoded and sent to the server. It should return None if the client
abort response *should be sent instead.

Changed in version 3.5: string usernames and passwords are now encoded to
utf-8 instead of being limited to ASCII.



Does this return an object which represents a connection to the IMAP server?




Thanks very much,

Julius

From alan.gauld at yahoo.co.uk  Sat Oct 16 03:58:56 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 16 Oct 2021 08:58:56 +0100
Subject: [Tutor] Python IMAP library
In-Reply-To: <CAEsMKX1fY-J+oGa=ZJR4G1XHWSiK0xpzhfXdST6ES7-QKK7RTQ@mail.gmail.com>
References: <CAEsMKX1fY-J+oGa=ZJR4G1XHWSiK0xpzhfXdST6ES7-QKK7RTQ@mail.gmail.com>
Message-ID: <ske0o0$l1b$1@ciao.gmane.io>

On 15/10/2021 20:42, Julius Hamilton wrote:
> Hey,
> 
> Is there any support community for this Python library? I don?t see any
> mention of it at the documentation:
> https://docs.python.org/3/library/imaplib.html

It is part of the standard library so the support community is a
combination of the official mailing lists, primarily this list
and the main python list.

> Could someone please help me understand the following?

Hopefully someone can, but not me. I've never used imaplib.


-- 
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 sjeik_appie at hotmail.com  Sat Oct 16 04:43:38 2021
From: sjeik_appie at hotmail.com (Albert-Jan Roskam)
Date: Sat, 16 Oct 2021 10:43:38 +0200
Subject: [Tutor] Order of unittests
In-Reply-To: <255a6e9f-36e9-500e-0ef9-b89c8179a418@web.de>
Message-ID: <DB6PR01MB3895016BCA3CA283FA48642483BA9@DB6PR01MB3895.eurprd01.prod.exchangelabs.com>

   On 15 Oct 2021 14:53, Peter Otten <__peter__ at web.de> wrote:

     On 12/10/2021 09:58, Albert-Jan Roskam wrote:
     >     Hi,
     >     How can I write a unittest where tge tesrs are run in the order in
     which
     >     they are defined? I tried the code below. I prefer not to change
     the names
     >     of the tests.

     The following monkey patch seems to work:

     # shadow the dir() built-in with an order-preserving analogue
     def my_dir(obj):
          return list(vars(obj))
     unittest.loader.dir = my_dir

     # disable sorting
     unittest.defaultTestLoader.sortTestMethodsUsing = None

     >     Thank you in advance!
     >

   ===>> Hi Peter,
   Thank you! That looks quite compact, so I'll give that a try on Monday. I
   could even use a lambda for my_dir(). I thought dir() was (re)implemented
   by defining, or in this case injecting, a __dir__ special method?
   Best wishes,
   Albert-Jan

From __peter__ at web.de  Sat Oct 16 10:50:43 2021
From: __peter__ at web.de (Peter Otten)
Date: Sat, 16 Oct 2021 16:50:43 +0200
Subject: [Tutor] Order of unittests
In-Reply-To: <DB6PR01MB3895016BCA3CA283FA48642483BA9@DB6PR01MB3895.eurprd01.prod.exchangelabs.com>
References: <255a6e9f-36e9-500e-0ef9-b89c8179a418@web.de>
 <DB6PR01MB3895016BCA3CA283FA48642483BA9@DB6PR01MB3895.eurprd01.prod.exchangelabs.com>
Message-ID: <c404f168-2cf3-0fe4-3d88-705c2242234c@web.de>

On 16/10/2021 10:43, Albert-Jan Roskam wrote:
>     On 15 Oct 2021 14:53, Peter Otten <__peter__ at web.de> wrote:

>     ===>> Hi Peter,
>     Thank you! That looks quite compact, so I'll give that a try on Monday. I
>     could even use a lambda for my_dir(). I thought dir() was (re)implemented
>     by defining, or in this case injecting, a __dir__ special method?

I should have warned that my my_dir()

>       # shadow the dir() built-in with an order-preserving analogue
>       def my_dir(obj):
>            return list(vars(obj))

is but a sketch that only works in the exact case you gave, i. e. it 
will miss __dir__(), inherited attributes, and probably something I 
can't think of at the moment.

A low-effort improvement that at least will not miss any names might be
to use the built-in dir() to find the names and vars() to partially 
(un)sort them:

# untested
def my_dir(obj):
     names = dir(obj)
     lookup = {n: i for i, n in enumerate(vars(obj))}
     return sorted(names, key=lambda name: lookup.get(name, -1))

I'm sure someone has produced a more thorough implementation -- you just 
have to find it ;)


From cs at cskk.id.au  Sat Oct 16 08:58:04 2021
From: cs at cskk.id.au (Cameron Simpson)
Date: Sat, 16 Oct 2021 23:58:04 +1100
Subject: [Tutor] Python IMAP library
In-Reply-To: <ske0o0$l1b$1@ciao.gmane.io>
References: <ske0o0$l1b$1@ciao.gmane.io>
Message-ID: <YWrMXBo9Px738gjF@cskk.homeip.net>

On 16Oct2021 08:58, Alan Gauld <alan.gauld at yahoo.co.uk> wrote:
>On 15/10/2021 20:42, Julius Hamilton wrote:
>> Is there any support community for this Python library? I don?t see 
>> any mention of it at the documentation:
>> https://docs.python.org/3/library/imaplib.html
>
>It is part of the standard library so the support community is a
>combination of the official mailing lists, primarily this list
>and the main python list.
>
>> Could someone please help me understand the following?
>
>Hopefully someone can, but not me. I've never used imaplib.

Me either, but I looked it over during another discussion.

The imaplib in the standard library is mostly a wrapper adapting between 
the IMAP4 protocol and Python. It doesn't do much sophisticated or 
convenient things - instead it follows the IMAP spec and uses it at a 
very low level. For example, there's no "fetch these messages" methods 
directly. Instead, for the latter, it lets you submit a search (which 
can be complex in IMAP) and returns the core protocol elements for the 
user to manage - because different kinds of searches have different 
kinds of results.

Instead I recommend you try one of the IMAP libraries from PyPI, which 
generally are higher level and easier to use.

Have a look here: https://pypi.org/search/?q=imap

and see if any of the modules are useful, maybe try 
https://pypi.org/project/IMAPClient/

Cheers,
Cameron Simpson <cs at cskk.id.au>

From sjeik_appie at hotmail.com  Sat Oct 16 12:28:04 2021
From: sjeik_appie at hotmail.com (Albert-Jan Roskam)
Date: Sat, 16 Oct 2021 18:28:04 +0200
Subject: [Tutor] Order of unittests
In-Reply-To: <c404f168-2cf3-0fe4-3d88-705c2242234c@web.de>
Message-ID: <DB6PR01MB38957AF88BF9196202F2257083BA9@DB6PR01MB3895.eurprd01.prod.exchangelabs.com>

   On 16 Oct 2021 16:50, Peter Otten <__peter__ at web.de> wrote:

     On 16/10/2021 10:43, Albert-Jan Roskam wrote:
     >     On 15 Oct 2021 14:53, Peter Otten <__peter__ at web.de> wrote:

     >     ===>> Hi Peter,
     >     Thank you! That looks quite compact, so I'll give that a try on
     Monday. I
     >     could even use a lambda for my_dir(). I thought dir() was
     (re)implemented
     >     by defining, or in this case injecting, a __dir__ special method?

     I should have warned that my my_dir()

     >       # shadow the dir() built-in with an order-preserving analogue
     >       def my_dir(obj):
     >            return list(vars(obj))

     is but a sketch that only works in the exact case you gave, i. e. it
     will miss __dir__(), inherited attributes, and probably something I
     can't think of at the moment.

     A low-effort improvement that at least will not miss any names might be
     to use the built-in dir() to find the names and vars() to partially
     (un)sort them:

     # untested
     def my_dir(obj):
          names = dir(obj)
          lookup = {n: i for i, n in enumerate(vars(obj))}
          return sorted(names, key=lambda name: lookup.get(name, -1))

     I'm sure someone has produced a more thorough implementation -- you just
     have to find it ;)

   ==>> Hi again,
   I just checked
   this: https://svn.python.org/projects/python/trunk/Lib/unittest/loader.py.
   The function "makeSuite" looks useful, in particular the sortUsing
   argument. If cmp = lambda a, b: 0, this means "everything is a tie",
   therefore no sorying, right? I'm using my phone, so no Python here :-(

 def makeSuite(testCaseClass, prefix='test', sortUsing=cmp,
               suiteClass=suite.TestSuite):
     return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass)

From manpritsinghece at gmail.com  Sat Oct 16 12:55:02 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Sat, 16 Oct 2021 22:25:02 +0530
Subject: [Tutor] Python program to remove first four even numbers from a list
Message-ID: <CAO1OCwbxwsd5-9Kjk-nmVj3PSVaL1yHhjqFiFii0vNiO3YL8Ww@mail.gmail.com>

Dear Sir ,

Consider a program that is written to remove first four even numbers from a
list:
def remove4even(seq):
    evencnt = 0
    lx = []
    for ele in seq:
        if evencnt > 3 or ele%2 != 0:
            lx.append(ele)
        if ele%2==0:
            evencnt += 1
    return lx

lst =[3, 6, 7, 5, 4, 7, 8, 9, 1, 8, 2, 5, 4]
ans = remove4even(lst)
print(ans) gives

[3, 7, 5, 7, 9, 1, 2, 5, 4]  that is the right answer

In this program i have used multiple if statements inside for loop. My

question is placing multiple if statements inside a for loop is a right

approach as i have adopted in this example?

Secondarily this example can be done with list comprehensions ?

Regards

Manprit Singh

From manpritsinghece at gmail.com  Sat Oct 16 13:06:05 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Sat, 16 Oct 2021 22:36:05 +0530
Subject: [Tutor] Python program to remove first four even numbers from a
 list
In-Reply-To: <CAO1OCwbxwsd5-9Kjk-nmVj3PSVaL1yHhjqFiFii0vNiO3YL8Ww@mail.gmail.com>
References: <CAO1OCwbxwsd5-9Kjk-nmVj3PSVaL1yHhjqFiFii0vNiO3YL8Ww@mail.gmail.com>
Message-ID: <CAO1OCwbdodsOnwzRppBkt54HF=tfe696zG889pqccvVy71+_6w@mail.gmail.com>

Although increment in evencount can be done in else clause

On Sat, 16 Oct, 2021, 22:25 Manprit Singh, <manpritsinghece at gmail.com>
wrote:

> Dear Sir ,
>
> Consider a program that is written to remove first four even numbers from
> a list:
> def remove4even(seq):
>     evencnt = 0
>     lx = []
>     for ele in seq:
>         if evencnt > 3 or ele%2 != 0:
>             lx.append(ele)
>         if ele%2==0:
>             evencnt += 1
>     return lx
>
> lst =[3, 6, 7, 5, 4, 7, 8, 9, 1, 8, 2, 5, 4]
> ans = remove4even(lst)
> print(ans) gives
>
> [3, 7, 5, 7, 9, 1, 2, 5, 4]  that is the right answer
>
> In this program i have used multiple if statements inside for loop. My
>
> question is placing multiple if statements inside a for loop is a right
>
> approach as i have adopted in this example?
>
> Secondarily this example can be done with list comprehensions ?
>
> Regards
>
> Manprit Singh
>
>

From wlfraed at ix.netcom.com  Sat Oct 16 14:23:01 2021
From: wlfraed at ix.netcom.com (Dennis Lee Bieber)
Date: Sat, 16 Oct 2021 14:23:01 -0400
Subject: [Tutor] Python IMAP library
References: <CAEsMKX1fY-J+oGa=ZJR4G1XHWSiK0xpzhfXdST6ES7-QKK7RTQ@mail.gmail.com>
Message-ID: <ek4mmgtvln8rscs592avtksh38gcj9dgu9@4ax.com>

On Fri, 15 Oct 2021 21:42:56 +0200, Julius Hamilton
<juliushamilton100 at gmail.com> declaimed the following:

>
>*mechanism* specifies which authentication mechanism is to be used - it
>should appear in the instance variable capabilities in the form
>AUTH=mechanism.
>
>
>When I create an IMAP4() object, I have to edit the capabilities variable
>with ?AUTH=mechanism?? What mechanisms are permitted or expected?
>
	You don't "edit the capabilities variable" -- It does not use to ask
for capabilities that the server doesn't support. "capabilities" is
something you retrieve from the server itself and then parse for those you
understand.

	You obtain the list of valid authorization modes from the server. And
method the server returns after "AUTH=" in the capabilities list is an
option you can use.

Reference the RFC for IMAP (pretty much ANY library that works with a
network protocol is going to require you to read the RFC for the
details)... From the source code of imaplib
"""
 Note: to use this module, you must read the RFCs pertaining to the
    IMAP4 protocol, as the semantics of the arguments to each IMAP4
    command are left to the invoker, not to mention the results. Also,
    most IMAP servers implement a sub-set of the commands available here.
"""

https://datatracker.ietf.org/doc/html/rfc3501#section-6.1.1
"""
A capability name which begins with "AUTH=" indicates that the
      server supports that particular authentication mechanism.  All
      such names are, by definition, part of this specification.  For
      example, the authorization capability for an experimental
      "blurdybloop" authenticator would be "AUTH=XBLURDYBLOOP" and not
      "XAUTH=BLURDYBLOOP" or "XAUTH=XBLURDYBLOOP".

<SNIP>

      Client and server implementations MUST implement the STARTTLS,
      LOGINDISABLED, and AUTH=PLAIN (described in [IMAP-TLS])
      capabilities.  See the Security Considerations section for
      important information.
"""


https://docs.python.org/3/library/imaplib.html
"""
IMAP4.login(user, password)

    Identify the client using a plaintext password. The password will be
quoted.

IMAP4.login_cram_md5(user, password)

    Force use of CRAM-MD5 authentication when identifying the client to
protect the password. Will only work if the server CAPABILITY response
includes the phrase AUTH=CRAM-MD5.
"""

	I haven't made sense of the full use of AUTHENTICATE, but it sounds
like it may be needed for more complex schemes beyond the above .login()
and .login_cram_md5(). IOW, you are implementing the client side of the
authentication protocol yourself, with an "object" (since it likely needs
state between calls with each server response, a function is not viable).


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


From wlfraed at ix.netcom.com  Sat Oct 16 14:40:59 2021
From: wlfraed at ix.netcom.com (Dennis Lee Bieber)
Date: Sat, 16 Oct 2021 14:40:59 -0400
Subject: [Tutor] Python program to remove first four even numbers from a
 list
References: <CAO1OCwbxwsd5-9Kjk-nmVj3PSVaL1yHhjqFiFii0vNiO3YL8Ww@mail.gmail.com>
Message-ID: <796mmgtv7ef609k33h4oa22satgk78bi8l@4ax.com>

On Sat, 16 Oct 2021 22:25:02 +0530, Manprit Singh
<manpritsinghece at gmail.com> declaimed the following:

>In this program i have used multiple if statements inside for loop. My
>
>question is placing multiple if statements inside a for loop is a right
>
>approach as i have adopted in this example?
>

	If the code produces the result you expect, then by definition it is
NOT WRONG. It may be inefficient, inelegant (or even downright ugly) -- but
that determination can only be made in relation to what some one has
decreed is "proper"... eg: a corporate code review process, running through
"linters", or a Python equivalent of https://en.wikipedia.org/wiki/MISRA_C

>Secondarily this example can be done with list comprehensions ?
>
	So far as I can tell -- NO. List comprehensions process one list
element at a time, and there is no means of having an external "counter"
modified within the comprehension.

	I could see one improvement... Using an enumerated sequence in the loop
would allow you to append the remaining sequence contents in one chunk once
you've reached the count limit, and you could then break out of the loop
entirely, rather than repetitively doing all those comparisons even though
the counter says you are done testing.

CAVEAT: newer Pythons keep adding more and more C-isms to the language.
First we got some ternary expression (which I've never used in Python --
the syntax just looks ugly to me, like something from an HP calculator
programmed in RPL -- in an HP48 and up, it is elegant -- but not in
Python), and more recently some sort of assignment expression; it is just
vaguely possible an assignment expression would allow for incrementing your
counter within the comprehension.


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


From mats at wichmann.us  Sat Oct 16 15:39:04 2021
From: mats at wichmann.us (Mats Wichmann)
Date: Sat, 16 Oct 2021 13:39:04 -0600
Subject: [Tutor] Order of unittests
In-Reply-To: <DB6PR01MB38954AAABFFEDC672D18874883B69@DB6PR01MB3895.eurprd01.prod.exchangelabs.com>
References: <DB6PR01MB38954AAABFFEDC672D18874883B69@DB6PR01MB3895.eurprd01.prod.exchangelabs.com>
Message-ID: <92b862a6-613d-e25c-3ece-b19316a940b8@wichmann.us>

On 10/12/21 01:58, Albert-Jan Roskam wrote:
>     Hi,
>     How can I write a unittest where tge tesrs are run in the order in which
>     they are defined? I tried the code below. I prefer not to change the names
>     of the tests.

in general, it's expected that the tests be written such that order does 
not matter. If it does matter you have several choices, most of which 
you've explored.

you spotted that unittest provides the TestSuite class to let you define 
your own order. I'm not sure what's wrong with explicitly adding the 
tests there in the order you want - adding them by poking around in the 
object's __dict__ does indeed seem a little hacky.

or, you can code the tests where order does matter - if, say, you're 
depending on setup to carry over from one test to the next - in a more 
monolithic fashion, making the related tests into a single test case, 
since if they're dependent, that's essentially what they are, a single 
test unit.

unittest does actually support supplying your own sort function, which 
you can simply set to None to avoid sorting.  Search for 
"sortTestMethodsUsing".


From learn2program at gmail.com  Sat Oct 16 18:52:08 2021
From: learn2program at gmail.com (Alan Gauld)
Date: Sat, 16 Oct 2021 23:52:08 +0100
Subject: [Tutor] Python program to remove first four even numbers from a
 list
In-Reply-To: <CAO1OCwbxwsd5-9Kjk-nmVj3PSVaL1yHhjqFiFii0vNiO3YL8Ww@mail.gmail.com>
References: <CAO1OCwbxwsd5-9Kjk-nmVj3PSVaL1yHhjqFiFii0vNiO3YL8Ww@mail.gmail.com>
Message-ID: <e2681f0d-7614-9853-8add-d7cdf69e55e3@yahoo.co.uk>


On 16/10/2021 17:55, Manprit Singh wrote:
> lst =[3, 6, 7, 5, 4, 7, 8, 9, 1, 8, 2, 5, 4]

> Secondarily this example can be done with list comprehensions ?

Just for laughs...

>>> count = 0
>>> [n for n in lst if n%2 or ((count := count+1) > 4)]
[3, 7, 5, 7, 9, 1, 2, 5, 4]

But I probably wouldn't recommend it. Explicit is better in this case I
think.

Alan G



From juliushamilton100 at gmail.com  Sat Oct 16 11:20:10 2021
From: juliushamilton100 at gmail.com (Julius Hamilton)
Date: Sat, 16 Oct 2021 17:20:10 +0200
Subject: [Tutor] Enter mode where you can input list indices
Message-ID: <CAEsMKX13LQT52+pj22Xs8iHFS85NOjQKnV2ut12EJtpWioykQA@mail.gmail.com>

Hey,

I would like to explore the contents of a list where I could just enter a
mode where any index I type in, it would print the value for some list,
like this:

>>> p()
1
["apple", "cat"]
1 2
cat
3
Index out of bounds

>>>

It will be necessary to loop until the input is nothing:

def p():

  n = input()

  while n != "":

After the input is received it must be parsed into a list of integers:
    n = n.split(' ')
    indices = []
      for item in n:
        indices.append(int(item))

This converts a sequence of integer characters to a list of integer
indices. Next, index the list (in the enclosing scope) by however many
indices there are:

    for i in indices:
      list = list[i]

    # then start again
    n = input()

There are a few questions to straighten out here which I will research and
think about but if anybody could help convert this pseudocode to effective
code and show me the most elegant way they'd achieve this I'd really
appreciate it.

Thanks very much,
Julius

From juliushamilton100 at gmail.com  Sat Oct 16 17:40:44 2021
From: juliushamilton100 at gmail.com (Julius Hamilton)
Date: Sat, 16 Oct 2021 23:40:44 +0200
Subject: [Tutor] Trim away parts of beautiful soup
Message-ID: <CAEsMKX0bvAcgNRJZkTzNmNOSB1jc8ATdgpvm0MPH_QoSLbr4aA@mail.gmail.com>

Hey,

I am exploring navigating a Beautiful Soup tree element by element starting
from the top. I look at what the element contains with the .attrs method.
If the tag is not needed, I delete it with .unwrap(). If the contents in an
element are not needed, I delete it with .decompose(). I learn what the
next round of elements is with:

for child in element.children:
  child.name.

I would prefer an easier way to do this than writing out the name of every
element, like soup.body.div.main.

Is there more of an application way to navigate the tree?

You could start on the ?top node? and just call simple methods like ?next
node? or ?child node? and ?name? and ?contents? and ?delete?.

Thanks very much,
Julius

From manpritsinghece at gmail.com  Sat Oct 16 21:09:34 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Sun, 17 Oct 2021 06:39:34 +0530
Subject: [Tutor] Python program to remove first four even numbers from a
 list
In-Reply-To: <e2681f0d-7614-9853-8add-d7cdf69e55e3@yahoo.co.uk>
References: <CAO1OCwbxwsd5-9Kjk-nmVj3PSVaL1yHhjqFiFii0vNiO3YL8Ww@mail.gmail.com>
 <e2681f0d-7614-9853-8add-d7cdf69e55e3@yahoo.co.uk>
Message-ID: <CAO1OCwZ0P+br+yP9NanHwBu3=n_oR5cuPOmru_zm10yto_sB=Q@mail.gmail.com>

Dear Sir,

So finally I came up with this solution:
def remove4even(seq):
    evencnt = 0
    lx = []
    for ele in seq:
        if evencnt > 3 or ele%2 != 0:
            lx.append(ele)
        else:
            evencnt += 1
    return lx

lst =[3, 6, 7, 5, 4, 7, 8, 9, 1, 8, 2, 5, 4]
print(remove4even(lst))       # gives the right answer as

[3, 7, 5, 7, 9, 1, 2, 5, 4]

and to bring these changes in the existing  same list(lst), just doing this:
lst =[3, 6, 7, 5, 4, 7, 8, 9, 1, 8, 2, 5, 4]
lst[:] = remove4even(lst)
print(lst)    will give the right answer [3, 7, 5, 7, 9, 1, 2, 5, 4]

Is there any other  good way to achieve this ? I don't like changing
mutable data inside functions.

Regards

Manprit Singh


On Sun, Oct 17, 2021 at 4:23 AM Alan Gauld <learn2program at gmail.com> wrote:

>
> On 16/10/2021 17:55, Manprit Singh wrote:
> > lst =[3, 6, 7, 5, 4, 7, 8, 9, 1, 8, 2, 5, 4]
>
> > Secondarily this example can be done with list comprehensions ?
>
> Just for laughs...
>
> >>> count = 0
> >>> [n for n in lst if n%2 or ((count := count+1) > 4)]
> [3, 7, 5, 7, 9, 1, 2, 5, 4]
>
> But I probably wouldn't recommend it. Explicit is better in this case I
> think.
>
> Alan G
>
>
> _______________________________________________
> 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 Oct 17 04:19:06 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 17 Oct 2021 09:19:06 +0100
Subject: [Tutor] Python program to remove first four even numbers from a
 list
In-Reply-To: <CAO1OCwZ0P+br+yP9NanHwBu3=n_oR5cuPOmru_zm10yto_sB=Q@mail.gmail.com>
References: <CAO1OCwbxwsd5-9Kjk-nmVj3PSVaL1yHhjqFiFii0vNiO3YL8Ww@mail.gmail.com>
 <e2681f0d-7614-9853-8add-d7cdf69e55e3@yahoo.co.uk>
 <CAO1OCwZ0P+br+yP9NanHwBu3=n_oR5cuPOmru_zm10yto_sB=Q@mail.gmail.com>
Message-ID: <skgm9q$17vi$1@ciao.gmane.io>

On 17/10/2021 02:09, Manprit Singh wrote:
> Dear Sir,
> 
> So finally I came up with this solution:
> def remove4even(seq):
>     evencnt = 0
>     lx = []
>     for ele in seq:
>         if evencnt > 3 or ele%2 != 0:
>             lx.append(ele)
>         else:
>             evencnt += 1
>     return lx
> 
> lst =[3, 6, 7, 5, 4, 7, 8, 9, 1, 8, 2, 5, 4]
> print(remove4even(lst))       # gives the right answer as
> 
> [3, 7, 5, 7, 9, 1, 2, 5, 4]
> 
> and to bring these changes in the existing  same list(lst), just doing this:
> lst =[3, 6, 7, 5, 4, 7, 8, 9, 1, 8, 2, 5, 4]
> lst[:] = remove4even(lst)

You don't need the slice. Just assign the new list to lst

lst = remove4even(lst)

> Is there any other  good way to achieve this ? I don't like changing
> mutable data inside functions.
What you have done is fine.

-- 
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 Oct 17 04:31:07 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 17 Oct 2021 09:31:07 +0100
Subject: [Tutor] Enter mode where you can input list indices
In-Reply-To: <CAEsMKX13LQT52+pj22Xs8iHFS85NOjQKnV2ut12EJtpWioykQA@mail.gmail.com>
References: <CAEsMKX13LQT52+pj22Xs8iHFS85NOjQKnV2ut12EJtpWioykQA@mail.gmail.com>
Message-ID: <skgn0c$o36$1@ciao.gmane.io>

On 16/10/2021 16:20, Julius Hamilton wrote:
> Hey,
> 
> I would like to explore the contents of a list where I could just enter a
> mode where any index I type in, it would print the value for some list,
> like this:
> 
>>>> p()
> 1
> ["apple", "cat"]
> 1 2
> cat
> 3
> Index out of bounds

You might want to look at the cmd module which provides a
framework for building interpreter like prompts into your program.

> def p():
>   n = input()

n is probably a bad name. index_str or similar
would be more descriptive.

>   while n != "":
> 
> After the input is received it must be parsed into a list of integers:
>     n = n.split(' ')
>     indices = []
>       for item in n:
>         indices.append(int(item))

This is basically a list comprehension:

indices = [int(item) for item in n]

> indices. Next, index the list (in the enclosing scope) by however many
> indices there are:
> 
>     for i in indices:
>       list = list[i]

This is the more challenging part, you probably want
to pass the list into the function. Or if you want to
use a different list for each iteration you would pass
a list of lists. In that ase your input() should
include a prompt describing which list is to be indexed.
Something like:

lists=(("list1",lst1),("list2",lst2,....)

def p(lists):
   for List in lists:
      index_str = input("type  list of indices for %s"%List[0]
      while index_str != "":
        ...
        for n in indices:
          print(List[1][n]
        ...
-- 
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 manpritsinghece at gmail.com  Sun Oct 17 11:03:48 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Sun, 17 Oct 2021 20:33:48 +0530
Subject: [Tutor] Python program to remove first four even numbers from a
 list
In-Reply-To: <skgm9q$17vi$1@ciao.gmane.io>
References: <CAO1OCwbxwsd5-9Kjk-nmVj3PSVaL1yHhjqFiFii0vNiO3YL8Ww@mail.gmail.com>
 <e2681f0d-7614-9853-8add-d7cdf69e55e3@yahoo.co.uk>
 <CAO1OCwZ0P+br+yP9NanHwBu3=n_oR5cuPOmru_zm10yto_sB=Q@mail.gmail.com>
 <skgm9q$17vi$1@ciao.gmane.io>
Message-ID: <CAO1OCwY8qE-3gTXAQ7x=y7bNn+Xg0W2wsqMNQn5U5E-YcKOgFQ@mail.gmail.com>

Dear sir,

By writing this :
lst[:] = remove4even(lst)   # here i am modify the existing list lst

But by doing this

lst = remove4even(lst)     #  Now variable lst is reassigned, so it is a
different object

Regards
Manprit Singh

On Sun, Oct 17, 2021 at 1:49 PM Alan Gauld via Tutor <tutor at python.org>
wrote:

> On 17/10/2021 02:09, Manprit Singh wrote:
> > Dear Sir,
> >
> > So finally I came up with this solution:
> > def remove4even(seq):
> >     evencnt = 0
> >     lx = []
> >     for ele in seq:
> >         if evencnt > 3 or ele%2 != 0:
> >             lx.append(ele)
> >         else:
> >             evencnt += 1
> >     return lx
> >
> > lst =[3, 6, 7, 5, 4, 7, 8, 9, 1, 8, 2, 5, 4]
> > print(remove4even(lst))       # gives the right answer as
> >
> > [3, 7, 5, 7, 9, 1, 2, 5, 4]
> >
> > and to bring these changes in the existing  same list(lst), just doing
> this:
> > lst =[3, 6, 7, 5, 4, 7, 8, 9, 1, 8, 2, 5, 4]
> > lst[:] = remove4even(lst)
>
> You don't need the slice. Just assign the new list to lst
>
> lst = remove4even(lst)
>
> > Is there any other  good way to achieve this ? I don't like changing
> > mutable data inside functions.
> What you have done is fine.
>
> --
> 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 Oct 17 15:35:33 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 17 Oct 2021 20:35:33 +0100
Subject: [Tutor] Python program to remove first four even numbers from a
 list
In-Reply-To: <CAO1OCwY8qE-3gTXAQ7x=y7bNn+Xg0W2wsqMNQn5U5E-YcKOgFQ@mail.gmail.com>
References: <CAO1OCwbxwsd5-9Kjk-nmVj3PSVaL1yHhjqFiFii0vNiO3YL8Ww@mail.gmail.com>
 <e2681f0d-7614-9853-8add-d7cdf69e55e3@yahoo.co.uk>
 <CAO1OCwZ0P+br+yP9NanHwBu3=n_oR5cuPOmru_zm10yto_sB=Q@mail.gmail.com>
 <skgm9q$17vi$1@ciao.gmane.io>
 <CAO1OCwY8qE-3gTXAQ7x=y7bNn+Xg0W2wsqMNQn5U5E-YcKOgFQ@mail.gmail.com>
Message-ID: <skhtu6$5vo$1@ciao.gmane.io>

On 17/10/2021 16:03, Manprit Singh wrote:
> Dear sir,
> 
> By writing this :
> lst[:] = remove4even(lst)   # here i am modify the existing list lst
> 
> But by doing this
> 
> lst = remove4even(lst)     #  Now variable lst is reassigned, so it is a
> different object

But an identical object. And the first method copies the object
returned from the function before throwing it away whereas the
direct assignment is much less processor (and time) intensive
and achieves the same result.

The slicing approach would be the best one if you wanted to
replace part of the original list with the returned values,
but if you are going to replace the whole list you might
as well just reassign the variable.

-- 
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 Richard at Damon-Family.org  Sun Oct 17 16:13:33 2021
From: Richard at Damon-Family.org (Richard Damon)
Date: Sun, 17 Oct 2021 16:13:33 -0400
Subject: [Tutor] Python program to remove first four even numbers from a
 list
In-Reply-To: <skhtu6$5vo$1@ciao.gmane.io>
References: <CAO1OCwbxwsd5-9Kjk-nmVj3PSVaL1yHhjqFiFii0vNiO3YL8Ww@mail.gmail.com>
 <e2681f0d-7614-9853-8add-d7cdf69e55e3@yahoo.co.uk>
 <CAO1OCwZ0P+br+yP9NanHwBu3=n_oR5cuPOmru_zm10yto_sB=Q@mail.gmail.com>
 <skgm9q$17vi$1@ciao.gmane.io>
 <CAO1OCwY8qE-3gTXAQ7x=y7bNn+Xg0W2wsqMNQn5U5E-YcKOgFQ@mail.gmail.com>
 <skhtu6$5vo$1@ciao.gmane.io>
Message-ID: <020fb75b-a1e7-2be2-1cea-128b8183c0b0@Damon-Family.org>

On 10/17/21 3:35 PM, Alan Gauld via Tutor wrote:
> On 17/10/2021 16:03, Manprit Singh wrote:
>> Dear sir,
>>
>> By writing this :
>> lst[:] = remove4even(lst)   # here i am modify the existing list lst
>>
>> But by doing this
>>
>> lst = remove4even(lst)     #  Now variable lst is reassigned, so it is a
>> different object
> But an identical object. And the first method copies the object
> returned from the function before throwing it away whereas the
> direct assignment is much less processor (and time) intensive
> and achieves the same result.
>
> The slicing approach would be the best one if you wanted to
> replace part of the original list with the returned values,
> but if you are going to replace the whole list you might
> as well just reassign the variable.
>
The difference would be if you had done:

copy = lst

lst[:] = ...


then copy is a copy of the new value in lst


but if you did:

copy = lst

lst = ...


Then copy is a copy of the OLD value in lst, and only lst is the new value.

Not to says this is good practice, but something to think of.

-- 
Richard Damon


From finnjavier08 at gmail.com  Sun Oct 17 14:15:58 2021
From: finnjavier08 at gmail.com (Finn Mason)
Date: Sun, 17 Oct 2021 12:15:58 -0600
Subject: [Tutor] Python program to remove first four even numbers from a
 list
In-Reply-To: <CAO1OCwY8qE-3gTXAQ7x=y7bNn+Xg0W2wsqMNQn5U5E-YcKOgFQ@mail.gmail.com>
References: <CAO1OCwbxwsd5-9Kjk-nmVj3PSVaL1yHhjqFiFii0vNiO3YL8Ww@mail.gmail.com>
 <e2681f0d-7614-9853-8add-d7cdf69e55e3@yahoo.co.uk>
 <CAO1OCwZ0P+br+yP9NanHwBu3=n_oR5cuPOmru_zm10yto_sB=Q@mail.gmail.com>
 <skgm9q$17vi$1@ciao.gmane.io>
 <CAO1OCwY8qE-3gTXAQ7x=y7bNn+Xg0W2wsqMNQn5U5E-YcKOgFQ@mail.gmail.com>
Message-ID: <CAJ3a0+3fWaA4+-hVOX+rViYeZvnh5YbBqkmk8wMkSPF20+whfw@mail.gmail.com>

On Sun, Oct 17, 2021, 9:04 AM Manprit Singh <manpritsinghece at gmail.com>
wrote:

> Dear sir,
>
> By writing this :
> lst[:] = remove4even(lst)   # here i am modify the existing list lst
>
> But by doing this
>
> lst = remove4even(lst)     #  Now variable lst is reassigned, so it is a
> different object


I can see how you reached that conclusion. However, you're wrong about the
slice.

When you slice a sequence, it *returns a copy* of the sequence. In Python,
all of these expressions are equivalent:

* lst[:]
* lst.copy()
* copy.copy(lst) # Using the built-in copy module
* list(lst)
* [x for x in lst]

We can check with the is operator, which checks if two objects refer to the
same value in memory:

\>>> lst[:] is lst
False

The expression with a slice is no different from the one without a slice
(and actually perhaps worse, if we're really worried about memory).

One of the great (or horrible, depending on who you ask) things about
Python is that you rarely have to worry about memory, since it's garbage
collected for you. Only make a copy when you don't want to mutate the
original mutable iten.

--
Finn Mason

From juliushamilton100 at gmail.com  Sun Oct 17 11:40:10 2021
From: juliushamilton100 at gmail.com (Julius Hamilton)
Date: Sun, 17 Oct 2021 17:40:10 +0200
Subject: [Tutor] Python IMAP library
In-Reply-To: <ek4mmgtvln8rscs592avtksh38gcj9dgu9@4ax.com>
References: <CAEsMKX1fY-J+oGa=ZJR4G1XHWSiK0xpzhfXdST6ES7-QKK7RTQ@mail.gmail.com>
 <ek4mmgtvln8rscs592avtksh38gcj9dgu9@4ax.com>
Message-ID: <CAEsMKX0bXeunW_7dXeNx1inGPrt0anbv3OcBhDyGCinCR7NJcg@mail.gmail.com>

Thanks very much.

Does anyone know what my options are for retrieving the email body of a
specific email using this library?

I?ll need a way to find the email. I guess I could search via subject
header, if this library supports that.

Or, I could place the email in a certain mailbox, for easy reference.

I believe I?ll use methods .fetch, .search and .select for this. I?ll be
researching this, unless about anybody can provide some code for this.

Thanks very much,
Julius

On Sat 16. Oct 2021 at 20:23, Dennis Lee Bieber <wlfraed at ix.netcom.com>
wrote:

> On Fri, 15 Oct 2021 21:42:56 +0200, Julius Hamilton
> <juliushamilton100 at gmail.com> declaimed the following:
>
> >
> >*mechanism* specifies which authentication mechanism is to be used - it
> >should appear in the instance variable capabilities in the form
> >AUTH=mechanism.
> >
> >
> >When I create an IMAP4() object, I have to edit the capabilities variable
> >with ?AUTH=mechanism?? What mechanisms are permitted or expected?
> >
>         You don't "edit the capabilities variable" -- It does not use to
> ask
> for capabilities that the server doesn't support. "capabilities" is
> something you retrieve from the server itself and then parse for those you
> understand.
>
>         You obtain the list of valid authorization modes from the server.
> And
> method the server returns after "AUTH=" in the capabilities list is an
> option you can use.
>
> Reference the RFC for IMAP (pretty much ANY library that works with a
> network protocol is going to require you to read the RFC for the
> details)... From the source code of imaplib
> """
>  Note: to use this module, you must read the RFCs pertaining to the
>     IMAP4 protocol, as the semantics of the arguments to each IMAP4
>     command are left to the invoker, not to mention the results. Also,
>     most IMAP servers implement a sub-set of the commands available here.
> """
>
> https://datatracker.ietf.org/doc/html/rfc3501#section-6.1.1
> """
> A capability name which begins with "AUTH=" indicates that the
>       server supports that particular authentication mechanism.  All
>       such names are, by definition, part of this specification.  For
>       example, the authorization capability for an experimental
>       "blurdybloop" authenticator would be "AUTH=XBLURDYBLOOP" and not
>       "XAUTH=BLURDYBLOOP" or "XAUTH=XBLURDYBLOOP".
>
> <SNIP>
>
>       Client and server implementations MUST implement the STARTTLS,
>       LOGINDISABLED, and AUTH=PLAIN (described in [IMAP-TLS])
>       capabilities.  See the Security Considerations section for
>       important information.
> """
>
>
> https://docs.python.org/3/library/imaplib.html
> """
> IMAP4.login(user, password)
>
>     Identify the client using a plaintext password. The password will be
> quoted.
>
> IMAP4.login_cram_md5(user, password)
>
>     Force use of CRAM-MD5 authentication when identifying the client to
> protect the password. Will only work if the server CAPABILITY response
> includes the phrase AUTH=CRAM-MD5.
> """
>
>         I haven't made sense of the full use of AUTHENTICATE, but it sounds
> like it may be needed for more complex schemes beyond the above .login()
> and .login_cram_md5(). IOW, you are implementing the client side of the
> authentication protocol yourself, with an "object" (since it likely needs
> state between calls with each server response, a function is not viable).
>
>
> --
>         Wulfraed                 Dennis Lee Bieber         AF6VN
>         wlfraed at ix.netcom.com
> http://wlfraed.microdiversity.freeddns.org/
>
> _______________________________________________
> 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 Oct 17 19:09:37 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 18 Oct 2021 00:09:37 +0100
Subject: [Tutor] Python IMAP library
In-Reply-To: <CAEsMKX0bXeunW_7dXeNx1inGPrt0anbv3OcBhDyGCinCR7NJcg@mail.gmail.com>
References: <CAEsMKX1fY-J+oGa=ZJR4G1XHWSiK0xpzhfXdST6ES7-QKK7RTQ@mail.gmail.com>
 <ek4mmgtvln8rscs592avtksh38gcj9dgu9@4ax.com>
 <CAEsMKX0bXeunW_7dXeNx1inGPrt0anbv3OcBhDyGCinCR7NJcg@mail.gmail.com>
Message-ID: <skiafh$bjq$1@ciao.gmane.io>

On 17/10/2021 16:40, Julius Hamilton wrote:
> Thanks very much.
> 
> Does anyone know what my options are for retrieving the email body of a
> specific email using this library?

Are you sure you need imap? Could you use the email module instead?
It seems to be a higher level library and more in tune with your
requirements.

-- 
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 Oct 17 19:20:11 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 18 Oct 2021 00:20:11 +0100
Subject: [Tutor] Python program to remove first four even numbers from a
 list
In-Reply-To: <CAJ3a0+3fWaA4+-hVOX+rViYeZvnh5YbBqkmk8wMkSPF20+whfw@mail.gmail.com>
References: <CAO1OCwbxwsd5-9Kjk-nmVj3PSVaL1yHhjqFiFii0vNiO3YL8Ww@mail.gmail.com>
 <e2681f0d-7614-9853-8add-d7cdf69e55e3@yahoo.co.uk>
 <CAO1OCwZ0P+br+yP9NanHwBu3=n_oR5cuPOmru_zm10yto_sB=Q@mail.gmail.com>
 <skgm9q$17vi$1@ciao.gmane.io>
 <CAO1OCwY8qE-3gTXAQ7x=y7bNn+Xg0W2wsqMNQn5U5E-YcKOgFQ@mail.gmail.com>
 <CAJ3a0+3fWaA4+-hVOX+rViYeZvnh5YbBqkmk8wMkSPF20+whfw@mail.gmail.com>
Message-ID: <skib3f$uqj$1@ciao.gmane.io>

On 17/10/2021 19:15, Finn Mason wrote:

>> By writing this :
>> lst[:] = remove4even(lst)   # here i am modify the existing list lst
>>
>> But by doing this
>>
>> lst = remove4even(lst)     #  Now variable lst is reassigned, so it is a
>> different object
> 
> 
> I can see how you reached that conclusion. However, you're wrong about the
> slice.
> 
> When you slice a sequence, it *returns a copy* of the sequence. 

That's true when the slice is an rvalue.

But if the slice is on the left side then slice assignment
takes place which replaces the slice with the new value.
It does not create a copy.

lst = [1,2,3,4,5,6,7,8,9]
lst[3:4] = [0,1,2]
print(lst)
[1, 2, 3, 0, 1, 2, 5, 6, 7, 8, 9]

The new values are inserted no copies are made.

So when you do

lst[:] = ...

You are *replacing* the entire list.
But because the OP is replacing it with another list
he is copying the new list into the old list.

> * lst[:]
> * lst.copy()
> * copy.copy(lst) # Using the built-in copy module
> * list(lst)
> * [x for x in lst]

as rvalues yes, but most of these cannot be used
as lvalues, whereas the slice can. But it works
differently on the left than on the right.

-- 
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 Oct 17 19:17:52 2021
From: cs at cskk.id.au (Cameron Simpson)
Date: Mon, 18 Oct 2021 10:17:52 +1100
Subject: [Tutor] Python IMAP library
In-Reply-To: <skiafh$bjq$1@ciao.gmane.io>
References: <skiafh$bjq$1@ciao.gmane.io>
Message-ID: <YWyvIO8ceIwhbBhd@cskk.homeip.net>

On 18Oct2021 00:09, Alan Gauld <alan.gauld at yahoo.co.uk> wrote:
>On 17/10/2021 16:40, Julius Hamilton wrote:
>> Does anyone know what my options are for retrieving the email body of 
>> a specific email using this library?
>
>Are you sure you need imap? Could you use the email module instead?
>It seems to be a higher level library and more in tune with your
>requirements.

The email module's great for representing a message _once you have it_.

Julius probably needs the imaplib module to obtain the message, if it is 
only available on an IMAP server. He can then use the email module to 
parse the message text he gets back from a search.

Cheers,
Cameron Simpson <cs at cskk.id.au>

From cs at cskk.id.au  Sun Oct 17 19:25:33 2021
From: cs at cskk.id.au (Cameron Simpson)
Date: Mon, 18 Oct 2021 10:25:33 +1100
Subject: [Tutor] Python IMAP library
In-Reply-To: <CAEsMKX0bXeunW_7dXeNx1inGPrt0anbv3OcBhDyGCinCR7NJcg@mail.gmail.com>
References: <CAEsMKX0bXeunW_7dXeNx1inGPrt0anbv3OcBhDyGCinCR7NJcg@mail.gmail.com>
Message-ID: <YWyw7WpmBEzUp2oZ@cskk.homeip.net>

On 17Oct2021 17:40, Julius Hamilton <juliushamilton100 at gmail.com> wrote:
>Does anyone know what my options are for retrieving the email body of a
>specific email using this library?
>
>I?ll need a way to find the email. I guess I could search via subject
>header, if this library supports that.

Ths depends entirely on what you know. Email messages each have a unique 
message-id (in the Message-ID header line). IMAP servers also allocate 
messages persistent UIDs I believe.

But if all you've got is a subject line, then that's all you can search 
for - bearing in mind that many of the messages in an email thread will 
all have the same subject line.

>I believe I?ll use methods .fetch, .search and .select for this. I?ll 
>be researching this, unless about anybody can provide some code for 
>this.

You could look at the source code for hte getmail utility - it uses the 
imaplib module directly to do its work:

http://pyropus.ca/software/getmail/

Cheers,
Cameron Simpson <cs at cskk.id.au>

From manpritsinghece at gmail.com  Tue Oct 19 06:49:35 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Tue, 19 Oct 2021 16:19:35 +0530
Subject: [Tutor] User defined exceptions
Message-ID: <CAO1OCwbbatNzvBRv7CnF_8=O8kV8pWgoiwtg9f_ngJFD_cKfLQ@mail.gmail.com>

Dear Sir,

With some more modifications, I have written a user defined class and
illustrated its use. Although I know in this example raising ValueError is
good.  The example here is to understand  what further we can do with user
defined exceptions: Just want you to read my comments at bottom and check
if these are correct or not.

class MarksError(Exception): # A simple user defined exception
    def __init__(self, high, low):
        self.high = high
        self.low = low
    def __str__(self):
        return f'Value must between {self.low} to {self.high}'

def grades(glist, score):
    if score < 0 or score > 100:
        raise MarksError(100, 0)
    for ch, rg in glist:
        if score < rg:
            return ch

lst = [("F", 60),
       ("D", 70),
       ("C", 80),
       ("B", 90),
       ("A", 101)]


try:
    marks= int(input("Enter marks"))
    grade = grades(lst, marks)

except MarksError as err:
    print(err)

else:
    print(f'for {marks} marks the grade is {grade}'

When i run this code with appropriate marks it displays correct grade

Enter marks78
for 78 marks the grade is C

When i run this code with marks > 100 or marks < 0

Enter marks107
Value must between 0 to 100

The Exception MarksError is raised, and due to the variable err in the

except block is bound to the exception instance raised inside the function

grades, print(err) will print the string returned by def__str__ inside the

class MarksError,  so the message "Value must between 0 to 100" is printed.

Regards

Manprit Singh

From alan.gauld at yahoo.co.uk  Tue Oct 19 12:42:57 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 19 Oct 2021 17:42:57 +0100
Subject: [Tutor] User defined exceptions
In-Reply-To: <CAO1OCwbbatNzvBRv7CnF_8=O8kV8pWgoiwtg9f_ngJFD_cKfLQ@mail.gmail.com>
References: <CAO1OCwbbatNzvBRv7CnF_8=O8kV8pWgoiwtg9f_ngJFD_cKfLQ@mail.gmail.com>
Message-ID: <skmsih$2ar$1@ciao.gmane.io>

On 19/10/2021 11:49, Manprit Singh wrote:
> Dear Sir,
> 
> With some more modifications, I have written a user defined class and
> illustrated its use. Although I know in this example raising ValueError is
> good.  The example here is to understand  what further we can do with user
> defined exceptions: Just want you to read my comments at bottom and check
> if these are correct or not.
> 
> class MarksError(Exception): # A simple user defined exception
>     def __init__(self, high, low):
>         self.high = high
>         self.low = low
>     def __str__(self):
>         return f'Value must between {self.low} to {self.high}'

> The Exception MarksError is raised, and due to the variable err in the
> except block is bound to the exception instance raised inside the function
> grades, print(err) will print the string returned by def__str__ inside the
> class MarksError,  so the message "Value must between 0 to 100" is printed.

That's correct and if you sere doing a lot of work with that exception
might be worth doing. But in practice, just passing the message into
the exception tends to be more flexible and less work.

Remember that we generally don't catch an exception unless we can
do something to correct the problem or to convert the stacktrace
into a more user friendly form (eg. inside a GUI/web app). So when
creating the exception class think about how you will be using it
when handling the exception. In this case the only use-case I can
see is during interactive input when you'd repeat the request to
the user. In that case raising the exception with the relevant
error string and in the handler simply printing err.args[0]

-- 
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 manpritsinghece at gmail.com  Wed Oct 20 14:29:46 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Wed, 20 Oct 2021 23:59:46 +0530
Subject: [Tutor] Using try, except else inside function definition
Message-ID: <CAO1OCwZ0h-a6GPNKV=-wRyiT6sXEPZBVjHS32NYZj5GTbW_Ryg@mail.gmail.com>

Dear Sir,

Kindly look at following examples:
1) This example consists of a function that is written to read a file and
print count of number of words in a file, and if the file not exists this
it should print "File  not exists"

def count_words(filename):
    try:
        with open(filename) as fileobj:
            content = fileobj.read()

    except FileNotFoundError:
        print(f'Sorry the file {filename} not exists')

    else:
        words = content.split()
        cntwd = len(words)
        print(f'The file {filename} has {cntwd} words')

file_name = "fileread.txt"
count_words(file_name)

This is working fine, my question is can we place try, except & else blocks
inside the function definition as done above.

In the second example I have written a function that takes a list and an
arbitrary object as an argument . The function must return the index of
first occurrence of that object in the list, if the object is not present
in the list the function should return -1

def indexofelement(seq, ele):
    try:
        if ele not in seq:
            raise ValueError

    except ValueError:
        return -1

    else:
        for ind, val in enumerate(seq):
            if val == ele:
                return ind



lst = [1, 3, 5, 7, 3, 5, 7]
num = 7
ans = indexofelement(lst, num)
print(ans)    # Gives the correct answer = 3

lst = [1, 3, 5, 7, 3, 5, 7]
num = 8
ans = indexofelement(lst, num)
print(ans)   # Gives the correct answer = -1

In this second example i am returning values from except block as well as
else block,  Except block will only work when exception occurs (when the
object is not present) it will return -1 else the function will return the
index of first occurence of the object in list due to esle block.

Returning values in this way from the function is ok ?

Need your guidance

Regards
Manprit Singh

From alan.gauld at yahoo.co.uk  Wed Oct 20 16:29:17 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 20 Oct 2021 21:29:17 +0100
Subject: [Tutor] Using try, except else inside function definition
In-Reply-To: <CAO1OCwZ0h-a6GPNKV=-wRyiT6sXEPZBVjHS32NYZj5GTbW_Ryg@mail.gmail.com>
References: <CAO1OCwZ0h-a6GPNKV=-wRyiT6sXEPZBVjHS32NYZj5GTbW_Ryg@mail.gmail.com>
Message-ID: <skpu70$ror$1@ciao.gmane.io>

On 20/10/2021 19:29, Manprit Singh wrote:

> def count_words(filename):
>     try:
>         with open(filename) as fileobj:
>             content = fileobj.read()
> 
>     except FileNotFoundError:
>         print(f'Sorry the file {filename} not exists')
> 
>     else:
>         words = content.split()
>         cntwd = len(words)
>         print(f'The file {filename} has {cntwd} words')
> 
> This is working fine, my question is can we place try, except & else blocks
> inside the function definition as done above.

The fact it is "working fine" tells you that you can.
And indeed that is perfectly normal.

The only thing I'd say is that the function is called
count words so I'd expect it to return a value not
print a message. The printing should be done outside
the function and the function just return the value
or raise the exception.

> def indexofelement(seq, ele):
>     try:
>         if ele not in seq:
>             raise ValueError
>     except ValueError:
>         return -1

This is kind of pointless. Instead of raising the
ValueError and immediately catching it just
return -1. Handling errors is relatively expensive
so if you don't need to do it its better to just
return the value directly. However in this case
you are probably better removing the try/except
construct and just raise the ValueError with a
suitable message.

>     else:
>         for ind, val in enumerate(seq):
>             if val == ele:
>                 return ind

> Returning values in this way from the function is ok ?

Its OK but its an old fashioned way of handling
errors - especially since -1 is a valid index in Python.
If a user used the index without checking they would
get a result(albeit a faulty one. If you raise the
exception instead the user has no choice but be
aware of it either by handling it or via the stacktrace
if they ignore it.

Part of the rationale for try/except style error handling
is to remove the need for checking for magic return values.

-- 
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 ejepujude at gmail.com  Wed Oct 20 16:59:21 2021
From: ejepujude at gmail.com (JUDE EJEPU)
Date: Wed, 20 Oct 2021 21:59:21 +0100
Subject: [Tutor] Mathematical operations on a list
Message-ID: <CANpzVC3CuiJf1wtYiRos42dzG9GmsiVg_y0+XgZfj=595kj14g@mail.gmail.com>

Sir,
I created a function to calculate a variable G
def gfactor(dist,electro):
       G = pie_value() * (dist**2 - electro**2)/(2*electro)
    return G

So I tried an example and it worked.
gFactor(10,2) ----> 75.408
However, when I passed a list of arguments,:
x = [1, 2, 3]
y = [0.5, 0.5, 1]
gFactor(x,y), I got an error

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-66124c985163> in <module>
----> 1 gFactor(x,y)

<ipython-input-3-9e0effe1021d> in gFactor(dist, electro)
     12     Output: ---> float
     13     """
---> 14     G = 3.142 * (dist**2 - electro**2)/(2*electro)
     15     return G

TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'int'


Please, how may I correct the function?

Thank you.

From cs at cskk.id.au  Wed Oct 20 19:00:30 2021
From: cs at cskk.id.au (Cameron Simpson)
Date: Thu, 21 Oct 2021 10:00:30 +1100
Subject: [Tutor] Mathematical operations on a list
In-Reply-To: <CANpzVC3CuiJf1wtYiRos42dzG9GmsiVg_y0+XgZfj=595kj14g@mail.gmail.com>
References: <CANpzVC3CuiJf1wtYiRos42dzG9GmsiVg_y0+XgZfj=595kj14g@mail.gmail.com>
Message-ID: <YXCfjoEnYYZXprTI@cskk.homeip.net>

On 20Oct2021 21:59, JUDE EJEPU <ejepujude at gmail.com> wrote:
>Sir,
>I created a function to calculate a variable G
>def gfactor(dist,electro):
>       G = pie_value() * (dist**2 - electro**2)/(2*electro)
>    return G

This is good, a function of 2 numbers.

>However, when I passed a list of arguments,:
>x = [1, 2, 3]
>y = [0.5, 0.5, 1]
>gFactor(x,y), I got an error

You're handing it lists. They are not numbers!

Please describe what result you _wanted_ to receive from this call.

I would not change the function at all.

Instead, guess at what you might want as being the equivalent of:

    [ gFactor(1, 0.5), gFactor(2, 0.5), gFactor(3, 1) ]

you would need to pair up the elements of your 2 lists and then call 
gFactor() with each pair.

_Please_ rename x and y to something else to indicate that they are 
lists and not numbers, for example "xs" and "ys", which I will use below 
to avoid confusion.

Python has a zip() builtin method to pair up lists (it will do more than 
pairs if you have more lists, BTW). So:

    paired = zip(xs, ys)

which would get you an iterable of pairs. You can then iterate over 
that:

    for x, y in paired:
        gFactor(x, y)

You probably want these as a list. You could do that like this:

    gs = []
    for x, y in paired:
        gs.append( gFactor(x, y) )

or more directly with a list comprehension:

    gs = [
        gFactor(x, y) for x, y in paired
    ]

which does the same thing.

Cheers,
Cameron Simpson <cs at cskk.id.au>

From alan.gauld at yahoo.co.uk  Wed Oct 20 19:11:13 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 21 Oct 2021 00:11:13 +0100
Subject: [Tutor] Mathematical operations on a list
In-Reply-To: <CANpzVC3CuiJf1wtYiRos42dzG9GmsiVg_y0+XgZfj=595kj14g@mail.gmail.com>
References: <CANpzVC3CuiJf1wtYiRos42dzG9GmsiVg_y0+XgZfj=595kj14g@mail.gmail.com>
Message-ID: <skq7ml$9ug$1@ciao.gmane.io>

On 20/10/2021 21:59, JUDE EJEPU wrote:
> Sir,
> I created a function to calculate a variable G
> def gfactor(dist,electro):
>        G = pie_value() * (dist**2 - electro**2)/(2*electro)
>     return G
> 
> So I tried an example and it worked.
> gFactor(10,2) ----> 75.408
> However, when I passed a list of arguments,:
> x = [1, 2, 3]
> y = [0.5, 0.5, 1]
> gFactor(x,y), I got an error

I'm not sure what you expected to happen but that's
what I would expect.

dist = x = [1,2,3]

What do you think [1,2,3]**2 should equal?
What is a list squared?

> Please, how may I correct the function?

I suspect you may be confusing Python lists with vectors?
If that the case you probably need to look at the
SciPy/numpy libraries.

If you do want to use lists of numbers as input then you
will need to process the lists inside your function. I've
no idea what you expected to happen so I can't advise
you on how to do tHat processing, but it probably
involves some kind of loop.

And if you want to be able to pass both lists and single
values then you'll need to test the types of the input
at the top of the function and branch accordingly.

-- 
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 ejepujude at gmail.com  Wed Oct 20 20:24:53 2021
From: ejepujude at gmail.com (JUDE EJEPU)
Date: Thu, 21 Oct 2021 01:24:53 +0100
Subject: [Tutor] Mathematical operations on a list
In-Reply-To: <skq7ml$9ug$1@ciao.gmane.io>
References: <CANpzVC3CuiJf1wtYiRos42dzG9GmsiVg_y0+XgZfj=595kj14g@mail.gmail.com>
 <skq7ml$9ug$1@ciao.gmane.io>
Message-ID: <CANpzVC27=O8XFdWZZSD3KsOk7OXW66_KNks_djBEfoZ_4T_w-A@mail.gmail.com>

Thank you so much for the input. I have learnt more than I bargained. I
will try out these suggestions. Your input are appreciated

On Thu, 21 Oct 2021, 00:12 Alan Gauld via Tutor, <tutor at python.org> wrote:

> On 20/10/2021 21:59, JUDE EJEPU wrote:
> > Sir,
> > I created a function to calculate a variable G
> > def gfactor(dist,electro):
> >        G = pie_value() * (dist**2 - electro**2)/(2*electro)
> >     return G
> >
> > So I tried an example and it worked.
> > gFactor(10,2) ----> 75.408
> > However, when I passed a list of arguments,:
> > x = [1, 2, 3]
> > y = [0.5, 0.5, 1]
> > gFactor(x,y), I got an error
>
> I'm not sure what you expected to happen but that's
> what I would expect.
>
> dist = x = [1,2,3]
>
> What do you think [1,2,3]**2 should equal?
> What is a list squared?
>
> > Please, how may I correct the function?
>
> I suspect you may be confusing Python lists with vectors?
> If that the case you probably need to look at the
> SciPy/numpy libraries.
>
> If you do want to use lists of numbers as input then you
> will need to process the lists inside your function. I've
> no idea what you expected to happen so I can't advise
> you on how to do tHat processing, but it probably
> involves some kind of loop.
>
> And if you want to be able to pass both lists and single
> values then you'll need to test the types of the input
> at the top of the function and branch accordingly.
>
> --
> 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 manpritsinghece at gmail.com  Wed Oct 20 21:29:30 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Thu, 21 Oct 2021 06:59:30 +0530
Subject: [Tutor] Using try, except else inside function definition
In-Reply-To: <skpu70$ror$1@ciao.gmane.io>
References: <CAO1OCwZ0h-a6GPNKV=-wRyiT6sXEPZBVjHS32NYZj5GTbW_Ryg@mail.gmail.com>
 <skpu70$ror$1@ciao.gmane.io>
Message-ID: <CAO1OCwY0EPU+3fPA8uEF3DRSipzMTrqO=jANp2Xjq3HnC3YPog@mail.gmail.com>

Dear Sir,

I have written the count_words function again, but this time i am not
including try except and else inside function, this seems more good to me

def count_words(filename):
    with open(filename) as fileobj:
        content = fileobj.read()
    return len(content.split())

try:
    filename ="fileread.txt"
    wdcnt = count_words(filename)

except FileNotFoundError:
    print("File not exists")

else:
    print("Number of words in file are", wdcnt)

What do you say? kindly comment

Regards
Manprit Singh

On Thu, Oct 21, 2021 at 1:59 AM Alan Gauld via Tutor <tutor at python.org>
wrote:

> On 20/10/2021 19:29, Manprit Singh wrote:
>
> > def count_words(filename):
> >     try:
> >         with open(filename) as fileobj:
> >             content = fileobj.read()
> >
> >     except FileNotFoundError:
> >         print(f'Sorry the file {filename} not exists')
> >
> >     else:
> >         words = content.split()
> >         cntwd = len(words)
> >         print(f'The file {filename} has {cntwd} words')
> >
> > This is working fine, my question is can we place try, except & else
> blocks
> > inside the function definition as done above.
>
> The fact it is "working fine" tells you that you can.
> And indeed that is perfectly normal.
>
> The only thing I'd say is that the function is called
> count words so I'd expect it to return a value not
> print a message. The printing should be done outside
> the function and the function just return the value
> or raise the exception.
>
> > def indexofelement(seq, ele):
> >     try:
> >         if ele not in seq:
> >             raise ValueError
> >     except ValueError:
> >         return -1
>
> This is kind of pointless. Instead of raising the
> ValueError and immediately catching it just
> return -1. Handling errors is relatively expensive
> so if you don't need to do it its better to just
> return the value directly. However in this case
> you are probably better removing the try/except
> construct and just raise the ValueError with a
> suitable message.
>
> >     else:
> >         for ind, val in enumerate(seq):
> >             if val == ele:
> >                 return ind
>
> > Returning values in this way from the function is ok ?
>
> Its OK but its an old fashioned way of handling
> errors - especially since -1 is a valid index in Python.
> If a user used the index without checking they would
> get a result(albeit a faulty one. If you raise the
> exception instead the user has no choice but be
> aware of it either by handling it or via the stacktrace
> if they ignore it.
>
> Part of the rationale for try/except style error handling
> is to remove the need for checking for magic return values.
>
> --
> 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 manpritsinghece at gmail.com  Thu Oct 21 03:40:23 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Thu, 21 Oct 2021 13:10:23 +0530
Subject: [Tutor] right way of modifying values of a dictonary
Message-ID: <CAO1OCwZoSJ2QS=rDYrbtAObF98L5RgOPOGLH1FfGdUAr03X5Eg@mail.gmail.com>

Dear sir ,

Take a dict as given below:
dicx = {"A": 23, "J": 38, "L": 29, "R": 26}
Now if i have to change the values in the existing dict( 1 in place of  odd
values and 0 in place of even values)
What will be the best way of the two:

1) First way :
>>> dicx = {"A": 23, "J": 38, "L": 29, "R": 26}
>>> dicx.update((key, val%2) for key, val in dicx.items())
>>> dicx
{'A': 1, 'J': 0, 'L': 1, 'R': 0}

2) Second way:

>>> dicx = {"A": 23, "J": 38, "L": 29, "R": 26}
>>> for key, val in dicx.items():
           dicx[key] = val%2


>>> dicx
{'A': 1, 'J': 0, 'L': 1, 'R': 0}

in the second way i am iterating over dicx,items() that doesn't seems fine
to me.

3) Third way:
>>> dicx = {"A": 23, "J": 38, "L": 29, "R": 26}
>>> for key in dicx.keys():
           dicx[key] = dicx[key]%2


>>> dicx
{'A': 1, 'J': 0, 'L': 1, 'R': 0}

Are 2nd and 3rd way are correct ways to do it ?

Regards

Manprit Singh

Need your guidance.

Regards
Manprit Singh

From alan.gauld at yahoo.co.uk  Thu Oct 21 05:20:47 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 21 Oct 2021 10:20:47 +0100
Subject: [Tutor] right way of modifying values of a dictonary
In-Reply-To: <CAO1OCwZoSJ2QS=rDYrbtAObF98L5RgOPOGLH1FfGdUAr03X5Eg@mail.gmail.com>
References: <CAO1OCwZoSJ2QS=rDYrbtAObF98L5RgOPOGLH1FfGdUAr03X5Eg@mail.gmail.com>
Message-ID: <skrbdf$1672$1@ciao.gmane.io>

On 21/10/2021 08:40, Manprit Singh wrote:

> 1) First way :
>>>> dicx = {"A": 23, "J": 38, "L": 29, "R": 26}
>>>> dicx.update((key, val%2) for key, val in dicx.items())
>>>> dicx
> {'A': 1, 'J': 0, 'L': 1, 'R': 0}
> 
> 2) Second way:
> 
>>>> dicx = {"A": 23, "J": 38, "L": 29, "R": 26}
>>>> for key, val in dicx.items():
>            dicx[key] = val%2
> 
>>>> dicx
> {'A': 1, 'J': 0, 'L': 1, 'R': 0}
> 
> 3) Third way:
>>>> dicx = {"A": 23, "J": 38, "L": 29, "R": 26}
>>>> for key in dicx.keys():
>            dicx[key] = dicx[key]%2
> 
>>>> dicx
> {'A': 1, 'J': 0, 'L': 1, 'R': 0}

Personally I'd probably use the third way as it is most explicit.
But the best, and most Pythonic, way is probably the first way.

> Are 2nd and 3rd way are correct ways to do it ?

Correct in the sense they give the correct result and are
easy to read and maintain. But they are probably not optimal.

-- 
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 Oct 21 05:22:06 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 21 Oct 2021 10:22:06 +0100
Subject: [Tutor] Using try, except else inside function definition
In-Reply-To: <CAO1OCwY0EPU+3fPA8uEF3DRSipzMTrqO=jANp2Xjq3HnC3YPog@mail.gmail.com>
References: <CAO1OCwZ0h-a6GPNKV=-wRyiT6sXEPZBVjHS32NYZj5GTbW_Ryg@mail.gmail.com>
 <skpu70$ror$1@ciao.gmane.io>
 <CAO1OCwY0EPU+3fPA8uEF3DRSipzMTrqO=jANp2Xjq3HnC3YPog@mail.gmail.com>
Message-ID: <skrbfu$1672$2@ciao.gmane.io>

On 21/10/2021 02:29, Manprit Singh wrote:
> Dear Sir,
> 
> I have written the count_words function again, but this time i am not
> including try except and else inside function, this seems more good to me
> 
> def count_words(filename):
>     with open(filename) as fileobj:
>         content = fileobj.read()
>     return len(content.split())
> 
> try:
>     filename ="fileread.txt"
>     wdcnt = count_words(filename)
> 
> except FileNotFoundError:
>     print("File not exists")
> 
> else:
>     print("Number of words in file are", wdcnt)

I'd say it was better because your function could now be used
in other contexts.

-- 
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 Oct 20 17:40:04 2021
From: breamoreboy at gmail.com (Mark Lawrence)
Date: Wed, 20 Oct 2021 22:40:04 +0100
Subject: [Tutor] Mathematical operations on a list
In-Reply-To: <CANpzVC3CuiJf1wtYiRos42dzG9GmsiVg_y0+XgZfj=595kj14g@mail.gmail.com>
References: <CANpzVC3CuiJf1wtYiRos42dzG9GmsiVg_y0+XgZfj=595kj14g@mail.gmail.com>
Message-ID: <f2cd1837-754f-7dd2-fd7a-06f30403ace7@gmail.com>

On 20/10/2021 21:59, JUDE EJEPU wrote:
> Sir,
> I created a function to calculate a variable G
> def gfactor(dist,electro):
>         G = pie_value() * (dist**2 - electro**2)/(2*electro)

Where is the function pie_value defined?

>      return G
> 
> So I tried an example and it worked.
> gFactor(10,2) ----> 75.408
> However, when I passed a list of arguments,:
> x = [1, 2, 3]
> y = [0.5, 0.5, 1]
> gFactor(x,y), I got an error
> 
> ---------------------------------------------------------------------------
> TypeError                                 Traceback (most recent call last)
> <ipython-input-7-66124c985163> in <module>
> ----> 1 gFactor(x,y)
> 
> <ipython-input-3-9e0effe1021d> in gFactor(dist, electro)
>       12     Output: ---> float
>       13     """
> ---> 14     G = 3.142 * (dist**2 - electro**2)/(2*electro)

pie_value has disappeared to be replaced by 3.142, please could we have 
some consistency.

>       15     return G
> 
> TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'int'
> 
> 
> Please, how may I correct the function?

You don't, you need to pass in correct Python types for dist and 
electro, whilst you're trying to call it with two lists.

> 
> Thank you.

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From dereje.anbessie at gmail.com  Thu Oct 21 05:36:56 2021
From: dereje.anbessie at gmail.com (dereje.anbessie at gmail.com)
Date: Thu, 21 Oct 2021 09:36:56 +0000 (UTC)
Subject: [Tutor] Using try, except else inside function definition
In-Reply-To: <skrbfu$1672$2@ciao.gmane.io>
References: <CAO1OCwZ0h-a6GPNKV=-wRyiT6sXEPZBVjHS32NYZj5GTbW_Ryg@mail.gmail.com>
 <skpu70$ror$1@ciao.gmane.io>
 <CAO1OCwY0EPU+3fPA8uEF3DRSipzMTrqO=jANp2Xjq3HnC3YPog@mail.gmail.com>
 <skrbfu$1672$2@ciao.gmane.io>
Message-ID: <926105688.4036345.1634809016937@mail.yahoo.com>

Thank you.? 

    On Thursday, October 21, 2021, 11:25:24 AM GMT+2, Alan Gauld via Tutor <tutor at python.org> wrote:  
 
 On 21/10/2021 02:29, Manprit Singh wrote:
> Dear Sir,
> 
> I have written the count_words function again, but this time i am not
> including try except and else inside function, this seems more good to me
> 
> def count_words(filename):
>? ? with open(filename) as fileobj:
>? ? ? ? content = fileobj.read()
>? ? return len(content.split())
> 
> try:
>? ? filename ="fileread.txt"
>? ? wdcnt = count_words(filename)
> 
> except FileNotFoundError:
>? ? print("File not exists")
> 
> else:
>? ? print("Number of words in file are", wdcnt)

I'd say it was better because your function could now be used
in other contexts.

-- 
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 monvansha at gmail.com  Wed Oct 20 18:35:19 2021
From: monvansha at gmail.com (Vanshika Sadhwani)
Date: Wed, 20 Oct 2021 18:35:19 -0400
Subject: [Tutor] Python
Message-ID: <10AC7556-6778-4727-A9B8-EFA864C2C8B8@gmail.com>

Hello Dear Sir/Ma?am, 

I had a doubt about one of my college assignments. I will provide a bit of background the on the assigned task - 

Tasks: In this assignment, you will write a complete program in Python that will repeatedly ask the user for a code (integer) and determine whether it is a valid Basic Code, a Positional Code or a UPC Code. It is possible that some integers may be valid for more than one of these codes; even all three! Your program should consist of two Python files: Assign2.py which handles all the input and output and code_check.py. Assign2.py should repeatedly prompt the user for input, a string of digits, and then call functions in code_check.py to determine whether the digits in the string correspond to one of the above codes, Basic, Position, UPC. 

The program should have a list for each type of code and when it finds that the string is a certain type of code, it should add the string to the list for that type of code. If a string is not one of the three types of codes, it should add it to a separate list. The program should repeatedly prompt the user for a string until the user enters a string that is zero, i.e., ?0?. The program should then output each list, as described below, when the user has finished. The file code_check.py should consist of three functions: one function for each type of code. Each function should take a string as a parameter, such as ?2452834? or ?033367258?, and determine whether it is valid code; the function should return True or False. For example, the function that checks whether an identification number is a UPC code should take ?2452834? as input and return True. Your program will make use of expressions, decisions, input/output, loops, lists and functions in Python. You should name your program Assign2.py. 



So I did do most of the coding for the assignment, however whenever I execute it, it doesn?t give me the output I need. I will put pictures of my code for the code_check.py file and Assign2.py file, Please let me know about the errors I am making


This is for code_check:
def basic_code(a):
    a = list(map(int, a.strip()))
    total = sum(a)
    valid_code = total % 10
    check_digit = a[+1]
    if valid_code == check_digit:
        return True
    else:
        return False


def positional_code(a):
    total = 0
    a = list(map(int, a.strip()))
    for i in range(0, len(a)):
        total += a[i]
    valid_code = total % 10
    check_digit = a[+1]
    if valid_code == check_digit:
        return True
    else:
        return False


def UPC(a):
    total = 0
    a = list(map(int, a.strip()))
    for i in range(0, len(a)):
        if i % 2 == 1:
            total += 3 * a[i]
    else:
        total += a[i]
    valid_code = total % 10
    if valid_code == 0:
        valid_code = 10 - valid_code
    check_digit = a[+1]
    if valid_code == check_digit:
        return True
    else:
        return False
This is for Assign2:
from code_check import*

codes = []
valid_basic = []
valid_positional = []
valid_UPC = []
none = []

while True:
    code = input("Please enter code (digits only) (enter 0 to quit): ")
    if code == '0':
        break
    codes.append(code)
    for code in codes:
        if basic_code(code) is True:
            valid_basic.append(code)
        elif positional_code(code) is True:
            valid_positional.append(code)
        elif UPC(code) is True:
            valid_UPC.append(code)
        else:
            none.append(code)


print("Summary")
print("Basic :" + ''.join(valid_basic))
print("Position :" + ''.join(valid_positional))
print("UPC :" + ''.join(valid_UPC))
print("None :" + ''.join(none))
This is what I am getting when I run the code



Please help me, I would really really appreciate it, 


Thank you 
Sincerely 
Vanshika Sadhwani




















From alan.gauld at yahoo.co.uk  Thu Oct 21 07:10:03 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 21 Oct 2021 12:10:03 +0100
Subject: [Tutor] Python
In-Reply-To: <10AC7556-6778-4727-A9B8-EFA864C2C8B8@gmail.com>
References: <10AC7556-6778-4727-A9B8-EFA864C2C8B8@gmail.com>
Message-ID: <skrhqb$sh5$1@ciao.gmane.io>

On 20/10/2021 23:35, Vanshika Sadhwani wrote:

> So I did do most of the coding for the assignment, however 
> whenever I execute it, it doesn?t give me the output I need. 

It is always good to tell us what it does produce and what
you expected. However...


> This is for code_check:
> def basic_code(a):
>     a = list(map(int, a.strip()))
>     total = sum(a)
>     valid_code = total % 10
>     check_digit = a[+1]

You don't need the plus sign in the index.
Also are you sure it is 1 you want to use?
That will give you the second digit in a...

>     if valid_code == check_digit:
>         return True
>     else:
>         return False

You could replace that if/else with

return valid_code == check_digit

> def positional_code(a):
>     total = 0
>     a = list(map(int, a.strip()))
>     for i in range(0, len(a)):
>         total += a[i]

Why not just use sum() as you did above?

Also in Python we try not to use index based loops.
It would be better to just write:

for n in a:
    total += n

And total = sum(a)

is better still.


>     valid_code = total % 10
>     check_digit = a[+1]
>     if valid_code == check_digit:
>         return True
>     else:
>         return False

This looks to be doing the same as the previous function?

> def UPC(a):
>     total = 0
>     a = list(map(int, a.strip()))
>     for i in range(0, len(a)):
>         if i % 2 == 1:
>             total += 3 * a[i]
>     else:
>         total += a[i]
>     valid_code = total % 10
>     if valid_code == 0:
>         valid_code = 10 - valid_code

You don;t need the subtraction since you've already
established that valid_code is zero.

>     check_digit = a[+1]
>     if valid_code == check_digit:
>         return True
>     else:
>         return False

> This is for Assign2:
> from code_check import*
> 
> codes = []
> valid_basic = []
> valid_positional = []
> valid_UPC = []
> none = []
> 
> while True:
>     code = input("Please enter code (digits only) (enter 0 to quit): ")
>     if code == '0':
>         break
>     codes.append(code)

I suspect the while loop should end here?

>     for code in codes:
>         if basic_code(code) is True:
>             valid_basic.append(code)
>         elif positional_code(code) is True:
>             valid_positional.append(code)
>         elif UPC(code) is True:
>             valid_UPC.append(code)
>         else:
>             none.append(code)
> 
> print("Summary")
> print("Basic :" + ''.join(valid_basic))
> print("Position :" + ''.join(valid_positional))
> print("UPC :" + ''.join(valid_UPC))
> print("None :" + ''.join(none))
> This is what I am getting when I run the code

Nothing 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 wlfraed at ix.netcom.com  Thu Oct 21 13:16:23 2021
From: wlfraed at ix.netcom.com (Dennis Lee Bieber)
Date: Thu, 21 Oct 2021 13:16:23 -0400
Subject: [Tutor] Python
References: <10AC7556-6778-4727-A9B8-EFA864C2C8B8@gmail.com>
Message-ID: <g773ngdinonqjnebfs7aq6q113ibaip7kv@4ax.com>

On Wed, 20 Oct 2021 18:35:19 -0400, Vanshika Sadhwani <monvansha at gmail.com>
declaimed the following:

	I'm not going to crawl through all of your code but will comment on one
facet.

>Tasks: In this assignment, you will write a complete program in Python that will repeatedly ask the user for a code (integer) and determine whether it is a valid Basic Code, a Positional Code or a UPC Code. It is possible that some integers may be valid for more than one of these codes; even all three! Your program should consist of two Python files:

	<SNIP>
 
>    for code in codes:
>        if basic_code(code) is True:
>            valid_basic.append(code)
>        elif positional_code(code) is True:
>            valid_positional.append(code)
>        elif UPC(code) is True:
>            valid_UPC.append(code)
>        else:
>            none.append(code)
>

	Your if/elif/else tree only saves the FIRST matching type, but the
program description explicitly states that codes could be valid for
multiple formats. You probably need to catch all valid formats, not just
the first one.

>
>print("Summary")
>print("Basic :" + ''.join(valid_basic))
>print("Position :" + ''.join(valid_positional))
>print("UPC :" + ''.join(valid_UPC))
>print("None :" + ''.join(none))

	The  "+" aren't really needed (you are generating one string on the
right, "adding" it to the string on the left [which creates another new
string], writing the result string, and then letting the runtime garbage
collect both the long string, and the string from the .join() ), comma
separated strings are acceptable. NOTE: you probably want to use " " (or '
') on those .join() operations, otherwise you are concatenating all the
values with no delimiters.

	Compare:

No delimiter
>>> print("string 1", "".join(["1", "A", "3"]))
string 1 1A3

Space delimiter
>>> print("string 1", " ".join(["1", "A", "3"]))
string 1 1 A 3

Comma-Space delimiter
>>> print("string 1", ", ".join(["1", "A", "3"]))
string 1 1, A, 3
>>> 


>This is what I am getting when I run the code

	If you attempted to paste an IMAGE, the forum strips attachments (it
may permit text attachments to pass, but no binary or executable formats).


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


From juliushamilton100 at gmail.com  Fri Oct 22 10:58:21 2021
From: juliushamilton100 at gmail.com (Julius Hamilton)
Date: Fri, 22 Oct 2021 16:58:21 +0200
Subject: [Tutor] Print elements of list with newlines
Message-ID: <CAEsMKX04YkNqtnTgaG_a3DeVrp-qTfpyoxnyAA3UcKF4J0QBzQ@mail.gmail.com>

Hey,

Is there any way to print the elements of a list one by one on new lines,
in a brief single line of code, as opposed to:

for item in list:
  print(item)

?

Thanks very much,
Julius

From juliushamilton100 at gmail.com  Fri Oct 22 12:06:24 2021
From: juliushamilton100 at gmail.com (Julius Hamilton)
Date: Fri, 22 Oct 2021 18:06:24 +0200
Subject: [Tutor] Get lines of web page properly segmented
Message-ID: <CAEsMKX0+6jWoTGShvcbP5Z9FdTpn07YUosaBCPG224GaYVrM2g@mail.gmail.com>

Hey,

This is something I have been researching for a long time, and it?s
surprisingly challenging. I would really appreciate anybody who can help me
finally resolve this question.

I want to segment texts which sometimes have text in them that doesn?t end
in a period - for example, the title of a section, or lines of code.

Usually when I retrieve text from a webpage, the sentences are broken up
with newlines, like this:

And Jeffrey went
to Paris that
weekend to meet
his family.

I cannot segment text on newlines if the sentences are broken by newlines,
but I need to go preserve the separation between different lines of code,
like:

print(x)
x = 3
quit()

I think I can either focus on getting the text from the source in a higher
quality format, so that the sentences are already connected and not broken,
or I have to find an efficient way to automatically join broken sentences
but nothing else.

I thought I could get better quality text by using Beautiful Soup, but I
just tried the .get_text() method and I was surprised to find that the
sentences are still broken by newlines. Maybe there are newlines even in
the HTML, or maybe there were HTML tags embedding links in the text, and
Beautiful Soup adds newlines when it extracts text.

Can anyone provide a working example of extracting webpage content so that
sentences are not broken with newlines?

Or if this is inevitable, what is an effective way to join broken sentences
automatically but nothing else? I think I?ll need AI for this.

Anyone who can help me, I really appreciate it.

Thanks very much,
Julius

From alan.gauld at yahoo.co.uk  Fri Oct 22 13:32:59 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 22 Oct 2021 18:32:59 +0100
Subject: [Tutor] Print elements of list with newlines
In-Reply-To: <CAEsMKX04YkNqtnTgaG_a3DeVrp-qTfpyoxnyAA3UcKF4J0QBzQ@mail.gmail.com>
References: <CAEsMKX04YkNqtnTgaG_a3DeVrp-qTfpyoxnyAA3UcKF4J0QBzQ@mail.gmail.com>
Message-ID: <skuskb$12i9$1@ciao.gmane.io>

On 22/10/2021 15:58, Julius Hamilton wrote:
> Hey,
> 
> Is there any way to print the elements of a list one by one on new lines,
> in a brief single line of code, as opposed to:
> 
> for item in list:
>   print(item)

The most general way is to generate a string with
newlines(or whatever) in and print the string:

print( '\n'.join(theList))

Thesimplest way for this specific case is to
use list unpacking:

print (*theList, sep='\n')


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 wlfraed at ix.netcom.com  Fri Oct 22 13:33:31 2021
From: wlfraed at ix.netcom.com (Dennis Lee Bieber)
Date: Fri, 22 Oct 2021 13:33:31 -0400
Subject: [Tutor] Python
References: <10AC7556-6778-4727-A9B8-EFA864C2C8B8@gmail.com>
 <g773ngdinonqjnebfs7aq6q113ibaip7kv@4ax.com>
Message-ID: <efs5ngduuk9jrs2843u7tr3kdal1e06vrb@4ax.com>


	o/~ Talking to myself in public o/~

On Thu, 21 Oct 2021 13:16:23 -0400, Dennis Lee Bieber
<wlfraed at ix.netcom.com> declaimed the following:

>On Wed, 20 Oct 2021 18:35:19 -0400, Vanshika Sadhwani <monvansha at gmail.com>
>declaimed the following:
>
>	I'm not going to crawl through all of your code but will comment on one
>facet.
>

	Okay, I lied -- I did look further.

	You must have some specification for the algorithms to apply to each
"code type", which you have not shown us.

	I mention this as your code for "basic" and "positional" codes compute
the exact same result; there is no difference other than using sum() in
one, and a for/+= loop in the other.

	Your code for UPC does not take into account that a valid UPC
(universal product code -- so "UPC code" is redundant) is exactly 12 digits
in length (a small modification to the algorithm would also allow it to
handle 13-digit European Article Number (EAN) codes which are basically a
UPC with a prefix country/zone designator).

	Part of your code seems to mix /validation/ of a code with the logic
required to generate a check digit. That is, one would process an 11-digit
"UPC", take the modulo 10, and (for non-zero) do that "check=10-mod" to
create the 12th digit for the UPC. Most algorithms that use "check=10-mod"
logic are meant to be verified by the taking the sum (accounting for any
position based multipliers) of the entire code modulo 10 and getting a 0 if
the code is valid.

https://www.codeproject.com/Articles/459507/Identification-numbers-and-check-digit-algorithms
For UPC...
"""
Verification: To verify the number, we can use this formula:

[3.d1 + 1.d2 + 3.d3 + 1.d4 + 3.d5 + 1.d6 + 3.d7 + 1.d8 + 3.d9 + 1.d10 +
3.d11 + 1.d12] mod10 = 0

Here d1, d2, d3...etc. are the digits. Starting from the left, we multiply
the digits with 3 and 1 alternatively.

Example: 036000 291452

3x0 + 1x3 + 3x6 + 1x0 + 3x0 + 1x0 + 3x2 + 1x9 + 3x1 + 1x4 + 3x5 + 1x2
=> 0+3+18+0+0+0+9+3+4+15+2 => 60 => 60mod10 => 0.

Hence the number is verified:
"""


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


From alan.gauld at yahoo.co.uk  Fri Oct 22 13:51:02 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 22 Oct 2021 18:51:02 +0100
Subject: [Tutor] Get lines of web page properly segmented
In-Reply-To: <CAEsMKX0+6jWoTGShvcbP5Z9FdTpn07YUosaBCPG224GaYVrM2g@mail.gmail.com>
References: <CAEsMKX0+6jWoTGShvcbP5Z9FdTpn07YUosaBCPG224GaYVrM2g@mail.gmail.com>
Message-ID: <skutm6$2ls$1@ciao.gmane.io>

On 22/10/2021 17:06, Julius Hamilton wrote:

> I want to segment texts which sometimes have text in them that doesn?t end
> in a period - for example, the title of a section, or lines of code.

I'm not clear on what you mean by "segment". That's not a
technical term I recognise... I'm guessing you mean you
want to separate the text from its context and then store
the text in some kind of variable? Is that it?

> Usually when I retrieve text from a webpage, the sentences are broken up
> with newlines, like this:
> 
> And Jeffrey went
> to Paris that
> weekend to meet
> his family.

That's probably how the text appears in the original HTML.

> I cannot segment text on newlines if the sentences are broken by newlines,
> but I need to go preserve the separation between different lines of code,
> like:
> 
> print(x)
> x = 3
> quit()

If the code is not separated naturally(as would happen if it
was quoted inside a <PRE></PRE> section or a <div> with code
CSS  formatting for example then you will need some kind of
code parser. The most likely case would be JavaScript code
in the header section. There are JavaScript parsers available
but it does make things ,much more complex.

> I think I can either focus on getting the text from the source in a higher
> quality format, so that the sentences are already connected and not broken,
> or I have to find an efficient way to automatically join broken sentences
> but nothing else.

As with everything in programming you need to very specifically
define what all those things mean. What is a "higher quality format"?
How do you define a "sentence" - its not something that HTML knows
about to an HTML parser won't help.

You can get the raw text out of the tag, but its up to you to
mess with sentences. The usual definition relies on punctuation
marks to terminate a sentence (.!?) You then split the text on the
punctuation marks.

> I thought I could get better quality text by using Beautiful Soup, but I
> just tried the .get_text() method and I was surprised to find that the
> sentences are still broken by newlines. Maybe there are newlines even in
> the HTML, or maybe there were HTML tags embedding links in the text, and
> Beautiful Soup adds newlines when it extracts text.

Beautiful Soup just extracts the HTML content. If the HTML text has
newlines BS will give you those newlines. They are part of the source text.


> Or if this is inevitable, what is an effective way to join broken sentences
> automatically but nothing else? I think I?ll need AI for this.

You definitely should not need AI this is the kind of stuff
programmers have been doing since the dawn of programming.
Fundamental text manipulation, you just need to decide what
your definitions are and then split the text accordingly.

You should get most of the way just using the standard string
split() method. Possibly applying it more than once per text block.

You may also want to join the lines together into one long
string before extracting sentences, something like:

listOfLines = BS.get_text()
lines = [line.strip() for line in listOfLines]  #strip removes \n
text_block = ' '.join(lines)  # add spaces so words don't run  together
sentences = text_block.split(sentence_markers)

That may not work perfectly but its a starter.

-- 
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 wlfraed at ix.netcom.com  Fri Oct 22 14:01:47 2021
From: wlfraed at ix.netcom.com (Dennis Lee Bieber)
Date: Fri, 22 Oct 2021 14:01:47 -0400
Subject: [Tutor] Print elements of list with newlines
References: <CAEsMKX04YkNqtnTgaG_a3DeVrp-qTfpyoxnyAA3UcKF4J0QBzQ@mail.gmail.com>
Message-ID: <5eu5ng9m7161j2o048nb8ic5fuaiqbmr8c@4ax.com>

On Fri, 22 Oct 2021 16:58:21 +0200, Julius Hamilton
<juliushamilton100 at gmail.com> declaimed the following:

>Hey,
>
>Is there any way to print the elements of a list one by one on new lines,
>in a brief single line of code, as opposed to:
>
>for item in list:
>  print(item)
>
	Suspect you won't like it (since you specified "single line")

	print("\n".join([str(itm) for itm in lst]))

List comprehension (hmmm, generator expression might work as well), taking
each item from the list, forcing the item into a STRING format, then join
the items with a new-line between each.

>>> lst = [	1,	3.14159,
... 	"a string",	("a", "tuple")	]
>>> print("\n".join([str(itm) for itm in lst]))
1
3.14159
a string
('a', 'tuple')
>>> 

>>> print("\n".join((str(itm) for itm in lst)))
1
3.14159
a string
('a', 'tuple')
>>> 

	Generator expression works too, and may avoid creating the intermediate
list.


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


From wlfraed at ix.netcom.com  Fri Oct 22 14:32:09 2021
From: wlfraed at ix.netcom.com (Dennis Lee Bieber)
Date: Fri, 22 Oct 2021 14:32:09 -0400
Subject: [Tutor] Get lines of web page properly segmented
References: <CAEsMKX0+6jWoTGShvcbP5Z9FdTpn07YUosaBCPG224GaYVrM2g@mail.gmail.com>
Message-ID: <c6v5ngdos9nlku88fmf6dfqjnpsqmgcd2j@4ax.com>

On Fri, 22 Oct 2021 18:06:24 +0200, Julius Hamilton
<juliushamilton100 at gmail.com> declaimed the following:


>
>I thought I could get better quality text by using Beautiful Soup, but I
>just tried the .get_text() method and I was surprised to find that the
>sentences are still broken by newlines. Maybe there are newlines even in
>the HTML, or maybe there were HTML tags embedding links in the text, and
>Beautiful Soup adds newlines when it extracts text.
>
	You'll have to examine the raw HTML to determine what structure is in
use... By definition, plain "new lines" in HTML are only for the use of the
editor, they are not something rendered when viewing the page.
If someone coded, say

<p>This is some text <br>
broken up by hard coded <br>
breaks</p>

I suspect anything that tries to extract "text" is going to have line
breaks at the <br> locations. Even worse would be...

<p>This is some text </p><p>broken up by hard coded</p>
<p>paragraph tags</p>

	Something like

<p>This is some text
broken up by simple
new-lines</p>

will be rendered by a browser as one line, only wrapping if the browser
window is narrower than the line. (Though the example at
https://www.crummy.com/software/BeautifulSoup/bs4/doc/ seems to be putting
out a new line for each anchor tag -- which is not something I'd expect!)

{and this is assuming /simple/ HTML -- not something where every tag
references some CSS tag which may be coming from another file}

	You'll have to provide example raw HTML for review (provide the HTML
AND what you expect to extract from it -- so a sample with more than one of
your "segments". Ideally your "segments" will have <p></p> or other block
delimiters which you can parse.)

	Some late comments: I would NOT use .get_text() on the whole HTML. I'd
try to iterate on the contents of the HTML looking for specific tags (and
classes of tags, if such are used). Then extract the contents of just those
tags for processing.


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


From cs at cskk.id.au  Fri Oct 22 19:03:12 2021
From: cs at cskk.id.au (Cameron Simpson)
Date: Sat, 23 Oct 2021 10:03:12 +1100
Subject: [Tutor] Print elements of list with newlines
In-Reply-To: <CAEsMKX04YkNqtnTgaG_a3DeVrp-qTfpyoxnyAA3UcKF4J0QBzQ@mail.gmail.com>
References: <CAEsMKX04YkNqtnTgaG_a3DeVrp-qTfpyoxnyAA3UcKF4J0QBzQ@mail.gmail.com>
Message-ID: <YXNDMCCe52cuGKYm@cskk.homeip.net>

On 22Oct2021 16:58, Julius Hamilton <juliushamilton100 at gmail.com> wrote:
>Is there any way to print the elements of a list one by one on new 
>lines, in a brief single line of code, as opposed to:
>
>for item in list:
>  print(item)

Well, there's:

    for item in list: print(item)

A better question might be: why do you want to?

Cheers,
Cameron Simpson <cs at cskk.id.au>

From juliushamilton100 at gmail.com  Mon Oct 25 07:40:39 2021
From: juliushamilton100 at gmail.com (Julius Hamilton)
Date: Mon, 25 Oct 2021 13:40:39 +0200
Subject: [Tutor] Simple curses application
Message-ID: <CAEsMKX1mS1T4ZnjY5-0ZpmshWos8KQUKdOqMjAQAQ5O6VbxNMA@mail.gmail.com>

Hey,

Here?s my attempt at some pseudocode, with a few questions about it:

import curses
import json

# load previous application data

data = open(?dr.dat?).json()

# ?

# Data is a list of dictionaries. Each text name is a key. The value is
three more dictionaries. The first is the text. The second is {index: } -
the location in the text where the reader left off. The second is
{comments: ??} - a text file.

So, data = [{?TheBible?: [{text: ?text of bible?}, {index: 0}, {comments:
??}]}]


You can launch the app with or without a command line argument - a filename
- which imports a new text into the data. The index starts at 0 for new
texts.

$ dr newtext


textname = $1

if textname != ??:

  data.add({textname: [{text: open(textname).read()}, {index: 0},
{comments: ??}]}].

else:

  # show a menu of imported texts with curses. The user can navigate up and
down with Vim keys: j and k, and choose one with ?enter?. What?s a good way
to do that with curses? Or a different library?

scr = curses.initscr()

# ?


Assuming they select one:

text = data[selection[text]]
index = data[selection[index]]
comments = data[selection[comments]]

lines = text.splitlines()


scr.addstr(line[index])
curses.refresh()

# How do I listen for user key presses ?l? and ?h?, left and right after
Vim? l puts the index up one and refreshes the screen, h the index down
one. c allows a the user to type into a text box on screen, beneath the
line. When they press enter, it?s appended as a new line to the ?comments?
file. q rewrites the data to the data file and closes the curses viewer.

Could anyone please correct my code and fill in these blank details? I?d
really appreciate it.

Thanks very much,
Julius

From alan.gauld at yahoo.co.uk  Mon Oct 25 13:37:19 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 25 Oct 2021 18:37:19 +0100
Subject: [Tutor] Simple curses application
In-Reply-To: <CAEsMKX1mS1T4ZnjY5-0ZpmshWos8KQUKdOqMjAQAQ5O6VbxNMA@mail.gmail.com>
References: <CAEsMKX1mS1T4ZnjY5-0ZpmshWos8KQUKdOqMjAQAQ5O6VbxNMA@mail.gmail.com>
Message-ID: <sl6q0f$so7$1@ciao.gmane.io>

On 25/10/2021 12:40, Julius Hamilton wrote:

> else:
> 
>   # show a menu of imported texts with curses. The user can navigate up and
> down with Vim keys: j and k, and choose one with ?enter?. What?s a good way
> to do that with curses? Or a different library?
> 
> scr = curses.initscr()

You should use the curses.wrapper() function for most curses programs,
it catches a lot of common problems and will save your sanity. You only
need to call initscr() if you are doing saome unusual initialisation or
low level control stuff.

The format is:

def main(screen):
   # all your curses code here

curses.wrapper(main)


The wrapper then calls your main function passing it a reference to
the main screen window. It will catch any exit conditions and tidy
up the terminal for you.

> Assuming they select one:
> 
> text = data[selection[text]]
> index = data[selection[index]]
> comments = data[selection[comments]]
> 
> lines = text.splitlines()
> 
> 
> scr.addstr(line[index])
> curses.refresh()
> 
> # How do I listen for user key presses

Use the getch() function.
Note that it returns an int so you need to compare the
value to ord('h') etc.

But note that curses does not provide any kind of mainloop capability
you need to write tat yourself. Something like:

while True:
    key = curses.getch()
    if key in [ ord('q'), ord('Q')]:   # q/Q to exit
       break
    elif key == ord('h'):  # do the h thing
    elif key == ord('j'):  # do the j thing
    etc...

<PLUG class="blatant">
You may find my book on curses useful, it's an Amazon Kindle
ebook and I priced it as low as I could while avoiding having
to pay Amazon for copies sold!

Programming curses in Python

You can also get it in paperback if you prefer.
</PLUG>

Finally, here is the minimal wrapper example from the book:

import curses as cur

def main(win):
    win.addstr(4,4,"Hello world")
    win.refresh()
    win.getch()

cur.wrapper(main)

That just displays the message and waits for the user
to hit any key to exit.

-- 
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 alexkleider at gmail.com  Mon Oct 25 17:03:57 2021
From: alexkleider at gmail.com (Alex Kleider)
Date: Mon, 25 Oct 2021 14:03:57 -0700
Subject: [Tutor] Simple curses application
In-Reply-To: <CAEsMKX1mS1T4ZnjY5-0ZpmshWos8KQUKdOqMjAQAQ5O6VbxNMA@mail.gmail.com>
References: <CAEsMKX1mS1T4ZnjY5-0ZpmshWos8KQUKdOqMjAQAQ5O6VbxNMA@mail.gmail.com>
Message-ID: <CAMCEyD5R6TGvRPLnvF0t_jRJubt7NjkXp4pJr8Hg=yO4HFeizA@mail.gmail.com>

On Mon, Oct 25, 2021 at 10:10 AM Julius Hamilton <
juliushamilton100 at gmail.com> wrote:

>
>   # show a menu of imported texts with curses. The user can navigate up and
> down with Vim keys: j and k, and choose one with ?enter?. What?s a good way
> to do that with curses? Or a different library?
>

You may well have already gotten as much as you need/want from Alan's
answer...
I gather that you already have a functioning program that runs with command
line arguments and your wish is to have it driven by a curses interface.
I have been dealing with the same scenario lately- creating a front end
curses interface to a command line driven code base.  Would be happy to
share/collaborate if you should have any interest in doing so. (I assume
doing so off list would be the most appropriate.)
Alex Kleider

_______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From edwinconnell at gmail.com  Mon Oct 25 20:08:40 2021
From: edwinconnell at gmail.com (Ed Connell)
Date: Mon, 25 Oct 2021 19:08:40 -0500
Subject: [Tutor] tkinter listbox function
Message-ID: <CADmpvFFWsCZxh1Dd8fzwVaCLKQ61mxu1y0kx8Do5RbXoGhoz8g@mail.gmail.com>

Hi again,

HELP!!!

I really, really, really want to know how to implement this function using
a Tkinter Lisbox.

def pickFromListTK( listOfChoices ):

   ---

    some code using a Listbo:

   ---

    return choice

The nonGUI version is simple, but I can't figure out the GUI version.
Thank you so much.

-- 
I have a right and a left brain, but there is nothing right in the left one
and there is nothing left in the right one!

From alan.gauld at yahoo.co.uk  Tue Oct 26 05:42:42 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 26 Oct 2021 10:42:42 +0100
Subject: [Tutor] tkinter listbox function
In-Reply-To: <CADmpvFFWsCZxh1Dd8fzwVaCLKQ61mxu1y0kx8Do5RbXoGhoz8g@mail.gmail.com>
References: <CADmpvFFWsCZxh1Dd8fzwVaCLKQ61mxu1y0kx8Do5RbXoGhoz8g@mail.gmail.com>
Message-ID: <sl8iij$b6p$1@ciao.gmane.io>

On 26/10/2021 01:08, Ed Connell wrote:
> Hi again,
> 
> HELP!!!
> 
> I really, really, really want to know how to implement this function using
> a Tkinter Lisbox.
> 
> def pickFromListTK( listOfChoices ):
> 
>    ---
> 
>     some code using a Listbo:
> 
>    ---
> 
>     return choice


It is not at all clear what you want the function to do.
Can you describe what the user would do to activate this
function and what the result would be?

If you just want the index of the selected item(or items
since there could be more than one) within the list
then the Listbox has a method for that, you don't need
to write a function.

eg:

class MyGUI(Frame):
   def __init__(self,parent):
      .... # build GUI
      self.myListbox = tkinter.Listbox(....)
      ...
      tkinter.Button(self, text="OK", command=self.handle_OK_button)
      ...

   def handle_OK_Button(self):
       selected = self.myListbox.curselection()
       for index in selected:
           item = self.myListbox.get(index)
           ... # process item here.


But unless you explain more about what the function is
supposed to do we can't really help. It may seem obvious
to you but it isn't to us!

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 manpritsinghece at gmail.com  Wed Oct 27 21:09:19 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Thu, 28 Oct 2021 06:39:19 +0530
Subject: [Tutor] Using formatted string
Message-ID: <CAO1OCwb6WCnXOOwQyZgnAKmpgv5V9wT7kyxwe8ebH3rjmD-pFQ@mail.gmail.com>

Dear Sir,

Suppose i have to print a number using f string , with the only feature
required that it should start with a +  sign if it a positive number or a
- sign if it is a negative number, the number can be an integer or a
floating point number,  Doing it in this way as shown in the examples below
done by me is ok ?
>>> a = -3.659
>>> b= -4
>>> c = 5
>>> d = 5.6
>>> f'{a:+}'
'-3.659'
>>> f'{b:+}'
'-4'
>>> f'{c:+}'
'+5'
>>> f'{d:+}'
'+5.6'
>>>
In the above examples, I have not written type characters (for example f
for float and d for int) after : .
Need your comments.

Regards
Manprit Singh

From juliushamilton100 at gmail.com  Thu Oct 28 11:45:35 2021
From: juliushamilton100 at gmail.com (Julius Hamilton)
Date: Thu, 28 Oct 2021 17:45:35 +0200
Subject: [Tutor] Pass options in one line (Selenium)
Message-ID: <CAEsMKX1W=Vq3tyJvOuPyqCi01LUpwXssp8sSPCnBtMs7mz5WTQ@mail.gmail.com>

Hey,

Would anyone know how to do the following in fewer lines?

from selenium import webdriver
from selenium.webdriver.firefox.options import Options

options = Options()
options.headless = True

driver = webdriver.Firefox(options = options)

Basically, I?d like to do this:

driver = webdriver.Firefox(options = Options().headless = True)

But the only issue is trying to instantiate a class, then modify a
property, and passing that as the argument to something else, all at once.

Maybe Options(self.headless = True)?

Thanks very much,
Julius

From alan.gauld at yahoo.co.uk  Thu Oct 28 19:44:14 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 29 Oct 2021 00:44:14 +0100
Subject: [Tutor] Pass options in one line (Selenium)
In-Reply-To: <CAEsMKX1W=Vq3tyJvOuPyqCi01LUpwXssp8sSPCnBtMs7mz5WTQ@mail.gmail.com>
References: <CAEsMKX1W=Vq3tyJvOuPyqCi01LUpwXssp8sSPCnBtMs7mz5WTQ@mail.gmail.com>
Message-ID: <slfckh$7km$1@ciao.gmane.io>

On 28/10/2021 16:45, Julius Hamilton wrote:
> Hey,
> 
> Would anyone know how to do the following in fewer lines?
> 
> from selenium import webdriver
> from selenium.webdriver.firefox.options import Options
> 
> options = Options()

You could omit the import since you only use Options once.
So it becomes

options = selenium.webdriver.firefox.options.Options()


> options.headless = True
> driver = webdriver.Firefox(options = options)
> 
> Basically, I?d like to do this:
> 
> driver = webdriver.Firefox(options = Options().headless = True)

But you can't because you can't do an assignment inside a
function call. And you can't pass a Boolean conditional value
to the Firefox initializer for options. So you need to create
the options object, set its values and pass it in, just
as you are doing.

> But the only issue is trying to instantiate a class, then modify a
> property, and passing that as the argument to something else, all at once.

Why do you want to? There are no prizes for writing difficult
to debug code. And hiding the options object makes it impossible
for you to access it and find out its settings. Why would you
want to do that?

There are no prizes for writing the shortest code. Write clear
and easy to understand code and your maintainers (who may be
you in 6 months) will thank you for it.

> Maybe Options(self.headless = True)?

You can only pass the parameters that are defined for the function
The option.__init__() does not have a parameter called self.headless.

Now, if you really, really want to do this you can, using a class.
But it adds more lines not less. You can define your own options class
derived from the selenium one and provide a headless parameter.

class HeadlessOptions(Options):
   def __init__(self, headless=True, *args, **kwargs):
       Options.__init__(self, *args,**args)
       self.headless = headless

Now you can create Firefox with

driver = webdriver.Firefox(options = HeadlessOptions())

But while saving the Options creation and assignment you now
have a class definition... Which version is easier to maintain
I'll leave as a moot point. Personally I'd go for the original
unless you have a lot of similar programs to write in which
case stick your class in a module so you can reuse 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 Jose at joserivera.ca  Fri Oct 29 17:38:16 2021
From: Jose at joserivera.ca (Jose Rivera)
Date: Fri, 29 Oct 2021 21:38:16 +0000
Subject: [Tutor] PYTHON INSTALLATION PROBLEM
Message-ID: <77E96EB7-7F22-4689-AEFF-C640CC15305B@joserivera.ca>

Hello,

I just downloaded the latest version of python to my Mac book but when I click on the python launcher on my dock is not opening. Have I done something wrong along the process of the installation? Please help. I am a new user and don?t know if I have done the installing properly. Thank you very much

[cid:27A2F04F-F440-4399-BA72-4FB60E21A292]

[cid:C128ED66-0362-4668-9393-1D0480998F05]

Sincerely,

Jose

From alan.gauld at yahoo.co.uk  Fri Oct 29 19:39:50 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 30 Oct 2021 00:39:50 +0100
Subject: [Tutor] PYTHON INSTALLATION PROBLEM
In-Reply-To: <77E96EB7-7F22-4689-AEFF-C640CC15305B@joserivera.ca>
References: <77E96EB7-7F22-4689-AEFF-C640CC15305B@joserivera.ca>
Message-ID: <sli0o7$td1$1@ciao.gmane.io>

On 29/10/2021 22:38, Jose Rivera wrote:
> Hello,
> 
> I just downloaded the latest version of python to my Mac book but 
> when I click on the python launcher on my dock is not opening. 

I'm not a Mac user so don;t know for sure what the installer does.
However, Python is normally a command-line interpreter without a GUI.

Try opening your terminal application and typing python.

You should see something fairly similar to:

Python 3.8.10 (default, Sep 28 2021, 16:10:42)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license()" for more information.
>>>

If the version corresponds to the one you installed then
everything is probably as it should be.

If not copy 'n paste the command and error message into a mail and
hopefully one of our mac users can help.

-- 
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 Richard at Damon-Family.org  Fri Oct 29 19:51:26 2021
From: Richard at Damon-Family.org (Richard Damon)
Date: Fri, 29 Oct 2021 19:51:26 -0400
Subject: [Tutor] PYTHON INSTALLATION PROBLEM
In-Reply-To: <77E96EB7-7F22-4689-AEFF-C640CC15305B@joserivera.ca>
References: <77E96EB7-7F22-4689-AEFF-C640CC15305B@joserivera.ca>
Message-ID: <8a1a66b6-5630-0dd4-debe-a460f039c7cb@Damon-Family.org>

On 10/29/21 5:38 PM, Jose Rivera wrote:
> Hello,
>
> I just downloaded the latest version of python to my Mac book but when I click on the python launcher on my dock is not opening. Have I done something wrong along the process of the installation? Please help. I am a new user and don?t know if I have done the installing properly. Thank you very much
>
On the Mac, 'Python Launcher' seems to just configure how python will 
run programs run under python. Generally from the Dock, you will want to 
click on the 'IDLE' icon, which launches the Python IDE, which gives and 
editor to write python programs or load a python script.

The other way to run python is from the command line, using a command 
like python3 myprog.py

-- 
Richard Damon


From cs at cskk.id.au  Fri Oct 29 20:08:55 2021
From: cs at cskk.id.au (Cameron Simpson)
Date: Sat, 30 Oct 2021 11:08:55 +1100
Subject: [Tutor] PYTHON INSTALLATION PROBLEM
In-Reply-To: <8a1a66b6-5630-0dd4-debe-a460f039c7cb@Damon-Family.org>
References: <8a1a66b6-5630-0dd4-debe-a460f039c7cb@Damon-Family.org>
Message-ID: <YXyNF2SH4fYosm6w@cskk.homeip.net>

On 29Oct2021 19:51, Richard Damon <Richard at Damon-Family.org> wrote:
>On the Mac, 'Python Launcher' seems to just configure how python will 
>run programs run under python. Generally from the Dock, you will want 
>to click on the 'IDLE' icon, which launches the Python IDE, which gives 
>and editor to write python programs or load a python script.
>
>The other way to run python is from the command line, using a command 
>like python3 myprog.py

Also, Macs ship with Python. If your MacOS is current, the supplied 
Python should be pretty modern.

Cheers,
Cameron Simpson <cs at cskk.id.au>

From Richard at Damon-Family.org  Fri Oct 29 22:59:22 2021
From: Richard at Damon-Family.org (Richard Damon)
Date: Fri, 29 Oct 2021 22:59:22 -0400
Subject: [Tutor] PYTHON INSTALLATION PROBLEM
In-Reply-To: <YXyNF2SH4fYosm6w@cskk.homeip.net>
References: <8a1a66b6-5630-0dd4-debe-a460f039c7cb@Damon-Family.org>
 <YXyNF2SH4fYosm6w@cskk.homeip.net>
Message-ID: <471537b1-d428-b8b7-9bab-b73c91ef416a@Damon-Family.org>

On 10/29/21 8:08 PM, Cameron Simpson wrote:
> On 29Oct2021 19:51, Richard Damon <Richard at Damon-Family.org> wrote:
>> On the Mac, 'Python Launcher' seems to just configure how python will
>> run programs run under python. Generally from the Dock, you will want
>> to click on the 'IDLE' icon, which launches the Python IDE, which gives
>> and editor to write python programs or load a python script.
>>
>> The other way to run python is from the command line, using a command
>> like python3 myprog.py
> Also, Macs ship with Python. If your MacOS is current, the supplied
> Python should be pretty modern.
>
> Cheers,
> Cameron Simpson <cs at cskk.id.au>

You might think that, but my Mac, running the latest version of OS-X, 
Monterey, reports for a "python --version"? that the system default 
python is still 2.7.10

Now, this system is a 2019 Year model, but was built as a upgrade to an 
older system. so that might be a reason.

Since I have been manually installing current Pythons, I don't know if 
they also have provided a python3 command with something more recent.

-- 
Richard Damon


From cs at cskk.id.au  Sat Oct 30 01:45:00 2021
From: cs at cskk.id.au (Cameron Simpson)
Date: Sat, 30 Oct 2021 16:45:00 +1100
Subject: [Tutor] PYTHON INSTALLATION PROBLEM
In-Reply-To: <471537b1-d428-b8b7-9bab-b73c91ef416a@Damon-Family.org>
References: <471537b1-d428-b8b7-9bab-b73c91ef416a@Damon-Family.org>
Message-ID: <YXzb3Fn6zu4+O2DQ@cskk.homeip.net>

On 29Oct2021 22:59, Richard Damon <Richard at Damon-Family.org> wrote:
>On 10/29/21 8:08 PM, Cameron Simpson wrote:
>>Also, Macs ship with Python. If your MacOS is current, the supplied
>>Python should be pretty modern.
>
>You might think that, but my Mac, running the latest version of OS-X, 
>Monterey, reports for a "python --version"? that the system default 
>python is still 2.7.10

I've got a similar Mac, running Catalina:

   % /usr/bin/python2 --version
   Python 2.7.16
   % /usr/bin/python3 --version
   Python 3.8.2

"python" is Python 2 here. Probably to support scripts in the vendor 
distribution which use /usr/bin/python and still expect python 2. That 
transition is a laborious QA process for any vendor.

But It's got an ok python3.

>Since I have been manually installing current Pythons, I don't know if 
>they also have provided a python3 command with something more recent.

Cheers,
Cameron Simpson <cs at cskk.id.au>

From ananda.murthy1 at gmail.com  Fri Oct 29 21:25:44 2021
From: ananda.murthy1 at gmail.com (Ananda Murthy)
Date: Fri, 29 Oct 2021 21:25:44 -0400
Subject: [Tutor] PYTHON INSTALLATION PROBLEM
In-Reply-To: <77E96EB7-7F22-4689-AEFF-C640CC15305B@joserivera.ca>
References: <77E96EB7-7F22-4689-AEFF-C640CC15305B@joserivera.ca>
Message-ID: <CAJCjhhW7Uqbs=0Xmn4JVqbicwyr3kfB4+KTEeQY4zxRox-5e5w@mail.gmail.com>

You need to go to the app installer...
ANANDA K. MURTHY

On Fri, Oct 29, 2021 at 7:35 PM Jose Rivera <Jose at joserivera.ca> wrote:

> Hello,
>
> I just downloaded the latest version of python to my Mac book but when I
> click on the python launcher on my dock is not opening. Have I done
> something wrong along the process of the installation? Please help. I am a
> new user and don?t know if I have done the installing properly. Thank you
> very much
>
> [cid:27A2F04F-F440-4399-BA72-4FB60E21A292]
>
> [cid:C128ED66-0362-4668-9393-1D0480998F05]
>
> Sincerely,
>
> Jose
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From bryan.m.obrien at gmail.com  Fri Oct 29 23:31:08 2021
From: bryan.m.obrien at gmail.com (Bryan O'Brien)
Date: Fri, 29 Oct 2021 22:31:08 -0500
Subject: [Tutor] PYTHON INSTALLATION PROBLEM
Message-ID: <B381828D-0956-4F0D-99E1-02EC95D26395@gmail.com>

?Likely, you have multiple Python executables on your system.   
This will necessitate modifying your PATH.  

In terminal, run:

which -a python <enter>

If multiple python versions exist (this is normal with MacOS), just ensure that the python you want to use is listed first in your path. 

grep -i path ~/.zshrc

HTH

> On Oct 29, 2021, at 22:00, Richard Damon <Richard at damon-family.org> wrote:
> 
> ?On 10/29/21 8:08 PM, Cameron Simpson wrote:
>>> On 29Oct2021 19:51, Richard Damon <Richard at Damon-Family.org> wrote:
>>> On the Mac, 'Python Launcher' seems to just configure how python will
>>> run programs run under python. Generally from the Dock, you will want
>>> to click on the 'IDLE' icon, which launches the Python IDE, which gives
>>> and editor to write python programs or load a python script.
>>> The other way to run python is from the command line, using a command
>>> like python3 myprog.py
>> Also, Macs ship with Python. If your MacOS is current, the supplied
>> Python should be pretty modern.
>> Cheers,
>> Cameron Simpson <cs at cskk.id.au>
> 
> You might think that, but my Mac, running the latest version of OS-X, Monterey, reports for a "python --version"  that the system default python is still 2.7.10
> 
> Now, this system is a 2019 Year model, but was built as a upgrade to an older system. so that might be a reason.
> 
> Since I have been manually installing current Pythons, I don't know if they also have provided a python3 command with something more recent.
> 
> -- 
> Richard Damon
> 
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

From Richard at Damon-Family.org  Sat Oct 30 06:52:58 2021
From: Richard at Damon-Family.org (Richard Damon)
Date: Sat, 30 Oct 2021 06:52:58 -0400
Subject: [Tutor] PYTHON INSTALLATION PROBLEM
In-Reply-To: <B381828D-0956-4F0D-99E1-02EC95D26395@gmail.com>
References: <B381828D-0956-4F0D-99E1-02EC95D26395@gmail.com>
Message-ID: <282ca79a-0b45-2444-0128-b925a7141ab5@Damon-Family.org>

Actually, it says I only have 1 'python', but multiple 'python3'
/usr/bin/python symlinks to a version 2.7 off in /System/Library/Frameworks/

All the versions 3.x only appear as python3 or python3.x

It could well be that they haven't fully removed python2.7 dependencies 
from the system (or maybe better, haven't validated that they have) so 
python means python2 for backwards compatibility.


On 10/29/21 11:31 PM, Bryan O'Brien wrote:
> ?Likely, you have multiple Python executables on your system.
> This will necessitate modifying your PATH.
>
> In terminal, run:
>
> which -a python <enter>
>
> If multiple python versions exist (this is normal with MacOS), just ensure that the python you want to use is listed first in your path.
>
> grep -i path ~/.zshrc
>
> HTH
>
>> On Oct 29, 2021, at 22:00, Richard Damon <Richard at damon-family.org> wrote:
>>
>> ?On 10/29/21 8:08 PM, Cameron Simpson wrote:
>>>> On 29Oct2021 19:51, Richard Damon <Richard at Damon-Family.org> wrote:
>>>> On the Mac, 'Python Launcher' seems to just configure how python will
>>>> run programs run under python. Generally from the Dock, you will want
>>>> to click on the 'IDLE' icon, which launches the Python IDE, which gives
>>>> and editor to write python programs or load a python script.
>>>> The other way to run python is from the command line, using a command
>>>> like python3 myprog.py
>>> Also, Macs ship with Python. If your MacOS is current, the supplied
>>> Python should be pretty modern.
>>> Cheers,
>>> Cameron Simpson <cs at cskk.id.au>
>> You might think that, but my Mac, running the latest version of OS-X, Monterey, reports for a "python --version"  that the system default python is still 2.7.10
>>
>> Now, this system is a 2019 Year model, but was built as a upgrade to an older system. so that might be a reason.
>>
>> Since I have been manually installing current Pythons, I don't know if they also have provided a python3 command with something more recent.
>>
>> -- 
>> Richard Damon
>>
>> _______________________________________________
>> Tutor maillist  -  Tutor at python.org
>> To unsubscribe or change subscription options:
>> https://mail.python.org/mailman/listinfo/tutor
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor


-- 
Richard Damon


From bryan.m.obrien at gmail.com  Sat Oct 30 07:10:24 2021
From: bryan.m.obrien at gmail.com (Bryan O'Brien)
Date: Sat, 30 Oct 2021 06:10:24 -0500
Subject: [Tutor] PYTHON INSTALLATION PROBLEM
In-Reply-To: <282ca79a-0b45-2444-0128-b925a7141ab5@Damon-Family.org>
References: <282ca79a-0b45-2444-0128-b925a7141ab5@Damon-Family.org>
Message-ID: <2EA2B90D-7EF1-48D5-AD8C-E6128F67D290@gmail.com>

So /usr/bin precedes your other python installations.   This is expected.   Don't modify /usr/bin/python.  The operating system might depend on its existence.    

Rather, pick one of the paths containing python3, and modify your ~/.zshrc - placing this python3  location before /usr/bin.  

You'll have to restart the terminal (or source ~/.zshrc) for the path changes to take effect.  

FWIW, I've found (on GitHub) the program known as "pyenv" to be invaluable - from a personal perspective.  Might be more than what you need/want, but an excellent python management/installer IMHO. 

> On Oct 30, 2021, at 05:54, Richard Damon <Richard at damon-family.org> wrote:
> 
> ?Actually, it says I only have 1 'python', but multiple 'python3'
> /usr/bin/python symlinks to a version 2.7 off in /System/Library/Frameworks/
> 
> All the versions 3.x only appear as python3 or python3.x
> 
> It could well be that they haven't fully removed python2.7 dependencies from the system (or maybe better, haven't validated that they have) so python means python2 for backwards compatibility.
> 
> 
>> On 10/29/21 11:31 PM, Bryan O'Brien wrote:
>> ?Likely, you have multiple Python executables on your system.
>> This will necessitate modifying your PATH.
>> 
>> In terminal, run:
>> 
>> which -a python <enter>
>> 
>> If multiple python versions exist (this is normal with MacOS), just ensure that the python you want to use is listed first in your path.
>> 
>> grep -i path ~/.zshrc
>> 
>> HTH
>> 
>>>> On Oct 29, 2021, at 22:00, Richard Damon <Richard at damon-family.org> wrote:
>>> 
>>> ?On 10/29/21 8:08 PM, Cameron Simpson wrote:
>>>>> On 29Oct2021 19:51, Richard Damon <Richard at Damon-Family.org> wrote:
>>>>> On the Mac, 'Python Launcher' seems to just configure how python will
>>>>> run programs run under python. Generally from the Dock, you will want
>>>>> to click on the 'IDLE' icon, which launches the Python IDE, which gives
>>>>> and editor to write python programs or load a python script.
>>>>> The other way to run python is from the command line, using a command
>>>>> like python3 myprog.py
>>>> Also, Macs ship with Python. If your MacOS is current, the supplied
>>>> Python should be pretty modern.
>>>> Cheers,
>>>> Cameron Simpson <cs at cskk.id.au>
>>> You might think that, but my Mac, running the latest version of OS-X, Monterey, reports for a "python --version"  that the system default python is still 2.7.10
>>> 
>>> Now, this system is a 2019 Year model, but was built as a upgrade to an older system. so that might be a reason.
>>> 
>>> Since I have been manually installing current Pythons, I don't know if they also have provided a python3 command with something more recent.
>>> 
>>> -- 
>>> Richard Damon
>>> 
>>> _______________________________________________
>>> Tutor maillist  -  Tutor at python.org
>>> To unsubscribe or change subscription options:
>>> https://mail.python.org/mailman/listinfo/tutor
>> _______________________________________________
>> Tutor maillist  -  Tutor at python.org
>> To unsubscribe or change subscription options:
>> https://mail.python.org/mailman/listinfo/tutor
> 
> 
> -- 
> Richard Damon
> 
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

From kaushalshriyan at gmail.com  Sat Oct 30 09:03:46 2021
From: kaushalshriyan at gmail.com (Kaushal Shriyan)
Date: Sat, 30 Oct 2021 18:33:46 +0530
Subject: [Tutor] New to Python Programming Language.
Message-ID: <CAD7Ssm-Sr7GK-D8_YRMbVp3R-E-4oHY0MsZEJmFUE3iLf9zJ3Q@mail.gmail.com>

Hi All,

I am new to Python programming language without any programming experience.

Please guide and suggest me to start learning it. I am very much eager to
learn and will dedicate every day to understand it. I look forward to
hearing from you.

Thanks in advance.

 Best regards,

Kaushal

From Richard at Damon-Family.org  Sat Oct 30 09:14:14 2021
From: Richard at Damon-Family.org (Richard Damon)
Date: Sat, 30 Oct 2021 09:14:14 -0400
Subject: [Tutor] PYTHON INSTALLATION PROBLEM
In-Reply-To: <2EA2B90D-7EF1-48D5-AD8C-E6128F67D290@gmail.com>
References: <282ca79a-0b45-2444-0128-b925a7141ab5@Damon-Family.org>
 <2EA2B90D-7EF1-48D5-AD8C-E6128F67D290@gmail.com>
Message-ID: <441e90ee-6fc5-7a30-8f7e-796d4eeac56f@Damon-Family.org>

I think you are misunderstanding.

'python' only exists in one place, so the path ordering doesn't matter, 
unless I create new symlinks with the name python as an alias for 
python3.x. This might break some system scripts that depend on python 
2.7, so I just live with using the command python3 to run python3 scripts.

The path does need to be kept up to date so the 'right' python 3.x is 
the python3 command, as each directory gives its executable a name like 
python3.10 and adds a python3 symlink to point to it (which allows me to 
use older versions when I need to).

The OP wasn't using the command line to try to run python, but was 
clicking on the app in the task bar under the apps folder. When doing 
that, why you probably really want is IDLE, not just the plain python 
interpreter.


On 10/30/21 7:10 AM, Bryan O'Brien wrote:
> So /usr/bin precedes your other python installations.   This is expected.   Don't modify /usr/bin/python.  The operating system might depend on its existence.
>
> Rather, pick one of the paths containing python3, and modify your ~/.zshrc - placing this python3  location before /usr/bin.
>
> You'll have to restart the terminal (or source ~/.zshrc) for the path changes to take effect.
>
> FWIW, I've found (on GitHub) the program known as "pyenv" to be invaluable - from a personal perspective.  Might be more than what you need/want, but an excellent python management/installer IMHO.
>
>> On Oct 30, 2021, at 05:54, Richard Damon <Richard at damon-family.org> wrote:
>>
>> ?Actually, it says I only have 1 'python', but multiple 'python3'
>> /usr/bin/python symlinks to a version 2.7 off in /System/Library/Frameworks/
>>
>> All the versions 3.x only appear as python3 or python3.x
>>
>> It could well be that they haven't fully removed python2.7 dependencies from the system (or maybe better, haven't validated that they have) so python means python2 for backwards compatibility.
>>
>>
>>> On 10/29/21 11:31 PM, Bryan O'Brien wrote:
>>> ?Likely, you have multiple Python executables on your system.
>>> This will necessitate modifying your PATH.
>>>
>>> In terminal, run:
>>>
>>> which -a python <enter>
>>>
>>> If multiple python versions exist (this is normal with MacOS), just ensure that the python you want to use is listed first in your path.
>>>
>>> grep -i path ~/.zshrc
>>>
>>> HTH
>>>
>>>>> On Oct 29, 2021, at 22:00, Richard Damon <Richard at damon-family.org> wrote:
>>>> ?On 10/29/21 8:08 PM, Cameron Simpson wrote:
>>>>>> On 29Oct2021 19:51, Richard Damon <Richard at Damon-Family.org> wrote:
>>>>>> On the Mac, 'Python Launcher' seems to just configure how python will
>>>>>> run programs run under python. Generally from the Dock, you will want
>>>>>> to click on the 'IDLE' icon, which launches the Python IDE, which gives
>>>>>> and editor to write python programs or load a python script.
>>>>>> The other way to run python is from the command line, using a command
>>>>>> like python3 myprog.py
>>>>> Also, Macs ship with Python. If your MacOS is current, the supplied
>>>>> Python should be pretty modern.
>>>>> Cheers,
>>>>> Cameron Simpson <cs at cskk.id.au>
>>>> You might think that, but my Mac, running the latest version of OS-X, Monterey, reports for a "python --version"  that the system default python is still 2.7.10
>>>>
>>>> Now, this system is a 2019 Year model, but was built as a upgrade to an older system. so that might be a reason.
>>>>
>>>> Since I have been manually installing current Pythons, I don't know if they also have provided a python3 command with something more recent.
>>>>
>>>> -- 
>>>> Richard Damon
>>>>
>>>> _______________________________________________
>>>> Tutor maillist  -  Tutor at python.org
>>>> To unsubscribe or change subscription options:
>>>> https://mail.python.org/mailman/listinfo/tutor
>>> _______________________________________________
>>> Tutor maillist  -  Tutor at python.org
>>> To unsubscribe or change subscription options:
>>> https://mail.python.org/mailman/listinfo/tutor
>>
>> -- 
>> Richard Damon
>>
>> _______________________________________________
>> Tutor maillist  -  Tutor at python.org
>> To unsubscribe or change subscription options:
>> https://mail.python.org/mailman/listinfo/tutor
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor


-- 
Richard Damon


From alan.gauld at yahoo.co.uk  Sat Oct 30 09:16:40 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 30 Oct 2021 14:16:40 +0100
Subject: [Tutor] New to Python Programming Language.
In-Reply-To: <CAD7Ssm-Sr7GK-D8_YRMbVp3R-E-4oHY0MsZEJmFUE3iLf9zJ3Q@mail.gmail.com>
References: <CAD7Ssm-Sr7GK-D8_YRMbVp3R-E-4oHY0MsZEJmFUE3iLf9zJ3Q@mail.gmail.com>
Message-ID: <sljgjs$ici$1@ciao.gmane.io>

On 30/10/2021 14:03, Kaushal Shriyan wrote:
> I am new to Python programming language without any programming experience.
> 

Hello and welcome.

> Please guide and suggest me to start learning it. 

There are many Python tutorials available many of which are aimed at
complete beginners like yourself.
There is a page listing them on the python web site:

https://wiki.python.org/moin/BeginnersGuide/NonProgrammers

It includes my tutorial(see .sig below)  which uses a comparative
approach and emphasises learning general programming techniques
rather that Python specific idioms.

But there are many others all with their own slant. Take a look,
pick one that suits your style of learning.

Do the examples, modify them, see if the changes produce the
results you expect.

If you don't understand anything, or can't get something to
work come back here and ask for help.

Always include your code and any error messages you get.


-- 
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 Oct 30 13:37:52 2021
From: mats at wichmann.us (Mats Wichmann)
Date: Sat, 30 Oct 2021 11:37:52 -0600
Subject: [Tutor] PYTHON INSTALLATION PROBLEM
In-Reply-To: <77E96EB7-7F22-4689-AEFF-C640CC15305B@joserivera.ca>
References: <77E96EB7-7F22-4689-AEFF-C640CC15305B@joserivera.ca>
Message-ID: <8af7f44c-5432-7412-090b-2803efd5cda6@wichmann.us>

On 10/29/21 15:38, Jose Rivera wrote:
> Hello,
> 
> I just downloaded the latest version of python to my Mac book but when I click on the python launcher on my dock is not opening. Have I done something wrong along the process of the installation? Please help. I am a new user and don?t know if I have done the installing properly. Thank you very much
> 

the behavior of that thing isn't entirely intuitive at first glance.

make sure you've read this:  https://docs.python.org/3/using/mac.html

From learn2program at gmail.com  Sat Oct 30 15:00:25 2021
From: learn2program at gmail.com (Alan Gauld)
Date: Sat, 30 Oct 2021 20:00:25 +0100
Subject: [Tutor] OT: Windoze via MacOS - Looking for some Off-list assistance
Message-ID: <739c8988-0fd2-fc28-14ba-44648e7e9e60@yahoo.co.uk>

Apologies for a very tenuously linked request.

It's upgrade time as my current Windoze PC is beginning to struggle.

I only really use it for 3 things:

1) Editing Photos

2) Editing Videos

3) writing books for commercial publication. (Which includes running
Python and C/C++ dev environments - see, there is a link! :-)

That gives me lots of options since all the programs I use for these
things can run on Windows or MacOSX.

So should I just buy a new Windows box? Or migrate to a new
M1 powered Mac mini? The motivation to migrate comes from
getting both my everyday and "media" PCs based on *nix. The
advantage of staying on Windows is that it is still the majority
option for readers of my books.

If anyone has objective experience of **both systems** (no fanboys or
Linux evangelists(*) please!) and is willing to answer a few questions
I have and share experiences off-list I'd appreciate it.

Also if anyone knows a non-partisan forum fr discussing such things
I'd love to know. Most of the ones I've seen advocate vigorously for
one or the other...

(*)Nothing against Linux; it's my main system but opensource apps
just don't come close for serious photo or video work and my
publishers insist on Microsoft tools(and yes, I could use wine,
but not for the other options).

Apologies again for the OT theme.

-- 
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 draculin at s.netic.de  Sat Oct 30 15:59:01 2021
From: draculin at s.netic.de (draculin)
Date: Sat, 30 Oct 2021 21:59:01 +0200
Subject: [Tutor] New to Python Programming Language.
In-Reply-To: <CAD7Ssm-Sr7GK-D8_YRMbVp3R-E-4oHY0MsZEJmFUE3iLf9zJ3Q@mail.gmail.com>
References: <CAD7Ssm-Sr7GK-D8_YRMbVp3R-E-4oHY0MsZEJmFUE3iLf9zJ3Q@mail.gmail.com>
Message-ID: <bd08f20d-d3b3-5651-4992-f06c1d04ca14@s.netic.de>

Hi,
I don't know how much time you'd have and how basic your level is, but 
I'd recommend you the series of Bryan Cairns, which I personally find 
very instructive ;-)
Take a look here:

https://www.youtube.com/watch?v=dVDRyLZXZCs
or here:
https://www.reddit.com/r/learnprogramming/comments/nwrsn6/video_series_learn_python_programming_for/

BR

On 30.10.2021 15:03, Kaushal Shriyan wrote:
> Hi All,
>
> I am new to Python programming language without any programming experience.
>
> Please guide and suggest me to start learning it. I am very much eager to
> learn and will dedicate every day to understand it. I look forward to
> hearing from you.
>
> Thanks in advance.
>
>   Best regards,
>
> Kaushal
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

From sjeik_appie at hotmail.com  Sat Oct 30 16:38:50 2021
From: sjeik_appie at hotmail.com (Albert-Jan Roskam)
Date: Sat, 30 Oct 2021 22:38:50 +0200
Subject: [Tutor] OT: Windoze via MacOS - Looking for some Off-list
 assistance
In-Reply-To: <739c8988-0fd2-fc28-14ba-44648e7e9e60@yahoo.co.uk>
Message-ID: <DB6PR01MB38950387B19467AFC678232483889@DB6PR01MB3895.eurprd01.prod.exchangelabs.com>

   Hi Alan,
   Have you considered running Windows on a VM with MacOS as a host? I used
   Win7 for work on a Debian host eith Virtualbox  for years and it worked
   well (Citrix didn't work well with Linux at that time). Often I also used
   Windows when I wanted to use hardware that had no reliable Linux drivers.
   It performs very well. Windows host + Linux VM performed noticably worse.
   You're right: eg GIMP is nice, but it is sort of Photoshop's cross-eyed
   brother. :-)
   Best wishes,
   Albert-Jan

From PyTutor at DancesWithMice.info  Sat Oct 30 16:43:48 2021
From: PyTutor at DancesWithMice.info (dn)
Date: Sun, 31 Oct 2021 09:43:48 +1300
Subject: [Tutor] New to Python Programming Language.
In-Reply-To: <CAD7Ssm-Sr7GK-D8_YRMbVp3R-E-4oHY0MsZEJmFUE3iLf9zJ3Q@mail.gmail.com>
References: <CAD7Ssm-Sr7GK-D8_YRMbVp3R-E-4oHY0MsZEJmFUE3iLf9zJ3Q@mail.gmail.com>
Message-ID: <19d64268-6d1a-e818-fa83-7448381ebc7f@DancesWithMice.info>

On 31/10/2021 02.03, Kaushal Shriyan wrote:
> Hi All,
> 
> I am new to Python programming language without any programming experience.
> 
> Please guide and suggest me to start learning it. I am very much eager to
> learn and will dedicate every day to understand it. I look forward to
> hearing from you.

Welcome to Python, and to the list!

This is a good question. Many people turn first to 'social networking'
and the likes of informal videos. Like @Alan, I suggest a more
structured approach, so that you can see progress, and learn the basics
without too many 'holes' (gaps in your knowledge).

Additional thoughts:
- books (library or purchase)
- online courses (which can usually be audited for $free, or you can pay
and receive a certificate upon achievement) eg coursera.org, edx.org

Remembering also, that we are 'here' and happy to help you along the way...


Disclaimer: I'm involved in courses (not Python) on the edX platform.
-- 
Regards,
=dn

From mats at wichmann.us  Sat Oct 30 17:58:22 2021
From: mats at wichmann.us (Mats Wichmann)
Date: Sat, 30 Oct 2021 15:58:22 -0600
Subject: [Tutor] New to Python Programming Language.
In-Reply-To: <CAD7Ssm-Sr7GK-D8_YRMbVp3R-E-4oHY0MsZEJmFUE3iLf9zJ3Q@mail.gmail.com>
References: <CAD7Ssm-Sr7GK-D8_YRMbVp3R-E-4oHY0MsZEJmFUE3iLf9zJ3Q@mail.gmail.com>
Message-ID: <2d3af8db-be71-9740-428f-58a8be418fed@wichmann.us>

On 10/30/21 07:03, Kaushal Shriyan wrote:
> Hi All,
> 
> I am new to Python programming language without any programming experience.
> 
> Please guide and suggest me to start learning it. I am very much eager to
> learn and will dedicate every day to understand it. I look forward to
> hearing from you.
> 
> Thanks in advance.
> 
>   Best regards,
> 
> Kaushal

I wanted to add to the other comments, there's now an astonishing amount 
of material on learning Python, free and paid.  The wiki page Alan 
pointed to is volunteer maintained, and can't pretend to be complete as 
a result - feel free to search elsewhere too. To the point where we know 
it's overwhelming to try to make a choice.  Since there is so much, you 
can try out different sources and see which feels like it works well for 
your learning style. If one doesn't, you can switch to a different one. 
The problem for us is there are so many nobody can know close to all of 
them, so it's hard to lean on any one given reviewer ("top five learning 
resources for Python", that kind of thing).




From phillor9 at gmail.com  Sun Oct 31 01:56:53 2021
From: phillor9 at gmail.com (Phil)
Date: Sun, 31 Oct 2021 15:56:53 +1000
Subject: [Tutor] Creating a two dimension set
Message-ID: <9e2be6f5-b825-5291-ff5b-103c74454f97@gmail.com>

As an example, if I wanted to create a two dimension list I would write:

num_rows = 9
num_cols = 9

self.solution = [[None] * num_cols for _ in range(num_rows)]

In my current creation I need a two dimension set and so I have used, 
again for example:

result = set(self.solution[row][col]) - 3

However, my code has grown and I find that I'm making mistakes and it 
would be much simpler if I'd created a two dimension set in the first 
place rather that converting the list to a set every time I need to 
access it.

I could, I suppose, use two for loops to create and initialise the set 
but there must be a simpler and less tedious way.

I have very poor Internet access at the moment and searching for an 
answer hasn't been fruitful due to frequent disconnections. All that 
I've gained is a headache.

-- 

Regards,
Phil


From cs at cskk.id.au  Sun Oct 31 16:08:08 2021
From: cs at cskk.id.au (Cameron Simpson)
Date: Mon, 1 Nov 2021 07:08:08 +1100
Subject: [Tutor] Creating a two dimension set
In-Reply-To: <9e2be6f5-b825-5291-ff5b-103c74454f97@gmail.com>
References: <9e2be6f5-b825-5291-ff5b-103c74454f97@gmail.com>
Message-ID: <YX73qIoLdaN0KfMB@cskk.homeip.net>

On 31Oct2021 15:56, Phil <phillor9 at gmail.com> wrote:
>As an example, if I wanted to create a two dimension list I would write:
>
>num_rows = 9
>num_cols = 9
>
>self.solution = [[None] * num_cols for _ in range(num_rows)]

Keeping in mind that this is a list of lists. Also, you're preallocating 
num_cols*nul_rows of storage. That can be wasteful if you're not filling 
much of it in.

>In my current creation I need a two dimension set and so I have used, 
>again for example:
>
>result = set(self.solution[row][col]) - 3

This line makes no sense to me: you cannot subtract a number from a set.  
And initialising a set requires an iterable - does your list-of-lists 
itself contain lists? The "None" in your first example suggests maybe 
not.

>However, my code has grown and I find that I'm making mistakes and it 
>would be much simpler if I'd created a two dimension set in the first 
>place rather that converting the list to a set every time I need to 
>access it.
>
>I could, I suppose, use two for loops to create and initialise the set 
>but there must be a simpler and less tedious way.

I do not fully understand your use case, partly because your second 
example is not sane Python.

I'm also not sure you mean "set". Can you tell us in more detail what 
you're doing, maybe a very small example programme?

Might I suggest a dict indexed by a 2-tuple of (row,col)?

A dict maps keys to values. If your keys are coordinate pairs you can 
use this mapping like a 2-dimensional array. Example:

    d = {}
    d[1, 2] = 9     # store 9 at (1,2)
    d[3, 5] = 10    # store 10 at (3,5)

There are 2 caveats here:

Dict keys must be static hashable values. ints, float, strings fit this 
bill. So do tuples of such values, eg (1,2).

The other issue is what to do with the coordinates you have not set. For 
example, what happens if you access d[2,2] in the above code? There is 
no (2,2) entry, and a dict will raise a KeyError exception.

You have 2 main approaches to this: a defaultdict (presupplied in the 
standard library) or a dict subclass with a __missing__ method. The 
former will fill in entries as you access them - this is easy and 
convenient and I suggest you use it first. The latter need not fill in 
entries, but is more work to implement.

Using a defaultdict is like this:

    from collections import defaultdict
    .......
    d = defaultdict(int)
    d[1, 2] = 9     # store 9 at (1,2)
    d[3, 5] = 10    # store 10 at (3,5)

This is as before, but accessing an unfilled entry will fill it with the 
result of calling int(), which makes a 0. You can give defaultdict any 
callable which requires not arguments. For example "float", the float 
type, which will return 0.0 from floatz(). Or a small lambda if you want 
"None":

    d = defaultdict(lambda: None)

Cheers,
Cameron Simpson <cs at cskk.id.au>