What we have
Our program asks users a question:
- Service level (g=great, o=ok, s=sucked)?
They type something and press Enter.
If they don't type something valid, we want to show an error message, and keep asking.
- Service level (g=great, o=ok, s=sucked)? Meh, ya know
- Please enter G, O, or S.
- Service level (g=great, o=ok, s=sucked)? I jes tole ya!
- Please enter G, O, or S.
- Service level (g=great, o=ok, s=sucked)? Passive aggressive much?
- Please enter G, O, or S.
- Service level (g=great, o=ok, s=sucked)? Ok, OK... O
- Please enter G, O, or S.
- Service level (g=great, o=ok, s=sucked)? O
- -----------------
So something like:
- while Input is not valid:
- Ask for input
We've got the same normalization issue from before.
What's normalization mean here?

Georgina
Like, converting user input to one format. Remove extra spaces, lowercase.
Aye.
Why does normalization help users?

Ethan
They don't have to worry about irrelevant differences in input, like "G", "g ", "G " and other things all work.
Right.
Why does normalization make coding easier?

Georgina
Ooo! I know! if
s and while
s are easier to write. Instead of...
- if service_level != 'G' && service_level != 'G ' && service_level != ' G ' && lots more
... we can write...
- if service_level != 'g' and service_level != 'o' and service_level != 's':
We need to normalize service_level
before this test, though.
Indeed!
Here's some pseudocode (code-ish, but easier to understand):
This is better:
- Initialize input varaible
- while Input is not valid:
- Ask user to input the service level
- Normalize input
- if input not valid:
- Show error message
Here's the code from last time.
- # Initialize service_level
- service_level = ''
- # Is the service level valid?
- while service_level != 'g' and service_level != 'o' and service_level != 's':
- # Don't have a valid service level yet
- # Ask user to input the service level
- service_level = input('Service level (g=great, o=ok, s=sucked)? ')
- # Normalize input
- service_level = service_level.strip().lower()
- # Is the service level valid?
- if service_level != 'g' and service_level != 'o' and service_level != 's':
- # Show error message
- print('Please enter G, O, or S.')
Why is line 2 there? The initialization thing.

Adela
Line 4 uses a variable called service_level
. If the variable doesn't exist yet, the program will crash. Line 2 creates the variable.
Bee tee dubs, we made the variable MT, so the while
would work the first time. We could have...
- service_level = 'burt is a good boi'
... or anything that isn't a valid value.
Good! And yes, Burt is a good boy.
My friend ​Burt
Let's make change the program, to make it more convenient for users.
So, we show the user the prompt:
- Service level (g=great, o=ok, s=sucked)?
Say they wanted to stop the program. What would they do?

Ray
Maybe type quit?
Does that work? Why?

Ray
Well, poop. The program loops until it gets g, o, or s.
If you hit Ctrl+C once or twice, the program will throw an error and stop.
Use Ctrl+C to stop the program in Spyder. What would your grandma think if she saw that message?

Adela
Euww. We don't want to show users errors like that. Abuela would freak out.
Let's give the user a quit option...
- Service level (g=great, o=ok, s=sucked, q=quit)? q
- OK, bye!
Here's the code again:
- # Initialize service_level
- service_level = ''
- # Is the service level valid?
- while service_level != 'g' and service_level != 'o' and service_level != 's':
- # Don't have a valid service level yet
- # Ask user to input the service level
- service_level = input('Service level (g=great, o=ok, s=sucked)? ')
- # Normalize input
- service_level = service_level.strip().lower()
- # Is the service level valid?
- if service_level != 'g' and service_level != 'o' and service_level != 's':
- # Show error message
- print('Please enter G, O, or S.')
We need to change a coupla things. First, we need to change the test on lines 4 and 11 so they accept q
. Right now, it's...
- service_level != 'g' and service_level != 'o' and service_level != 's'
How would you change the test?

Adela
I think it's...
- service_level != 'g' and service_level != 'o' and service_level != 's' and service_level != 'q'
Aye!

Ethan
Hey, that test is long, it's getting hard to fit it on a line. What should I do?
One way is to add \ to break up the line:
- service_level != 'g' and service_level != 'o' \
- and service_level != 's' and service_level != 'q'
We'll see some other ways later.
OK, we're adding a quit option. We'll change the code, adding to the test:
- service_level != 'g' and service_level != 'o' and service_level != 's' and service_level != 'q'
What else do we need to change? Running the program and checking the I/O might help.

Ethan
Oh! We need to tell users about the option. Change the prompts!
Correct!
- service_level = input('Service level (g=great, o=ok, s=sucked, q=quit)? ')
- ...
- print('Please enter G, O, S, or Q.')
Good! Here's the new code for the loop.
- # Initialize
- service_level = ''
- while service_level != 'g' and service_level != 'o' \
- and service_level != 's' and service_level != 'q':
- # Get user input
- service_level = input(
- 'Service level (g=great, o=ok, s=sucked, q=quit)? '
- )
- # Normalize service level
- service_level = service_level.strip().lower()
- # Validate service level
- if service_level != 'g' and service_level != 'o' \
- and service_level != 's' and service_level != 'q':
- print('Please enter G, O, S, or Q.')
That's it.
Lines 6 - 8 show another way to break up lines that are too long. Remember, input()
is a function. You call a function like this:
- function(arguments)
(Arguments are often called parameters. It's just a different name.)
You can line break with the args:
- function(
- arguments
- )
It's cleaner than a \, but in...
- while service_level != 'g' and service_level != 'o' and service_level != 's' and service_level != 'q':
... there are no parens to break. So, we have to use \.
We wanted to add a new input option, so we:
- Changed the
if
andwhile
tests, so the new option would be valid. - Changed the prompts, to tell the user about the new option.
Run the program with the new code. Does quit work? Why?

Adela
Why won't it... Aha!
We changed validation so q
is acceptable, but the program doesn't do anything with it. We didn't tell the program to stop when the user types q
.
Aye, that's right.
So, after the input is validated, let's add another if
so the program exits if the user typed q
.
Try adding the if
. What's the new code?

Georgina
Yeehah! I dun got it, cowboys!
- # Initialize
- service_level = ''
- while service_level != 'g' and service_level != 'o' \
- and service_level != 's' and service_level != 'q':
- # Get user input
- ...
- # Check for exit.
- if service_level == 'q':
- print('OK, bye!')
- sys.exit()
- # Processing
- if service_level == 'g':
- ...
Good. So, to add a quit option, we:
- In validation:
- Changed the
if
andwhile
tests, so the quit option would be valid. - Changed the prompts, to tell the user about the quit option.
- Changed the
- After validation, added code to implement the new option.