Re: Friday Finking: Contorted loops
On 09/09/2021 22:36, dn via Python-list wrote: > Even in fairly modest Python constructs, we quickly repeal the one-in, > one-out philosophy because try...except operates by providing another > exit-path. Exceptions are exceptional by their nature (or should be!) As such they can arguably be excused from the SP strictures. But python complicates this tenet still further by adding an else clause to its loops. And complicating this still more is that these else clauses have almost exactly opposite effects. while...else... executes the else if the body of the loop does NOT get executed. for...else... executes the else iff ALL iterations of the for loop DO complete. This confuses beginners immensely - and quite a few non beginners too; which is probably why they are not often seen "in the wild". This adds to the question of where exactly does a Python loop end? Is it after the code-suite following the loop construct? Or is it after the else code-suite, where such exists? Returning to the specific case of a repeat structure. In the case of a while loop the else offers another option: while condition loop-body else loop-body Now loop-body always gets executed at least once. But at the cost of duplicating the loop-body code, thus violating DRY. Just another thought... -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos -- https://mail.python.org/mailman/listinfo/python-list
Re: Friday Finking: Contorted loops
On 10/09/21 11:47 am, Terry Reedy wrote: 2. It is rare useful. For loops are common. While loops are occasional (nearly an order of magnitude less common than for loops. Fractional loop constructs are rare. I would say that fractional loops are more common than loops which truly need to execute completely at least once, and aren't bugs waiting to be triggered by an edge case such as empty input. I seem to remember someone - maybe Wirth? - long ago expressing the opinion that repeat-until loops often tended to be error prone, but I can't provide a reference, sorry. -- Greg -- https://mail.python.org/mailman/listinfo/python-list
Re: Change the display style of the text on the STACKLINE.
On 10/09/21 6:11 pm, Roland Mueller wrote: When I call print(s) it even shows ABCD and D is underscored. But copying the output to mail looses the underscore ... If the terminal understands unicode, Combining Low Line: U+0332 might help -- Greg -- https://mail.python.org/mailman/listinfo/python-list
Re: Making command-line args available to deeply-nested functions
George Fischhof writes: > George Fischhof ezt írta (időpont: 2021. aug. 29., V, > 21:27): > >> >> >> Loris Bennett ezt írta (időpont: 2021. aug. >> 26., Cs, 16:02): >> >>> George Fischhof writes: >>> >>> [snip (79 lines)] >>> >>> >> > Hi, >>> >> > >>> >> > Also you can give a try to click and / or typer packages. >>> >> > Putting args into environment variables can be a solution too >>> >> > All of these depends on several things: personal preferences, >>> colleagues >>> >> / >>> >> > firm standards, the program, readability, variable accessibility (IDE >>> >> > support, auto completition) (env vars not supported by IDEs as they >>> are >>> >> not >>> >> > part of code) >>> >> >>> >> Thanks for the pointers, although I have only just got my head around >>> >> argparse/configargparse, so click is something I might have a look at >>> >> for future project. >>> >> >>> >> However, the question of how to parse the arguments is somewhat >>> separate >>> >> from that of how to pass (or not pass) the arguments around within a >>> >> program. >>> >>> [snip (16 lines)] >>> > >>> > Hi, >>> > I thought not just parsing, but the usage method: you add a decorator to >>> > the function where you want to use the parameters. This way you do not >>> have >>> > to pass the value through the calling hierarchy. >>> > >>> > Note: typer is a newer package, it contains click and leverages command >>> > line parsing even more. >>> >>> Do you have an example of how this is done? From a cursory reading of >>> the documentation, it didn't seem obvious to me how to do this, but then >>> I don't have much understanding of how decorators work. >>> >>> Cheers, >>> >>> Loris >>> >>> >>> -- >>> This signature is currently under construction. >>> -- >>> https://mail.python.org/mailman/listinfo/python-list >> >> >> Hi, >> >> will create a sample code on Monday - Tuesday >> >> BR, >> George >> > > > Hi, > > here is the program ;-) (see below) > typer does not uses decorators, to solve this problem they advice to use > click's decorators, mixing typer and click. > Practically I prefer not to mix them, also the parts for easiest way to do > this just available in latest click, which is not supported in typer. > > So I created all the stuff in click, 8.x should be used > > BR, > George > > > import click > > > # read command line parameters > @click.command() > @click.option('--level_1', help='Level 1') > @click.option('--level_2', help='Level 2') > def main(level_1, level_2): > # put command line parameters into global context > ctx = click.get_current_context() > ctx.meta['level_1'] = level_1 > ctx.meta['level_2'] = level_2 > > level_1_function() > > > # pass / inject level_1 parameter to this function > @click.decorators.pass_meta_key('level_1') > def level_1_function(level_1): > print(f'level 1 variable: {level_1}') > level_2_function() > > > # pass / inject level_2 parameter to this function > @click.decorators.pass_meta_key('level_2') > def level_2_function(level_2): > print(f'level 2 variable: {level_2}') > > > if __name__ == "__main__": > main() Thanks for the example - that's very interesting. However, after a bit of reflection I think I am going to stick to explicit argument passing, so that I can have more generic modules that can be used by other programs. I'll then just encapsulate the argument parsing in a single function corresponding to the command line tool. Cheers, Loris -- This signature is currently under construction. -- https://mail.python.org/mailman/listinfo/python-list
Re: Friday Finking: Contorted loops
On 10/09/2021 00:47, Terry Reedy wrote: > even one loop is guaranteed.) "do-while" or "repeat-until is even rarer > since fractional-loop include this as a special case. Is there any empirical evidence to support this? Or is it just a case of using the tools that are available? In my experience of using Pascal (and much later with Delphi) that I used repeat loops at least as often as while loops, possibly more. But using Python and to a lesser extent C (which has a rather horrible do/while) construct I use while loops (often with an if-break) simply because that's what the language offers. So is it the case that the "need" for repeat loops is rare, simply a result of there being no native repeat loop available? After all we could have done without a for loop too and just used a while loop for everything (as was done in Oberon(?) ) Would we then state that the use of for loops was rare? But I would hope that any empirical research would look at the wider function of the loop and its purpose rather than merely analyzing the syntax and keywords. -- 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 -- https://mail.python.org/mailman/listinfo/python-list
Re: Friday Finking: Contorted loops
On 2021-09-10 12:38, Alan Gauld via Python-list wrote: On 09/09/2021 22:36, dn via Python-list wrote: Even in fairly modest Python constructs, we quickly repeal the one-in, one-out philosophy because try...except operates by providing another exit-path. Exceptions are exceptional by their nature (or should be!) As such they can arguably be excused from the SP strictures. But python complicates this tenet still further by adding an else clause to its loops. And complicating this still more is that these else clauses have almost exactly opposite effects. while...else... executes the else if the body of the loop does NOT get executed. for...else... executes the else iff ALL iterations of the for loop DO complete. [snip] In both cases, it executes the 'else' part if it didn't break out of the loop. That's it. If all of the iterations completed, then there was no break, so the 'else' part is executed. If there were no iterations, then there was no break, so the 'else' part is executed. It's the same for both of them. -- https://mail.python.org/mailman/listinfo/python-list
Re: Friday Finking: Contorted loops
On 10/09/2021 16:36, MRAB wrote: >> while...else... >> >> executes the else if the body of the loop does NOT get executed. >> >> for...else... >> >> executes the else iff ALL iterations of the for loop DO complete. >> > [snip] > > In both cases, it executes the 'else' part if it didn't break out of the > loop. That's it. OK, That's a useful perspective that is at least consistent. Unfortunately it's not how beginners perceive it and it causes regular confusion about how/when they should use else with a loop. -- 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 -- https://mail.python.org/mailman/listinfo/python-list
Re: Change the display style of the text on the STACKLINE.
pe 10. syysk. 2021 klo 17.22 Greg Ewing (greg.ew...@canterbury.ac.nz) kirjoitti: > On 10/09/21 6:11 pm, Roland Mueller wrote: > > When I call print(s) it even shows ABCD and D is underscored. But > copying > > the output to mail looses the underscore ... > > If the terminal understands unicode, Combining Low Line: U+0332 > might help > > > The problem was to get the string to this mail. In my terminal it was OK. -- https://mail.python.org/mailman/listinfo/python-list
Re: Friday Finking: Contorted loops
r...@zedat.fu-berlin.de (Stefan Ram) writes: > r...@zedat.fu-berlin.de (Stefan Ram) writes: >>can be misleading, because the "..." part can still contain >>"break", "raise", "continue", and "return" statement. So one >>better should always be on the watch when reading source code >>of a language like Python than relying only on the condition >>behind the "while". > > The existence of statements like "break" renders > proof techniques for loops (such as Hoare's) with > their invariants and inference rules unapplicable. Also the reason to avoid repeat-until loops: the loop "invariant" isn't the same on the first iteration as on subsequent iterations. -- https://mail.python.org/mailman/listinfo/python-list
RE: Friday Finking: Contorted loops
So why use the word "else" when it really does not mean what users consider else? Again, we have words like "finally" used in some places to mean it should be done no matter what, like closing a file that may be open. What phrase used either in one or all contexts might have been better, if longer? I mean in the case where your while is NOT entered, "else" almost makes sense. But it could also have been loop_skipped or something. In other cases, it could be some name like "loop_completed_normally" or whatever. Reusing the keyword "else" over and over for "if" statements and perhaps some kind of case/switch statement and while loops and so on, may be parsimonious but ... -Original Message- From: Python-list On Behalf Of Alan Gauld via Python-list Sent: Friday, September 10, 2021 11:58 AM To: python-list@python.org Subject: Re: Friday Finking: Contorted loops On 10/09/2021 16:36, MRAB wrote: >> while...else... >> >> executes the else if the body of the loop does NOT get executed. >> >> for...else... >> >> executes the else iff ALL iterations of the for loop DO complete. >> > [snip] > > In both cases, it executes the 'else' part if it didn't break out of > the loop. That's it. OK, That's a useful perspective that is at least consistent. Unfortunately it's not how beginners perceive it and it causes regular confusion about how/when they should use else with a loop. -- 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 -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
RE: Friday Finking: Contorted loops
In this discussion, I shudder to mention that people often simply use all kinds of additional logic to get a result. How much code have you seen that has some variable like "completed = False" that can be set to True in multiple places and many areas inside the loop are enclosed in an IF statement that only executes when completed remains False. So there is one clean exit in the sense that even when only half a loop has been done, it continues to the end of the loop and leaves before the next iteration. True, there is no break or return from the middle of the loop but logically there is if not for the convoluted code to avoid it. Similarly, can most "while" loops that you want to be "until" loops not be made with a bit of code? I mean set first_time to True before starting. Set your while condition to while first_time OR condition or some other such logic. That guarantees you go into the loop even when condition is False. Within the loop, negate first_time. Does that look more like a simulated repeat until, with extra overhead? As I see it, there are many viewpoints here. From a programming perspective, it is nice to be able to state the overall shape of what you are doing in an upfront-way and also something others can read. Some things like the C-style for loop provide a bit of this but in a way I think outsiders may stare at as in for (initialize; compare-condition; iterate-change) { ... } That is sort of compact but I have seen it get quite complex. If designed for readers, it might be designed a bit like what we do with keywords in functions headers where you might specify the "names" of each such section to make it clearer, and not just positional. But some forms of loops like do {...} until ... Make you have to scan forward to see what makes them end. That is not necessarily bad as you may need to read the code to see how it sets up the variables controlling the exit condition. But if you want a wide open setup, where the conditions for the loop being entered can be specified, then the condition for it to be repeated (if different) can be specified and the condition at the end that makes you exit without trying the condition on top, you can go nuts. As mentioned, some languages have else clauses or finally clauses and error handling with things like try() or some kind of on.exit() can cause weird things. Some languages may even want you to be able to test some condition automatically after every single statement and exit immediately. Even if you disagree with the idea of picking a few constructs that are commonly used or encouraged, you may want to consider what happens when you make a language so bloated that compiling or interpreting it becomes a big challenge and it has too many keywords. When it comes to other perspectives like having algorithms able to evaluate a program and prove it has no bugs, you may end up with a very restricted programming language and still fail. Throw in the reality that your loop may use variable manipulated in parallel by other threads and that your thread may be killed as it runs and I wonder. -Original Message- From: Python-list On Behalf Of Greg Ewing Sent: Friday, September 10, 2021 2:40 AM To: python-list@python.org Subject: Re: Friday Finking: Contorted loops On 10/09/21 11:47 am, Terry Reedy wrote: > 2. It is rare useful. For loops are common. While loops are > occasional (nearly an order of magnitude less common than for loops. > Fractional loop constructs are rare. I would say that fractional loops are more common than loops which truly need to execute completely at least once, and aren't bugs waiting to be triggered by an edge case such as empty input. I seem to remember someone - maybe Wirth? - long ago expressing the opinion that repeat-until loops often tended to be error prone, but I can't provide a reference, sorry. -- Greg -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
leave
Sent with [ProtonMail](https://protonmail.com/) Secure Email. -- https://mail.python.org/mailman/listinfo/python-list
Re: Friday Finking: Contorted loops
On 2021-09-10 at 15:08:19 -0600, Joe Pfeiffer wrote: > r...@zedat.fu-berlin.de (Stefan Ram) writes: > > The existence of statements like "break" renders > > proof techniques for loops (such as Hoare's) with > > their invariants and inference rules unapplicable. > > Also the reason to avoid repeat-until loops: the loop "invariant" isn't > the same on the first iteration as on subsequent iterations. I am by no means an expert, nor likely even a neophyte, but why would the loop invariant not be the same on the first iteration? I can certainly see that the exit condition may not make sense at the beginning of the first iteration (e.g., there is not yet any data to compare to the sentinel), but ISTM that claiming that the exit condition is a loop invariant isn't kosher (because all you're claiming is that the compiler works). I can also see that certain state information may not be captured until the end of the first iteration. But presumably said state information can change from iteration to iteration, so I can't see how you'd derive an invariant involving it. -- https://mail.python.org/mailman/listinfo/python-list
Re: Change the display style of the text on the STACKLINE.
On Friday, September 10, 2021 at 2:12:31 PM UTC+8, Roland Mueller wrote: > pe 10. syysk. 2021 klo 8.53 hongy...@gmail.com (hongy...@gmail.com) > kirjoitti: > > On Thursday, September 9, 2021 at 8:57:37 PM UTC+8, Roland Mueller wrote: > > > Hello > > > > > > to 9. syysk. 2021 klo 6.53 hongy...@gmail.com (hongy...@gmail.com) > > > kirjoitti: > > > > I'm using the following code in my forked project [1]: > > > > > > > > percol.view.STACKLINE = 'Fold:F1,F2,F3 Push:C-p Pop:M-p Script:M-s > > Dir:M-d > > > > Dircmd:M-b' > > > > > > > > I would like to change the display style of the text mentioned above, > > for > > > > example, to underline some characters in it, as shown below: > > > > > > > > _D_ir:M-d > > > > > > > > > > > You can use e.g. str.replace() or re.sub() > > > > > > >>> percol.view.STACKLINE = percol.view.STACKLINE.replace('D', '_D_') > > > Result: 'Fold:F1,F2,F3 Push:C-p Pop:M-p Script:M-s _D_ir:M-d > > _D_ircmd:M-b' > > > > > > >>> import re > > > > > > Replace D with _D_ > > > >>> percol.view.STACKLINE = re.sub(r'([D])', > > > r'_\1_', percol.view.STACKLINE) > > > Result: 'Fold:F1,F2,F3 Push:C-p Pop:M-p Script:M-s _D_ir:M-d > > _D_ircmd:M-b' > > > > > > Replace D and M with _D_, _M_ > > > >>> percol.view.STACKLINE = re.sub(r'([DM])', r'_\1_', > > > percol.view.STACKLINE) > > > 'Fold:F1,F2,F3 Push:C-p Pop:_M_-p Script:_M_-s _D_ir:_M_-d > > _D_ircmd:_M_-b' > > > > > > Regards, > > > Roland > > > > I tried with the following, but failed to achieve the expected effect: > > > > class Term: > > HEADER = '\033[95m' > > OKBLUE = '\033[94m' > > OKGREEN = '\033[92m' > > WARNING = '\033[93m' > > FAIL = '\033[91m' > > ENDC = '\033[0m' > > LIGHTCYAN = '\033[1;36m' > > LIGHTGRAY = '\033[0;37m' > > YELLOW = '\033[0;33m' > > BOLD = '\033[1m' > > UNDERLINE = '\033[4m' > > > > [...] > > > > percol.view.STACKLINE = percol.view.STACKLINE.replace('D', Term.UNDERLINE > > + 'D' + Term.ENDC) > > > > The result will look like this: > > > > Fold:F1,F2,F3 Push:C-p Pop:M-p Script:M-s ?[4mD?[0mir:M-d > > ?[4mD?[0mircmd:M-b > > > > I cannot repeat that. Are you sure that the '?' shown in your output are > not due to your terminal settings that influence how strings printed by > Python or inside used terminal are shown? > > Python 3.9.6 (default, Jul 16 2021, 00:00:00) > [GCC 11.1.1 20210531 (Red Hat 11.1.1-3)] on linux > Type "help", "copyright", "credits" or "license" for more information. > >>> UL = '\033[4m' > >>> UL > '\x1b[4m' > >>> ENDC = '\033[0m' > >>> ENDC > '\x1b[0m' > > >>> s = UL + 'D' + ENDC > >>> s > '\x1b[4mD\x1b[0m' > > >>> s = 'ABCDE' > >>> s = s.replace('D', UL + 'D' + ENDC) > >>> s > 'ABC\x1b[4mD\x1b[0mE' > > When I call print(s) it even shows ABCD and D is underscored. If I test the code snippet above with ipython/ptpython/python, I got the same result as you described. But the problem I reported here is triggered by running the command line wrapper of the project by `Ctrl-r`, which is worked with curses library. And I also noticed the following file [1] used by the project, which may be pertinent to the problem discussed here. But till now I still can't think of a solution. [1] https://github.com/hongyi-zhao/ariadne/blob/master/percol/ansi.py > But copying > the output to mail looses the underscore ... > [image: image.png] > > BR, > Roland > > Regards, > > HY > > > > > > > > > > > > How to achieve this purpose? > > > > > > > > [1] > > > > > > https://github.com/hongyi-zhao/ariadne/blob/838179bb4275ac85f5342d9e7d086d6ade3be1de/rc.py#L55 > > > > > > > > > > Regards, > > > > HY > > > > -- > > > > https://mail.python.org/mailman/listinfo/python-list > > > > > > -- > > https://mail.python.org/mailman/listinfo/python-list > > -- https://mail.python.org/mailman/listinfo/python-list
Re: Change the display style of the text on the STACKLINE.
On Saturday, September 11, 2021 at 7:43:44 AM UTC+8, hongy...@gmail.com wrote: > On Friday, September 10, 2021 at 2:12:31 PM UTC+8, Roland Mueller wrote: > > pe 10. syysk. 2021 klo 8.53 hongy...@gmail.com (hongy...@gmail.com) > > kirjoitti: > > > On Thursday, September 9, 2021 at 8:57:37 PM UTC+8, Roland Mueller wrote: > > > > Hello > > > > > > > > to 9. syysk. 2021 klo 6.53 hongy...@gmail.com (hongy...@gmail.com) > > > > kirjoitti: > > > > > I'm using the following code in my forked project [1]: > > > > > > > > > > percol.view.STACKLINE = 'Fold:F1,F2,F3 Push:C-p Pop:M-p Script:M-s > > > Dir:M-d > > > > > Dircmd:M-b' > > > > > > > > > > I would like to change the display style of the text mentioned above, > > > for > > > > > example, to underline some characters in it, as shown below: > > > > > > > > > > _D_ir:M-d > > > > > > > > > > > > > > You can use e.g. str.replace() or re.sub() > > > > > > > > >>> percol.view.STACKLINE = percol.view.STACKLINE.replace('D', '_D_') > > > > Result: 'Fold:F1,F2,F3 Push:C-p Pop:M-p Script:M-s _D_ir:M-d > > > _D_ircmd:M-b' > > > > > > > > >>> import re > > > > > > > > Replace D with _D_ > > > > >>> percol.view.STACKLINE = re.sub(r'([D])', > > > > r'_\1_', percol.view.STACKLINE) > > > > Result: 'Fold:F1,F2,F3 Push:C-p Pop:M-p Script:M-s _D_ir:M-d > > > _D_ircmd:M-b' > > > > > > > > Replace D and M with _D_, _M_ > > > > >>> percol.view.STACKLINE = re.sub(r'([DM])', r'_\1_', > > > > percol.view.STACKLINE) > > > > 'Fold:F1,F2,F3 Push:C-p Pop:_M_-p Script:_M_-s _D_ir:_M_-d > > > _D_ircmd:_M_-b' > > > > > > > > Regards, > > > > Roland > > > > > > I tried with the following, but failed to achieve the expected effect: > > > > > > class Term: > > > HEADER = '\033[95m' > > > OKBLUE = '\033[94m' > > > OKGREEN = '\033[92m' > > > WARNING = '\033[93m' > > > FAIL = '\033[91m' > > > ENDC = '\033[0m' > > > LIGHTCYAN = '\033[1;36m' > > > LIGHTGRAY = '\033[0;37m' > > > YELLOW = '\033[0;33m' > > > BOLD = '\033[1m' > > > UNDERLINE = '\033[4m' > > > > > > [...] > > > > > > percol.view.STACKLINE = percol.view.STACKLINE.replace('D', Term.UNDERLINE > > > + 'D' + Term.ENDC) > > > > > > The result will look like this: > > > > > > Fold:F1,F2,F3 Push:C-p Pop:M-p Script:M-s ?[4mD?[0mir:M-d > > > ?[4mD?[0mircmd:M-b > > > > > > I cannot repeat that. Are you sure that the '?' shown in your output are > > not due to your terminal settings that influence how strings printed by > > Python or inside used terminal are shown? > > > > Python 3.9.6 (default, Jul 16 2021, 00:00:00) > > [GCC 11.1.1 20210531 (Red Hat 11.1.1-3)] on linux > > Type "help", "copyright", "credits" or "license" for more information. > > >>> UL = '\033[4m' > > >>> UL > > '\x1b[4m' > > >>> ENDC = '\033[0m' > > >>> ENDC > > '\x1b[0m' > > > > >>> s = UL + 'D' + ENDC > > >>> s > > '\x1b[4mD\x1b[0m' > > > > >>> s = 'ABCDE' > > >>> s = s.replace('D', UL + 'D' + ENDC) > > >>> s > > 'ABC\x1b[4mD\x1b[0mE' > > > > When I call print(s) it even shows ABCD and D is underscored. > If I test the code snippet above with ipython/ptpython/python, I got the same > result as you described. But the problem I reported here is triggered by > running the command line wrapper of the project by `Ctrl-r`, which is worked > with curses library. And I also noticed the following file [1] used by the > project, which may be pertinent to the problem discussed here. > But till now I still can't think of a solution. > > [1] https://github.com/hongyi-zhao/ariadne/blob/master/percol/ansi.py And refer to the following file used in the project: https://github.com/hongyi-zhao/ariadne/blob/master/percol/display.py Regards, HY -- https://mail.python.org/mailman/listinfo/python-list
Re: Friday Finking: Contorted loops
On 9/10/2021 7:38 AM, Alan Gauld via Python-list wrote: But python complicates this tenet still further by adding an else clause to its loops. And complicating this still more is that these else clauses have almost exactly opposite effects. To the contrary... if...else executes the else part if the condition is false. while...else... executes the else if the body of the loop does NOT get executed. IE, executes the else part if the condition is false. A while statement is, or can be viewed as, an if statement with a goto ending the if part. for...else... executes the else iff ALL iterations of the for loop DO complete. IE, executes the else part of the condition is false. A for loop is, or can be viewed as syntactic sugar for a while loop. The condition is that next(iterable) yields a value. It is possible that the doc could be improved. I have not looked for a while. Or maybe it needs to be read more. -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
Re: Friday Finking: Contorted loops
2qdxy4rzwzuui...@potatochowder.com writes: > On 2021-09-10 at 15:08:19 -0600, > Joe Pfeiffer wrote: > >> r...@zedat.fu-berlin.de (Stefan Ram) writes: > >> > The existence of statements like "break" renders >> > proof techniques for loops (such as Hoare's) with >> > their invariants and inference rules unapplicable. >> >> Also the reason to avoid repeat-until loops: the loop "invariant" isn't >> the same on the first iteration as on subsequent iterations. > > I am by no means an expert, nor likely even a neophyte, but why would > the loop invariant not be the same on the first iteration? > > I can certainly see that the exit condition may not make sense at the > beginning of the first iteration (e.g., there is not yet any data to > compare to the sentinel), but ISTM that claiming that the exit condition > is a loop invariant isn't kosher (because all you're claiming is that > the compiler works). Precisely because you've got knowledge of the exit condition on iterations after the first, but not the first one. So, unlike a while loop, you don't have the same knowledge on every pass. > I can also see that certain state information may not be captured until > the end of the first iteration. But presumably said state information > can change from iteration to iteration, so I can't see how you'd derive > an invariant involving it. -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 31/08/2021 01.50, Chris Angelico wrote: > On Mon, Aug 30, 2021 at 11:13 PM David Raymond > wrote: >> >>> def how_many_times(): >>> x, y = 0, 1 >>> c = 0 >>> while x != y: >>> c = c + 1 >>> x, y = roll() >>> return c, (x, y) >> >> Since I haven't seen it used in answers yet, here's another option using our >> new walrus operator >> >> def how_many_times(): >> roll_count = 1 >> while (rolls := roll())[0] != rolls[1]: >> roll_count += 1 >> return (roll_count, rolls) >> > > Since we're creating solutions that use features in completely > unnecessary ways, here's a version that uses collections.Counter: > > def how_many_times(): > return next((count, rolls) for count, rolls in > enumerate(iter(roll, None)) if len(Counter(rolls)) == 1) > > Do I get bonus points for it being a one-liner that doesn't fit in > eighty characters? Herewith my claim to one-liner fame (assuming such leads in any way to virtue or fame) It retains @Peter's preference for a more re-usable roll_die() which returns a single event, cf the OP's roll() which returns two results). import itertools, random def roll_die(): while True: yield random.randrange(1, 7) def how_many_times(): return list( itertools.takewhile( lambda r:r[ 0 ] != r[ 1 ], zip( roll_die(), roll_die() ) ) ) Also, a claim for 'bonus points' because the one-liner will fit within 80-characters - if only I didn't have that pernicious and vile habit of coding a more readable layout. It doesn't use a two-arg iter, but still rates because it does use a relatively-obscure member of the itertools library... https://docs.python.org/3.8/library/itertools.html#itertools.takewhile -- Regards, =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On Sat, Sep 11, 2021 at 3:26 PM dn via Python-list wrote: > > On 31/08/2021 01.50, Chris Angelico wrote: > > On Mon, Aug 30, 2021 at 11:13 PM David Raymond > > wrote: > >> > >>> def how_many_times(): > >>> x, y = 0, 1 > >>> c = 0 > >>> while x != y: > >>> c = c + 1 > >>> x, y = roll() > >>> return c, (x, y) > >> > >> Since I haven't seen it used in answers yet, here's another option using > >> our new walrus operator > >> > >> def how_many_times(): > >> roll_count = 1 > >> while (rolls := roll())[0] != rolls[1]: > >> roll_count += 1 > >> return (roll_count, rolls) > >> > > > > Since we're creating solutions that use features in completely > > unnecessary ways, here's a version that uses collections.Counter: > > > > def how_many_times(): > > return next((count, rolls) for count, rolls in > > enumerate(iter(roll, None)) if len(Counter(rolls)) == 1) > > > > Do I get bonus points for it being a one-liner that doesn't fit in > > eighty characters? > > > Herewith my claim to one-liner fame (assuming such leads in any way to > virtue or fame) > > It retains @Peter's preference for a more re-usable roll_die() which > returns a single event, cf the OP's roll() which returns two results). > > > import itertools, random > > def roll_die(): > while True: > yield random.randrange(1, 7) > > def how_many_times(): > return list( itertools.takewhile( lambda r:r[ 0 ] != r[ 1 ], > zip( roll_die(), roll_die() ) > ) >) > > Also, a claim for 'bonus points' because the one-liner will fit within > 80-characters - if only I didn't have that pernicious and vile habit of > coding a more readable layout. > > It doesn't use a two-arg iter, but still rates because it does use a > relatively-obscure member of the itertools library... > Nice, but that's only going to give you the ones that don't match. You can then count those, and that's a start, but how do you capture the matching rolls? I smell another opportunity for gratuitous use of a language feature: nonlocal. In a lambda function. Which may require shenanigans of epic proportions. ChrisA -- https://mail.python.org/mailman/listinfo/python-list