Service level

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:

I/O

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
Ethan

OK. Let's see...

Should I start with the old tip code?

Sure.

Ethan
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
  • Meal cost?60
  • -----------------
  • Meal cost: 60.0
  • Tip: 9.0
  • Total: 69.0
  • ​​​​​​​
  • 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
  • ​​​​​​​

Ethan
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
Adela

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

Ethan
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
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
Georgina

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

Ethan
Ethan

Hey, yeah, that makes sense. I'll add the calculating code.

  1. # Processing
  2. tip = meal_cost * tip_rate / 100
  3. total = meal_cost + tip
  4.  
  5. # Output
  6. print('-----------------')
  7. print('-----------------')
  8. print('Meal cost: ' + str(meal_cost))
  9. print('Tip rate: ' + str(tip_rate) + '%')
  10. print('Tip: ' + str(tip))
  11. print('Total: ' + str(total))
  12. ​​​​​​​
Ray
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
Ethan

Right!

OK, let me check out the output code again, to make sure we have the variables we need.

  1. # Processing
  2. tip = meal_cost * tip_rate / 100
  3. total = meal_cost + tip
  4.  
  5. # Output
  6. print('-----------------')
  7. print('Meal cost: ' + str(meal_cost))
  8. print('Tip rate: ' + str(tip_rate) + '%')
  9. print('Tip: ' + str(tip))
  10. 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
Georgina

You'll need another variable for the service level.

Ethan
Ethan

Right.

Hmm, I'll just add the input code

  1. # Input
  2. meal_cost = float(input('Meal cost? '))
  3. service_level = input('Service level (g=great, o=ok, s=sucked)? ')
  4.  
  5. # Processing
  6. Something here
  7. tip = meal_cost * tip_rate / 100
  8. total = meal_cost + tip
  9.  
  10. # Output
  11. print('-----------------')
  12. print('Meal cost: ' + str(meal_cost))
  13. print('Tip rate: ' + str(tip_rate) + '%')
  14. print('Tip: ' + str(tip))
  15. print('Total: ' + str(total))
  16. ​​​​​​​
Ethan
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.

Reflect

The code that goes where line 6 is. What should it do? In your own words.

If you were logged in as a student, the lesson would pause here, and you'd be asked to type in a response. If you want to try that out, ask for an account on this site.
Ethan
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.

Cute mammal

if statements

An if statement is an if-this-then-do-that thing. For example:

  1. if 2 < 9:
  2.     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:

  1. # Input
  2. width = float(input("What's the width? "))
  3. height = float(input("What's the height? "))
  4.  
  5. # Output
  6. if width < height:
  7.     print('The width (' + str(width) + ') is smaller.')
  8.     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:

  1. # Input
  2. width = float(input("What's the width? "))
  3. height = float(input("What's the height? "))
  4.  
  5. # Output
  6. if width < height:
  7.     print('The width (' + str(width) + ') is smaller.')
  8.     print('Yeah, and the height (' + str(height) + ') is larger')
  9. else:
  10.     print('The height (', height, ') is smaller.')
  11.     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.

Reflect

What's the bug?

If you were logged in as a student, the lesson would pause here, and you'd be asked to type in a response. If you want to try that out, ask for an account on this site.
Adela: Aha!
Adela

I see it! width and height could be the same!

Aye, they could.

Reflect

With the current program, what's the output if width and height are equal?

If you were logged in as a student, the lesson would pause here, and you'd be asked to type in a response. If you want to try that out, ask for an account on this site.
Ethan
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:

  1. # Input
  2. width = float(input("What's the width? "))
  3. height = float(input("What's the height? "))
  4.  
  5. # Output
  6. if width < height:
  7.     print('The width (' + str(width) + ') is smaller.')
  8.     print('Yeah, and the height (' + str(height) + ') is larger')
  9. else:
  10.     print('The height (' + str(height) + ') is smaller.')
  11.     print('Yeah, and the width (' + str(width) + ') is larger')
Reflect

Why was that the output?

If you were logged in as a student, the lesson would pause here, and you'd be asked to type in a response. If you want to try that out, ask for an account on this site.
Georgina
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
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:

  1. # Input
  2. width = float(input("What's the width?"))
  3. height = float(input("What's the height?"))
  4.  
  5. # Output
  6. if width < height:
  7.     print('The width (', width, ') is smaller.')
  8.     print('Yeah, and the height (', height, ') is larger')
  9. elif width > height:
  10.     print('The height (', height, ') is smaller.')
  11.     print('Yeah, and the width (', width, ') is larger')
  12. else:
  13.     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 elifs as you like. For example:

  1. # Input
  2. animal = input("What's the animal?")
  3.  
  4. # Processing
  5. if animal == 'dog':
  6.     message = 'The best animal!'
  7. elif animal == 'goat':
  8.     message = 'Goats are cool!'
  9. elif animal == 'cat':
  10.     message = 'Cats are OK, I guess.'
  11. elif animal == 'bat':
  12.     message = 'Bats eat a lot of bugs. We need them.'
  13. elif animal == 'emu':
  14.     message = 'Emus are stroppy.'
  15. elif animal == 'apatosaurus':
  16.     message = 'Wait... where did you see THAT?'
  17. elif animal == 'clown':
  18.     message = 'Scary! Keep away!'
  19. else:
  20.     message = "Sorry, I don't know the animal " + animal + '.'
  21.  
  22. # Output
  23. print(message)

Only one of these blocks will run.

  • If animal is "dog", line 6 will run, and Python will skip down to after the else block.
  • If animal is "emu", line 14 will run, and Python will skip down to after the else block.
  • If all the other tests are false, the else code will run.

Use as many elifs 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:

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.

Reflect

Try writing the code that will work out the tip_rate, given the service_level.

If you were logged in as a student, the lesson would pause here, and you'd be asked to type in a response. If you want to try that out, ask for an account on this site.

This will do it:

  • if service_level == 'g':
  •     tip_rate = 20
  • elif service_level == 'o':
  •     tip_rate = 15
  • else:
  •     tip_rate = 10
Reflect

There's code for testing for "g" and "o". Why no test for "s"?

If you were logged in as a student, the lesson would pause here, and you'd be asked to type in a response. If you want to try that out, ask for an account on this site.
Ray
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

  1. # Compute tip for a meal.
  2. # By Kieran Mathieson, June 14, Year of the Dragon
  3.  
  4. # Input
  5. meal_cost = float(input('Meal cost? '))
  6. service_level = input('Service level (g=great, o=ok, s=sucked)? ')
  7.  
  8. #Processing
  9. if service_level == 'g':
  10.     tip_rate = 20
  11. elif service_level == 'o':
  12.     tip_rate = 15
  13. else:
  14.     tip_rate = 10
  15. tip = meal_cost * tip_rate / 100
  16. total = meal_cost + tip
  17.  
  18. # Output
  19. print('-----------------')
  20. print('Meal cost: ' + str(meal_cost))
  21. print('Tip rate: ' + str(tip_rate) + '%')
  22. print('Tip: ' + str(tip))
  23. 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

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.