Chris Angelico <ros...@gmail.com> writes: > On Fri, Sep 3, 2021 at 4:33 AM Hope Rouselle <hrouse...@jevedi.com> 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(100000000)"), 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