4
$\begingroup$

I keep seeing examples like the first program bellow, in teaching materials.

Is there a pedagogical reason to teach this first program, compared to the second?

answer=input("Do you wish to continue?")

while answer == "yes":
    answer=input("Do you wish to continue?")

print ("Good bye")

2nd program

answer="yes"

while answer == "yes":
    answer=input("Do you wish to continue?")

print ("Good bye")

An argument for the 2nd one

I think the 2nd program is more elegant: it has less repeated code.

note: when I wrote this I copied the 1st line into the other 2 places, then when I tested it I discovered that I missed the closing ", so had to fix it 3 times. This is an example of why repeated code is a problem, when a program needs re-editing. In the second version, the only repeated code is "yes", so still some room for improvement.

$\endgroup$
  • $\begingroup$ Im' not Python programmer, but I'd expect an equivalent to a "do { answer=input("Do you wish to continue?") } while (answer == "yes")", or even "while (answer = input("....") == yes);" $\endgroup$ – pojo-guy Jan 27 '18 at 15:45
  • 1
    $\begingroup$ @pojo-guy python does not have do …while, and combining assignment into a predicate has been shown to cause much confusion in professional programmers (I would expect the same for beginners). $\endgroup$ – ctrl-alt-delor Jan 28 '18 at 10:50
  • 1
    $\begingroup$ Do you need answer? while input( "Do you wish to continue?" ) == "yes": ... $\endgroup$ – user1692597 Jan 30 '18 at 3:27
  • $\begingroup$ The reason you teach the 1st before the 2nd is because it is the logical result of a flowchart. You loop if the answer is yes, so, you enter the loop if the answer is yes, then you continue till it is not yes. The 2nd example is an optimization of the 1st. $\endgroup$ – Gorchestopher H Jan 31 '18 at 19:29
  • $\begingroup$ @GorchestopherH you have precisely said a reason why the 2nd is better. We are not in the 1960s any more. We now have structured programming, and don't use flow chart. What is more there is no reason that a flow chart can not model ether of these two programs. $\endgroup$ – ctrl-alt-delor Jan 31 '18 at 19:38
3
$\begingroup$

This is a really good place to introduce boolean variables (or just to use them, if they've already been introduced. It also introduces the idea of descriptive variable names.

user_wishes_to_continue = True

while user_wishes_to_continue:
    answer = raw_input("Do you wish to continue?")
    if answer != "yes":
        user_wishes_to_continue = False

print ("Good bye")

Note: here I use raw_input, which returns the user input as a string, rather than input, which interprets the user input as python code (meaning that you have to put "yes" with the quotation marks each time.

$\endgroup$
  • $\begingroup$ nice answer. As I think that conditionals are over used, I would prefer this: user_wishes_to_continue = (answer == "yes") $\endgroup$ – ctrl-alt-delor Jan 30 '18 at 10:05
  • $\begingroup$ raw_input vs input I don't get it. Was this true in python 2? I don't remember. In python3 I get name 'raw_input' is not defined. $\endgroup$ – ctrl-alt-delor Feb 11 '18 at 12:57
  • $\begingroup$ It’s true for python 2; with regular old “input” it tries to interpret the input as a python expression $\endgroup$ – J. Antonio Perez Feb 11 '18 at 13:02
2
$\begingroup$

I think too much emphasis is placed on the "kind" of loop (e.g while vs. repeat until), and on how to structure a while loop if you need to pre fetch some values before you can consider exit condition(s).

Instead, I tutor my students about the infinite loop construct. And then about testing for exit condition(s), and advancing the loop (e.g. fetching), but that those two should occur in the order they naturally arise for the situation (and that we can have multiple exit conditions as needed).

I feel that the while and repeat-until constructs are false source-code optimizations and code should not be considered better for their use over more general looping constructs.

Using the infinite loop method tends to simplify mental task of writing a loop, since you can think about what to do inside the loop instead of how to write what you need in terms of one of the other more limited/specialized looping constructs before you even know what's needed. We also don't have to think in terms of priming before/outside the loop (with code that is then repeated inside the loop).

If it turns out that the exit test is at the beginning then it can be simply and mechanically transformed into a while loop, though I explain that they should not feel this transformation is necessary and might even have to be reversed/undone later (just like they should not feel it necessary to remove block {}s for single line then and else statements).

If the language in question doesn't have an infinite loop construct I advocate while True ..., for the infinite loop, so students can get onto the business of writing the loop instead of thinking about how to structure a loop they haven't even yet written as a while loop.

(The other loop construct I advocate is the counted/bounded for-loop, used when we know up front that some number of iterations are needed instead of a more general exit condition.)

Thus, my answer would be a third option:

while True:
    answer=input("Do you wish to continue?")
    if answer != "yes"
        break;

print ("Good bye")

Compared with the first, it is DRY, and compared with the second, you don't require the students to fake the loop condition to "yes" before running the loop. (Yes, this could be transformed into a repeat-until, but I would say that is an uncessary transformation, though if done, could be done after writing the loop.)

$\endgroup$
  • 1
    $\begingroup$ This kind of thinking doesn't scale. The whole purpose of using a meaningful boolean condition in a loop declaration is so that someone (who could well be yourself!) maintaining the code later can determine at a glance the approximate behavior and purpose of the loop. Writing loops this way forces you to later read every line of code to figure out even the most basic of behaviors; inner break statements can be arbitrarily nested, and thus arbitrarily complex. $\endgroup$ – Ben I. Jan 29 '18 at 0:45
  • $\begingroup$ @BenI. I see student struggling to write loops, because they're thinking about too many things at once. Scaling is and should be their last concern when first learning loops. However, your point is taken, in that we should teach scaling, though perhaps not before the basic concepts of loops. $\endgroup$ – Erik Eidt Jan 29 '18 at 1:10
  • $\begingroup$ Interesting point, and you may be right. I teach sophomores, so they have already written loops before they see me. Perhaps this could be a viable approach at the start. $\endgroup$ – Ben I. Jan 29 '18 at 1:24
  • $\begingroup$ While I don't like the resulting code. I do like the idea of starting with an infinite loop, and then transforming it, to have an exit condition. I have also had problems explaining while True. $\endgroup$ – ctrl-alt-delor Jan 29 '18 at 10:12
2
$\begingroup$

Of the two alternatives listed, I prefer the second, because it Says It Once. (In this case, it's only a call to input() but it's easy to imagine a case where some computation needs to be done as part of the test).

But there's yet another way to write it. If I were to describe verbally what I'm trying to do, I would say something like "Do some stuff (the body of the loop) at least once, and then keep doing it as long as the user wants to continue". And that can be expressed

first_time = True
while first_time or answer == "yes":
    first_time = False
    answer=input("Do you wish to continue?")

print ("Good bye")
$\endgroup$
1
$\begingroup$

I don't particularly care for either as a first program, but the second version makes the case for Say It Once, i.e. don't repeat code.

However (a) it is awfully early to be stressing that rule and there are better examples that can come along soon, and (b) making the case for the rule requires showing (and discussing) both programs.

Showing both can also help make the case (in a smallish way) that different programs have the same effect.

On the other hand, I wouldn't rate one over the other based on just the fact that you mis-typed, but rather that programs change. Saying the same things twice doesn't hold up well if the prompt needs changing and you want it to be the same on the first and subsequent responses.

However, you might want them to not be the same. That again requires some explanation and discussion.

But that is a lot of weight for the first program to carry.


For the mis-typing issue I'd rather use a UI that makes the syntax error visible before you progress any further making that moot.

$\endgroup$
  • $\begingroup$ Not the firs program, but the first program is like one I have seen early in a course. The error I made is just an example of why you may need to re-edit. $\endgroup$ – ctrl-alt-delor Jan 24 '18 at 18:33
  • $\begingroup$ Could you add some advice as to how to introduce loops? (in python). I like to start with a forever loop in scratch. But python does not have them. [May be this is a new question] $\endgroup$ – ctrl-alt-delor Jan 24 '18 at 18:37
  • $\begingroup$ What you have is fine, but it is a lot for a first program. In python you can say while true:, of course. You can also write a function that just loops forever and call it. Since you write it, you can have it expect a lambda expression. (Caveat - I haven't worked out the details of this and tried to integrate it early, but I think it would work.) Python is pretty flexible. $\endgroup$ – Buffy Jan 24 '18 at 18:52
1
$\begingroup$

There are different loop structures for very good reasons. In my early introductory programming examples, I stress at least three types of loops which are not interchangeable:
1. Loops that read data require a priming read before the test at the top.
2. Loops that test at the top can use a flag variable which is changed in the body.
3. Loops that test at the bottom must execute at least once.

These must be explained clearly and with good explanations of why they are used in different circumstances, otherwise you will be condemning people to making many painful bugs which could be easily avoided.

The other vital concept is that every loop (including recursive method calling, as in Functional programming) has three requirements:
1. The control variable must be initialized before the loop begins.
2. The control variable must be updated in the body of the loop.
3. The test that controls the loop must have an achievable end condition.

Without those basics in place, students will flounder.

$\endgroup$
  • $\begingroup$ Welcome to Computer Science Educators. This is a great first answer, and we're always glad to have CS educators join us here. :) It sounds like you'll have a lot to contribute. Feel free to ping me if you need any help navigating around while you get started. (Just add another comment to this answer and start typing @b and my name should pop up.) $\endgroup$ – Ben I. Jan 24 '18 at 17:44
1
$\begingroup$

Some programming and coding workflows\patterns make the repetition rather insignificant.

For example, if one teaches to have constants set from the beginning, something like:

init:
    questionText="Do you wish to continue?
    accept="good"
    finished="good bye"

main code:
    answer=input(questionText)
    while answer=="yes":
        print(accept)
        answer=input(questionText)

    print(finished)

and then if there was a mistake in the text, (as there is in my example), it's very easy to fix, without needing to copy-paste.

As for elegance, I agree that the second option is a bit more elegant. However, it forces the code to enter the loop, and when teaching, it's far better to break an example into smaller parts, so as to allow students to understand each component separately, before they tackle the entire thing.

$\endgroup$
-3
$\begingroup$

Sure, start with the infinite loop, then teach ending conditions later. That is kind of how people learn lots of things: eat, later worry about getting overweight. Maybe we should simply teach all the kinds of bugs, then get to how to actually think through a problem later. After all, doctors are taught about all the kinds of diseases. Health is just a byproduct, maybe, eventually.

Structuring thought and approaching a problem are less important than the initial struggle to grasp the idea that some things in life repeat. It will come after a while. If they repeat the struggle enough. Wait...

$\endgroup$
  • 1
    $\begingroup$ This doesn't really sure like an answer to the question (beyond the first sentence). Can you please add a more direct answer to the question as asked? $\endgroup$ – thesecretmaster Jan 29 '18 at 14:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.