Learn to Program

Flow Control

Chapter 6

 

Ahhhh, flow control. This is where it all comes together. Even though this chapter is shorter and easier than the methods chapter, it will open up a whole world of programming possibilities. After this chapter, we'll be able to write truly interactive programs; in the past we have made programs which say different things depending on your keyboard input, but after this chapter they will actually do different things, too. But before we can do that, we need to be able to compare the objects in our programs. We need...

Comparison Methods

Let's rush through this part so we can get to the next section, Branching, where all the cool stuff happens. So, to see if one object is greater than or less than another, we use the methods > and <, like this:

print(1 > 2)
print(1 < 2)
False
True

No problem. Likewise, we can find out if an object is greater-than-or-equal-to another (or less-than-or-equal-to) with the methods >= and <=

print(5 >= 5)
print(5 <= 4)
True
False

And finally, we can see if two objects are equal or not using == (which means "are these equal?") and != (which means "are these different?"). It's important not to confuse = with ==. = is for telling a variable to point at an object (assignment), and == is for asking the question: "Are these two objects equal?"

print(1 == 1)
print(2 != 1)
True
True

Of course, we can compare strings, too. When strings get compared, they compare their lexicographical ordering, which basically means their dictionary ordering. cat comes before dog in the dictionary, so:

print('cat' < 'dog')
True

There's a catch, though: the way computers usually do things, they order capital letters as coming before lowercase letters. (That's how they store the letters in fonts, for example: all the capital letters first, then the lowercase ones.) This means that it will think 'Zoo' comes before 'ant', so if you want to figure out which word would come first in a real dictionary, make sure to use lower() (or upper or capitalize()) on both words before you try to compare them.

One last note before Branching: The comparison methods aren't giving us the strings 'True' and 'False'; they are giving us the special objects True and False. (Of course, str(True) gives us 'True', which is why print printed 'True'.) True and False are used all the time in...

Branching

Branching is a simple concept, but powerful. In fact, it's so simple that I bet I don't even have to explain it at all; I'll just show you:

print('Hello, what\'s your name?')
name = input()
print('Hello, ' + name + '.')
if name == 'Chris':
  print('What a lovely name!')
Hello, what's your name?
Chris
Hello, Chris.
What a lovely name!

But if we put in a different name...

Hello, what's your name?
Chewbacca
Hello, Chewbacca.

And that is branching. If what comes after the if is True, we run the code that is indented to the right below the if. If what comes after the if is False, we don't. Plain and simple.

Often, we would like a program to do one thing if an expression is True, and another if it is False. That's what else is for:

print('I am a fortune-teller.  Tell me your name:')
name = input()
if name == 'Chris':
  print('I see great things in your future.')
else:
  print('Your future is... Oh my!  Look at the time!')
  print('I really have to go, sorry!')
I am a fortune-teller.  Tell me your name:
Chris
I see great things in your future.

Now let's try a different name...

I am a fortune-teller.  Tell me your name:
Ringo
Your future is... Oh my!  Look at the time!
I really have to go, sorry!

Branching is kind of like coming to a fork in the code: Do we take the path for people whose name == 'Chris', or else do we take the other path?

And just like the branches of a tree, you can have branches which themselves have branches:

print('Hello, and welcome to 7th grade English.')
print('My name is Mrs. Gabbard.  And your name is...?')
name = input()

if name == name.capitalize():
  print('Please take a seat, ' + name + '.')
else:
  print(name + '?  You mean ' + name.capitalize() + ', right?')
  print('Don\'t you even know how to spell your name??')
  reply = input()
  if reply.lower() == 'yes':
    print('Hmmph!  Well, sit down!')
  else:
    print('GET OUT!!')
Hello, and welcome to 7th grade English.
My name is Mrs. Gabbard.  And your name is...?
chris
chris?  You mean Chris, right?
Don't you even know how to spell your name??
yes
Hmmph!  Well, sit down!

Fine, I'll capitalize it...

Hello, and welcome to 7th grade English.
My name is Mrs. Gabbard.  And your name is...?
Chris
Please take a seat, Chris.

Sometimes it might get confusing trying to figure out where all of the ifs and elses go. What I do is write the else at the same time I write the if. So as I was writing the above program, this is how it looked first:

print('Hello, and welcome to 7th grade English.')
print('My name is Mrs. Gabbard.  And your name is...?')
name = input()

if name == name.capitalize():

else:

Then I filled it in with comments, stuff in the code the computer will ignore:

print('Hello, and welcome to 7th grade English.')
print('My name is Mrs. Gabbard.  And your name is...?')
name = input()

if name == name.capitalize():
  # She's civil.
else:
  # She gets mad.

Anything after a # is considered a comment (unless, of course, you are in a string). After that, I replaced the comments with working code. Some people like to leave the comments in; personally, I think well-written code usually speaks for itself. I used to use more comments, but the more "fluent" in Python I become, the less I use them. I actually find them distracting much of the time. It's a personal choice; you'll find your own (usually evolving) style. So my next step looked like this:

print('Hello, and welcome to 7th grade English.')
print('My name is Mrs. Gabbard.  And your name is...?')
name = input()

if name == name.capitalize():
  print('Please take a seat, ' + name + '.')
else:
  print(name + '?  You mean ' + name.capitalize() + ', right?')
  print('Don\'t you even know how to spell your name??')
  reply = input()
  if reply.lower() == 'yes':
  else:

Again, I wrote down the if and else at the same time. It really helps me keep track of "where I am" in the code. It also makes the job seem easier because I can focus on one small part, like filling in the code between the if and the else. The other benefit of doing it this way is that the computer can understand the program at any stage. Every one of the unfinished versions of the program I showed you would run. They weren't finished, but they were working programs. That way I could test it as I wrote it, which helped to see how it was coming along and where it still needed work. When it passed all of the tests, that's how I knew I was done!

These tips will help you write programs with branching, but they also help with the other main type of flow control:

Looping

Often, you'll want your computer to do the same thing over and over again—after all, that's what computers are supposed to be so good at.

When you tell your computer to keep repeating something, you also need to tell it when to stop. Computers never get bored, so if you don't tell it to stop, it won't. We make sure this doesn't happen by telling the computer to repeat certain parts of a program while a certain condition is True. This works very similarly to how if works:

command = ''

while command != 'bye':
  print(command)
  command = input()

print('Come again soon!')
Hello?
Hello?
Hi!
Hi!
Very nice to meet you.
Very nice to meet you.
Oh... how sweet!
Oh... how sweet!
bye
Come again soon!

And that's a loop. (You may have noticed the blank line at the beginning of the output; it's from the first print, before the first input(). How would you change the program to get rid of this first line. Test it! Did it work exactly like the program above, other than that first blank line?)

Loops allow you to do all kinds of interesting things, as I'm sure you can imagine. However, they can also cause problems if you make a mistake. What if your computer gets trapped in an infinite loop? If you think this may have happened, just hold down the Ctrl key and press C.

Before we start playing around with loops, though, let's learn a few things to make our job easier.

A Little Bit of Logic

Let's take a look at our first branching program again. What if my wife came home, saw the program, tried it out, and it didn't tell her what a lovely name she had? Well... she probably wouldn't care. But I'd care! So let's rewrite it:

print('Hello, what\'s your name?')
name = input()
print('Hello, ' + name + '.')
if name == 'Chris':
  print('What a lovely name!')
else:
  if name == 'Katy':
    print('What a lovely name!')
Hello, what's your name?
Katy
Hello, Katy.
What a lovely name!

It works... but it isn't a very pretty program. Why not? Well, the best rule I ever learned in programming was the DRY rule: Don't Repeat Yourself. I could probably write a small book just on why that is such a good rule. In our case, we repeated the line print('What a lovely name!'). Why is this such a big deal? Well, what if I made a spelling mistake when I rewrote it? What if I wanted to change it from 'lovely' to 'beautiful' on both lines? I'm lazy, remember? Basically, if I want the program to do the same thing when it gets 'Chris' or 'Katy', then it should really do the same thing:

print('Hello, what\'s your name?')
name = input()
print('Hello, ' + name + '.')
if name == 'Chris' or name == 'Katy':
  print('What a lovely name!')
Hello, what's your name?
Katy
Hello, Katy.
What a lovely name!

Much better. In order to make it work, I used or. The other logical operators are and and not. It is always a good idea to use parentheses when working with these. Let's see how they work:

i_am_chris  = True
i_am_purple = False
i_like_food = True
i_eat_rocks = False

print(i_am_chris  and i_like_food)
print(i_like_food and i_eat_rocks)
print(i_am_purple and i_like_food)
print(i_am_purple and i_eat_rocks)
print()
print(i_am_chris  or i_like_food)
print(i_like_food or i_eat_rocks)
print(i_am_purple or i_like_food)
print(i_am_purple or i_eat_rocks)
print()
print(not i_am_purple)
print(not i_am_chris )
True
False
False
False

True
True
True
False

True
False

The only one of these which might trick you is or. In English, we often use "or" to mean "one or the other, but not both." For example, your mom might say, "For dessert, you can have pie or cake." She did not mean you could have them both! A computer, on the other hand, uses or to mean "one or the other, or both." (Another way of saying it is, "at least one of these is True.") This is why computers are more fun than moms.

A Few Things to Try

When you finish those, take a break! You've learned a lot already. Congratulations! Are you surprised at the number of things you can tell a computer to do? A few more chapters and you'll be able to program just about anything. Seriously! Just look at all the things you can do now that you couldn't do without looping and branching.

Now let's learn about a new kind of object, one which keeps track of lists of other objects: arrays.