◀ Stage Select World 1 · Stage 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 stage puts it front and centre.

Ready?

Step-by-step lessons

Ask, Convert, Answer

Four short lessons: how input() works, the one trap everybody falls into, asking more than one question, and printing something a person can actually read.

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 World 2 and World 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?

Type it yourself

Code Lab

Four exercises on asking a person a question and doing something sensible with the answer. Each one types its answers in for you — you can see exactly what they are above each editor. Your prompts show up in the console but are not part of what gets checked, so word them however you like.

0 of 4 cleared

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

Ask a question

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

    Every answer arrives as text

    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 stages? , convert the answer to a whole number in stages, and print the XP that earns at 200 per stage. With 4 typed in, the output is 800 XP.

    Typed in for you when this runs: 4

    your_code.py
    Python
    Hint

    stages = int(input("How many stages? ")) does the reading and converting in one line. Then f"{stages * 200} XP".

    Output
    
          
      03

      More than one question

      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
      
            
        04

        Output people can actually read

        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
        
              
          Boss round

          Assignment: The Order Desk

          One graded task. Pass every check and the stage is cleared and the title is yours — one more stage towards the Python Practitioner certificate.

          This one is graded. You can see 2 of the checks up front, and 3 stay hidden until you run. The hidden ones test the same job from angles you have not been shown, so code that genuinely solves the problem clears this and code shaped around the visible examples does not. Pass them all and the stage is yours.

          Run the order desk

          To do

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

          Ask, in this exact order:

          • the customer's name — keep it as text in name
          • the item — text, in item
          • how many — a whole number, in quantity

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

          Then print exactly three lines:

          Customer: Kenji
          Order: 3 x Green Tea
          Total: 12.75

          The total must show two decimal places, and must be calculated. The hidden checks confirm it holds for a different order as well.

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

          your_code.py
          Python
          Hint

          Read all three first, converting the quantity with int(). Then total = quantity * unit_price, and print with f-strings — the last one needs {total:.2f} so 12.75 does not come out as 12.749999.

          Output
          
                
            Lock it in

            Guess the Term

            Read the clues and name the concept. The fewer clues you need, the more points you score.

            Round 1 Score 0
            Keep it handy

            Input & Output Quick Reference

            The whole stage on one screen.

            Reading

            input("Name: ")

            Prompt, wait, return the typed line. End the prompt with a space.

            str

            Always text

            No exceptions. Convert before doing arithmetic.

            One line each

            Answers match calls by order, nothing else.

            Converting

            int(input(...))

            For counts and whole numbers.

            float(input(...))

            For prices and measurements.

            ValueError

            What you get when the text is not a number.

            print() settings

            sep

            Between values

            A space by default. sep="" removes it.

            end

            After the values

            A newline by default. end="" stays on the line.

            f""

            f-strings

            Usually clearer than juggling sep and commas.

            Lining Up

            .ljust(10)

            Pad on the right. Names go left.

            {n:>6}

            Right-align in six. Numbers go right.

            .2f

            {total:.2f}

            Two decimals, always.

            Notification