Specs
The standard tip rate is 15%, but that's not always used. If service is outstanding, it might be 20% or even 25%. If the service sucks, it might be 10%, 5%, or even nothing, depending on the amount of suckitude.
Let's change our program, so the user enters the service level, and the program works out the appropriate tip rate. The I/O (input/output) will look like this in the console:
For the service level, the user types g, o, or s. The program works out the tip rate from that.
- Great: 20%
- OK: 15%
- Sucked: 10%
Ethan codes
Ethan, you want to try this one? With everyone's help, of course.

Ethan
OK. Let's see...
Should I start with the old tip code?
Sure.

Ethan
Ooo! I know! Let's start by comparing the output, so we know what the new program is going to add.
Note
Ethan is working backwards, starting with the output, so he knows what the new code should do.
Here's the output:
Previous I/O | New I/O |
---|---|
|
|

Ethan
There's one new line of input, for the service level.
One new line of output: the tip rate. The tip rate depends on the service level.

Adela
You'll need a new variable for tip rate, I'm guessing.

Ethan
Makes sense. Here's the old output code, with a new line.
- # Output
- print('-----------------')
- print('Meal cost: ' + meal_cost)
- print('Tip rate: ' + tip_rate + '%')
- print('Tip: ' + tip)
- print('Total: ' + total)
-

Ethan
Wait. I forget the number-to-string thing.
- # Output
- print('-----------------')
- print('Meal cost: ' + str(meal_cost))
- print('Tip rate: ' + str(tip_rate) + '%')
- print('Tip: ' + str(tip))
- print('Total: ' + str(total))
-
Good!

Georgina
We'll need to work out the tip amount, from the tip rate and meal cost.

Ethan
Hey, yeah, that makes sense. I'll add the calculating code.
- # Processing
- tip = meal_cost * tip_rate / 100
- total = meal_cost + tip
- # Output
- print('-----------------')
- print('-----------------')
- print('Meal cost: ' + str(meal_cost))
- print('Tip rate: ' + str(tip_rate) + '%')
- print('Tip: ' + str(tip))
- print('Total: ' + str(total))
-

Ray
Cool! You're using a tip rate of, like, 20 rather than 0.2. That's why you have the divide-by-100 thing.

Ethan
Right!
OK, let me check out the output code again, to make sure we have the variables we need.
- # Processing
- tip = meal_cost * tip_rate / 100
- total = meal_cost + tip
- # Output
- print('-----------------')
- print('Meal cost: ' + str(meal_cost))
- print('Tip rate: ' + str(tip_rate) + '%')
- print('Tip: ' + str(tip))
- print('Total: ' + str(total))
I'll start from the bottom. OK, total
is worked out in line 3. Got that one.
tip
is in line 2.
tip_rate
, output in line 8... We don't code for that yet.
meal_cost
in line 7 is an input from the user.
Oh, the service level is an input, too. You can tell from the I/O.
- Meal cost? 60
- Service level (g=great, o=ok, s=sucked)? g
- -----------------
- Meal cost: 60.0
- Tip rate: 20 %
- Tip: 12.0
- Total: 72.0

Georgina
You'll need another variable for the service level.

Ethan
Right.
Hmm, I'll just add the input code
- # Input
- meal_cost = float(input('Meal cost? '))
- service_level = input('Service level (g=great, o=ok, s=sucked)? ')
- # Processing
- Something here
- tip = meal_cost * tip_rate / 100
- total = meal_cost + tip
- # Output
- print('-----------------')
- print('Meal cost: ' + str(meal_cost))
- print('Tip rate: ' + str(tip_rate) + '%')
- print('Tip: ' + str(tip))
- print('Total: ' + str(total))
-

Ethan
Hmm, I don't know what code goes in line 6.
Can you tell me what that bit of code should do? Using the variables you have.
The code that goes where line 6 is. What should it do? In your own words.

Ethan
Let's see... It should take the service_level
, g, o, or s, and work out tip_rate
. If service_level
is g, make tip_rate
20, and so on.
if
statements
An if
statement is an if-this-then-do-that thing. For example:
- if 2 < 9:
- print('Two is smaller')
More generally:
- if condition:
- >action
condition
is either true or false, like 2 < 9
. Notice the : at the end of the line. Python code needs that.
If condition
is true, do action
. If it's false, skip action
.
action
is a code block. One or more statements indented at the same level.
A code block can have any number of statements:
- # Input
- width = float(input("What's the width? "))
- height = float(input("What's the height? "))
- # Output
- if width < height:
- print('The width (' + str(width) + ') is smaller.')
- print('Yeah, and the height (' + str(height) + ') is larger')
If condition
is true, both statements are run, because they are in one code block. Otherwise, none of them are run.
You can add an else
. Here's an example:
- # Input
- width = float(input("What's the width? "))
- height = float(input("What's the height? "))
- # Output
- if width < height:
- print('The width (' + str(width) + ') is smaller.')
- print('Yeah, and the height (' + str(height) + ') is larger')
- else:
- print('The height (', height, ') is smaller.')
- print('Yeah, and the width (', width, ') is larger')
Remember, the condition in the if
is either true or false. If true, do the first code block. If false, do the second. The code block can have as many statements as you want.
There's a bug here.
What's the bug?

Adela
I see it! width
and height
could be the same!
Aye, they could.
With the current program, what's the output if width
and height
are equal?

Ethan
I tried it, and got this:
- What's the width? 5
- What's the height? 5
- The height (5.0) is smaller.
- Yeah, and the width (5.0) is larger
Here's the code again:
- # Input
- width = float(input("What's the width? "))
- height = float(input("What's the height? "))
- # Output
- if width < height:
- print('The width (' + str(width) + ') is smaller.')
- print('Yeah, and the height (' + str(height) + ') is larger')
- else:
- print('The height (' + str(height) + ') is smaller.')
- print('Yeah, and the width (' + str(width) + ') is larger')
Why was that the output?

Georgina
When width
and height
are equal, this...
if width < height:
... is false. So, run the code in the else
block.
Right! Good thinking.

Ray
OK, so there are three possibilities:
- width > height
- width < height
- width and height are equal
But an if
test is either true or false. Just two possibilities.
What do we do?
Here's one way to do it:
- # Input
- width = float(input("What's the width?"))
- height = float(input("What's the height?"))
- # Output
- if width < height:
- print('The width (', width, ') is smaller.')
- print('Yeah, and the height (', height, ') is larger')
- elif width > height:
- print('The height (', height, ') is smaller.')
- print('Yeah, and the width (', width, ') is larger')
- else:
- print('The width (' + str(width) + ' and the height(' + str(height) + ') are equal.')
elif
is short for "else if." So if width < height
, do the first code block. If width > height
, do the second. If neither is true, do the third.
You can have as many elif
s as you like. For example:
- # Input
- animal = input("What's the animal?")
- # Processing
- if animal == 'dog':
- message = 'The best animal!'
- elif animal == 'goat':
- message = 'Goats are cool!'
- elif animal == 'cat':
- message = 'Cats are OK, I guess.'
- elif animal == 'bat':
- message = 'Bats eat a lot of bugs. We need them.'
- elif animal == 'emu':
- message = 'Emus are stroppy.'
- elif animal == 'apatosaurus':
- message = 'Wait... where did you see THAT?'
- elif animal == 'clown':
- message = 'Scary! Keep away!'
- else:
- message = "Sorry, I don't know the animal " + animal + '.'
- # Output
- print(message)
Only one of these blocks will run.
- If
animal
is "dog", line 6 will run, and Python will skip down to after theelse
block. - If
animal
is "emu", line 14 will run, and Python will skip down to after theelse
block. - If all the other tests are false, the
else
code will run.
Use as many elif
s are you like. No limit.
Important!
The operator for "is equal to" is ==
, not =
. =
is assignment.
I could have written the code like this:
- ...
- if animal == 'dog':
- print('The best animal!')
- elif animal == 'goat':
- print('Goats are cool!')
- elif animal == 'cat':
- print('Cats are OK, I guess.')
- ...
That would work. However, I prefer to put the output strings into a variable, and output that:
- ...
- if animal == 'dog':
- message = 'The best animal!'
- elif animal == 'goat':
- message = 'Goats are cool!'
- elif animal == 'cat':
- message = 'Cats are OK, I guess.'
- ...
- # Output
- print(message)
This way is more flexible. Say your boss wants you to add "© Mega Corp" at the end of the output.
If I used a bunch of print()
s, I could change each one.
- ...
- if animal == 'dog':
- print('The best animal! © Mega Corp')
- elif animal == 'goat':
- print('Goats are cool! © Mega Corp')
- elif animal == 'cat':
- print('Cats are OK, I guess. © Mega Corp')
- ...
More work, and there's a chance of error in copying the extra output
However, with this code...
- ...
- if animal == 'dog':
- message = 'The best animal!'
- elif animal == 'goat':
- message = 'Goats are cool!'
- elif animal == 'cat':
- message = 'Cats are OK, I guess.'
- ...
- # Output
- print(message)
... there's just one print()
, in line 23.
- # Output
- print(message)
I change that one line to:
- print(message + ' © Mega Corp')
I'm done. A quick change.
Now, say your boss decides you need a period at the end of 'Corp', making it 'Corp.'. With my approach, you add one character to one line, and you're done.
That's a common pattern:
Accumulate output in a variable
Rather than have a bunch of print()
s, assemble what you want to output into a variable, and print()
that.
Tip rate selector
We want to take the service_level
the user enters (great, OK, or sucked), and work out the value for tip_rate
. 20% for great, 15% for OK, 10% for sucked. We'll use the code here:
- service_level = input('Service level (g=great, o=ok, s=sucked)? ')
- Something to work out tip_rate.
- tip = meal_cost * tip_rate / 100
- ...
Let's make an if
to do that.
Try writing the code that will work out the tip_rate
, given the service_level
.
This will do it:
- if service_level == 'g':
- tip_rate = 20
- elif service_level == 'o':
- tip_rate = 15
- else:
- tip_rate = 10
There's code for testing for "g" and "o". Why no test for "s"?

Ray
If service_level
is not g and it's not o, it has to be s.
Indeed. As long as the user didn't type something invalid. We'll test for that later.
The final code
- # Compute tip for a meal.
- # By Kieran Mathieson, June 14, Year of the Dragon
- # Input
- meal_cost = float(input('Meal cost? '))
- service_level = input('Service level (g=great, o=ok, s=sucked)? ')
- #Processing
- if service_level == 'g':
- tip_rate = 20
- elif service_level == 'o':
- tip_rate = 15
- else:
- tip_rate = 10
- tip = meal_cost * tip_rate / 100
- total = meal_cost + tip
- # Output
- print('-----------------')
- print('Meal cost: ' + str(meal_cost))
- print('Tip rate: ' + str(tip_rate) + '%')
- print('Tip: ' + str(tip))
- print('Total: ' + str(total))
Summary
- An if statement is an if-this-then-do-that thing.
if _condition_:
_action_
- Condition is either true or false, like
legs == 4
. - Action is a code block. One or more statements indented at the same level.
elif
is short for else-if. It helps you do multiway tests.- If no conditions are true, run the
else
block, if present.
Exercise
Boat rental
Write a program to work out the price for a boat rental. The user enters the number of people in the party, from 1 on up. Assume the user makes no typing or other mistakes.
The price depends on the number of people. For a party up to six people, you can use the small boat, for a cost of $180 per person for the day. For more than six people, you need the bigger boat. It costs $220 per person.
The output tells the user the total price, and which boat will be used. Here's some I/O:
- Crusty Cathy's Boat Rental
- ====== ======= ==== ======
- How many people? 10
- We'll need a bigger boat.
- Total price: 2200
More:
- Crusty Cathy's Boat Rental
- ====== ======= ==== ======
- How many people? 2
- The small boat will work fine.
- Total price: 360
Upload a zip of your project folder. The usual coding standards apply.