Hour 5. Processing Input and Output


What You’ll Learn in This Hour:

Image How to get user information from the command line

Image How to safely get a user’s password

Image How to better format user input

Image How to better format output

Image When to input and output information in the real world


Eventually, you are going to need to get information from the user. Most programs require some sort of interaction at some point. Some interact with people directly, such as word processing programs and games. If you press the up arrow in a game, your character usually moves forward. If you type hello in a word processing program, the letters appear in your document. Some programs interact with other programs, such as a widget on your smartphone that displays the weather in your current location. Regardless of where it comes from, at some point, you have to figure out how to use information from other sources.

Getting Information from the Command Line

Programs get information from other sources through an interface. An interface can be many things, as shown in Figure 5.1. It might be a web page, an app on a smartphone, or a game on a computer. Right now, our interface is the command line.

Image

FIGURE 5.1 Types of interfaces.

input() and raw_input() allow you to get information from the user on the command line. input() is for gathering information literally, whereas raw_input() is used for anything that might not be a number.

What do we mean when we say that input() gets information literally? We mean that whatever the user enters will be saved exactly as it is, and Python will try to match what was entered to the correct data type. If the user enters 5, then that value will be saved as an integer. If the user enters 5.0, that value will be saved as a float.

In the following example, the user enters 5 when prompted, which is stored in number as an integer (user input is bold):

>>> number = input()
5
>>> number
5

input() cannot take a string without quotes. Consider the following example. Raw text (with no quotes) causes an error, but adding quotes doesn’t.

>>> s = input()
Hello
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'Hello' is not defined
>>> s = input()
"Hello"
>>> s
'Hello'

So what does raw_input() do? It saves whatever the user enters as a string. If the user enters 5, then 5 is saved as a string, not an integer.

Here, the user inputs Katie, which is stored in name as a string:

>>> name = raw_input()
Katie
>>> name
'Katie'

raw_input() is a bit safer to use than input(). If Python can’t convert what the user has entered when you use input(), the program will stop running. For example, what if the user is prompted for her age, and she adds “years” onto the end of it?

>>> age = input()
30 years
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    30 years
           ^
SyntaxError: unexpected EOF while parsing

If we had used raw_input(), we wouldn’t have gotten an error, and could have cleaned up the input later on.

Prompts

If you want Python to use a prompt, you can give it one in the parentheses. It can be a raw string (some text enclosed in quotes) or a variable that’s storing a string.

Here, rather than have the user give her input on an empty line, she’s given a helpful prompt:

>>> name = raw_input("Please give me your name: ")
Please give me your name: Katie
>>> name
'Katie'

You can use any string, but keep in mind that you need to make it easy for your users to understand that they need to enter something. The prompt should probably end with something that indicates that user input is required (such as a colon or question mark), and it should indicate what they should enter.

Converting input

As mentioned before, input() comes with a significant drawback: If the user inputs anything that’s not a number, the program will crash. For example, what if a developer from the U.S. happens to have a user from the UK? In the U.S., ZIP Codes are generally entered as five numbers. In the United Kingdom, these codes (called postcodes there) always have a combination of letters and numbers in them.

Let’s say our user is from London and has a postcode of W11 2BQ:

>>> zipcode = input()
W11 2BQ
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "<string>", line 1
     W11 2BQ
        ^ SyntaxError: invalid syntax

Even wrapped in a try/except statement, this means you lose data from the user. Everyone has had the frustration of having to enter data twice. Therefore, it’s generally recommended to get information from a user by using raw_input().

But what if you do need a number? Easy: Strings can be converted into numbers. Python has a built-in function called float() that converts a string, if possible, to a float.

In the following example, we get the user’s age using raw_input(), then convert that age to a float using float():

>>> age = raw_input()
30
>>> age
'30'
>>> age = float(age)
>>> age
30.0

Python also comes with a built-in for converting strings (and floats!) into integers. int() attempts to turn any value you give it into an integer, converting a string filled with numbers into an actual number, or rounding down a float to the nearest whole number.

In this example, we convert weight, which holds a float, to an integer:

>>> weight = 170.5
>>> int(weight)
170

If the number can’t be converted, Python will throw an error. For example, Python can’t convert a float that happens to be stored in a string. What if someone entered his age as 11.5?

>>> age = raw_input("What is your age? ")
What is your age? 11.5
>>> age
'11.5'
>>> int(age)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '11.5'

In later hours, we’ll look at ways to get input from the user that won’t crash your program, or force your program to stop.

Getting a Password

What if you need to get a password from the user while giving him security from prying eyes? Python comes with a library that allows you to get information from the user while hiding his typing. This is useful not only for passwords but for information the user might want to keep hidden, such as social security numbers, credit cards, and the answers to security questions.

The function for getting passwords isn’t loaded by default like input() and raw_input() are. You have to tell Python that you want to use this function by using an import statement.

In this example, we’ll get a password from the user. Note that there isn’t any input shown from the user (his input is never shown on the screen):

>>> from getpass import getpass
>>> password = getpass()
Password:
>>> password
'hello'

We’ll go into imports more in Hour 13, “Using Python’s Modules to Add Functionality,” but for now, know that we’re asking Python to load the getpass function from the getpass library.


Warning: input on Different Systems

Not every system is able to get input without showing it on the screen. Python will do its best to not show a user’s password when he types it.

If the user’s system can’t help but print out the user’s password as he types it, a warning will be printed.


You’ll notice in the example that we didn’t give getpass() a prompt, and yet it printed out Password: anyway. This is part of the getpass() function: If we don’t give it a prompt, it will set the prompt to Password: by default. You can still give getpass() a prompt if you need to, though.

In this example, we give getpass() a prompt for getting the user’s password:

>>> from getpass import getpass
>>> password = getpass('Password, please: ')
Password, please:
>>> password
'hello'

Cleaning Up User Input

You should never accept what information the user gives you without seeing if you can clean it up a bit. Why? A user might use extra whitespace, or provide a value that will crash your program. At best, this can make the rest of the output of your program ugly. At worst, it can crash it completely.

Your first defense is making sure users know what to enter. Providing the user with examples can go a long way toward getting good data. For example, if you ask a user for the year he was born, you might want a four-digit year, but end up getting two digits (80) or four digits plus some text (2001 AD). Adding an example makes it clear what format you want.

In this example, we offer the user an example year to make it clear we want four digits:

>>> year = raw_input("What year were you born [ex: 1980]? ")
What year were you born [ex: 1980]? 1967

When you get data from the user, check it against what you’re expecting. If we know that we want a four-digit year with all numbers, we have the tools to check for that. In this example, we check the length of year before moving on. If it’s not four, we show an error message.

>>> year = raw_input("What year were you born [ex: 1980]? ")
What year were you born [ex: 1980]? 92
>>> if len(year) != 4 or not year.isdigit():
...   print "I'm sorry, I don't like that number."
... else:
...   print "That's good. Moving on!"
...
I'm sorry, I don't like that number.

But what if your user’s data is just a little bit less clean than it should be? Perhaps the user added some whitespace onto the end of the input. In that case, rather than reject it outright, we can clean it up with strip(), which you learned about in Hour 4, “Storing Text in Strings.”

In this example, the user has entered his street name, but added an extra space at the end. We clean it up using strip().

>>> name = raw_input("Street name please: ")
Street name please: Covington Drive
>>> name
' Covington Drive '
>>> name = name.strip()
>>> name
'Covington Drive'

As you learn more Python, you’ll learn more ways to clean up data from the user. Keep this in the back of your mind as you read: A program that can survive the people who use it is a robust program indeed.

Formatting Output

Now that we can get clean data from the user, let’s see if we can get our output to look nicer. Many times, we’ll want to put that value from a variable (or more than one variable) into a larger string. In Hour 4, you learned that you can add strings together to make new strings. That can start to get unwieldy as the strings get longer, and can easily lead to some poor formatting if you forget to add extra spaces around the variables.

In this code sample, we print a greeting using several strings that have been stored earlier. The result is a bit hard to read, and isn’t formatted well.

>>> name = "Hannah"
>>> time = "morning"
>>> print "Good" + time + "," + name + ". How are you doing?"
Goodmorning,Hannah. How are you doing?

Python comes with several ways to format output so that it’s much easier to maintain and much easier to read. The newest way is to use the format() function that comes with strings. Using curly brackets ({}), you can set aside a space for a variable to be inserted.

In this example, we use format() to output a similar greeting as the previous example, but with better readability:

>>> greeting = "Good {}, {}. How are you doing?"
>>> name = "Hannah"
>>> time = "morning"
>>> print greeting.format(time, name)
Good morning, Hannah. How are you doing?

Empty curly brackets can be somewhat ambiguous, so Python also allows you to put text in the brackets to make it clear to other developers what should go in there. This text is called a key, and you have to tell Python explicitly what variable goes with which key.

In this example, we fill the curly brackets with a key that describes what sort of value should go in that particular slot. time would naturally hold the time of day, and special1 and special2 would hold the various specials.

>>> specials_text = "Good {time}! Today's specials are: {special1} and {special2}."
>>> time = "afternoon"
>>> food1 = "spam with eggs"
>>> food2 = "eggs with spam"
>>> print specials_text.format(time=time, special1 = food1, special2 = food2)
Good afternoon! Today's specials are: spam with eggs and eggs with spam.

If you don’t want to set keys for your variable slots, you can still control which variables go in which slots by putting an integer in each slot, starting with zero.

In this example, the variable slots are filled with three integers: 0, 1, and 2. We then give format() three strings. The string is printed with the three strings inserted in the order that they were given to format().

>>> line = "Cities with Python meet-ups: {0}, {1}, {2}"
>>> print line.format("District of Columbia", "Portland", "and many more!")
Cities with Python meet-ups: District of Columbia, Portland, and many more!

The first item in the parentheses goes into the bracket with a zero, the second item goes into the bracket with a one, and so on.

What happens if you don’t have enough values to fill the given keys? Python will give you an error, and your program will stop running. In this example, we have three slots for fruit, but we only gave format() two kinds of fruit:

>>> fruit = "Types of fruit on sale: {}, {}, and {}."
>>> fruit.format('apples', 'pears')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: tuple index out of range

But what if we have more than three types of fruit? In that case, Python doesn’t give us an error, but also only displays the first three items given to format():

>>> fruit = "Types of fruit on sale: {}, {}, and {}."
>>> fruit.format('apples', 'pears', 'mangos', 'bananas')
'Types of fruit on sale: apples, pears, and mangos.'

Because we didn’t indicate where we might want to show a fourth item, “bananas” was left out.

Managing Input and Output in the Real World

Getting input and formatting output is often where scripts go from “okay” to really useful. Let’s revisit our cook from the previous hour. In her first script, she printed out a message for all the specials of the day. What if she wanted to print out only the specials for that mealtime?

The cook decides to add a line to her script that asks the waiter to enter what mealtime he wants to know about. She then adds some if statements so that only the mealtime the waiter is interested in is printed out.

breakfast_special = "Texas Omelet"
breakfast_notes = "Contains brisket, horseradish cheddar"
lunch_special = "Greek patty melt"
lunch_notes = "Like the regular one, but with tzatziki sauce"
dinner_special = "Buffalo steak"
dinner_notes = "Top loin with hot sauce and blue cheese. NOT BUFFALO MEAT."

meal_time = raw_input('Which mealtime do you want? [breakfast, lunch, dinner] ')
print 'Specials for {}:'.format(meal_time)
if meal_time == 'breakfast':
   print breakfast_special
   print breakfast_notes
elif meal_time == 'lunch':
   print lunch_special
   print lunch_notes
elif meal_time == 'dinner':
   print dinner_special
   print dinner_notes
else:
   print 'Sorry, {} isn't valid.'.format(meal_time)

At the end of the script, the cook even adds an else statement so that an error is printed if the waiter makes a typo, or tries to look up a mealtime that doesn’t exist.

When the waiter runs the script, he sees the following:

$ python specials.py
Which mealtime do you want? [breakfast, lunch, dinner] lunch
Specials for lunch:
Greek patty melt
Like the regular one, but with tzatziki sauce

But what happens if the waiter enters a mealtime that’s not offered at the restaurant?

$ python specials.py
Which mealtime do you want? [breakfast, lunch, dinner] dessert
Specials for dessert:
Sorry, dessert isn't valid.

The program, rather than crashing, informs the waiter that “dessert” isn’t a valid choice.

Summary

During this hour, you learned how to use input() and raw_input() to get information from the user. You also learned how to use getpass() to get information from users that they may not want displayed on the screen.

You also learned about several ways you might clean up user data, such as removing whitespace or specified characters from the beginning and/or ends of strings.

Finally, you learned about formatting strings with the format() function, and how to use it to insert values into a string.

Q&A

Q. Can a user enter something other than strings and numbers?

A. input() can get all kinds of data from the command line. The main drawback, however, is that the user needs to know exactly how to format the data, and any typos will cause the program to crash.

In the next hour, you’ll learn about lists. For now, know that a list is a group of items enclosed by brackets. Here’s how they would be supplied by a user using input():

>>> items = input('Please give me a list of numbers: ')
Please give me a list of numbers: [1, 4, 6, 7, 100]
>>> items
[1, 4, 6, 7, 100]

Q. I was looking at some Python code another person wrote. Why is the percent sign (%) sometimes used to format strings?

A. If you look through some old Python code, you might notice something that looks like this:

>>> print "Good %s, %s. How are you?" % ('morning', 'Jacob')
Good morning, Jacob. How are you?

The percent sign (%) plus a letter is an older way of formatting strings. The format() function was introduced in Python 2.6.

Workshop

The Workshop contains quiz questions and exercises to help you solidify your understanding of the material covered. Try to answer all questions before looking at the answers that follow.

Quiz

1. What is the difference between input() and raw_input()?

2. You want the user to enter his social security number, but he probably doesn’t want to display those numbers on the screen. How would you get this information from the user securely?

3. How would you remove extra whitespace from just the end of a string?

4. How do you insert strings into other strings without using the addition operator? How do you indicate where you want strings inserted?

5. How do you convert a string to a float? How about an integer?

Answers

1. input() gets raw data from the user. If he enters 5, that value will be saved as an integer. If raw_input() is used, that value would be saved as a string.

2. You would use getpass from the getpass library. This requires importing getpass from the getpass library first.

3. If you just want to remove whitespace from the end of a string, you would use the rstrip() function. If you used the strip() function, then whitespace from the beginning and the end of the string would be removed.

4. The format() function is used to insert strings into other strings. The curly brackets ({ }) indicate where you want values inserted.

5. The float() built-in will convert a value to a float, if possible. The int() built-in converts values to integers.

Exercises

1. The cook’s script could be a bit more robust. Rewrite it so that it doesn’t matter whether the waiter entered extra whitespace or happened to capitalize some or all of the letters.

2. Ask a user for the name of an item, the number being purchased, and the cost of the item. Then, print out the total and thank the user for shopping with you. The output should look like this:

Give me your name, please: [Name]
How many widgets are you buying? [#]
How much do they cost, per item? [#.##]
Your total is $[#.##].
Thanks for shopping with us today, [Name]!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.58.50.156