On Sat, Apr 21, 2012 at 6:11 AM, John Zelle <john.zelle@wartburg.edu> wrote:
Kirby,
There are some nice thoughts here that I don't really disagree with, but your code examples don't use the while conditions well. If you put a condition on the loop, there should be no reason to retest the same condition inside the loop. Think of the loop condition as a guard, inside the loop it is true, outside the loop it has become false.
Ah now there's a good rule of thumb maybe. Whatever sentinel condition let you into the loop should not be retested inside the loop. That sounds cogent. A related but somewhat contrary mental picture is: only let live fish into the fish tank, but some die once already inside the tank. Are there cases where you need a preview, aren't ready to exit yet, so need to re-test inside?
That suggests the more elegant (in my eyes) way to write your first example as a sort of sentinel loop:
guess = int(input("Guess? ")) while(guess != secret): // as long as the user didn't get it, get another guess
Pausing here: I see this style quite often, of parens crammed right up against the while keyword. I 'm always worried when I see that in beginner Python that they're imagining while is a callable, and their feeding it some kind of argument. Same with if: I'll get if(x>5): You're an experienced Pythonista though...
print("Nope, try again") guess = int(input("Guess? ")) // Here we know the condition is false print("You guessed it")
There's no reason for the re-test of the loop condition to either break or continue.
Or is there sometimes? I'm thinking this is an excellent rule of thumb of the kind that needs to be broken. Python in particular is interesting because it tries to stay simple - economical in providing control over flow. Other languages gorge themselves on all imaginable kinds of loop syntax, bulking up their keyword vocabulary in the process sometimes (e.g. 'until'). I agree your examples look more elegant and economical than mine featuring a re-test.
This applies to the second example as well, but a post-loop conditional will still be required to figure out why the loop quit:
allowed = 5
guess = int(input("Guess? ")) tries = 1
while guess != secret and tries < allowed: //user gets to try again print("Nope, try again") guess = int(input("Guess? ")) tries += 1
if tries <= allowed: print("You guessed it") else: print("You've maxed out.")
This is where the while statement's option else suite proves useful, if you want to execute a block precisely because the while condition has flipped. I tend to find this useful in conjunction with 'break' though, exploding my earlier hypothesis that while loops should have only one entrance and one exit. while guess != secret: # front door if tries > allowed: print("Bummer") break # back door tries += 1 guess = input ("Guess? ") else: print("Congratulations!") Most public spaces have multiple exits, including a fire escape for emergencies. We haven't even touched on try: / except: as a way to escape a while loop. Mostly I just want these considerations to rise to the surface and ruffle the surface awareness of the beginner mind programmer. This is being a good thread for that. Kirby