Re: on writing a while loop for rolling two dice
dn writes: [...] > Further, if you look at the OP's original solution, it only publishes > the last pair, ie the match, without mention of the list of non-matches. > Was it perhaps only a means of testing the solution? It was a means of showing the student that indeed they obtained a match. If the exercise asked for returning a single die or no die at all, they would make mistakes and there'd be no sign of them being wrong. For instance, one trouble a lot of them went through was to start counting from zero and so their number of rolls was off by one. (I didn't see that coming!) The reason they fall for this is that they also test little --- for some it never occurred a match on the first roll, so they never saw the zero counter coming out. -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 11/09/2021 10:09, dn via Python-list wrote: The stated requirement is: "I'd like to get the number of times I tried". Given such: why bother with returning any of the pairs of values? Indeed, if that's the requirement, then you can do even better, noting that the probability of getting a matched pair is 1/6 (6 matches out of 6*6 possibilities). So the answer to the problem is exactly the same as rolling a single die until you get any particular number (e.g., 1). This is somewhat easier to simulate than the two-dice problem (and the number of throws until a match is also a known, analytic distribution that you could sample from, but this is probably easier). -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 2021-09-08 13:07:47 +1200, Greg Ewing wrote: > On 8/09/21 2:53 am, Grant Edwards wrote: > >#define IF if ( > >#define THEN ) { > >#define ELSE } else { > >#define ENDIF } > > I gather that early versions of some of the Unix utilities were > written by someone who liked using macros to make C resemble Algol. Steve Bourne, the author of the eponymous shell. hp -- _ | Peter J. Holzer| Story must make more sense than reality. |_|_) || | | | h...@hjp.at |-- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" signature.asc Description: PGP signature -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 11/09/2021 18.03, Chris Angelico wrote: > 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. The stated requirement is: "I'd like to get the number of times I tried". Given such: why bother with returning any of the pairs of values? Further, if you look at the OP's original solution, it only publishes the last pair, ie the match, without mention of the list of non-matches. Was it perhaps only a means of testing the solution? Regret that I'll settle for (or continue to seek) 'fame'. I don't play guitar, so have no use for epic. -- 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
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 Wed, 8 Sep 2021 16:32:45 - (UTC), Grant Edwards declaimed the following: >On 2021-09-08, Dennis Lee Bieber wrote: > >> I spent close to 20 years (80s-90s) maintaining the /output/ of such >> a preprocessor. > >Ouch. I hope it paid well. ;) Only if one ignores the bloody cost of apartments (given the rent paid over the 30 years I spent in that 1BR 680sq.ft. unit I should have owned it, if not half the facility ) > >> The software had apparently originated with a sub-contractor, and we >> did not have access to their preprocessor > >Allowing that to happen is definitely a major management F*%k-up for >which somebody should have had their career ended. > For all I know, someone might have... Back when the application was running on PDP-11 (I joined the program early 80s, when the "mission planning" software was being ported to the VAX-11). Most of the "mission planning" software was local-grown, so was DEC FORTRAN (may have started as F-IV, and developed F77 during maintenance and the porting to the VAX). Not the part I maintained -- which drove a Ramtek 9300 graphics engine (only one engine could be installed into a VAX, it was that archaic). It got to the point where I think Ramtek service was recycling the parts when ever we had a service call. Eventually I proposed that a VAXstation (DECWindows) and GKS could replace most of the display side. We weren't approved to rewrite the application to directly display -- but rewriting the Ramtek library to send the plotting data to a separate program, which managed the display window, was in the budget. > >I would have though that would have been pretty trivial compared to >maintaining the output source for 20 years. I'm not so sure -- that "one file per executable" would have led to long compile times (first for the preprocessor, then for the generated F-IV output), vs my rewrites into multiple files, where only isolated changes needed to be recompiled. Humorously, the graphics application suite was known as "MESS" (I can't go deeper into the acronym without violating security classification). -- Wulfraed Dennis Lee Bieber AF6VN wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On Wed, 8 Sep 2021 14:46:28 - (UTC), Grant Edwards declaimed the following: >On 2021-09-08, charles hottel wrote: > >> So what do yoy think or feel about a language like RATFOR (Rational >> FORTRAN) which was implemented as macros? Should they instead have >> simply adapted themselves to FORTRAN? > >That's an interesting question. If the langauge is complete, >well-defined, and well-documented then it's not that much different >than any other source language than gets translated into a lower level >language (e.g. C -> assembly). My recollection of RATFOR was that it >provided enough signifcant "features" that weren't available in the >underlying FORTRAN to make it worthwhile. > Primarily providing block structured IF/ELSE and loops -- in a language that only really provided IF/GOTO... My college tried using one of these (for some reason the name TextFOR sticks with me)... The experiment only lasted one term. The preprocessor ate CPU and I/O time -- with the result that the FORTRAN class used two or three times the times of the COBOL class! (The native compilers were designed as re-entrant, allowing multiple compiles to share one in-core image; the preprocessor no doubt ran as one image per compile, triggering lots of page swapping to disk) -- Wulfraed Dennis Lee Bieber AF6VN wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 2021-09-08, Dennis Lee Bieber wrote: > I spent close to 20 years (80s-90s) maintaining the /output/ of such > a preprocessor. Ouch. I hope it paid well. ;) Back when I did a lot of TeX/LaTeX stuff on VMS, I used to make occasional fixes and add (very minor) features to one of the dvi handling executables (I don't remember if it was the VT2xx previewer, or the laser-printer "driver") using the VMS "PATCH" utility. I also can't remember how we ended up without source code for that piece of the toolchain when we build all of the reset of it from source. > The software had apparently originated with a sub-contractor, and we > did not have access to their preprocessor Allowing that to happen is definitely a major management F*%k-up for which somebody should have had their career ended. > (and/or no one ported it to the VAX-11 from PDP-11). I would have though that would have been pretty trivial compared to maintaining the output source for 20 years. -- Grant -- https://mail.python.org/mailman/listinfo/python-list
RE: on writing a while loop for rolling two dice
Charles, This forum is for python discussions so I will clarify that there is nothing wrong with making up a new language, including by bootstrapping an old language. But why not call it new and do not try to confuse people using the old. Python has grown and added much over the years and even had a fairly negative experience in a transition from versions 2 to 3 as some people complain their old software no longer works. If you look at a language like C which was remade into C++, guess what? It has a new name and makes no claims to be fully compatible. If RATFOR was a more pleasant programming environment for some people and purposes, fine. I note Python has many modules that for some people become the most used parts even when the base language might allow some similar functionality. Someone who learns python but has never experienced those, may feel a bit lost. And you can customize Python to a point where it does things in fairly hidden ways too. There are no promises of purity. What this particular discussion began with was much lower level and about various ways of writing a while loop within very basic Python and seems to be heading away into discussions of other languages. I happen to enjoy learning and contrasting lots of languages but doubt many others do and most people want to learn just a few good tools and use them to get their job done. My point was if you have a tool you like and you try another you don't, then rather than trying to force the new one, just use what works and leave others that like it alone. Make your own religion and let others keep theirs. However, improvements and increased functionality may be more welcome, than examples where the interface was changed with no benefits. -Original Message- From: Python-list On Behalf Of charles hottel Sent: Tuesday, September 7, 2021 11:31 PM To: python-list@python.org Subject: Re: on writing a while loop for rolling two dice So what do yoy think or feel about a language like RATFOR (Rational FORTRAN) which was implemented as macros? Should they instead have simply adapted themselves to FORTRAN? -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On Wed, 8 Sep 2021 00:24:44 +0100, Alan Gauld via Python-list declaimed the following: > >That was quite common in C before it became popular(early/mid 80s). >I've seen Pascal, Algol and Coral macro sets in use. >You could even download pre-written ones from various >bulletin boards (remember them?!) for a while. And if one wants to expose themselves to real horror -- look at the output of one of those "structured FORTRAN" preprocessors (RATFOR, TEXTFOR, others) that were cropping up in the late 70s to generate FORTRAN-IV from code written with block IF, WHILE, etc. I spent close to 20 years (80s-90s) maintaining the /output/ of such a preprocessor. The software had apparently originated with a sub-contractor, and we did not have access to their preprocessor (and/or no one ported it to the VAX-11 from PDP-11). At first my practice was to study a file in detail, and then rewrite it using F77 with separately compiled subroutines (the preprocessor was "one file per program" and implemented BASIC-style GOSUB, relying on shared variables and ASSIGNed GOTO for the return address -- I had to move the shared variables to COMMON blocks to make separate subroutines usable). By the end of those decades, I'd been exposed to the preprocessor enough to hand-write smaller patches within its style. The only good thing is that is left the structured source as comments, and tended to right-justify the F-IV output, so easy to locate... -- Wulfraed Dennis Lee Bieber AF6VN wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 2021-09-08, charles hottel wrote: > So what do yoy think or feel about a language like RATFOR (Rational > FORTRAN) which was implemented as macros? The RATFOR implementations I've seen weren't done using macros. It was a preprocessor, yes. But it generates code for the various structured statement types (while, for, if/then/else) and source structures (open/close brace) the way a compiler does, even though the generated code is FORTRAN66 rather than assembly or bytecode or whatever. > Should they instead have simply adapted themselves to FORTRAN? -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 2021-09-08, charles hottel wrote: > So what do yoy think or feel about a language like RATFOR (Rational > FORTRAN) which was implemented as macros? Should they instead have > simply adapted themselves to FORTRAN? That's an interesting question. If the langauge is complete, well-defined, and well-documented then it's not that much different than any other source language than gets translated into a lower level language (e.g. C -> assembly). My recollection of RATFOR was that it provided enough signifcant "features" that weren't available in the underlying FORTRAN to make it worthwhile. That seems to me to be qualitatively different than a set of macros that simply make one language look (somewhat) like a different language with a similar level of abstraction -- without providing anything other than cosmetic changes. -- Grant -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 9/7/2021 9:20 PM, Avi Gross wrote: Greg, Yes, a smart person may come up with such tricks but a really smart person, in my view, adjusts. With some exceptions, such as when trying to port existing code to a new language quickly, someone who is not too obsessive will try to pick up the goals and spirit of a new language and use them when it seems reasonable. And, a smart person, if they see nothing new, might just go back to their old language or ... Pick a language that easily supports regular expressions and object creation and functional programming and so on, like python, and ask why you might want to use it to simulate a really old version of BASIC when you can just use BASIC. Admittedly, most people are not flexible. I find that with human languages too that some learn another language just enough to recognize words but not to use the changed grammar or the different idioms and never become fluent. I am amused though at the fact that python, by using indentation rather than things like curly braces, would make some of the games like shown below quite a bit more difficult. -Original Message- From: Python-list On Behalf Of Greg Ewing Sent: Tuesday, September 7, 2021 9:08 PM To: python-list@python.org Subject: Re: on writing a while loop for rolling two dice On 8/09/21 2:53 am, Grant Edwards wrote: #define IF if ( #define THEN ) { #define ELSE } else { #define ENDIF } ... I gather that early versions of some of the Unix utilities were written by someone who liked using macros to make C resemble Algol. I guess you can get away with that sort of thing if you're a Really Smart Person. -- Greg -- https://mail.python.org/mailman/listinfo/python-list So what do yoy think or feel about a language like RATFOR (Rational FORTRAN) which was implemented as macros? Should they instead have simply adapted themselves to FORTRAN? -- https://mail.python.org/mailman/listinfo/python-list
RE: on writing a while loop for rolling two dice
I think I already agreed with much of your point. That is indeed the problem. You are allowed to do some possibly non-standard things. A static evaluation/replacement may show the wrong function being called and a dynamic one may still mess up as there are many ways to do indirection. I mention this partially because of a recent discussion on another computer where the question was why they got an error message that the object being given a function was not a data.frame or something compatible. What was being passed was a data structure meant to hold some simulation of an EXCEL spreadsheet. Not quite the same. But they insisted it had to be a data.frame because they called functionA() and it is documented to return a data.frame. It turned out that they had loaded lots of packages (modules but not) and had not paid attention when they got a message that one function called functionA was now being covered by another with the same name. Each such package loaded often gets a new namespace/environment and when searching for a function by name, the new package was ahead of the older package, hence the warning. So one solution was to change his code in one of several ways, but more generally to call any functions that may be hidden this way in a fully qualified manner as in packageA::functionA(...) do you do not accidentally get package::functionA(...) Now note this is not so much a bug as a feature in that language and It is quite common to sort of redefine a function name to do what you want. But if you have developed your own package and want to guarantee the user does not undo your work in specific cases, you should also call some things as explicitly within your own namespace. Back to Python, it is a tad too flexible in some places and my point was that it would be interesting, along the lines of a linter, to have some tools that help explain what the program might be doing a tad more explicitly. But as an interpreted language, so much can happen at runtime that this may not be very effective or accurate. The language is full of places where slipping in another object means you over-rode the meaning of += for instance. -Original Message- From: Python-list On Behalf Of Richard Damon Sent: Tuesday, September 7, 2021 10:09 PM To: python-list@python.org Subject: Re: on writing a while loop for rolling two dice On 9/7/21 3:51 PM, Avi Gross via Python-list wrote: > and similarly changes any function imported directly to also be fully > qualified. One danger with this is that it can actual change the behavior of the program. Maybe more likely with global objects than functions, but still an issue. Remember, "from module import fun" will bind the name fun in this modules namespace to the current definiton of the object fun in the other modules name space. If after that point, something rebinds the name in the other module, the module that did the from import won't see that change, but if the reference is changed to module.fun, it will. Since that rebinding might even be some third module doing a 'monkey patch', detecting if it is safe is basically impossible. Admittedly, if this is an issue, the sensitivity to timing makes the difference something very fussy to exactly the order you do things, the cases where the difference is intended is likely fairly small. -- Richard Damon -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 9/7/21 3:51 PM, Avi Gross via Python-list wrote: > and similarly changes any function imported directly > to also be fully qualified. One danger with this is that it can actual change the behavior of the program. Maybe more likely with global objects than functions, but still an issue. Remember, "from module import fun" will bind the name fun in this modules namespace to the current definiton of the object fun in the other modules name space. If after that point, something rebinds the name in the other module, the module that did the from import won't see that change, but if the reference is changed to module.fun, it will. Since that rebinding might even be some third module doing a 'monkey patch', detecting if it is safe is basically impossible. Admittedly, if this is an issue, the sensitivity to timing makes the difference something very fussy to exactly the order you do things, the cases where the difference is intended is likely fairly small. -- Richard Damon -- https://mail.python.org/mailman/listinfo/python-list
RE: on writing a while loop for rolling two dice
Greg, Yes, a smart person may come up with such tricks but a really smart person, in my view, adjusts. With some exceptions, such as when trying to port existing code to a new language quickly, someone who is not too obsessive will try to pick up the goals and spirit of a new language and use them when it seems reasonable. And, a smart person, if they see nothing new, might just go back to their old language or ... Pick a language that easily supports regular expressions and object creation and functional programming and so on, like python, and ask why you might want to use it to simulate a really old version of BASIC when you can just use BASIC. Admittedly, most people are not flexible. I find that with human languages too that some learn another language just enough to recognize words but not to use the changed grammar or the different idioms and never become fluent. I am amused though at the fact that python, by using indentation rather than things like curly braces, would make some of the games like shown below quite a bit more difficult. -Original Message- From: Python-list On Behalf Of Greg Ewing Sent: Tuesday, September 7, 2021 9:08 PM To: python-list@python.org Subject: Re: on writing a while loop for rolling two dice On 8/09/21 2:53 am, Grant Edwards wrote: >#define IF if ( >#define THEN ) { >#define ELSE } else { >#define ENDIF } >... I gather that early versions of some of the Unix utilities were written by someone who liked using macros to make C resemble Algol. I guess you can get away with that sort of thing if you're a Really Smart Person. -- Greg -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 8/09/21 2:53 am, Grant Edwards wrote: #define IF if ( #define THEN ) { #define ELSE } else { #define ENDIF } ... I gather that early versions of some of the Unix utilities were written by someone who liked using macros to make C resemble Algol. I guess you can get away with that sort of thing if you're a Really Smart Person. -- Greg -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 07/09/2021 15:53, Grant Edwards wrote: > I remember engineering manager I worked with about 35 years ago who > used a set of C macros to try to make his code look as much like BASIC > as possible: > > #define IF if ( > #define THEN ) { > #define ELSE } else { > #define ENDIF } > ... > > IIRC he copied them out of a magazine article. That was quite common in C before it became popular(early/mid 80s). I've seen Pascal, Algol and Coral macro sets in use. You could even download pre-written ones from various bulletin boards (remember them?!) for a while. -- 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: on writing a while loop for rolling two dice
Although I sort of agree with Alister, I also note that many languages deliberately provide you with the means to customize in ways that make your personal life more amenable while making it perhaps harder for others. Consider the humble import statement frequently used as: import numpy as np import pandas as pd The above is perfectly legal and in some circles is expected. But I suspect many people do not care about being able to type a slightly abbreviated np.name(..) rather than numpy.name(...) and yet others import specific functions from a package like: from numpy import arrange The bottom line is that there are many ways the same code can be called, including quite a few other variations I am not describing. People can customize their code in many ways including making it look more like the way they might program in some other computer language/environment. Anyone reading their code with a different viewpoint may have some adjustment issues. I am wondering if anyone has written programs that would take some complete body of code and not prettify it or reformat it as some tools do, but sort of make it into a standard format. In the above example, it might undo things like renaming numpy to np and change all the code that looks like np.name to numpy.name and similarly changes any function imported directly to also be fully qualified. Of course, some code I have seen changes things mid-stream or has some if statement that sets one of several function calls to be the one to use beyond that point. So, I am not sanguine on trying to enforce some standards to make your code easy to read by others and am more a fan of suggesting enough comments in the code to guide anyone on your own idiosyncratic uses. -Original Message- From: Python-list On Behalf Of alister via Python-list Sent: Tuesday, September 7, 2021 2:58 PM To: python-list@python.org Subject: Re: on writing a while loop for rolling two dice On Tue, 07 Sep 2021 14:53:29 +, Grant Edwards wrote: > On 2021-09-06, Stefan Ram wrote: >> "Avi Gross" writes: >>> In languages like C/C++ there are people who make up macros like: >>>#define INDEFINITELY_LOOP while (true) Or something like that and >>>then allow the preprocessor to replace INDEFINITELY_LOOP with valid C >>>code. >> >> Those usually are beginners. >> >>>So, how to do something like that in python, is a challenge left to >>>the user >> >> Such a use of macros is frowned upon by most C programmers, >> because it renders the code unreadable. > > I remember engineering manager I worked with about 35 years ago who > used a set of C macros to try to make his code look as much like BASIC > as > possible: > > #define IF if ( #define THEN ) { #define ELSE } else { > #define ENDIF } > ... > > IIRC he copied them out of a magazine article. > > He then proceeded to try to implement a tree search algorithm (he > didn't actually know that's what he was doing) using his new > "language" without using recursion (which he had never heard of and > couldn't grok) by keeping track of state using an array. It did not go > well and made him a bit of a laughingstock. IIRC, he had first tried > to write it in actual BASIC, but gave up on that before switching to C > and his ridiculous macro set. 1 Simple rule, if you are programming in language 'a' then write Language 'a' Code it. Just because you can do something doesn't mean you should -- Help! I'm trapped in a Chinese computer factory! -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On Tue, 7 Sep 2021 16:08:04 +1200, Greg Ewing declaimed the following: >On 7/09/21 11:38 am, Avi Gross wrote: > >> #define INDEFINITELY_LOOP while (true) >> >> So, how to do something like that in python, is a challenge left to the user >> ? > >def hell_frozen_over(): > return False > >while not hell_frozen_over(): > Hell typically freezes every January (scroll down to monthly average): https://www.worldweatheronline.com/hell-weather-averages/michigan/us.aspx -- Wulfraed Dennis Lee Bieber AF6VN wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
Grant Edwards writes: > On 2021-09-06, Stefan Ram wrote: >> "Avi Gross" writes: >>> In languages like C/C++ there are people who make up macros like: >>>#define INDEFINITELY_LOOP while (true) >>>Or something like that and then allow the preprocessor to replace >>>INDEFINITELY_LOOP with valid C code. >> >> Those usually are beginners. [...] >> Such a use of macros is frowned upon by most C programmers, >> because it renders the code unreadable. > > I remember engineering manager I worked with about 35 years ago who > used a set of C macros to try to make his code look as much like BASIC > as possible: > > #define IF if ( > #define THEN ) { > #define ELSE } else { > #define ENDIF } > ... > > IIRC he copied them out of a magazine article. > > He then proceeded to try to implement a tree search algorithm (he > didn't actually know that's what he was doing) using his new > "language" without using recursion (which he had never heard of and > couldn't grok) by keeping track of state using an array. It did not go > well and made him a bit of a laughingstock. IIRC, he had first tried > to write it in actual BASIC, but gave up on that before switching to C > and his ridiculous macro set. LOL! (Had fun reading this.) -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On Tue, 07 Sep 2021 14:53:29 +, Grant Edwards wrote: > On 2021-09-06, Stefan Ram wrote: >> "Avi Gross" writes: >>> In languages like C/C++ there are people who make up macros like: >>>#define INDEFINITELY_LOOP while (true) >>>Or something like that and then allow the preprocessor to replace >>>INDEFINITELY_LOOP with valid C code. >> >> Those usually are beginners. >> >>>So, how to do something like that in python, is a challenge left to the >>>user >> >> Such a use of macros is frowned upon by most C programmers, >> because it renders the code unreadable. > > I remember engineering manager I worked with about 35 years ago who used > a set of C macros to try to make his code look as much like BASIC as > possible: > > #define IF if ( #define THEN ) { #define ELSE } else { > #define ENDIF } > ... > > IIRC he copied them out of a magazine article. > > He then proceeded to try to implement a tree search algorithm (he didn't > actually know that's what he was doing) using his new "language" without > using recursion (which he had never heard of and couldn't grok) by > keeping track of state using an array. It did not go well and made him a > bit of a laughingstock. IIRC, he had first tried to write it in actual > BASIC, but gave up on that before switching to C and his ridiculous > macro set. 1 Simple rule, if you are programming in language 'a' then write Language 'a' Code it. Just because you can do something doesn't mean you should -- Help! I'm trapped in a Chinese computer factory! -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 2021-09-06, Stefan Ram wrote: > "Avi Gross" writes: >> In languages like C/C++ there are people who make up macros like: >>#define INDEFINITELY_LOOP while (true) >>Or something like that and then allow the preprocessor to replace >>INDEFINITELY_LOOP with valid C code. > > Those usually are beginners. > >>So, how to do something like that in python, is a challenge left to the >>user > > Such a use of macros is frowned upon by most C programmers, > because it renders the code unreadable. I remember engineering manager I worked with about 35 years ago who used a set of C macros to try to make his code look as much like BASIC as possible: #define IF if ( #define THEN ) { #define ELSE } else { #define ENDIF } ... IIRC he copied them out of a magazine article. He then proceeded to try to implement a tree search algorithm (he didn't actually know that's what he was doing) using his new "language" without using recursion (which he had never heard of and couldn't grok) by keeping track of state using an array. It did not go well and made him a bit of a laughingstock. IIRC, he had first tried to write it in actual BASIC, but gave up on that before switching to C and his ridiculous macro set. -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 7/09/21 11:38 am, Avi Gross wrote: #define INDEFINITELY_LOOP while (true) So, how to do something like that in python, is a challenge left to the user 😉 def hell_frozen_over(): return False while not hell_frozen_over(): -- Greg -- https://mail.python.org/mailman/listinfo/python-list
RE: on writing a while loop for rolling two dice
It has been nearly three decades since I have had to write in C, Stefan, but what I suggested jokingly is quite mild compared to what the winners of the obfuscated C Contest do: https://www.ioccc.org/ Time for me to drop out of this thread. Personally I fully agree uses of "while' as described are perfectly understandable. Features that sophisticated programmers love tend to confuse novices. I recall my exposure to PERL where weird things seemed to just happen with no rhyme or reason or connections. Turned out just about everything puts things into or takes them out of hidden variables so much of the time, a string of commands just does what might be expected. Another variant on the elusive concept of a pipeline. But all the nice gimmicks and tricks make novices a bit puzzled. On the other hand, you can still write most programs the old fashioned way and sort of start normal then head off into hyperspace at warp speed. Python too has a way to write fairly unsophisticated programs as well as idioms and methods that rapidly become hard to comprehend. -Original Message- From: Python-list On Behalf Of Stefan Ram Sent: Monday, September 6, 2021 7:49 PM To: python-list@python.org Subject: Re: on writing a while loop for rolling two dice "Avi Gross" writes: > In languages like C/C++ there are people who make up macros like: >#define INDEFINITELY_LOOP while (true) >Or something like that and then allow the preprocessor to replace >INDEFINITELY_LOOP with valid C code. Those usually are beginners. >So, how to do something like that in python, is a challenge left to the >user Such a use of macros is frowned upon by most C programmers, because it renders the code unreadable. "while(1)" in C or "while True:" in Python is perfectly clear. Don't fix it if it ain't broke! -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Non sequitur: on writing a while loop for rolling two dice
RESEND with clarification! On Mon, 6 Sep 2021 20:11:41 -0400, Avi Gross via Python-list declaimed the following: >changing. Ages ago we had code that processed MTA headers and every time we >had a meeting of standards bodies, we kept adding ever more headers and Why did my mind immediately flash on "The Man Who Never Returned"? (AKA: "M.T.A.", Kingston Trio song) (Especially as you describe just the opposite -- many returns ) -- Wulfraed Dennis Lee Bieber AF6VN wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list
Non sequitur: on writing a while loop for rolling two dice
On Mon, 6 Sep 2021 20:11:41 -0400, Avi Gross via Python-list declaimed the following: >changing. Ages ago we had code that processed MTA headers and every time we >had a meeting of standards bodies, we kept adding ever more headers and Why did my mind immediately flash on "The Man Who Never Returned"? (Especially as you describe just the opposite -- many returns ) -- Wulfraed Dennis Lee Bieber AF6VN wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list
RE: on writing a while loop for rolling two dice
I hate to quibble but as almost anything in Python can evaluate to being truthy, a command like while "never" evaluates to true as the string is not empty. I meant a generator like >>> def boring(): while True: yield() >>> for _ in boring(): print("repeating ...") The above gives me a nice infinite loop, with the second one looking like a normal loop but actually doing nothing much. -Original Message- From: Python-list On Behalf Of 2qdxy4rzwzuui...@potatochowder.com Sent: Monday, September 6, 2021 8:28 PM To: python-list@python.org Subject: Re: on writing a while loop for rolling two dice On 2021-09-06 at 20:11:41 -0400, Avi Gross via Python-list wrote: > And in the python version, has anyone made a generator that returned > NULL or the like so you can say uselessly: > > for ( _ in forever() ) ... while "forever": ... -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 2021-09-06 at 20:11:41 -0400, Avi Gross via Python-list wrote: > And in the python version, has anyone made a generator that returned > NULL or the like so you can say uselessly: > > for ( _ in forever() ) ... while "forever": ... -- https://mail.python.org/mailman/listinfo/python-list
RE: on writing a while loop for rolling two dice
Let me add something, Stefan. Some people just want to get a job done. For this person, he had a very specific need for a one-time project where the rest of it was understood but one small step was confusing. Frankly, he could have done it faster by opening a text editor on something like a CSV file and flipped some (actual) three-sided coins while manually doing a cut and past of lines into three new files and near the end, make sure the last few only went into files with a missing row or two. I have too often had people ask me for programming help and when I suggested they learn how to do it or let me make a more careful piece of code that checks for errors or will easily work under various changed conditions, guess what I usually encounter? Many just want it DONE. They often sheepishly come back some time later with some variant of the same need that mysteriously does not work with code they asked to be designed to just work in one case! Often they hack away at the code in odd ways first and then come to me to have it fixed. But there are costs to generality and creating functions with dozens of optional arguments and that handle a wide variety of inputs and thus constantly are checking what types they are working with and perhaps converting to others or need to create objects with lots of dunders, can also make it error prone. Looking at our forever loop discussion, how often are the contents of the loop written with multiple terminating parts within the loop body that get complex? I mean lots of break or continue statements all over the place with multi-part if statements. Some can be rewritten as a more standard loop with a condition like "while (a < 5 && found_it == FALSE || ( ... )) ..." and often in the body you need if statements that let you skip the rest if found_it is true. It can be a mess either way. At times you need to consider rewriting it from scratch. This especially happens as requirements keep changing. Ages ago we had code that processed MTA headers and every time we had a meeting of standards bodies, we kept adding ever more headers and keywords that often required some existing code to also look at other headers that now might be present as they might change what you did in existing code locations. I eventually suggested a rewrite and it turned out to be more compact now that we evaluated some things first, rather than within many existing parts. Has anyone mentioned the really stupid looking forever loop in languages with the other style of for loop? for ( ; ;) All that generally was, was an initialization command before a while and so on but here all three parts were null, so why use it? And in the python version, has anyone made a generator that returned NULL or the like so you can say uselessly: for ( _ in forever() ) ... -Original Message- From: Python-list On Behalf Of Stefan Ram Sent: Monday, September 6, 2021 12:34 PM To: python-list@python.org Subject: Re: on writing a while loop for rolling two dice "Avi Gross" writes: >For some people the "while true" method seems reasonable but it has a >problem if the internal body does not have some guarantee of an exit. >And A programming error where the condition used does not express the intent of the programmer can happen with any kind of while loop. >help explain to the reader what your intention is, if done properly. It >also can confuse if you put in "while 5 < 6" or other weird ways to say >do this indefinitely. If any reader cannot understand "while True:", it's not a problem with the source code. When someone writes "while True:", it is clearly his intention that the following indented code is repeated until it's exited by some means, which means is not the while condition. >His solution was to repeat large sections of code, three times, with >some modification, for the cases where the remainder (modulo N) was 0, 1 or 2. This is typical of - beginners who just do not know the means of the language to reduce redundancy yet, - less experience programmers, who know the language but still are not able to apply features to reduce redundancy always, - premature publication of unfinished code where the redundancy has not yet been reduced, or - programmers who do not have the personal means to climb to the level of abstraction needed to remove the redundancy in a specific case. And, I think you wrote that too, sometimes less smart code is more readable or maintainable. Maybe three very similar blocks are repeated literally because future modifications are expected that will make them less similar. -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
RE: on writing a while loop for rolling two dice
I actually like it if a language lets you spell out your intention, although adding many keywords is not a plus. So, yes something like: loop ... end loop; Is appealing as it makes clear the decision on when to exit the loop must be within the loop (or till something kills ...) In languages like C/C++ there are people who make up macros like: #define INDEFINITELY_LOOP while (true) Or something like that and then allow the preprocessor to replace INDEFINITELY_LOOP with valid C code. So, how to do something like that in python, is a challenge left to the user 😉 Bottom line I find is it is a great idea to write comments as even if you are the one reviewing the code much later, you may struggle to figure out what you did and why. -Original Message- From: Python-list On Behalf Of Dennis Lee Bieber Sent: Sunday, September 5, 2021 12:50 PM To: python-list@python.org Subject: Re: on writing a while loop for rolling two dice On Sat, 4 Sep 2021 12:27:55 -0500, "Michael F. Stemper" declaimed the following: > >Kernighan and Ritchie agree(d) with you. Per _The C Programming >Language__: > Experience shows that do-while is much less used that while > and for. > And just for confusion, consider languages with "repeat / until"... "do / while" repeats so long as the condition evaluates to "true"; "repeat / until" /exits/ when the condition evaluates to "true". Then... there is Ada... While one is most likely to encounter constructs: for ix in start..end loop ... end loop; and while condition loop ... end loop; the core construct is just a bare loop ... end loop; which, with the "exit when condition" statement allows low-level emulation of any loop... (same as Python "if condition: break" loop-- "while" loop exit when not condition; ... end loop; loop-- "repeat / until" ... exit when condition; end loop; loop-- split ... exit when condition; ... end loop; {I'm not going to do the "for" loop, but one can easily manage initialization/increment/test statements}. To really get your mind blown, look at loops in REXX... do while condition ... end do until condition /* note that the termination parameter is listed at top, */ /* but takes effect at the bottom, so always one pass */ ... end do forever ... if condition then leave ... end do idx = start to end /* optional: by increment */ ... end do idx = 1 by increment for repetitions ... end AND worse! You can combine them... do idx = start for repetitions while condition1 until condition2 ... end {I need to check if both while and until can be in the same statement} -- Wulfraed Dennis Lee Bieber AF6VN wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On Sat, 4 Sep 2021 12:27:55 -0500, "Michael F. Stemper" declaimed the following: > >Kernighan and Ritchie agree(d) with you. Per _The C Programming >Language__: > Experience shows that do-while is much less used that while > and for. > And just for confusion, consider languages with "repeat / until"... "do / while" repeats so long as the condition evaluates to "true"; "repeat / until" /exits/ when the condition evaluates to "true". Then... there is Ada... While one is most likely to encounter constructs: for ix in start..end loop ... end loop; and while condition loop ... end loop; the core construct is just a bare loop ... end loop; which, with the "exit when condition" statement allows low-level emulation of any loop... (same as Python "if condition: break" loop-- "while" loop exit when not condition; ... end loop; loop-- "repeat / until" ... exit when condition; end loop; loop-- split ... exit when condition; ... end loop; {I'm not going to do the "for" loop, but one can easily manage initialization/increment/test statements}. To really get your mind blown, look at loops in REXX... do while condition ... end do until condition /* note that the termination parameter is listed at top, */ /* but takes effect at the bottom, so always one pass */ ... end do forever ... if condition then leave ... end do idx = start to end /* optional: by increment */ ... end do idx = 1 by increment for repetitions ... end AND worse! You can combine them... do idx = start for repetitions while condition1 until condition2 ... end {I need to check if both while and until can be in the same statement} -- Wulfraed Dennis Lee Bieber AF6VN wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list
RE: on writing a while loop for rolling two dice
For some people the "while true" method seems reasonable but it has a problem if the internal body does not have some guarantee of an exit. And that exit can be subtle. Many have mentioned ways an end condition can fail due to rounding errors not being exactly equal to what you are looking for, or an asymptotic process that approaches zero with a cutoff that is thus never reached. But I have seen some cases where you want a process or thread to run indefinitely until it is killed by another process or you reboot. You could of course use something like flag="green" and have your while keep testing that value but that is just wasted motion. Of course, properly used, it does help explain to the reader what your intention is, if done properly. It also can confuse if you put in "while 5 < 6" or other weird ways to say do this indefinitely. I think part of this conversation is about programming styles and what we should teach new students versus those who are trying to find more creative ways to do things or more efficiently or more generality. Sometimes a more direct method may be reasonable. On another forum, I saw someone write somewhat lengthy and redundant code on how to deal with partitioning data into three clusters randomly. My algorithm was general and handled any number of N clusters and since N often does not cleanly divide the number of items, has to place the remaining items into one of the N clusters or distribute them one at a time into some to make them almost even in size. His solution was to repeat large sections of code, three times, with some modification, for the cases where the remainder (modulo N) was 0, 1 or 2. The latter method was longer but in an odd way, much easier to understand. It boiled down to, if you have one extra put it here. If you have two, put one here and one there. My method had all kinds of bells and whistles that this specific case did not need. Let me end with asking if anyone has ever seen a mild variant of this: ... # code while false apologize() ... # more code -Original Message- From: Python-list On Behalf Of Hope Rouselle Sent: Thursday, September 2, 2021 10:42 AM To: python-list@python.org Subject: Re: on writing a while loop for rolling two dice David Raymond writes: >> 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) That's nice, although it doesn't seem more readable to a novice seeing a while for the first time, seeing a loop for the first time, than that while-True version. In fact, I think the while-True is the clearest so far. But it's always nice to spot a walrus in the wild! (If you're somewhere safe, that is.) -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
"Michael F. Stemper" writes: > On 04/09/2021 08.53, Hope Rouselle wrote: >> Chris Angelico writes: > >>> And at this point, it's looking pretty much identical to the for loop >>> version. Ultimately, they're all the same and you can pick and choose >>> elements from each of them. >> I see. That's why C must have added the do-while, but yeah --- it's >> not >> really worth it. > > Kernighan and Ritchie agree(d) with you. Per _The C Programming > Language__: > Experience shows that do-while is much less used that while > and for. > > (Second edition, Section 3.6, page 63) Special thanks for the reference! Here's what they say on the first edition. ``As might be expected, do-while is much less used than while and for, accounting for perhaps five percent of all loops.'' (First edition, section 3.6, page 59.) They looked into a sample and decided to remove the statistic. :-) -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
"Peter J. Holzer" writes: > On 2021-09-02 11:28:21 -0300, Hope Rouselle wrote: >> dn writes: >> > On 29/08/2021 08.46, Hope Rouselle wrote: >> >> Here's my solution: >> >> >> >> --8<---cut here---start->8--- >> >> def how_many_times(): >> >> x, y = 0, 1 >> >> c = 0 >> >> while x != y: >> >> c = c + 1 >> >> x, y = roll() >> >> return c, (x, y) >> > >> >> >> >> Why am I unhappy? I'm wish I could confine x, y to the while loop. >> >> The introduction of ``x, y = 0, 1'' must feel like a trick to a >> >> novice. How would you write this? > [...] >> But perhaps we may agree that while rolling dice until a certain >> success, we want to roll them while something happens or doesn't happen. >> One of the two. So while-True is a bit of a jump. Therefore, in this >> case, the easier and more natural option is to say while-x-not-equal-y. >> >> But this approach seems to force me into initializing x, y with >> different values. > > You can get around this by using NaN: > > def how_many_times(): > c, x, y = 0, math.nan, math.nan > while x != y: > c = c + 1 > x, y = roll() > return c, x, y > > Not sure if this is an improvement. Now you have to explain to your > students why math.nan != math.nan. > > When I need a guaranteed unique value I often just use object(): > > def how_many_times(): > c, x, y = 0, object(), object() > while x != y: > c = c + 1 > x, y = roll() > return c, x, y > > Of course now you are back to two different values, but they look the > same. Which may be better or worse for your students. Plus x and y are > now bound to objects of different types during their lifetime, which may > be a bit dicey. Lol. I would argue that it's quite appropriate to the event (``of rolling dice'' --- clarity-obsession). :D Pretty nice alternatives. Thank you so much. -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
Chris Angelico writes: > On Fri, Sep 3, 2021 at 4:33 AM Hope Rouselle wrote: >> Yeah. Here's a little context. I came across this by processing a list >> of exercises. (I'm teaching a course --- you know that by now, I >> guess.) So the first thing I observed was the equal volume of work >> dedicated to while loops and for loops --- so I decided to compared >> which appeared more often in a certain sample of well-written Python >> code. It turns out the for loop was much more frequent. Students have >> been reporting too much work in too little time, so I decided to reduce >> the number of exercises involving while loops. When I began to look at >> the exercises, to see which ones I'd exclude, I decided to exclude them >> all --- lol! --- except for one. The one that remained was this one >> about rolling dice until a satisfying result would appear. (All other >> ones were totally more naturally written with a for loop.) >> >> So if I were to also write this with a for-loop, it'd defeat the purpose >> of the course's moment. Besides, I don't think a for-loop would improve >> the readability here. > > It's on the cusp. When you ask someone to express the concept of "do > this until this happens", obviously that's a while loop; but as soon > as you introduce the iteration counter, it becomes less obvious, since > "iterate over counting numbers until this happens" is a quite viable > way to express this. However, if the students don't know > itertools.count(), they'll most likely put in an arbitrary limit (like > "for c in range(1)"), which you can call them out for. > >> But I thought your protest against the while-True was very well put: >> while-True is not too readable for a novice. Surely what's readable or >> more-natural /to someone/ is, well, subjective (yes, by definition). >> But perhaps we may agree that while rolling dice until a certain >> success, we want to roll them while something happens or doesn't happen. >> One of the two. So while-True is a bit of a jump. Therefore, in this >> case, the easier and more natural option is to say while-x-not-equal-y. > > That may be the case, but in Python, I almost never write "while > True". Consider the two while loops in this function: > > https://github.com/Rosuav/shed/blob/master/autohost_manager.py#L92 > > Thanks to Python's flexibility and efficient compilation, these loops > are as descriptive as those with actual conditions, while still > behaving exactly like "while True". (The inner loop, "more pages", > looks superficially like it should be a for loop - "for page in > pages:" - but the data is coming from successive API calls, so it > can't know.) That's pretty nice. I did suggest the same to my students, showing your code to them, actually. The course explicitly avoided talking about regular values being considered True, but now I couldn't keep the truth from them. >> I don't see it. You seem to have found what we seem to agree that it >> would be the more natural way to write the strategy. But I can't see >> it. It certainly isn't >> >> --8<---cut here---start->8--- >> def how_many_times_1(): >> c, x, y = 0, None, None >> while x != y: >> c = c + 1 >> x, y = roll() >> return c, x, y >> --8<---cut here---end--->8--- >> >> nor >> >> --8<---cut here---start->8--- >> def how_many_times_2(): >> c, x, y = 0, None, None >> while x == y: >> c = c + 1 >> x, y = dados() >> return c, x, y >> --8<---cut here---end--->8--- >> >> What do you have in mind? I couldn't see it. > > You're overlaying two loops here. One is iterating "c" up from zero, > the other is calling a function and testing its results. It's up to > you which of these should be considered the more important, and which > is a bit of extra work added onto it. With the counter as primary, you > get something like this: > > for c in itertools.count(): > x, y = roll() > if x == y: return c, x, y > > With the roll comparison as primary, you get this: > > c, x, y = 0, 0, 1 > while x != y: > x, y = roll() > c += 1 > return c, x, y > > Reworking the second into a do-while style (Python doesn't have that, > so we have to write it manually): > > c = 0 > while "x and y differ": > x, y = roll() > c += 1 > if x == y: break > return c, x, y > > And at this point, it's looking pretty much identical to the for loop > version. Ultimately, they're all the same and you can pick and choose > elements from each of them. I see. That's why C must have added the do-while, but yeah --- it's not really worth it. (An educational investigation. Thank you.) -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 04/09/2021 08.53, Hope Rouselle wrote: Chris Angelico writes: And at this point, it's looking pretty much identical to the for loop version. Ultimately, they're all the same and you can pick and choose elements from each of them. I see. That's why C must have added the do-while, but yeah --- it's not really worth it. Kernighan and Ritchie agree(d) with you. Per _The C Programming Language__: Experience shows that do-while is much less used that while and for. (Second edition, Section 3.6, page 63) -- Michael F. Stemper Outside of a dog, a book is man's best friend. Inside of a dog, it's too dark to read. -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 2021-09-02 11:28:21 -0300, Hope Rouselle wrote: > dn writes: > > On 29/08/2021 08.46, Hope Rouselle wrote: > >> Here's my solution: > >> > >> --8<---cut here---start->8--- > >> def how_many_times(): > >> x, y = 0, 1 > >> c = 0 > >> while x != y: > >> c = c + 1 > >> x, y = roll() > >> return c, (x, y) > > > >> > >> Why am I unhappy? I'm wish I could confine x, y to the while loop. > >> The introduction of ``x, y = 0, 1'' must feel like a trick to a > >> novice. How would you write this? [...] > But perhaps we may agree that while rolling dice until a certain > success, we want to roll them while something happens or doesn't happen. > One of the two. So while-True is a bit of a jump. Therefore, in this > case, the easier and more natural option is to say while-x-not-equal-y. > > But this approach seems to force me into initializing x, y with > different values. You can get around this by using NaN: def how_many_times(): c, x, y = 0, math.nan, math.nan while x != y: c = c + 1 x, y = roll() return c, x, y Not sure if this is an improvement. Now you have to explain to your students why math.nan != math.nan. When I need a guaranteed unique value I often just use object(): def how_many_times(): c, x, y = 0, object(), object() while x != y: c = c + 1 x, y = roll() return c, x, y Of course now you are back to two different values, but they look the same. Which may be better or worse for your students. Plus x and y are now bound to objects of different types during their lifetime, which may be a bit dicey. hp -- _ | Peter J. Holzer| Story must make more sense than reality. |_|_) || | | | h...@hjp.at |-- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" signature.asc Description: PGP signature -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
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) I would go even further, saying there is no need to «roll dices»: def how_many_times(): nb_times = random.choice([n for n in range(50) for _ in range(round(1*(1/6)*(5/6)**(n-1)))]) return nb_times, (random.randint(1, 6),) * 2 If i had more time on my hands, i would do something with bissect to get nb_times with more precision, as i have (mis)calculated that the probability of having nb_times = N is N = (1/6) * (5/6) ** (N-1) Something like this may work: nb_times = [random.random() < (1/6) * (5/6) ** (N-1) for N in range(1, 50)].index(True)+1 -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On Fri, Sep 3, 2021 at 4:51 AM Hope Rouselle wrote: > > Chris Angelico writes: > > > 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? > > Lol. You do not. In fact, this should be syntax error :-D --- as I > guess it would be if it were a lambda expression? It got split across lines when I posted it, but if I did this in a program, I'd make it a single long line. That said, though - Python doesn't mind if you mess up the indentation inside a parenthesized expression. Even broken like this, it WILL work. It just looks even uglier than it does with proper indentation :) BTW, this sort of thing is great as an anti-plagiarism check. If a student ever turns in an abomination like this, you can be extremely confident that it was copied from some programming site/list. Especially since I've used the two-arg version of iter() in there - that's quite a rarity. Hm. My mind is straying to evil things. The two-arg iter can do SO much more than I'm using it for here. By carefully designing the second argument, we could make something that is equal to anything whose two elements are equal, which would then terminate the loop. This... could be a lot worse than it seems. I'll leave it as an exercise for the reader to figure out how to capture the matching elements for return. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On Fri, Sep 3, 2021 at 4:33 AM Hope Rouselle wrote: > Yeah. Here's a little context. I came across this by processing a list > of exercises. (I'm teaching a course --- you know that by now, I > guess.) So the first thing I observed was the equal volume of work > dedicated to while loops and for loops --- so I decided to compared > which appeared more often in a certain sample of well-written Python > code. It turns out the for loop was much more frequent. Students have > been reporting too much work in too little time, so I decided to reduce > the number of exercises involving while loops. When I began to look at > the exercises, to see which ones I'd exclude, I decided to exclude them > all --- lol! --- except for one. The one that remained was this one > about rolling dice until a satisfying result would appear. (All other > ones were totally more naturally written with a for loop.) > > So if I were to also write this with a for-loop, it'd defeat the purpose > of the course's moment. Besides, I don't think a for-loop would improve > the readability here. It's on the cusp. When you ask someone to express the concept of "do this until this happens", obviously that's a while loop; but as soon as you introduce the iteration counter, it becomes less obvious, since "iterate over counting numbers until this happens" is a quite viable way to express this. However, if the students don't know itertools.count(), they'll most likely put in an arbitrary limit (like "for c in range(1)"), which you can call them out for. > But I thought your protest against the while-True was very well put: > while-True is not too readable for a novice. Surely what's readable or > more-natural /to someone/ is, well, subjective (yes, by definition). > But perhaps we may agree that while rolling dice until a certain > success, we want to roll them while something happens or doesn't happen. > One of the two. So while-True is a bit of a jump. Therefore, in this > case, the easier and more natural option is to say while-x-not-equal-y. That may be the case, but in Python, I almost never write "while True". Consider the two while loops in this function: https://github.com/Rosuav/shed/blob/master/autohost_manager.py#L92 Thanks to Python's flexibility and efficient compilation, these loops are as descriptive as those with actual conditions, while still behaving exactly like "while True". (The inner loop, "more pages", looks superficially like it should be a for loop - "for page in pages:" - but the data is coming from successive API calls, so it can't know.) > I don't see it. You seem to have found what we seem to agree that it > would be the more natural way to write the strategy. But I can't see > it. It certainly isn't > > --8<---cut here---start->8--- > def how_many_times_1(): > c, x, y = 0, None, None > while x != y: > c = c + 1 > x, y = roll() > return c, x, y > --8<---cut here---end--->8--- > > nor > > --8<---cut here---start->8--- > def how_many_times_2(): > c, x, y = 0, None, None > while x == y: > c = c + 1 > x, y = dados() > return c, x, y > --8<---cut here---end--->8--- > > What do you have in mind? I couldn't see it. You're overlaying two loops here. One is iterating "c" up from zero, the other is calling a function and testing its results. It's up to you which of these should be considered the more important, and which is a bit of extra work added onto it. With the counter as primary, you get something like this: for c in itertools.count(): x, y = roll() if x == y: return c, x, y With the roll comparison as primary, you get this: c, x, y = 0, 0, 1 while x != y: x, y = roll() c += 1 return c, x, y Reworking the second into a do-while style (Python doesn't have that, so we have to write it manually): c = 0 while "x and y differ": x, y = roll() c += 1 if x == y: break return c, x, y And at this point, it's looking pretty much identical to the for loop version. Ultimately, they're all the same and you can pick and choose elements from each of them. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
Chris Angelico writes: > 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? Lol. You do not. In fact, this should be syntax error :-D --- as I guess it would be if it were a lambda expression? -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
David Raymond writes: >> 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) That's nice, although it doesn't seem more readable to a novice seeing a while for the first time, seeing a loop for the first time, than that while-True version. In fact, I think the while-True is the clearest so far. But it's always nice to spot a walrus in the wild! (If you're somewhere safe, that is.) -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
dn writes: > On 29/08/2021 08.46, Hope Rouselle wrote: >> Here's my solution: >> >> --8<---cut here---start->8--- >> def how_many_times(): >> x, y = 0, 1 >> c = 0 >> while x != y: >> c = c + 1 >> x, y = roll() >> return c, (x, y) > >> >> Why am I unhappy? I'm wish I could confine x, y to the while loop. The >> introduction of ``x, y = 0, 1'' must feel like a trick to a novice. How >> would you write this? > >> r...@zedat.fu-berlin.de (Stefan Ram) writes: >>> """Rolls two dice until both yield the same value. >>> Returns the number of times the two dice were rolled >>> and the final value yielded.""" >>> roll_count = 0 >>> while True: >>> outcome = roll_two_dice() >>> roll_count += 1 >>> if outcome[ 0 ]== outcome[ 1 ]: break >>> return roll_count, outcome[ 0 ] >> >> You totally convinced me. Thanks. > > On the other hand... > whilst you expressed concern about the apparently disconnected 'set up' > necessary before the loop, this solution adds a "True/Forever" and a > "Break" construct, which some may deem not that much better (if at all) > > The idea of abrogating the while-condition but then adding another > (disconnected) condition to break, seems to hold equal potential for > confusion. or the type of dissatisfaction which motivated the original > question! Pretty well observed! Hats to you. > Looking at that from the inside-out, the loop's contents perform two > functions: the rolling and counting (per Statement of Requirements), but > also a loop-controlling element. Thus the reader's question: "what does > this loop do?" is conflated with "how many times does it do it?". Well put. > Let's go completely off-the-rails, why not use a never-ending range() to > fuel a for-loop 'counter', and within that loop perform the dice-roll(s) > and decide if it is time to 'break'. The range replaces the "True". The > for-loops index or 'counter' will deliver the desired result. > > Neat? No! > Readable? No! > An improvement over the while-True? Definitely not! > Yet, the mechanism is the same AND offers a built-in counter. Hmmm... Yeah. Here's a little context. I came across this by processing a list of exercises. (I'm teaching a course --- you know that by now, I guess.) So the first thing I observed was the equal volume of work dedicated to while loops and for loops --- so I decided to compared which appeared more often in a certain sample of well-written Python code. It turns out the for loop was much more frequent. Students have been reporting too much work in too little time, so I decided to reduce the number of exercises involving while loops. When I began to look at the exercises, to see which ones I'd exclude, I decided to exclude them all --- lol! --- except for one. The one that remained was this one about rolling dice until a satisfying result would appear. (All other ones were totally more naturally written with a for loop.) So if I were to also write this with a for-loop, it'd defeat the purpose of the course's moment. Besides, I don't think a for-loop would improve the readability here. But I thought your protest against the while-True was very well put: while-True is not too readable for a novice. Surely what's readable or more-natural /to someone/ is, well, subjective (yes, by definition). But perhaps we may agree that while rolling dice until a certain success, we want to roll them while something happens or doesn't happen. One of the two. So while-True is a bit of a jump. Therefore, in this case, the easier and more natural option is to say while-x-not-equal-y. But this approach seems to force me into initializing x, y with different values. > Returning to the concern: > > x, y = 0, 1 > c = 0 > > The first line is purely to ensure that the loop executes at least once, > ie the two assigned-values are not 'real'. Hence the disquiet! > > Initiating the counter is unavoidable (@Chris' suggestion notwithstanding). > > However, remember that Python (like decent DBs) has a concept (and an > idiom) of a value to be used when we don't (yet) know what the value > is/should be! Further that Python allows such a value to be used in > comparisons: > >>>> None != None > False >>>> None == None > True > > Leading to: > > c, x, y = 0, None, None > while ... > > > Which solution reverts to the original loop-contents. which seem more > obvious an
Re: on writing a while loop for rolling two dice
On 30/08/2021 06:17, dn via Python-list wrote: OTOH the simulation of rolling n-number of dice, as would happen in the real-world, would be broken by making the computer's algorithm more efficient (rolling until the first non-equal value is 'found'). Does that mean the realism of the model dies? You've got to ask your dietician... (I'm sure everyone agrees that I should stop here. And stop I will) -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On Tue, Aug 31, 2021 at 12:28 AM Peter Otten <__pete...@web.de> wrote: > > On 30/08/2021 15:50, Chris Angelico wrote: > > > def how_many_times(): > > return next((count, rolls) for count, rolls in > > enumerate(iter(roll, None)) if len(Counter(rolls)) == 1) > > > That's certainly the most Counter-intuitive version so far;) Thank you, I appreciate that :) > > Do I get bonus points for it being a one-liner that doesn't fit in > > eighty characters? > > Nah, but you'll get an honorable mention when you run it through > pycodestyle without line break... > Are there any linters that warn against "unintuitive use of two-argument iter()"? ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 30/08/2021 15:50, Chris Angelico wrote: def how_many_times(): return next((count, rolls) for count, rolls in enumerate(iter(roll, None)) if len(Counter(rolls)) == 1) That's certainly the most Counter-intuitive version so far;) Do I get bonus points for it being a one-liner that doesn't fit in eighty characters? Nah, but you'll get an honorable mention when you run it through pycodestyle without line break... -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
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? ChrisA -- https://mail.python.org/mailman/listinfo/python-list
RE: on writing a while loop for rolling two dice
> 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) -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 30/08/2021 00.47, Peter Otten wrote: > On 29/08/2021 12:13, dn via Python-list wrote: >> On 29/08/2021 20.06, Peter Otten wrote: >> ... >>> OK, maybe a bit complicated... but does it pay off if you want to >>> generalize? >>> >> def roll_die(faces): >>> while True: yield random.randrange(1, 1 + faces) >>> >> def hmt(faces, dies): >>> for c, d in enumerate(zip(*[roll_die(faces)]*dies), 1): >>> if len(set(d)) == 1: return c, d >> >> >> Curiosity: >> why not add dies as a parameter of roll_die()? > > Dunno. Maybe because I've "always" [1] wanted a version of > random.randrange() that generates values indefinitely. It would need to > check its arguments only once, thus leading to some extra Each code-unit should do one job, and do it well! SRP... >> Efficiency: >> - wonder how max( d ) == min( d ) compares for speed with the set() type >> constructor? > > I did the simplest thing, speed was not a consideration. If it is, and > dies (sorry for that) is large I'd try > > first = d[0] > all(x == first for x in d) # don't mind one duplicate test > > For smaller numbers of dice I'd unpack (first, *rest) inside the for > loop. But it's a trade-off, you' have to measure if/when it's better to > go through the whole tuple in C. For larger numbers of dice, and presuming a preference for an inner-function which rolls only a single die per call; would it be more efficient to test each individual die's value against the first, immediately after its (individual) roll/evaluation (rinse-and-repeat for each die thereafter)? This, on the grounds that the first mis-match obviates the need to examine (or even roll), any other die/dice in the collection. OTOH the simulation of rolling n-number of dice, as would happen in the real-world, would be broken by making the computer's algorithm more efficient (rolling until the first non-equal value is 'found'). Does that mean the realism of the model dies? (sorry - no, I'm not sorry - you deserved that!) Does one "roll" a die, or "shake the dice"??? We don't know the OP's requirements wrt to execution-efficiency. However, as you (also) probably suffered, such exercises regularly feature in stats and probability courses. Sometimes 'the numbers' are quite large in order to better-illustrate ("smooth") distribution characteristics, etc. I have a love?hate relationship with questions of Python and 'efficiency'. Today, discovered that using a cut-down Linux version (on AWS) was actually slower than using a full-fat distribution - upon analysis, my friendly 'expert' was able to point the finger at the way the two distros compiled/prepared/distribute the(ir) Python Interpreter. (I'm glad he thought such investigation 'fun'!) All of which further complicates the business of design, given we already know of situations where approach-a will run faster than approach-b, on your machine; yet the comparison may be reversed on mine. This discussion forms a sub-set of that: when to use the built-in functions (implemented in C) because they are (claimed to be) more efficient than another approach - and, when one approach using a built-in function might be faster than another 'built-in'/C-coded approach. ("small things amuse small minds" - mind how you describe my mind!) "Bottom line": I prefer to think of Python's "efficiency" as reflected in the amount of my time that is needed, in order to complete a project! >> - alternately len( d ) < 2? >> - or len( d ) - 1 coerced to a boolean by the if? >> - how much more efficient is any of this (clever thinking!) than the >> OP's basic, simpler, and thus more readable, form? > > It really isn't efficiency, it's a (misled?) sense of aesthetics where > I've come to prefer > > - for-loops over while, even when I end up with both to get the desired for > > - enumerate() over an explicit counter even though there is the extra > unpack, and you still need to initialize the counter in the general case: > > for i, item in enumerate([]): pass > print(f"There are {i+1} items in the list.") # Oops Next thing you'll be using for-else... [insane giggling] It's interesting how we arrive at these views (as a trainer I spend a lot of time trying to detect how learners build their mental maps, or "models", of each topic). I've always had a clear 'formula'/rule/hobgoblin: if the number of loops can be predicted, use 'for', otherwise use 'while'. Of course, Python alters that view because it offers a for-each, which means that I don't need to know the number of loops, only that the loop will cycle through each item in the iterable. It used to be a far simpler world! That said, I really miss the option of while controlling the loop with a pre-condition AND having a repeat...until controlling the loop with a post-condition - the former enabling >=0 loops; the latter, requiring at least one! Using enumerate() may be a matter of aesthetics (English-English spelling!). However, it is a basic Python idiom. It is as much
Re: on writing a while loop for rolling two dice
On Mon, Aug 30, 2021 at 9:53 AM dn via Python-list wrote: > > On 29/08/2021 22.24, Chris Angelico wrote: > > On Sun, Aug 29, 2021 at 8:14 PM dn via Python-list > > wrote: > >> Efficiency: > >> - wonder how max( d ) == min( d ) compares for speed with the set() type > >> constructor? > > > > That may or may not be an improvement. > > > >> - alternately len( d ) < 2? > >> - or len( d ) - 1 coerced to a boolean by the if? > > > > Neither of these will make any notable improvement. The work is done > > in constructing the set, and then you're taking the length. How you do > > the comparison afterwards is irrelevant. > > It was far too late for either of us (certainly this little boy) to be > out-and-coding - plus an excellent illustration of why short-names are a > false-economy which can quickly (and easily) lead to "technical debt"! > > > The "d" is a tuple (the 'next' returned from the zip-output object) > consisting of a number of die-throw results). Thus, can toss that into > len() without (any overhead of) conversion to a set. Oh. Well, taking the length of the tuple is fast... but useless. The point was to find out if everything in it was unique :) Conversion to set tests this because the length of the set is the number of unique elements; checking max and min works because two scans will tell you if they're all the same; using all with a generator stops early if you find a difference, but requires back-and-forth calls into Python code; there are various options, and the choice probably won't make a material performance difference anyway :) ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 29/08/2021 22.24, Chris Angelico wrote: > On Sun, Aug 29, 2021 at 8:14 PM dn via Python-list > wrote: >> Efficiency: >> - wonder how max( d ) == min( d ) compares for speed with the set() type >> constructor? > > That may or may not be an improvement. > >> - alternately len( d ) < 2? >> - or len( d ) - 1 coerced to a boolean by the if? > > Neither of these will make any notable improvement. The work is done > in constructing the set, and then you're taking the length. How you do > the comparison afterwards is irrelevant. It was far too late for either of us (certainly this little boy) to be out-and-coding - plus an excellent illustration of why short-names are a false-economy which can quickly (and easily) lead to "technical debt"! The "d" is a tuple (the 'next' returned from the zip-output object) consisting of a number of die-throw results). Thus, can toss that into len() without (any overhead of) conversion to a set. -- Regards, =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 29/08/2021 12:13, dn via Python-list wrote: On 29/08/2021 20.06, Peter Otten wrote: ... OK, maybe a bit complicated... but does it pay off if you want to generalize? def roll_die(faces): while True: yield random.randrange(1, 1 + faces) def hmt(faces, dies): for c, d in enumerate(zip(*[roll_die(faces)]*dies), 1): if len(set(d)) == 1: return c, d Curiosity: why not add dies as a parameter of roll_die()? Dunno. Maybe because I've "always" [1] wanted a version of random.randrange() that generates values indefinitely. It would need to check its arguments only once, thus leading to some extra Efficiency: - wonder how max( d ) == min( d ) compares for speed with the set() type constructor? I did the simplest thing, speed was not a consideration. If it is, and dies (sorry for that) is large I'd try first = d[0] all(x == first for x in d) # don't mind one duplicate test For smaller numbers of dice I'd unpack (first, *rest) inside the for loop. But it's a trade-off, you' have to measure if/when it's better to go through the whole tuple in C. - alternately len( d ) < 2? - or len( d ) - 1 coerced to a boolean by the if? - how much more efficient is any of this (clever thinking!) than the OP's basic, simpler, and thus more readable, form? It really isn't efficiency, it's a (misled?) sense of aesthetics where I've come to prefer - for-loops over while, even when I end up with both to get the desired for - enumerate() over an explicit counter even though there is the extra unpack, and you still need to initialize the counter in the general case: for i, item in enumerate([]): pass print(f"There are {i+1} items in the list.") # Oops English language 'treachery': - one die - multiple dice You might have inferred that I knew (or had looked up) the singular of dice, so this is but a momentary lapse of reason. It hurts me more than you, trust me. Not as much, as going on record with confusing they're and their, but still ;) (probably not followed in US-English (can't recall), particularly on computers running the Hollywood Operating System). I've come to the conclusion that International English is hopelessly and inevitably broken. That's the price native speakers have to pay for having they're (oops, I did it again!) language used as lingua franca. Continuous Education: Thanks for the reminder that enumerate() can be seeded with a "start" value! [1] I think I've suggested reimplementing the whole module in terms of generators -- can't find the post though. -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On Sun, Aug 29, 2021 at 8:14 PM dn via Python-list wrote: > Efficiency: > - wonder how max( d ) == min( d ) compares for speed with the set() type > constructor? That may or may not be an improvement. > - alternately len( d ) < 2? > - or len( d ) - 1 coerced to a boolean by the if? Neither of these will make any notable improvement. The work is done in constructing the set, and then you're taking the length. How you do the comparison afterwards is irrelevant. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 29/08/2021 20.06, Peter Otten wrote: ... > OK, maybe a bit complicated... but does it pay off if you want to > generalize? > def roll_die(faces): > while True: yield random.randrange(1, 1 + faces) > def hmt(faces, dies): > for c, d in enumerate(zip(*[roll_die(faces)]*dies), 1): > if len(set(d)) == 1: return c, d Curiosity: why not add dies as a parameter of roll_die()? Efficiency: - wonder how max( d ) == min( d ) compares for speed with the set() type constructor? - alternately len( d ) < 2? - or len( d ) - 1 coerced to a boolean by the if? - how much more efficient is any of this (clever thinking!) than the OP's basic, simpler, and thus more readable, form? English language 'treachery': - one die - multiple dice (probably not followed in US-English (can't recall), particularly on computers running the Hollywood Operating System). Continuous Education: Thanks for the reminder that enumerate() can be seeded with a "start" value! -- Regards, =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 28/08/2021 14:00, Hope Rouselle wrote: def how_many_times(): x, y = 0, 1 c = 0 while x != y: c = c + 1 x, y = roll() return c, (x, y) --8<---cut here---end--->8--- Why am I unhappy? I'm wish I could confine x, y to the while loop. The introduction of ``x, y = 0, 1'' must feel like a trick to a novice. How would you write this? Thank you! I'd probably hide the while loop under the rug: >>> import random >>> def roll_die(): while True: yield random.randrange(1, 7) Then: >>> def hmt(): for c, (x, y) in enumerate(zip(roll_die(), roll_die()), 1): if x == y: return c, (x, y) >>> hmt() (1, (2, 2)) >>> hmt() (4, (4, 4)) >>> hmt() (1, (5, 5)) OK, maybe a bit complicated... but does it pay off if you want to generalize? >>> def roll_die(faces): while True: yield random.randrange(1, 1 + faces) >>> def hmt(faces, dies): for c, d in enumerate(zip(*[roll_die(faces)]*dies), 1): if len(set(d)) == 1: return c, d >>> hmt(10, 1) (1, (2,)) >>> hmt(10, 2) (3, (10, 10)) >>> hmt(10, 3) (250, (5, 5, 5)) >>> hmt(1, 10) (1, (1, 1, 1, 1, 1, 1, 1, 1, 1, 1)) You decide :) -- https://mail.python.org/mailman/listinfo/python-list
RE: on writing a while loop for rolling two dice
And there is the ever popular recursive version you call with no while loop in sight. And, oddly, no variable declared in your main body: # CODE START --- import random def roll2(): return random.randint(1,6), random.randint(1,6) def roll_equal(counter): first, second = roll2() encountered = counter + 1 if (first == second): return(encountered) else: return(roll_equal(encountered)) #--- CODE END --- Since the result is usually a single digit of iterations, no biggie. Here is some output: >>> roll_equal(0) 6 >>> roll_equal(0) 7 >>> roll_equal(0) 1 >>> roll_equal(0) 7 >>> roll_equal(0) 6 >>> [ roll_equal(0) for n in range(10)] [3, 4, 2, 5, 8, 1, 1, 2, 3, 9] >>> [ roll_equal(0) for n in range(10)] [3, 3, 7, 19, 7, 2, 1, 3, 8, 4] >>> [ roll_equal(0) for n in range(10)] [1, 3, 1, 13, 11, 4, 3, 5, 2, 4] And the code can be a tad shorter, LOL! But obviously then you have more overhead than an iterative solution or one using a generator ... -Original Message- From: Python-list On Behalf Of Alan Gauld via Python-list Sent: Saturday, August 28, 2021 6:52 PM To: python-list@python.org Subject: Re: on writing a while loop for rolling two dice On 28/08/2021 21:50, Hope Rouselle wrote: >>> roll_count = 0 >>> while True: >>> outcome = roll_two_dice() >>> roll_count += 1 >>> if outcome[ 0 ]== outcome[ 1 ]: break return roll_count, >>> outcome[ 0 ] >> > > Wait, I'm surprised ``outcome'' is still a valid name at the > return-statement. Wasn't it defined inside the while? If that really bugs you just replace the break with the return. >>> if outcome[ 0 ]== outcome[ 1 ]: >>>return roll_count, outcome[ 0 ] Now its all inside the loop. But remember readable code is better than cute code every time. And personally I'd just declare the x,y up front. Easier to understand and debug IMHO. -- 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: on writing a while loop for rolling two dice
On 28/08/2021 21:50, Hope Rouselle wrote: >>> roll_count = 0 >>> while True: >>> outcome = roll_two_dice() >>> roll_count += 1 >>> if outcome[ 0 ]== outcome[ 1 ]: break >>> return roll_count, outcome[ 0 ] >> > > Wait, I'm surprised ``outcome'' is still a valid name at the > return-statement. Wasn't it defined inside the while? If that really bugs you just replace the break with the return. >>> if outcome[ 0 ]== outcome[ 1 ]: >>>return roll_count, outcome[ 0 ] Now its all inside the loop. But remember readable code is better than cute code every time. And personally I'd just declare the x,y up front. Easier to understand and debug IMHO. -- 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: on writing a while loop for rolling two dice
On 8/28/2021 8:00 AM, Hope Rouselle wrote: How should I write this? I'd like to roll two six-sided dice until I get the same number on both. I'd like to get the number of times I tried. Here's a primitive I'm using: --8<---cut here---start->8--- x, y = roll() x 6 y 6 # lucky x, y = roll() x 4 y 1 # unlucky --8<---cut here---end--->8--- Here's my solution: --8<---cut here---start->8--- def how_many_times(): x, y = 0, 1 c = 0 while x != y: c = c + 1 x, y = roll() return c, (x, y) --8<---cut here---end--->8--- Why am I unhappy? I'm wish I could confine x, y to the while loop. The introduction of ``x, y = 0, 1'' must feel like a trick to a novice. How would you write this? Thank you! Something like (untested) c = 0 while True: c += 1 x, y = roll() if x == y: return c, (x,y) or even better to me, as it will not loop forever if you mess up the condition for i in range(1, 100): x, y = roll() if x == y: return i, (x,y) # return "The universe ends as the essentially impossible happened" -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 29/08/2021 08.46, Hope Rouselle wrote: > Here's my solution: > > --8<---cut here---start->8--- > def how_many_times(): > x, y = 0, 1 > c = 0 > while x != y: > c = c + 1 > x, y = roll() > return c, (x, y) > > Why am I unhappy? I'm wish I could confine x, y to the while loop. The > introduction of ``x, y = 0, 1'' must feel like a trick to a novice. How > would you write this? > r...@zedat.fu-berlin.de (Stefan Ram) writes: >> """Rolls two dice until both yield the same value. >> Returns the number of times the two dice were rolled >> and the final value yielded.""" >> roll_count = 0 >> while True: >> outcome = roll_two_dice() >> roll_count += 1 >> if outcome[ 0 ]== outcome[ 1 ]: break >> return roll_count, outcome[ 0 ] > > You totally convinced me. Thanks. On the other hand... whilst you expressed concern about the apparently disconnected 'set up' necessary before the loop, this solution adds a "True/Forever" and a "Break" construct, which some may deem not that much better (if at all) The idea of abrogating the while-condition but then adding another (disconnected) condition to break, seems to hold equal potential for confusion. or the type of dissatisfaction which motivated the original question! Looking at that from the inside-out, the loop's contents perform two functions: the rolling and counting (per Statement of Requirements), but also a loop-controlling element. Thus the reader's question: "what does this loop do?" is conflated with "how many times does it do it?". Let's go completely off-the-rails, why not use a never-ending range() to fuel a for-loop 'counter', and within that loop perform the dice-roll(s) and decide if it is time to 'break'. The range replaces the "True". The for-loops index or 'counter' will deliver the desired result. Neat? No! Readable? No! An improvement over the while-True? Definitely not! Yet, the mechanism is the same AND offers a built-in counter. Hmmm... Returning to the concern: x, y = 0, 1 c = 0 The first line is purely to ensure that the loop executes at least once, ie the two assigned-values are not 'real'. Hence the disquiet! Initiating the counter is unavoidable (@Chris' suggestion notwithstanding). However, remember that Python (like decent DBs) has a concept (and an idiom) of a value to be used when we don't (yet) know what the value is/should be! Further that Python allows such a value to be used in comparisons: >>> None != None False >>> None == None True Leading to: c, x, y = 0, None, None while ... Which solution reverts to the original loop-contents. which seem more obvious and thus more readable. (YMMV!) Simplicity over 'being clever'... -- Regards, =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
Hope Rouselle writes: > r...@zedat.fu-berlin.de (Stefan Ram) writes: > >> Hope Rouselle writes: >>>How would you write this? >> >> """Rolls two dice until both yield the same value. >> Returns the number of times the two dice were rolled >> and the final value yielded.""" >> roll_count = 0 >> while True: >> outcome = roll_two_dice() >> roll_count += 1 >> if outcome[ 0 ]== outcome[ 1 ]: break >> return roll_count, outcome[ 0 ] > > You totally convinced me. Thanks. Wait, I'm surprised ``outcome'' is still a valid name at the return-statement. Wasn't it defined inside the while? Shouldn't its scope be restricted to the while block? I had no idea. I should learn some Python. -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
r...@zedat.fu-berlin.de (Stefan Ram) writes: > Hope Rouselle writes: >>How would you write this? > > """Rolls two dice until both yield the same value. > Returns the number of times the two dice were rolled > and the final value yielded.""" > roll_count = 0 > while True: > outcome = roll_two_dice() > roll_count += 1 > if outcome[ 0 ]== outcome[ 1 ]: break > return roll_count, outcome[ 0 ] You totally convinced me. Thanks. -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On Sun, Aug 29, 2021 at 7:37 AM Hope Rouselle wrote: > > How should I write this? I'd like to roll two six-sided dice until I > get the same number on both. I'd like to get the number of times I > tried. Here's a primitive I'm using: > > --8<---cut here---start->8--- > >>> x, y = roll() > >>> x > 6 > >>> y > 6 # lucky > > >>> x, y = roll() > >>> x > 4 > >>> y > 1 # unlucky > --8<---cut here---end--->8--- > > Here's my solution: > > --8<---cut here---start->8--- > def how_many_times(): > x, y = 0, 1 > c = 0 > while x != y: > c = c + 1 > x, y = roll() > return c, (x, y) > --8<---cut here---end--->8--- > > Why am I unhappy? I'm wish I could confine x, y to the while loop. The > introduction of ``x, y = 0, 1'' must feel like a trick to a novice. How > would you write this? Thank you! Your loop, fundamentally, is just counting. So let's just count. def how_many_times(): for c in itertools.count(): ... Inside that loop, you can do whatever you like, including returning immediately if you have what you want. I'll let you figure out the details. :) ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
r...@zedat.fu-berlin.de (Stefan Ram) writes: > Hope Rouselle writes: >>Wait, I'm surprised ``outcome'' is still a valid name at the >>return-statement. Wasn't it defined inside the while? Shouldn't its >>scope be restricted to the while block? I had no idea. I should learn >>some Python. > > In Python, local names can be introduced by an assignment > and have function scope. There is no block scope in Python. > > Below, "name" /is/ a local name already, but is being > used before being assigned to. > > def function(): > if False: > name = 0 > return name > > function() > > # return name > # UnboundLocalError: local variable 'name' referenced before assignment I appreciated the example. I had no idea. (I had looked up the rules and it was pretty simple to understand, but an example is always nice.) Thank you so much. -- https://mail.python.org/mailman/listinfo/python-list
on writing a while loop for rolling two dice
How should I write this? I'd like to roll two six-sided dice until I get the same number on both. I'd like to get the number of times I tried. Here's a primitive I'm using: --8<---cut here---start->8--- >>> x, y = roll() >>> x 6 >>> y 6 # lucky >>> x, y = roll() >>> x 4 >>> y 1 # unlucky --8<---cut here---end--->8--- Here's my solution: --8<---cut here---start->8--- def how_many_times(): x, y = 0, 1 c = 0 while x != y: c = c + 1 x, y = roll() return c, (x, y) --8<---cut here---end--->8--- Why am I unhappy? I'm wish I could confine x, y to the while loop. The introduction of ``x, y = 0, 1'' must feel like a trick to a novice. How would you write this? Thank you! -- https://mail.python.org/mailman/listinfo/python-list
Re: exiting a while loop
On 2020-05-22, DL Neil via Python-list wrote: > On 23/05/20 4:31 AM, Grant Edwards wrote: >> On 2020-05-22, Peter Otten <__pete...@web.de> wrote: >> >>> If you want to terminate the script you can use exit. However exit >>> is a function, and you have to call it >>> >>> exit() >> >> >> >> Actually it's an instance of _sitebuiltins.Quitter not a function. >> >> You still have to call it. ;) >> >> > Which definition (may) make it 'worse' (when compared with "break"): Oh, he definitely wanted break instead of exit(), and I assume the OP had already taken that advice. That's why I'm claiming extra pedant points: clarifying a pointless detail about something the OP didn't want to be using in first place and which had already been replaced by something else. -- Grant -- https://mail.python.org/mailman/listinfo/python-list
Re: exiting a while loop
On 5/22/2020 12:31 PM, Grant Edwards wrote: On 2020-05-22, Peter Otten <__pete...@web.de> wrote: If you want to terminate the script you can use exit. However exit is a function, and you have to call it exit() Actually it's an instance of _sitebuiltins.Quitter not a function. Which means that it is not part of the language and is not guaranteed to exist and will not if the local site module does not inject it. quit() and exit() are only meant for interactive use at the >>> prompt as a cross-platform alternative to ^D or ^Z on non-Windows or Windows. They should not be used in programs unless explicitly defined or imported. The reason both exist, violating the 'one obvious rule' is because both are (were) used used in various other REPLs and interactive text programs. -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
Re: exiting a while loop
On 23/05/20 4:31 AM, Grant Edwards wrote: On 2020-05-22, Peter Otten <__pete...@web.de> wrote: If you want to terminate the script you can use exit. However exit is a function, and you have to call it exit() Actually it's an instance of _sitebuiltins.Quitter not a function. You still have to call it. ;) Which definition (may) make it 'worse' (when compared with "break"): doesn't exit() also close the application-window under some OpSys (if not all) - which would 'disappear' the output before it could be read? -- Regards =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: exiting a while loop
On 2020-05-22, Peter Otten <__pete...@web.de> wrote: > If you want to terminate the script you can use exit. However exit > is a function, and you have to call it > > exit() Actually it's an instance of _sitebuiltins.Quitter not a function. You still have to call it. ;) -- Grant -- https://mail.python.org/mailman/listinfo/python-list
Re: exiting a while loop
On 2020-05-22 7:49 a.m., John Yeadon via Python-list wrote: > Am I unreasonable in expecting this code to exit when required? Yes. > # Add up the powers of 2 starting with 2**0 until 2 million is met. > n = 1 > target = 200 > sum = 0 > > while True: > x = 2 ** (n - 1) > sum += x > print(n, sum) > if sum >= target: > print("Target met.") > exit > n += 1 > > print("\n", n, "terms are required.") I think that you meant "break", not "exit". -- D'Arcy J.M. Cain Vybe Networks Inc. A unit of Excelsior Solutions Corporation - Propelling Business Forward http://www.VybeNetworks.com/ IM:da...@vex.net VoIP: sip:da...@vybenetworks.com -- https://mail.python.org/mailman/listinfo/python-list
Re: exiting a while loop
On Friday, May 22, 2020, at 7:49, John Yeadon via Python-list wrote: > Am I unreasonable in expecting this code to exit when required? Yes. :-) > # Add up the powers of 2 starting with 2**0 until 2 million is met. > n = 1 > target = 200 > sum = 0 > > while True: > x = 2 ** (n - 1) > sum += x > print(n, sum) > if sum >= target: > print("Target met.") > exit Try break instead of exit. See https://docs.python.org/3/reference/compound_stmts.html#the-for-statement for more information. > n += 1 > > print("\n", n, "terms are required.") -- “Atoms are not things.” – Werner Heisenberg Dan Sommers, http://www.tombstonezero.net/dan -- https://mail.python.org/mailman/listinfo/python-list
Re: exiting a while loop
John Yeadon via Python-list wrote: > Am I unreasonable in expecting this code to exit when required? It is unreasonable to expect something that doesn't match what you read in the tutorial ;) If you want to terminate the script you can use exit. However exit is a function, and you have to call it exit() to actually do anything. If you want to terminate just the loop, which is more likely because there is a print() following it, you can do this with break (which is a statement, so no trailing ()): > # Add up the powers of 2 starting with 2**0 until 2 million is met. > n = 1 > target = 200 > sum = 0 > > while True: > x = 2 ** (n - 1) > sum += x > print(n, sum) > if sum >= target: > print("Target met.") break > n += 1 > > print("\n", n, "terms are required.") -- https://mail.python.org/mailman/listinfo/python-list
Re: exiting a while loop
No not really. If you use a breakpoint and a debugger you will find out that your code continues till 2 M is met and then stops printing numbers continuously. On Fri, 22 May, 2020, 5:20 pm John Yeadon via Python-list, < python-list@python.org> wrote: > Am I unreasonable in expecting this code to exit when required? > > > # Add up the powers of 2 starting with 2**0 until 2 million is met. > n = 1 > target = 200 > sum = 0 > > while True: > x = 2 ** (n - 1) > sum += x > print(n, sum) > if sum >= target: > print("Target met.") > exit > n += 1 > > print("\n", n, "terms are required.") > > -- > https://mail.python.org/mailman/listinfo/python-list > -- https://mail.python.org/mailman/listinfo/python-list
Re: exiting a while loop
On Fri, May 22, 2020 at 7:51 AM John Yeadon via Python-list wrote: > > Am I unreasonable in expecting this code to exit when required? > > > # Add up the powers of 2 starting with 2**0 until 2 million is met. > n = 1 > target = 200 > sum = 0 > > while True: > x = 2 ** (n - 1) > sum += x > print(n, sum) > if sum >= target: > print("Target met.") > exit > n += 1 > > print("\n", n, "terms are required.") exit() -- https://mail.python.org/mailman/listinfo/python-list
exiting a while loop
Am I unreasonable in expecting this code to exit when required? # Add up the powers of 2 starting with 2**0 until 2 million is met. n = 1 target = 200 sum = 0 while True: x = 2 ** (n - 1) sum += x print(n, sum) if sum >= target: print("Target met.") exit n += 1 print("\n", n, "terms are required.") -- https://mail.python.org/mailman/listinfo/python-list
Re: How can i stop this Infinite While Loop - Python
TLDR; declare if homework; doing someone's homework doesn't really help; Python is not ALGOL/Pascal/C/C++ by any other name; Python assignments should promote learning semantics as well as syntax; sometimes re-stating the problem leads to an alternate/better solution. On 31/10/19 12:55 AM, ferzan saglam wrote: I have tried many ways to stop the infinite loop but my program doesn't seem to stop after 10 items! It keeps going...!) --- total = 0 while True: print('Cost of item') item = input() if item != -1: total += int(item) else: break print(total) --- A critique of this thread, plus a suggested approach to a solution:- 1 the OP This is a contrived coding problem. Is it part of a course? To establish an honest relationship with your list-colleagues, should you have declared it as 'homework'? Remembering that no-one 'here' is paid to be helpful, did you politely respond with the clarification requested? (see also later threads) There is an interesting psychology that you will notice when working with other people who are happy to be helpful (per this list-community); that if one stops to think about *how* to pose a question, sometimes the answer 'appears' - a burst of inspiration in your mind. That can be difficult to remember if you've been struggling with a problem for hours with the resultant level of frustration. At least the title of the post: "How can i stop this Infinite While Loop" is descriptive. Compared with some first-time poster's titles, this is clear and competent. Thanks! Thinking about it though, is there a hint of the nature of the problem, or even then an answer, in there? ie pausing to think about it, is the problem actually the "stop" (as emphasised) or might it be the "while"? (more below) 2 respondents This was an 'easy answer' question, so "well done" and "thank you" for jumping-in with the intention of contributing something to the community - quite possibly a first post for some. I encourage you to participate and do NOT wish to criticise you for having the best of motivations. However, it is always a good idea to consider not only "the question", as asked, but to 'first ask why?' (which happens to (almost) be the title of a thoroughly-recommendable book for managers, potential-managers, and certainly coaches/mentors to read). You can see this in one respondent's <<user the possibility to try 10 times or enter -1 to end the script, right?>>> If (and this is *my* assumption!), the OP is a student attempting to learn Python, cf an experienced pythonista; giving "the answer" is NOT as helpful as it might seem. That's why the "pseudo code" solution was 'better' than a Python equivalent. What should the OP learn? Given 'the answer', would the OP be able to solve a similar problem when next encountered? If the OP's learning-objective is 'Python', then the pseudo-code helped clarify the necessary thinking, without detracting from the OP's learning-opportunity. (cf an algorithms course) In fact, and quite coincidentally, the best learning-opportunity here, has probably been the "off by one" experience - which the OP did indeed learn for himself. (Well done!) 3 the question itself/the questioner The way the OP has attempted to solve this contrived-problem indicates a fundamental lack of understanding of the way Python works and/or the way pythonista think. However, the way the question has been posed indicates much the same! It smacks of an old, even ancient, ComSc problem; previously applied to other languages (something I might have written when learning/teaching FORTRAN more than four decades ago, for example). How does this coding-problem contribute to the *Python* learning process? (as well as contributing towards the learning ComSc principles, eg managing/terminating loops) Thus: The output I am aiming for is for the code to stop asking 'Cost of item' after 10 inputs or until -1 is typed, but the code repeats itself on an infinite loop. I cannot seem to stop the infinite loop. expresses the problem, but in the manner of other languages. The focus has been put on the "-1" fact - how to "stop". (remember the OP's title!) Question: since we no longer present data as decks of punched-cards, what is today's more usual way to indicate EOF/EOD? ("end of file", "end of data") Is the minus-one "flag" a very good approach, or even particularly representative of work-place 'realities'? Towards a solution: OK, let's not argue the point - it's certainly beyond the OP's control, so we must consider it a
Re: How can i stop this Infinite While Loop - Python
ferzan saglam wrote: > On Wednesday, October 30, 2019 at 2:19:32 PM UTC, Matheus Saraiva wrote: >> rounds = 0 >> while rounds <= 10: ... > Thanks, it Works superbly. > To get the limit of 10 i wanted, i had to make a slight change: > while rounds <= 9 . That's the (in)famous "off by one" bug ;) To stay consistent with Python's range() and slices it's best to always use "half-open" intervals which include the lower, but not the upper bound. In your case you would keep the start value of 0 and the limit of 10, but change the comparison: rounds = 0 while rounds < 10: ... rounds += 1 -- https://mail.python.org/mailman/listinfo/python-list
Re: How can i stop this Infinite While Loop - Python
On Wednesday, October 30, 2019 at 2:19:32 PM UTC, Matheus Saraiva wrote: > m 30/10/2019 08:55, ferzan saglam escreveu: > > total = 0 > > while True: > > > >print('Cost of item') > >item = input() > > > >if item != -1: > > total += int(item) > >else: > > break > > > > print(total) > The program does not stop because its code does not contain any deals > that make the loop stop after 10 rounds. You can simply implement a > counter that counts the number of times the loop has passed. > > You also did not convert item to int to make the comparison. > > total = 0 > rounds = 0 > while rounds <= 10: > > print('Cost of item') > item = input() > > if int(item) > -1: > total += int(item) > rounds += 1 > else: > break > > print(total) Thanks, it Works superbly. To get the limit of 10 i wanted, i had to make a slight change: while rounds <= 9 . -- https://mail.python.org/mailman/listinfo/python-list
Re: How can i stop this Infinite While Loop - Python
> On Oct 30, 2019, at 4:55 AM, ferzan saglam wrote: > > I have tried many ways to stop the infinite loop but my program doesn't seem > to stop after 10 items! It keeps going...!) > > --- > total = 0 > while True: > > print('Cost of item') > item = input() > > if item != -1: >total += int(item) > else: >break > > print(total) > --- > > > The output I am aiming for is for the code to stop asking 'Cost of item' > after 10 inputs or until -1 is typed, but the code repeats itself on an > infinite loop. I cannot seem to stop the infinite loop. > > Thanks for any help in advance. > -- > https://mail.python.org/mailman/listinfo/python-list > Perhaps some pseudo-code will help. The basic problem involves a loop, as you recognized, but there are two ways to exit the loop: 1) if the user types "-1" 2) if the user gets to 10 items Your code needs to account for both. Here's an description of the solution: Initialize a total at zero Initialize a counter at zero# the user has entered zero prices Loop forever Ask the user to enter a price or type a -1 to indicate that they are finished Convert the user's answer to an integer (assuming all values are integers here) if the user's answer was -1 exit the loop here Add the user's answer to your total Since the user has given you another answer, increment the counter if the user has given you the maximum number of answers exit the loop here Report the total (and perhaps the number of prices entered) Hope that helps, Irv -- https://mail.python.org/mailman/listinfo/python-list
Re: How can i stop this Infinite While Loop - Python
> item = input() > if item != -1: If you try this in the REPL, you'll see that 'item' is a string. You're trying to compare it to an integer, which will always fail. The cheapest way to fix this is probably: if item != '-1': Best, G -- https://mail.python.org/mailman/listinfo/python-list
Re: How can i stop this Infinite While Loop - Python
m 30/10/2019 08:55, ferzan saglam escreveu: total = 0 while True: print('Cost of item') item = input() if item != -1: total += int(item) else: break print(total) The program does not stop because its code does not contain any deals that make the loop stop after 10 rounds. You can simply implement a counter that counts the number of times the loop has passed. You also did not convert item to int to make the comparison. total = 0 rounds = 0 while rounds <= 10: print('Cost of item') item = input() if int(item) > -1: total += int(item) rounds += 1 else: break print(total) -- https://mail.python.org/mailman/listinfo/python-list
Re: How can i stop this Infinite While Loop - Python
>From what I understand you want to give the user the possibility to try 10 times or enter -1 to end the script, right? If so, you need to check if item is -1 or total tries are already 10 and in such a case break the loop. No need for an else branch. Note, input returns an str object but you compare against an integer -> item != -1 This total += int(item) should be raised by one as you don't know what item actually is, it might be a text Eren Am Mi., 30. Okt. 2019 um 13:01 Uhr schrieb ferzan saglam < ferzan...@gmail.com>: > I have tried many ways to stop the infinite loop but my program doesn't > seem to stop after 10 items! It keeps going...!) > > --- > total = 0 > while True: > > print('Cost of item') > item = input() > > if item != -1: > total += int(item) > else: > break > > print(total) > --- > > > The output I am aiming for is for the code to stop asking 'Cost of item' > after 10 inputs or until -1 is typed, but the code repeats itself on an > infinite loop. I cannot seem to stop the infinite loop. > > Thanks for any help in advance. > -- > https://mail.python.org/mailman/listinfo/python-list > -- https://mail.python.org/mailman/listinfo/python-list
How can i stop this Infinite While Loop - Python
I have tried many ways to stop the infinite loop but my program doesn't seem to stop after 10 items! It keeps going...!) --- total = 0 while True: print('Cost of item') item = input() if item != -1: total += int(item) else: break print(total) --- The output I am aiming for is for the code to stop asking 'Cost of item' after 10 inputs or until -1 is typed, but the code repeats itself on an infinite loop. I cannot seem to stop the infinite loop. Thanks for any help in advance. -- https://mail.python.org/mailman/listinfo/python-list
Re: possible bug in while loop test
On 2017-09-02 18:53, Charles Hixson wrote: python3 --version Python 3.5.3 Running on Debian stretch In this code s is a string parameter while (j < k and \ (s[j].isalnum()) or \ (s[j] in seps and s[j+1].isalnum()) ): j = j + 1 print ("i = {0}, j = {1}, k = {2}, len[s] = {3}". \ format(i, j, k, len(s) ) ) Yields the result: i = 25, j = 27, k = 31, len[s] = 32 i = 25, j = 28, k = 31, len[s] = 32 i = 25, j = 29, k = 31, len[s] = 32 i = 25, j = 30, k = 31, len[s] = 32 i = 25, j = 31, k = 31, len[s] = 32 Traceback (most recent call last): File "parse1.py", line 40, in print (parse1("The gostack distimms the doshes.")) File "parse1.py", line 21, in parse1 (s[j] in seps and s[j+1].isalnum()) ): IndexError: string index out of range I hesitate to report this, because I've been wrong so often, but it looks to me like the last iteration should not have happened since j is not less than k. The last iteration happened because j < k when you tested the while loop's condition. You then added 1 to j before printing out j and k. At this print, j >= k. -- https://mail.python.org/mailman/listinfo/python-list
Re: possible bug in while loop test
Charles Hixson wrote: > python3 --version > Python 3.5.3 > > Running on Debian stretch > > In this code s is a string parameter > > while (j < k and \ > (s[j].isalnum()) or \ >(s[j] in seps and s[j+1].isalnum()) ): > j = j + 1 > print ("i = {0}, j = {1}, k = {2}, len[s] = {3}". \ > format(i, j, k, len(s) ) ) > > Yields the result: > > i = 25, j = 27, k = 31, len[s] = 32 > i = 25, j = 28, k = 31, len[s] = 32 > i = 25, j = 29, k = 31, len[s] = 32 > i = 25, j = 30, k = 31, len[s] = 32 > i = 25, j = 31, k = 31, len[s] = 32 > Traceback (most recent call last): >File "parse1.py", line 40, in > print (parse1("The gostack distimms the doshes.")) >File "parse1.py", line 21, in parse1 > (s[j] in seps and s[j+1].isalnum()) ): > IndexError: string index out of range > > I hesitate to report this, because I've been wrong so often, but it > looks to me like the last iteration should not have happened since j is > not less than k. You have made a bit of a mess of the while condition. Removing random space and newlines: (j < k and (s[j].isalnum()) or (s[j] in seps and s[j+1].isalnum())) The structure is a and b or (c and d) # a: j False as you suspect, but then (c and d) is evalued, and if c succeeds also the expression d aka s[j+1].isalnum() which fails on accessing s[j+1]. -- https://mail.python.org/mailman/listinfo/python-list
possible bug in while loop test
python3 --version Python 3.5.3 Running on Debian stretch In this code s is a string parameter while (j < k and \ (s[j].isalnum()) or \ (s[j] in seps and s[j+1].isalnum()) ): j = j + 1 print ("i = {0}, j = {1}, k = {2}, len[s] = {3}". \ format(i, j, k, len(s) ) ) Yields the result: i = 25, j = 27, k = 31, len[s] = 32 i = 25, j = 28, k = 31, len[s] = 32 i = 25, j = 29, k = 31, len[s] = 32 i = 25, j = 30, k = 31, len[s] = 32 i = 25, j = 31, k = 31, len[s] = 32 Traceback (most recent call last): File "parse1.py", line 40, in print (parse1("The gostack distimms the doshes.")) File "parse1.py", line 21, in parse1 (s[j] in seps and s[j+1].isalnum()) ): IndexError: string index out of range I hesitate to report this, because I've been wrong so often, but it looks to me like the last iteration should not have happened since j is not less than k. -- https://mail.python.org/mailman/listinfo/python-list
Re: Python while loop
In <0c642381-4dd2-48c5-bb22-b38f2d5b2...@googlegroups.com> paul.garcia2...@gmail.com writes: > Write a program which prints the sum of numbers from 1 to 101 > (1 and 101 are included) that are divisible by 5 (Use while loop) > x=0 > count=0 > while x<=100: > if x%5==0: > count=count+x > x=x+1 > print(count) > > Question: How does python know what count means? "count" is an english word meaning "how many things do I have?", but python doesn't know that. In python, "count" is just a name; you could have called it "hamburger" and python would treat it just the same. -- John Gordon A is for Amy, who fell down the stairs gor...@panix.com B is for Basil, assaulted by bears -- Edward Gorey, "The Gashlycrumb Tinies" -- https://mail.python.org/mailman/listinfo/python-list
Re: Python while loop
On 29/11/2016 23:58, paul.garcia2...@gmail.com wrote: Write a program which prints the sum of numbers from 1 to 101 ( 1 and 101 are included) that are divisible by 5 (Use while loop) This is the code: x=0 count=0 while x<=100: if x%5==0: count=count+x x=x+1 print(count) This looks at numbers from 0 to 100 inclusive, not 1 to 101. Although it doesn't affect the result. (It will add in 0 which is divisible by 5, but that doesn't change it either. If this is an exercise however, checking the correct range might be important!) -- Bartc -- https://mail.python.org/mailman/listinfo/python-list
Re: Python while loop
On 2016-11-29 23:58, paul.garcia2...@gmail.com wrote: Write a program which prints the sum of numbers from 1 to 101 ( 1 and 101 are included) that are divisible by 5 (Use while loop) This is the code: x=0 count=0 while x<=100: if x%5==0: count=count+x x=x+1 print(count) Question: How does python know what count means ? I see that its declared. What i wanna know is how does it know the iteration or each number it finds divisible by 5 is the "Count" ?? It doesn't, it's just a name, and, anyway, in the code, 'x' is the count... If it _did_ know (which is doesn't), wouldn't it be complaining that 'count' isn't the count but the sum? :-) -- https://mail.python.org/mailman/listinfo/python-list
Python while loop
Write a program which prints the sum of numbers from 1 to 101 ( 1 and 101 are included) that are divisible by 5 (Use while loop) This is the code: x=0 count=0 while x<=100: if x%5==0: count=count+x x=x+1 print(count) Question: How does python know what count means ? I see that its declared. What i wanna know is how does it know the iteration or each number it finds divisible by 5 is the "Count" ?? -- https://mail.python.org/mailman/listinfo/python-list
Re: Iteration, while loop, and for loop
Elizabeth Weiss wrote: > words=["hello", "world", "spam", "eggs"] > counter=0 > max_index=len(words)-1 > > while counter<=max_index: > word=words[counter] > print(word + "!") > counter=counter + 1 while 0 < 10: get 0'th element do something with element increment 0 to 1 (repeat) words[0] gets the 0'th word (arrays/lists start at 0, not 1) That example of his is badly presented.. 1. use i, x, y, z, count in that order for integers 2. do your dirty work in a function 3. keep loops clean and tidy 4. keep data far away from code 5. avoid " when ' does the trick 6. try to create black box functions - that work no matter what you throw at them.. without sacrificing readability - programming is about aesthetics and readability - quite artsy.. (I'm not an expert so.. some of this might be outright wrong) words=['hello', 'world', 'spam', 'eggs'] def display(txt, decoration='!'): message = str(txt) + str(decoration) print(message) i = 0 i_max = len(words) - 1 while i <= i_max: word = words[i] i += 1 display(word) languages that don't have 'for' like C, will use 'while' - in python 'for' is preferred - faster, readable - especially for the example you cited. -- https://mail.python.org/mailman/listinfo/python-list
Re: while loop (Reposting On Python-List Prohibited)
On 12/10/2016 11:15, Peter Otten wrote: BartC wrote: On 12/10/2016 05:30, Lawrence D’Oliveiro wrote: On Wednesday, October 12, 2016 at 11:23:48 AM UTC+13, BartC wrote: while n>=x: n=n-1 print "*"* n else: print ("2nd loop exit n=",n,"x=",x) What is the difference between that and while n>=x: n=n-1 print "*"* n print ("2nd loop exit n=",n,"x=",x) ? None at all. Not so much in this specific example: that message will be shown whether there have been 0 or more iterations of the loop body. But with 'else', if you see the message it means the while statement has been entered. Here: if cond: while n>=x: n=n-1 print "*"* n else: print ("2nd loop exit n=",n,"x=",x) Lawrence is right. The enclosing if doesn't make a difference. The idea is to detect whether the while loop has been entered. With while-else-print, it will always execute the else (assuming no break). With while then print, you can't tell if it has attempted to or not. My example above has wrapped the if-cond around the whole of while-else because it has to (that's the advantage). With a separate print it need not do that: if cond: while n>=x: n=n-1 print "*"* n print ("2nd loop exit n=",n,"x=",x) With real code it may not be as easy to see. 'else' adds structure. -- bartc -- https://mail.python.org/mailman/listinfo/python-list
Re: while loop (Reposting On Python-List Prohibited)
BartC wrote: > On 12/10/2016 05:30, Lawrence D’Oliveiro wrote: >> On Wednesday, October 12, 2016 at 11:23:48 AM UTC+13, BartC wrote: >>> while n>=x: >>> n=n-1 >>> print "*"* n >>> else: >>> print ("2nd loop exit n=",n,"x=",x) >> >> What is the difference between that and >> >> while n>=x: >> n=n-1 >> print "*"* n >> print ("2nd loop exit n=",n,"x=",x) >> >> ? >> >> None at all. >> > > Not so much in this specific example: that message will be shown whether > there have been 0 or more iterations of the loop body. > > But with 'else', if you see the message it means the while statement has > been entered. Here: > > if cond: > while n>=x: >n=n-1 >print "*"* n > else: >print ("2nd loop exit n=",n,"x=",x) Lawrence is right. The enclosing if doesn't make a difference. > when cond is false, nothing will be printed. You then know the while > statement hasn't been entered, so it's not looping for some other reason > than its loop condition being false from the start. > > Another situation is when the loop body contains 'break'; then it will > bypass the 'else' part. This is the only case where while...else makes sense: the code in the else suite is executed if and only if the break was not reached. -- https://mail.python.org/mailman/listinfo/python-list
Re: while loop (Reposting On Python-List Prohibited)
On 12/10/2016 05:30, Lawrence D’Oliveiro wrote: On Wednesday, October 12, 2016 at 11:23:48 AM UTC+13, BartC wrote: while n>=x: n=n-1 print "*"* n else: print ("2nd loop exit n=",n,"x=",x) What is the difference between that and while n>=x: n=n-1 print "*"* n print ("2nd loop exit n=",n,"x=",x) ? None at all. Not so much in this specific example: that message will be shown whether there have been 0 or more iterations of the loop body. But with 'else', if you see the message it means the while statement has been entered. Here: if cond: while n>=x: n=n-1 print "*"* n else: print ("2nd loop exit n=",n,"x=",x) when cond is false, nothing will be printed. You then know the while statement hasn't been entered, so it's not looping for some other reason than its loop condition being false from the start. Another situation is when the loop body contains 'break'; then it will bypass the 'else' part. -- Bartc -- https://mail.python.org/mailman/listinfo/python-list
Re: while loop (Reposting On Python-List Prohibited)
On 11/10/2016 22:26, Lawrence D’Oliveiro wrote: On Wednesday, October 12, 2016 at 6:58:46 AM UTC+13, dhawan...@gmail.com wrote: Only first loop is executing not the second one? n=6 x=1 while x<=n: print("*"*x) x+=1 print('n=', n) print('x=', x) while n>=x: n=n-1 print("*"* n) * ** *** * ** n= 6 x= 7 Moral: always use debug print statements to figure out what is going on. 'else' can be used here: n=6 x=1 while x<=n: print "*"*x x+=1 while n>=x: n=n-1 print "*"* n else: print ("2nd loop exit n=",n,"x=",x) -- Bartc -- https://mail.python.org/mailman/listinfo/python-list
Re: while loop
dhawanpawa...@gmail.com writes: > n=6 > x=1 > while x<=n: > print "*"*x > x+=1 > while n>=x: > n=n-1 > print "*"* n > > > Only first loop is executing not the second one? It's a basic fact about while loops that after the loop the condition is false. The two conditions x <= n and n >= x are equivalent. -- https://mail.python.org/mailman/listinfo/python-list
Re: while loop
On 10/11/2016 11:58 AM, dhawanpawa...@gmail.com wrote: > > n=6 > x=1 > while x<=n: > print "*"*x > x+=1 > while n>=x: > n=n-1 > print "*"* n > > > Only first loop is executing not the second one? Did you try printing out the loop variable to see what it does and what it is after the loop is finished? -- https://mail.python.org/mailman/listinfo/python-list
Re: while loop
On Tue, Oct 11, 2016 at 1:58 PM, wrote: > > n=6 > x=1 > while x<=n: > print "*"*x > x+=1 > while n>=x: > n=n-1 > print "*"* n > > > Only first loop is executing not the second one? Because after the first loop n < x -- https://mail.python.org/mailman/listinfo/python-list
while loop
n=6 x=1 while x<=n: print "*"*x x+=1 while n>=x: n=n-1 print "*"* n Only first loop is executing not the second one? -- https://mail.python.org/mailman/listinfo/python-list