Topic 05

Asking the User

Hands-on

A program that always does the same thing is a poster. The moment it can ask a question and act on the answer, it becomes a tool. Python's input function does the asking: it shows a message, waits for the person at the keyboard to type something and press Enter, and hands back what they typed. There is one catch, and it produces the first real crash almost every beginner meets: the answer always arrives as text, even when the person typed a number.

Think of a paper form with a box labelled age. People can write anything in that box: 34, thirty-four, or a smiley face. Before anyone does arithmetic with it, a clerk has to check that it is a number and read it as one. In a program, you are the clerk.

input Asks and Waits

Inside the brackets of input goes the question to show. Python prints it, waits, and gives back the typed answer as a string. In the session below, the person types 34. The answer is the text 34 in quotes, and type confirms it is a str.

Asking a question at the prompt
>>> answer = input("Your age: ")
Your age: 34
>>> answer
'34'
>>> type(answer)
<class 'str'>

Text In, Number Needed

To do arithmetic with an answer, convert it. The int function turns text into a whole number, and float turns it into a decimal: int("34") is the number 34, and adding one gives 35. There is a limit. int accepts only text that looks like a whole number, so int("4.5") is a ValueError. For a value with a decimal point, use float, or Decimal when it is money.

Converting text to numbers
>>> int(answer) + 1
35
>>> int("4.5")
Traceback (most recent call last):
  File "<python-input-4>", line 1, in <module>
    int("4.5")
    ~~~^^^^^^^
ValueError: invalid literal for int() with base 10: '4.5'
>>> float("4.5")
4.5

A Tip Calculator

Here is the first program in this book that responds to a person. It asks for the bill and for the tip percentage, works out the tip, and prints the tip and the total. The bill is money, so it becomes a Decimal made straight from the typed text, exactly as the arithmetic page recommended; Decimal accepts a string. The percentage is a whole number, so it goes through int. The tip is the bill times the percentage divided by a hundred, and the f-strings show both results with two decimal places.

tip.py
from decimal import Decimal

bill = Decimal(input("Bill amount: "))
percent = int(input("Tip percent: "))

tip = bill * percent / 100
print(f"Tip: {tip:.2f}")
print(f"Total: {bill + tip:.2f}")

Run it with python tip.py on Windows or python3 tip.py on a Mac. With a bill of 48.50 and a tip of 15 percent, the tip is 7.28 and the total 55.78.

A run with sensible answers
Bill amount: 48.50
Tip percent: 15
Tip: 7.28
Total: 55.78

The First Real Crash

Now run it again and type the word forty as the percentage. The program stops with a traceback. Read the last line first: ValueError, invalid literal for int with base 10, and then the word forty. In plain words, int was given text it could not read as a whole number. The line above the message shows exactly which instruction failed: line 4, the one that converts the percentage.

The same program, given a word instead of a number
Bill amount: 48.50
Tip percent: forty
Traceback (most recent call last):
  File "/Users/you/python-course/tip.py", line 4, in <module>
    percent = int(input("Tip percent: "))
ValueError: invalid literal for int() with base 10: 'forty'

The program is not wrong for sensible input. The input was not what it expected. Asking again until the answer is usable needs a loop, which arrives in Chapter 4, and handling the error gracefully is the subject of Chapter 8. For now, the skill is reading the message and knowing what it means.

From keyboard to number
The person types 15at the prompt
→
input gives "15"text, not a number
→
int turns it into 15now arithmetic works
Common Confusions
  • "If the person types digits, input gives me a number." input always gives back text. Convert it with int, float or Decimal before doing arithmetic.
  • "The crash means my program is wrong." The program is right for the input it was designed for. Bad input needs its own handling, which Chapters 4 and 8 add.
  • "int rounds a decimal typed as text." int("4.5") is a ValueError, not 4. Use float or Decimal for text with a decimal point.
Why It Matters
  • "Everything from outside is text until proven otherwise" applies to people, files and the internet alike. This page is the first time you meet it; it will not be the last.
  • A program that asks and responds is the point where programming starts to feel useful, even at a few lines long.

Knowledge Check

The person types 34 when input asks. What type is the value it gives back?

  • An int, because the person typed only digits
  • A float, because Python treats typed numbers as decimals
  • A str, because input always gives back plain text
  • A bool, because the person has answered the question asked

What does int("forty") do?

  • Gives 40, reading the word as a number
  • Gives 0, because the text contains no digits
  • Gives back the text forty unchanged
  • Raises a ValueError, because forty is not digits

Which function should read the typed text "4.5" as a number?

  • int, which rounds it to 4 on the way in
  • float, or Decimal when the value is money
  • str, which turns the typed text into a number
  • input, called a second time with the text

In the tip calculator, why is the bill made with Decimal and the percent with int?

  • Decimal is needed for any number above one hundred
  • The percent must stay text so it prints with a sign
  • The bill is money with cents; the percent is a whole number
  • Python requires two different types in every sum

You got correct