◀ Course contents Part 1 · Module 1-05

Input & Output

A program that can hold a conversation

Until now your programs have known everything in advance. The moment they can ask a question, the same twelve lines work for any answer — and one specific trap accounts for most first-week frustration, so this module puts it front and centre.

Ready?

1

input(): Stop and Wait for an Answer

input() does three things: it prints whatever you pass it, pauses the program, and hands back the line the person typed once they press Enter.

name = input("Your name: ")
print(f"Welcome, {name}.")

Note the space at the end of "Your name: ". Without it the cursor sits flush against the colon and the program looks broken. It is a one-character detail that separates a program that feels finished from one that does not.

1

Prompt

Say what you want, in the words the person would use.

2

Wait

Nothing after this line runs until Enter is pressed.

3

Return

You get the typed line back, without the Enter.

How this works in the Lab

The exercises here supply the answers for you — you can see exactly what gets typed above each editor, one line per input() call. Ask for more answers than are supplied and you get a clear EOFError rather than a program that hangs forever waiting for a keyboard that is not there.

Quick check

What happens to the line print("Done") written after an input() call?

2

The Trap: Every Answer Arrives as Text

input() always returns a str. Someone types 7 and your program receives the text "7". There is no exception to this and no setting that changes it.

age = input("Age: ")   # they type 30
age + 1                # TypeError: can only concatenate str (not "int") to str
age * 2                # "3030"  — worse, because it does not even fail

That second line is the dangerous one. It does not crash, it just silently produces nonsense, and you find out much later when a total looks impossible.

The fix is one function call, and the convention is to do it on the same line as the question:

age = int(input("Age: "))
price = float(input("Price: "))
Fragile

Convert where it is needed

Twelve lines later, and again in three other places. Miss one and the bug is silent.

Sturdy

Convert at the edge

Right where the value enters. Everything downstream works with a real number.

Quick check

A program does quantity = input("How many? ") and then print(quantity * 3). The person types 5. What appears?

3

More Than One Question

Each input() reads exactly one line. Ask three times and you get three answers, in the order you asked. There is nothing more to it than that — but the order matters, and it is a common source of confusion when the answers are being supplied rather than typed.

name = input("Name: ")
item = input("Item: ")
quantity = int(input("How many? "))

print(f"{quantity} x {item} for {name}")

Each answer gets converted to whatever it needs to be. Text stays text; a count becomes an int; a price becomes a float.

What happens when they type nonsense

int(input("Age: ")) raises a ValueError if someone types "thirty" — the program stops with a traceback. For now that is fine and honest. Once you have if statements and try blocks, in Part 2 and Part 3, you will be able to catch it and ask again politely.

Read it. Convert it. Then use it. In that order, every time.

Quick check

A program asks for an item, then a quantity. The answers supplied are Tea then 3. The author swaps the two input() lines but nothing else. What happens?

4

Output People Can Actually Read

print() takes two settings beyond the values themselves. sep is what goes between them, a space by default. end is what goes after them, a newline by default.

print("a", "b", sep="-")     # a-b
print("2026", "09", "01", sep="/")   # 2026/09/01
print("Loading", end="")     # next print continues on the same line

For anything tabular, the trick is fixed widths. Strings have ljust and rjust, which pad a value out to a given number of characters:

print(f"{'Tea'.ljust(10)}{2.5:>6.2f}")    # Tea         2.50
print(f"{'Rice'.ljust(10)}{12.0:>6.2f}")  # Rice       12.00

Names padded on the right, numbers padded on the left, and suddenly a receipt reads like a receipt. The format spec >6.2f is doing both jobs at once: right-align inside six characters, with two decimal places.

Quick check

You want two print() calls to produce one line of output. What do you change?

0 of 9 completed

Real Python runs right here in your browser — nothing to install, nothing sent to a server. The interpreter downloads once the first time you press Run, then stays cached.

01

To do

input() stops the program, waits for someone to type a line, and hands back what they typed. Whatever you pass to it is printed first as the prompt.

name = input("What is your name? ")

Notice the space at the end of the prompt. Without it the cursor sits flush against the question mark, which looks broken.

Your task: ask Your name: , store the answer in name, and greet them with an f-string reading Welcome to the dojo, Kenji. — including the full stop.

The answer is typed in for you, so the program can run without you sitting at the keyboard.

Typed in for you when this runs: Kenji

your_code.py
Python
Hint

f"Welcome to the dojo, {name}." puts the answer into the sentence. The full stop goes inside the quotes, after the closing brace.

Output

      
    02

    To do

    This is the single most common beginner trap, so it is worth stating plainly: input() always hands back a str. Type 7 and you get the text "7", not the number.

    age = input("Age: ")
    age + 1 → TypeError
    int(age) + 1 → works

    So the pattern is: read it, convert it, then use it. Doing the conversion on the same line is fine and very common: age = int(input("Age: ")).

    Your task: ask How many modules? , convert the answer to a whole number in modules, and print how many lab exercises that comes to at 9 per module. With 4 typed in, the output is 36 exercises.

    Typed in for you when this runs: 4

    your_code.py
    Python
    Hint

    modules = int(input("How many modules? ")) does the reading and converting in one line. Then f"{modules * 9} exercises".

    Output
    
          
      03

      To do

      The previous exercise said it; this one shows you what it looks like when you forget. input() hands back text, and text cannot be added to a number.

      The error is worth reading carefully: TypeError: can only concatenate str (not "int") to str. Python is saying it looked at the left-hand side, saw a string, assumed you meant to join something on, and then found a number instead. The wording follows from the type it found first.

      Your task: run it, read the error, then convert at the right moment so it prints 30.

      Typed in for you when this runs: 29

      your_code.py
      Python
      Hint

      Either convert on the way in — age = int(input("Age: ")) — or convert where it is used: int(age) + 1. The first is usually better, because then age is a number everywhere below.

      Output
      
            
        04

        To do

        People type trailing spaces. They hold shift too long. They answer Yes, YES, yes and mean the same thing every time, and a program that only accepts one of those is a program people describe as broken.

        The standard move is to normalise the answer the moment it arrives: .strip() for the spaces, .lower() for the capitals. Then compare against one known form.

        answer = input("Confirm? ").strip().lower()
        confirmed = answer == "yes"

        Your task: the answer typed in is " YES ". Normalise it into answer, work out confirmed, and print two lines:

        answer: yes
        Confirmed: True

        Typed in for you when this runs: YES

        your_code.py
        Python
        Hint

        Chain the two methods onto the input: input("Confirm? ").strip().lower(). Then confirmed = answer == "yes" — a comparison produces True by itself.

        Output
        
              
          05

          To do

          int(answer) raises a ValueError the moment someone types twelve, or 12.5, or nothing at all. On a real form that is a crash, and the crash is your fault rather than theirs.

          .isdigit() asks the question first: it is True only when every character is a digit. "12" passes; "12.5", "-3" and "" do not.

          Your task: the answer typed in is 12.5. Work out looks_whole with .isdigit(), then convert it safely into quantity by going through float first. Print two lines:

          Whole number: False
          Using: 12

          Handling the bad case properly needs an if, which is the very next part. For now, notice that the check and the conversion are two separate steps.

          Typed in for you when this runs: 12.5

          your_code.py
          Python
          Hint

          raw.isdigit() answers the first one. For the conversion, int(raw) would raise here — go through float(raw) and let int() chop the decimal off.

          Output
          
                
            06

            To do

            Each input() reads one line. Ask twice and you get two answers, in the order you asked for them.

            Convert each one to whatever it needs to be — text stays text, a quantity becomes an int, a price becomes a float.

            Your task: ask for an item name, then a quantity, then a unit price, in that order. Print one line using an f-string: 3 x Tea = 7.50, with the total shown to two decimal places.

            Typed in for you when this runs: Tea ⏎ 3 ⏎ 2.5

            your_code.py
            Python
            Hint

            int() for the quantity, float() for the price. Then f"{quantity} x {item} = {quantity * price:.2f}" — the format spec goes after the whole calculation.

            Output
            
                  
              07

              To do

              Each input() takes one line from whatever is feeding the program — a person typing, or a file piped in. Three calls, three lines, in order.

              Your task: three daily readings arrive on three lines. Read them into day_one, day_two and day_three as whole numbers, then print the total and the average to two decimal places:

              Total: 39
              Average: 13.00

              Work the average out from the three variables. Doing three readings by hand is exactly the sort of repetition for loops remove in the next part — for now, notice the repetition.

              Typed in for you when this runs: 12 ⏎ 19 ⏎ 8

              your_code.py
              Python
              Hint

              int(input()) three times — the prompt is optional and can be left out entirely. Then total = day_one + day_two + day_three, and average = total / 3.

              Output
              
                    
                08

                To do

                print() has two extra settings that save a lot of fiddling. sep changes what goes between the values (a space by default), and end changes what goes after them (a newline by default).

                print("a", "b", sep="-")   →  a-b
                print("Loading", end="") → no line break after it

                For lining columns up, strings have ljust and rjust, which pad a value out to a given width.

                Your task: print a two-row receipt where the item name is padded to 10 characters and the price is right-aligned in 6, so the output is exactly:

                Tea............ 2.50
                Rice...........12.00

                (The dots above stand in for spaces so you can see the widths — print real spaces.)

                your_code.py
                Python
                Hint

                f"{first_item.ljust(10)}{first_price:>6.2f}" does both jobs at once: ljust pads the name out on the right, and >6.2f right-aligns the number inside six characters with two decimals.

                Output
                
                      
                  09

                  To do

                  Command-line tools ask a few questions on first run and then echo back what they understood. That confirmation block is not decoration — it is the only chance anyone has to notice the port went in as text, or the name picked up a trailing space.

                  Two habits make it readable. Every prompt ends with a space, so the cursor does not sit against the question mark. And every label is padded to the same width, so the values start in one column.

                  Your task: ask three questions in this order — the project name, the port, and whether debug mode is on. Keep the name as text, convert the port to a whole number, and turn the debug answer into a real bool (True only for yes, whatever the spacing or capitals). Then print:

                  Project dojo-api
                  Port 8080
                  Debug True

                  Each label is left-aligned in an eight-character column.

                  Typed in for you when this runs: dojo-api ⏎ 8080 ⏎ YES

                  your_code.py
                  Python
                  Hint

                  port = int(input("Port: ")). For debug, normalise first: input("Debug? ").strip().lower() == "yes". A row looks like print(f"{'Project':<8}{project}").

                  Output
                  
                        

                    Run the order desk

                    To do

                    Someone walks up to the counter. Ask them four questions, work out what they owe, and print a receipt that lines up.

                    Ask, in this exact order:

                    • the customer's name — text, in name
                    • the item — text, in item
                    • how many — a whole number, in quantity
                    • express delivery? — a real bool in express, True only for yes, whatever the spacing or capitals

                    Every item costs 4.25. Put that in unit_price and work total out from it.

                    Then print exactly four lines:

                    Customer  Kenji
                    Order 3 x Green Tea
                    Express True
                    Total 12.75

                    Typed in for you when this runs: Kenji ⏎ Green Tea ⏎ 3 ⏎ YES

                    your_code.py
                    Python
                    Hint

                    Read all four first. int() around the quantity; for express, normalise with .strip().lower() and compare to "yes". Then total = quantity * unit_price, and a row looks like print(f"{'Customer':<10}{name}"). The total needs {total:.2f} or 12.75 can print as 12.749999999999998.

                    Output
                    
                          

                      Notification