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: References: 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: <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: <21f94f80-e335-30fa-4fbd-85de063ae02c@yahoo.co.uk> <747a70ce-40b0-f954-2760-5f492f9d24ea@DancesWithMice.info> Message-ID: On Fri, 1 Oct 2021 23:50:07 +1300, dn via Tutor 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, 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: References: <21f94f80-e335-30fa-4fbd-85de063ae02c@yahoo.co.uk> <747a70ce-40b0-f954-2760-5f492f9d24ea@DancesWithMice.info> 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 > 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: <21f94f80-e335-30fa-4fbd-85de063ae02c@yahoo.co.uk> <747a70ce-40b0-f954-2760-5f492f9d24ea@DancesWithMice.info> <208a9207-efbe-9d77-9f4d-2b7599585108@DancesWithMice.info> Message-ID: <62velgdpldbo9j9o0spg2vmq9uv1trmfuu@4ax.com> On Sat, 2 Oct 2021 08:06:20 +1300, dn via Tutor 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 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: 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 > 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: 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: 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: References: Message-ID: 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 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 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 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: 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: 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: 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: 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: Message-ID: <58thlg1vsasjsbnl2oh9n0a5pbi98d5da0@4ax.com> On Sat, 2 Oct 2021 20:48:31 +0200, Julius Hamilton 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: Message-ID: On Sat, 2 Oct 2021 22:22:35 +0200, Julius Hamilton 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: Message-ID: On Sat, 2 Oct 2021 23:27:34 +0200, Julius Hamilton 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: References: 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: References: Message-ID: 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: 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: References: Message-ID: 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: References: Message-ID: 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: References: Message-ID: 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: References: Message-ID: 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: References: Message-ID: 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: Message-ID: On Sun, 3 Oct 2021 13:40:40 +0100, Alan Gauld via Tutor 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 {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: 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: References: Message-ID: 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: 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: References: 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: References: 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: References: Message-ID: 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: 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: References: Message-ID: On Tue, 5 Oct 2021 at 11:14, Manprit Singh 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: References: 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 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: References: Message-ID: 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 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: References: Message-ID: 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 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: References: Message-ID: 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: Message-ID: <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com> On Tue, 5 Oct 2021 07:22:24 +0530, Manprit Singh 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: <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com> Message-ID: On 06/10/2021 07.39, Dennis Lee Bieber wrote: > On Tue, 5 Oct 2021 07:22:24 +0530, Manprit Singh > 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: <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com> Message-ID: 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: References: <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com> 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: <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com> <2a6795d3-bca8-ee38-5b0f-ae1e9510a6cc@DancesWithMice.info> Message-ID: 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: <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com> Message-ID: On Wed, 6 Oct 2021 08:08:56 +1300, dn via Tutor 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: <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com> Message-ID: 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 wrote: > On Tue, 5 Oct 2021 07:22:24 +0530, Manprit Singh > 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: <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com> Message-ID: 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 wrote: > On Tue, 5 Oct 2021 07:22:24 +0530, Manprit Singh > 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: References: <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com> Message-ID: 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: 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: <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com> Message-ID: On Wed, 6 Oct 2021 16:34:43 +0530, Manprit Singh 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 ). . -- 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: References: <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com> Message-ID: 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, wrote: > On Wed, 6 Oct 2021 16:34:43 +0530, Manprit Singh > 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 ). > . > > > -- > 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: References: <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com> Message-ID: 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 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: References: <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com> Message-ID: 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: <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com> Message-ID: <86bslgde9v3dc5abfu8jjcdh615o50k5bv@4ax.com> On Thu, 7 Oct 2021 03:53:11 +0530, Manprit Singh 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: <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com> <86bslgde9v3dc5abfu8jjcdh615o50k5bv@4ax.com> Message-ID: 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 wrote: > On Thu, 7 Oct 2021 03:53:11 +0530, Manprit Singh > 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: References: <790plg9076329aepsm7bv64iv1fb0rr4lq@4ax.com> <86bslgde9v3dc5abfu8jjcdh615o50k5bv@4ax.com> Message-ID: 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: 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: References: Message-ID: 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: References: 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: References: 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: References: <1473cc08-e6ef-26c9-b521-812d1e3b8ba5@yahoo.co.uk> 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: 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: Message-ID: <5mc4mghk9320f90kco4fs3bsccuk4h5ml6@4ax.com> On Sat, 9 Oct 2021 23:58:34 +0200, Julius Hamilton 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: <1473cc08-e6ef-26c9-b521-812d1e3b8ba5@yahoo.co.uk> <0bbf726e-84ba-3962-b1cc-bc1631cc8fa0@yahoo.co.uk> Message-ID: 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 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: References: <1473cc08-e6ef-26c9-b521-812d1e3b8ba5@yahoo.co.uk> <0bbf726e-84ba-3962-b1cc-bc1631cc8fa0@yahoo.co.uk> Message-ID: 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 2. The user 3. The program responds by 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: 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: 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: Message-ID: 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: References: Message-ID: On Tue, 12 Oct 2021 at 10:34, Albert-Jan Roskam 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: On 12 Oct 2021 11:38, Albert-Jan Roskam wrote: On 12 Oct 2021 11:18, Sarfraaz Ahmed 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: References: Message-ID: Please see my reply inline. On Tue, Oct 12, 2021 at 3:25 PM Albert-Jan Roskam wrote: > On 12 Oct 2021 11:38, Albert-Jan Roskam > wrote: > > On 12 Oct 2021 11:18, Sarfraaz Ahmed 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: Message-ID: On Tue, 12 Oct 2021 08:13:09 +0530, Manprit Singh 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: 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: References: Message-ID: 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 wrote: > On Tue, 12 Oct 2021 08:13:09 +0530, Manprit Singh > 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: References: Message-ID: 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: References: 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: <502d6c5c-51bb-6054-bb96-5e98326e8fd4@gmail.com> Message-ID: 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: <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: 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: References: Message-ID: 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: References: Message-ID: 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: References: 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: Message-ID: On Fri, 15 Oct 2021 12:43:04 +0100, Alan Gauld via Tutor 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: References: 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: 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*)? 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: References: Message-ID: 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: 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: References: <255a6e9f-36e9-500e-0ef9-b89c8179a418@web.de> Message-ID: 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: References: Message-ID: On 16Oct2021 08:58, Alan Gauld 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 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: Message-ID: 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: 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: References: Message-ID: Although increment in evencount can be done in else clause On Sat, 16 Oct, 2021, 22:25 Manprit Singh, 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: Message-ID: On Fri, 15 Oct 2021 21:42:56 +0200, Julius Hamilton 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". 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: Message-ID: <796mmgtv7ef609k33h4oa22satgk78bi8l@4ax.com> On Sat, 16 Oct 2021 22:25:02 +0530, Manprit Singh 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: References: 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: References: Message-ID: 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: 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: 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: References: Message-ID: 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 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: References: Message-ID: 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: References: Message-ID: 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: References: Message-ID: 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 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: References: Message-ID: 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: References: 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: References: Message-ID: On Sun, Oct 17, 2021, 9:04 AM 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 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: References: Message-ID: 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 wrote: > On Fri, 15 Oct 2021 21:42:56 +0200, Julius Hamilton > 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". > > > > 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: References: Message-ID: 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: References: Message-ID: 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: References: Message-ID: On 18Oct2021 00:09, Alan Gauld 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 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: References: Message-ID: On 17Oct2021 17:40, Julius Hamilton 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 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: 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: References: Message-ID: 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: 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: References: Message-ID: 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: 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) in ----> 1 gFactor(x,y) 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: References: Message-ID: On 20Oct2021 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 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 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: References: Message-ID: 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: References: Message-ID: 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, 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: References: Message-ID: 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 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: 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: References: Message-ID: 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: References: Message-ID: 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: References: Message-ID: 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) > in > ----> 1 gFactor(x,y) > > 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: References: 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 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: 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: On Wed, 20 Oct 2021 18:35:19 -0400, Vanshika Sadhwani 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: > 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: 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: 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: References: Message-ID: 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> Message-ID: o/~ Talking to myself in public o/~ On Thu, 21 Oct 2021 13:16:23 -0400, Dennis Lee Bieber declaimed the following: >On Wed, 20 Oct 2021 18:35:19 -0400, Vanshika Sadhwani >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: References: Message-ID: 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
 section or a 
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: Message-ID: <5eu5ng9m7161j2o048nb8ic5fuaiqbmr8c@4ax.com> On Fri, 22 Oct 2021 16:58:21 +0200, Julius Hamilton 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: Message-ID: On Fri, 22 Oct 2021 18:06:24 +0200, Julius Hamilton 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

This is some text
broken up by hard coded
breaks

I suspect anything that tries to extract "text" is going to have line breaks at the
locations. Even worse would be...

This is some text

broken up by hard coded

paragraph tags

Something like

This is some text broken up by simple new-lines

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

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: References: Message-ID: On 22Oct2021 16:58, Julius Hamilton 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 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: 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: References: Message-ID: 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... 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. 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: References: Message-ID: 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: 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: References: Message-ID: 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: 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: 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: References: Message-ID: 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: 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: On 29Oct2021 19:51, Richard Damon 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 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: References: <8a1a66b6-5630-0dd4-debe-a460f039c7cb@Damon-Family.org> 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 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 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: On 29Oct2021 22:59, Richard Damon 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 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: You need to go to the app installer... ANANDA K. MURTHY On Fri, Oct 29, 2021 at 7:35 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 > > [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: ?Likely, you have multiple Python executables on your system. This will necessitate modifying your PATH. In terminal, run: which -a python 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 wrote: > > ?On 10/29/21 8:08 PM, Cameron Simpson wrote: >>> On 29Oct2021 19:51, Richard Damon 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 > > 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: References: 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 > > 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 wrote: >> >> ?On 10/29/21 8:08 PM, Cameron Simpson wrote: >>>> On 29Oct2021 19:51, Richard Damon 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 >> 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 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 >> >> 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 wrote: >>> >>> ?On 10/29/21 8:08 PM, Cameron Simpson wrote: >>>>> On 29Oct2021 19:51, Richard Damon 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 >>> 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: 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 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 >>> >>> 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 wrote: >>>> ?On 10/29/21 8:08 PM, Cameron Simpson wrote: >>>>>> On 29Oct2021 19:51, Richard Damon 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 >>>> 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: References: Message-ID: 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: References: Message-ID: 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: 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: References: 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: References: 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: On 31Oct2021 15:56, Phil 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