Skip to content
HopperHopper

Course navigation

Phase 1 · FoundationsDay 1

Setup and your first program

  • About 60 minutes
  • 9 sections
  • Runnable Python examples
  • Practice questions

Before you start

About 60 minutes

By the end you will be able to

  1. Install Python, check its version from the terminal, and use the REPL as a calculator.
  2. Create a .py file and run it from the terminal.
  3. Use print, comments, and top-to-bottom order to write a short program.
  4. Read a SyntaxError or NameError and explain what it is pointing at.

What to remember from earlier

This is the first day, so you need no programming experience. You only need everyday computer skills: saving a file into a folder, finding that folder again, and typing exactly what you see. If you have ever followed instructions like "type this into the box and press Enter," you are ready.

Section 1 of 9

1.1 Installing Python and Opening a Terminal

A computer does exactly what it is told, one instruction at a time, and nothing more. A program is a list of instructions written for a computer, and a programming language is a language with strict rules for writing those instructions. This course teaches the programming language Python, one of the most popular languages in the world because its programs are short and read almost like English.

Your computer does not understand Python on its own. It needs a program called the Python interpreter, which reads Python instructions and carries them out. “Installing Python” means installing the interpreter. Today you will also install a code editor, an app for writing program files. Any plain text editor works, but a code editor colors the parts of your code and catches some mistakes as you type.

Install the tools

  1. Go to python.org, open Downloads, and download the newest Python 3 for your computer (Windows or macOS). Any version 3.12 or newer works for this course. On Linux, Python is usually installed already.
  2. Run the installer. On Windows, if the installer shows a checkbox to add Python to PATH, tick it; that lets the terminal find Python.
  3. Install VS Code from code.visualstudio.com, open it, and install the Python extension from the Extensions panel.

Check that it worked

To talk to the interpreter you use a terminal: a window where you type a command, press Enter, and read the reply as text. Every computer has one (Terminal on macOS and Linux, PowerShell or Terminal on Windows), and VS Code has one built in: choose Terminal → New Terminal.

Type this command into the terminal and press Enter:

python --version

The command has two parts: python names the program to run, and --version asks it only to report which version it is. If Python is installed, the terminal answers with one line that starts with Python 3. followed by the rest of the version number. Version numbers change often, so yours will not match anyone else’s exactly; what matters is that it starts with Python 3 and is 3.12 or newer.

Key idea

The Python interpreter is the program that runs Python code. Typing python --version in a terminal checks that it is installed and shows which version you have.

Now vary one thing: the computer. On macOS and Linux the command is often python3 instead of python, and on Windows py sometimes works when python does not. Each is the same interpreter under a different name:

python3 --version
py --version

Use whichever one answers with Python 3, and use that same word everywhere this course says python.

Watch out

“Command not found” or “Python 2.” If the terminal says it does not recognize python, the interpreter is either not installed or the terminal cannot find it. Try python3 (macOS, Linux) or py (Windows). If none of them work on Windows, run the installer again and tick the PATH checkbox. Then close the terminal and open a new one: a terminal that was already open does not notice new installs. If the reply starts with Python 2, that is an old version that some computers keep for other programs; use python3 instead.

Pause and try

Question 1 · Short answer

Sam types python --version and the terminal says the command was not found. Name two things Sam should try, and explain why each might help.

Check your reasoning

Model answer: First, try python3 --version (on a Mac or Linux) or py --version (on Windows), because the interpreter may be installed under a different name. Second, close the terminal and open a new one, because a terminal that was open during the install does not see the newly installed program. (Rerunning the installer on Windows and ticking the PATH checkbox is also a good answer.)

A complete answer must:

  • name two of: trying python3 or py, opening a new terminal, or reinstalling with the PATH option ticked, and
  • say why each could help (another name for the same program, or a terminal that cannot find it yet).

Reread 1.1 Installing Python and Opening a Terminal if your answer differed.

Section 2 of 9

1.2 The REPL: Python as a Calculator

You have Python installed. What is the fastest way to try one small instruction and see what Python does with it?

Python has an interactive mode for exactly this. Type python (with nothing after it) in the terminal and press Enter. The terminal changes: a few lines about the version appear, then a new prompt, >>>. That prompt means “Python is listening; type one instruction.” This mode is called the REPL, short for Read, Evaluate, Print, Loop: Python reads what you type, evaluates it (works out its value), prints the result, and loops back to >>> for the next one.

The simplest thing to type is an expression: a piece of code that Python can work out to a value, such as 2 + 3. Python uses + to add, - to subtract, * (an asterisk) to multiply, and / to divide.

Worked example: Using the REPL as a calculator

Here is a REPL session. Lines that start with >>> are what you type (without typing the >>> itself); the line under each one is Python’s reply.

>>> 2 + 3
5
>>> 10 - 4
6
>>> 6 * 7
42
>>> 7 / 2
3.5
>>> 8 / 2
4.0

Walk through it the way the REPL does:

You type Python works out Python prints
2 + 3 add 2 and 3 5
10 - 4 subtract 4 from 10 6
6 * 7 multiply 6 by 7 42
7 / 2 divide 7 by 2 3.5
8 / 2 divide 8 by 2 4.0

Notice the last line: dividing with / always gives an answer with a decimal point, even when it comes out even. Python keeps whole numbers and decimal numbers as two different kinds of value, and Day 2 explains why. For today, read 4.0 as “4”.

Now vary one thing: the order of the operations. Python follows the same order of operations as math class: multiplication and division happen before addition and subtraction, and parentheses go first.

>>> 2 + 3 * 4
14
>>> (2 + 3) * 4
20

In 2 + 3 * 4, Python multiplies 3 * 4 first to get 12, then adds 2 to get 14. In (2 + 3) * 4, the parentheses make Python add first to get 5, then multiply by 4 to get 20. The numbers are the same; only the order changed, and so did the answer.

To leave the REPL, type exit() and press Enter. The >>> prompt disappears and you are back at the ordinary terminal.

Key idea

In the REPL, type an expression after >>> and Python prints its value right away. It is the quickest way to test an idea, and you leave it with exit().

Watch out

Typing a terminal command at >>>. The terminal and the REPL look alike, but they understand different things. The terminal understands commands like python --version; the REPL understands only Python. Typing a terminal command into the REPL causes an error:

>>> python --version
Traceback (most recent call last):
  ...
NameError: name 'python' is not defined

The REPL prints a few more lines where ... appears here. You will learn to read this kind of message in 1.9; for now, notice that the REPL did not understand. The fix is to type exit() first, then run the command at the ordinary terminal prompt. The reverse mistake also happens: Python code typed at the ordinary terminal prompt gets an error from the terminal, not an answer from Python. Look for >>> before typing Python.

Pause and try

Question 2 · Tracing

Predict exactly what the REPL prints for each line. Then type them into the REPL to check.

>>> 9 - 2 * 3
>>> (9 - 2) * 3
>>> 9 / 3
Check your reasoning
>>> 9 - 2 * 3
3
>>> (9 - 2) * 3
21
>>> 9 / 3
3.0
  • 9 - 2 * 3: multiplication first, 2 * 3 is 6, then 9 - 6 is 3.
  • (9 - 2) * 3: parentheses first, 9 - 2 is 7, then 7 * 3 is 21.
  • 9 / 3: division with / always shows a decimal point, so it prints 3.0, not 3.

Reread 1.2 The REPL: Python as a Calculator if any answer differed.

Section 3 of 9

1.3 Writing and Running a Script

The REPL forgets everything when you close it. Real programs need to be saved, run again tomorrow, and shared with a friend. For that you write the instructions into a file.

A script is a file of Python code that the interpreter runs from the first line to the last. Python script files end in .py. You write the file in your editor, save it, and then ask the interpreter to run it from the terminal.

Worked example: Your first script

  1. Make a folder named day01 somewhere easy to find, such as your Documents folder.
  2. In VS Code, choose File → Open Folder and open day01.
  3. Choose File → New File, name it hello.py, and type these two lines:
hello.py
print("Hello, world!")
print("I am learning Python.")
  1. Save the file, then open the terminal with Terminal → New Terminal. It starts inside day01, the folder you opened.
  2. Run the script by typing python followed by the file name:
python hello.py

The interpreter opens hello.py, runs line 1, then line 2, and the terminal shows:

Hello, world!
I am learning Python.

You have written and run your first program. Every later day works the same way: edit the file, save, run it again with the same command.

Scripts and the REPL do not behave the same in one important way. Vary one thing: put a bare expression in a script, as you would in the REPL.

silent_sum.py
print("Adding 2 and 3:")
2 + 3
Adding 2 and 3:

Line 2 is never shown. The interpreter still works out 2 + 3, but a script only shows what you explicitly tell it to show; the automatic “print the value” step belongs to the REPL. To see the answer in a script, ask for it with print:

printed_sum.py
print("Adding 2 and 3:")
print(2 + 3)
Adding 2 and 3:
5
Question REPL Script
How do I start it? python python name.py
Is the code saved? No, it is gone when you exit Yes, in the .py file
Values shown by itself? Yes, after every expression No, only what you print
Best for Trying one small idea A whole program you will run again

Key idea

A script is a saved .py file that you run with python name.py. Unlike the REPL, a script shows only what you print.

Watch out

Running the file from the wrong place. If the terminal is not in the folder that holds hello.py, the interpreter reports that it can’t open the file, because it looks for hello.py in the terminal’s current folder. Open the day01 folder in VS Code and use its terminal, so they always match. Also check that you saved the file: the interpreter runs the version on disk, not the unsaved text in your editor. And run python hello.py at the ordinary terminal prompt, not at >>>, where it is a Python error.

Pause and try

Question 3 · Tracing

This file is saved as predict_script.py and run with python predict_script.py. What does the terminal show?

predict_script.py
print("Start")
4 * 5
print(4 * 5)
Check your reasoning
Start
20

Line 1 prints Start. Line 2 is a bare expression: Python works out 20, but a script does not show values on its own, so nothing appears. Line 3 prints 20 because print asks for it. If you wrote 20 twice, you were thinking of the REPL, which shows every expression’s value.

Reread 1.3 Writing and Running a Script if your output differed.

Question 4 · Multiple choice

Which job is the REPL better suited for than a script?

  1. A program you want to run again next week
  2. Checking what 15 * 4 gives before you use it
  3. A program you want to send to a friend
  4. A program with forty lines
Check your reasoning

B. The REPL shows the value of an expression the moment you press Enter, so it is ideal for a quick one-off check.

  • A is wrong: the REPL forgets everything when you exit; a saved .py file can be run again.
  • C is wrong: you can only send a file, and REPL work is not saved in one.
  • D is wrong: typing forty lines one at a time, with nothing saved, is exactly what a script avoids.

Reread 1.3 Writing and Running a Script if you chose differently.

Section 4 of 9

1.4 Printing Text and Numbers

Scripts only show what you print, so print is the most important tool of the day. It is worth knowing exactly how it treats text and numbers.

print is a function: a named instruction that does one job when you use it. Using a function is called calling it, and you call a function by writing its name followed by parentheses: print(...). The value inside the parentheses is the argument, the thing you hand to the function to work on. print displays its argument in the terminal and then moves to a new line.

Text in Python goes inside double quotes, like "Hello". A piece of text in quotes is called a string. (Single quotes work too; Day 3 covers strings in depth.) Numbers are written without quotes.

The quotes change everything. Python treats whatever is inside quotes as plain text to copy exactly, and it works out anything outside quotes as an expression.

Worked example: Quotes or no quotes

print_basics.py
print("Total cost:")
print(4 + 5)
print("4 + 5")
Total cost:
9
4 + 5
Line Argument What Python does Printed
1 "Total cost:" It is a string, so copy the text inside the quotes Total cost:
2 4 + 5 No quotes, so work out the expression: 9 9
3 "4 + 5" It is a string, so copy the characters exactly 4 + 5

Lines 2 and 3 differ only by the quotes, and that is the whole difference between doing the math and showing the math.

Now vary the number of arguments. print can take several, separated by commas; it prints them on one line with one space between each. And print() with nothing inside prints an empty line.

print_commas.py
print("Tickets:", 3 * 12)
print()
print("Thanks for visiting!")
Tickets: 36

Thanks for visiting!

Line 1 has two arguments: the string "Tickets:" and the expression 3 * 12. Python works out 36, then prints the text, a space, and the number. Line 2 prints a blank line, and line 3 prints the last string.

Key idea

print displays its arguments on one line, separated by spaces, then moves to the next line. Text in quotes is printed exactly as written; an expression without quotes is worked out first.

Watch out

Putting quotes around math you want worked out. print("6 * 7") prints 6 * 7, not 42, because the quotes turn it into text. Remove the quotes when you want the answer. The opposite mistake, leaving the quotes off words, causes an error you will meet in 1.9.

Pause and try

Question 5 · Multiple choice

Which line prints 7?

  1. print("3 + 4")
  2. print(3 + 4)
  3. print("3", "+", "4")
  4. print(34)
Check your reasoning

B. With no quotes, 3 + 4 is an expression, so Python works it out and prints 7.

  • A is wrong: the quotes make "3 + 4" a string, so it prints 3 + 4 exactly.
  • C is wrong: it prints three strings separated by spaces, which also shows 3 + 4.
  • D is wrong: 34 is the number thirty-four; nothing adds the digits, so it prints 34.

Reread 1.4 Printing Text and Numbers if you chose differently.

Question 6 · Tracing

What does this line print?

price_line.py
print("Price:", 2 * 5, "dollars")
Check your reasoning
Price: 10 dollars

There are three arguments. The first and last are strings, printed as written. The middle one, 2 * 5, has no quotes, so Python works out 10. print puts one space between each argument.

Reread 1.4 Printing Text and Numbers if your output differed.

Section 5 of 9

1.5 Python Reads Top to Bottom

Your scripts so far have had a few lines each, and their output appeared in the same order as the lines. That is not a coincidence, and it is the rule every Python program follows.

Each line of instructions in a program is a statement: one complete instruction, such as one call to print. When you run a script, the interpreter starts at line 1 and carries out the statements one at a time, from top to bottom. It finishes each statement before starting the next, and it never skips ahead or rearranges them to make more sense.

Worked example: Following the order

morning_steps.py
print("Wake up")
print("Eat breakfast")
print("Walk to school")
Step Line run Terminal so far
1 1 Wake up
2 2 Wake up, Eat breakfast
3 3 Wake up, Eat breakfast, Walk to school
Wake up
Eat breakfast
Walk to school

Now change one thing: move the last line to the top. The statements are the same, but the order is not:

morning_steps_swapped.py
print("Walk to school")
print("Wake up")
print("Eat breakfast")
Walk to school
Wake up
Eat breakfast

Python ran the lines in exactly the order you wrote them, even though walking to school before waking up makes no sense. Python cannot know what you meant; it follows the order on the page.

Key idea

A script’s statements run one at a time, from the top line to the bottom line, in exactly the order written.

Watch out

“Python will know what I meant.” A program can run without any error message and still do the wrong thing, as morning_steps_swapped.py did. No error does not mean correct. Before you run a program, write down what it should print; afterward, compare.

Pause and try

Question 7 · Short answer

This program should count down 3, 2, 1, then print Liftoff!. Run it, compare with what it should do, and say which change fixes it.

countdown_wrong.py
print(3)
print(1)
print(2)
print("Liftoff!")
Check your reasoning

It prints 3, 1, 2, Liftoff!, because the statements run in the order written and lines 2 and 3 are in the wrong order. Swap them:

countdown_fixed.py
print(3)
print(2)
print(1)
print("Liftoff!")
3
2
1
Liftoff!

There was no error message, because every line is valid Python. Only comparing the output with what should happen revealed the problem.

Reread 1.5 Python Reads Top to Bottom if your fix differed.

Section 6 of 9

1.6 Comments: Notes Python Ignores

Next week you will open today’s files and wonder what they were for. Programmers solve this by leaving notes in the code itself, written for people, not for Python.

A comment starts with # (the hash sign) and runs to the end of that line. The interpreter ignores everything from the # onward. A comment can fill a whole line, or follow code on the same line, where the code before the # still runs.

Worked example: Comments in a receipt program

receipt_comments.py
# Print a shopping receipt
print("Apples:", 3 * 2)
print("Bread:", 4)  # one loaf
# print("Milk:", 2)
print("Done")
Apples: 6
Bread: 4
Done
Line What the interpreter does
1 Whole line is a comment: skipped
2 Prints Apples: 6
3 Prints Bread: 4; the comment # one loaf after the code is ignored
4 Starts with #, so the whole line is a comment, even though it looks like code
5 Prints Done

Line 4 shows a common trick called commenting out: putting # in front of a line of code turns it off without deleting it. Remove the # and the line runs again.

Now vary where the # sits: inside quotes, it is just a character in the text, not the start of a comment.

hash_in_quotes.py
print("Room #12")  # the # before 12 is part of the text
Room #12

The first # is inside the string, so it prints. The second # is outside the quotes, so the rest of the line is a comment.

Key idea

A # outside quotes starts a comment, and Python ignores the rest of that line. Comments explain code to people; commenting out a line turns it off.

Watch out

Commenting the wrong part of a line. A # at the start of a line turns off everything on it. Students sometimes put # in front of a print to add a note and are surprised when that line stops printing. Put notes on their own line, or after the code.

Pause and try

Question 8 · Tracing

What does this program print?

comment_trace.py
# Team scores
print("Red team:", 10 + 5)
# print("Blue team:", 8)
print("Green team:", 7)  # print("Gold team:", 9)
Check your reasoning
Red team: 15
Green team: 7

Line 1 is a comment. Line 2 prints Red team: and 15. Line 3 is commented out, so Blue team never prints. Line 4 prints Green team: 7; everything after its #, including the code print("Gold team:", 9), is a comment and does not run.

Reread 1.6 Comments: Notes Python Ignores if your output differed.

Section 7 of 9

1.7 Indentation Is Part of the Syntax

So far, every line you have seen starts at the very left edge. That is not just tidiness. In most writing, extra spaces at the start of a line are harmless. In Python they carry meaning.

Every language has rules for how sentences must be built; “dog the ran” breaks English grammar. The rules for how code must be written are the language’s syntax. Indentation means the spaces at the start of a line, and in Python indentation is part of the syntax: it shows which lines belong together in a group. You will build those groups on Day 4. Until then, every statement belongs at the left edge, so any spaces before a statement break the rules.

There is one more fact you need: before running anything, the interpreter reads the whole file to check its syntax. If it finds a broken rule anywhere, it reports the error and runs nothing, not even the lines above the mistake.

Worked example: One stray indent stops everything

unexpected_indent.py
print("Line one")
    print("Line two")

Line 2 begins with four spaces. Running it prints no Line one at all, only this:

  File ".../day01/unexpected_indent.py", line 2
    print("Line two")
IndentationError: unexpected indent

The first line names the file (yours shows the full path to your own folder) and the line, 2. The middle line shows that line of code. The last line names the problem: an IndentationError, and specifically an unexpected indent, meaning spaces where Python did not expect any. Delete the four spaces and both lines print.

Now vary where the extra spaces go. Blank lines and spaces inside a line do not count as indentation:

spacing_inside_lines.py
print("Start")

print(2+3)
print(2   +   3)
Start
5
5

The blank line is skipped, and 2+3 and 2 + 3 mean the same as 2 + 3. Only spaces at the start of a line are part of the syntax. (Most Python programmers write one space on each side of +, as in 2 + 3, because it is easiest to read.)

Key idea

In Python, spaces at the start of a line are part of the syntax. Until you learn to group lines, every statement starts at the left edge; a stray indent is an IndentationError and nothing in the file runs.

Watch out

Invisible spaces. An accidental space or Tab at the start of a line is hard to see, so the error can seem to come from nowhere. When you see unexpected indent, go to the line number it gives, put the cursor at the very start of the line, and delete until the code touches the left edge.

Pause and try

Question 9 · Multiple choice

What happens when this program runs?

indent_question.py
print("Welcome")
print("Today we learn Python")
  print("Let's begin")
print("Goodbye")
  1. It prints Welcome and Today we learn Python, then reports an error.
  2. It reports IndentationError: unexpected indent for line 3 and prints nothing.
  3. It prints all four lines; the extra spaces are ignored.
  4. It prints lines 1, 2, and 4 and skips line 3.
Check your reasoning

B. Line 3 starts with two spaces, which breaks Python’s syntax. The interpreter checks the whole file before running any of it, so it reports the IndentationError and runs nothing.

  • A is wrong: it pictures Python running lines 1 and 2 before reaching the mistake. Syntax is checked first, for the whole file.
  • C is wrong: spaces at the start of a line are part of Python’s syntax, not decoration.
  • D is wrong: Python never skips a broken line; it refuses to run the file.

Reread 1.7 Indentation Is Part of the Syntax if you chose differently.

Section 8 of 9

1.8 Reading a SyntaxError

Everyone who writes code makes mistakes, every day. The difference between a beginner who gets stuck and one who keeps going is reading the error message instead of panicking. Python’s messages tell you where to look and what is wrong.

An error message is the report the interpreter prints when it cannot continue. A SyntaxError is the general name for a broken syntax rule: a missing parenthesis, a missing quote, a missing comma. The IndentationError from 1.7 is one special kind of syntax error. Like it, every SyntaxError is found before the program runs, so nothing prints.

Worked example: A parenthesis that was never closed

never_closed.py
print("Hello")
print("World"
print("Bye")
  File ".../day01/never_closed.py", line 2
    print("World"
         ^
SyntaxError: '(' was never closed

Read it in three parts:

  1. Where: line 2 of never_closed.py.
  2. Exactly where: the caret ^ under the code points at the ( after print.
  3. What: '(' was never closed. Every ( needs a matching ), and this one has none.

Add ) to the end of line 2 and all three lines print. Notice that Hello did not print first: the error was found while Python checked the file, before anything ran.

Now vary the mistake: leave off a closing quote instead.

unclosed_quote.py
print("Hello)
print("Bye")
  File ".../day01/unclosed_quote.py", line 1
    print("Hello)
          ^
SyntaxError: unterminated string literal (detected at line 1)

A string literal is a string typed directly into the code, like "Hello". Unterminated means it was never ended: the opening " has no closing " on that line, so Python thinks the ) is part of the text. The caret points at the quote that was opened. The fix is print("Hello").

Mistake Example Last line of the message
Missing ) print("Hi" SyntaxError: '(' was never closed
Missing closing quote print("Hi) SyntaxError: unterminated string literal …
Stray space at the start Spaces before print("Hi") IndentationError: unexpected indent

Older versions of Python may word these messages differently, but they always give the line number and the kind of error.

Key idea

A SyntaxError means the code breaks Python’s rules. Python finds it before running anything; read the line number, the caret, and the last line to find and fix it.

Watch out

Fixing the line the message names, when the mistake is just before it. Usually the line number points straight at the mistake. Occasionally Python only notices a problem a little later, so if the named line looks perfect, check the line above it too.

Pause and try

Question 10 · Debugging

This program reports an error and prints nothing. Find the mistake, quote the error message’s last line, and write the fix.

debug_syntax.py
print("Quiz time!")
print("Question 1)
print("Good luck!")
Check your reasoning

Python reports, for line 2:

SyntaxError: unterminated string literal (detected at line 2)

Line 2 opens a string with " before Question but never closes it. Add the closing quote before the ):

debug_syntax_fixed.py
print("Quiz time!")
print("Question 1")
print("Good luck!")
Quiz time!
Question 1
Good luck!

Quiz time! did not print before the fix because a syntax error stops the whole file before anything runs.

Reread 1.8 Reading a SyntaxError if you missed it.

Section 9 of 9

1.9 Reading a NameError

Some mistakes follow every syntax rule, so Python happily starts running the program, and only discovers the problem when it reaches the broken line.

Python knows a set of built-in names, such as print. When a line uses a name Python does not know, it stops at that line with a NameError. Because the file’s syntax was fine, the program really did start, so every line before the mistake has already run.

Worked example: A misspelled function name

misspelled_print.py
print("Ready")
pront("Go")
print("Done")
Ready
Traceback (most recent call last):
  File ".../day01/misspelled_print.py", line 2, in <module>
    pront("Go")
    ^^^^^
NameError: name 'pront' is not defined. Did you mean: 'print'?

The report Python prints when a running program stops is called a traceback, because it traces back to the line where things went wrong. Read it from the top:

Part Meaning
Ready Normal output: line 1 ran before the error
Traceback (most recent call last): Python is about to show where the running program stopped
File "...", line 2, in <module> The file and line; <module> just means “in the main part of your file”
pront("Go") and ^^^^^ The line itself, with carets under the name Python did not recognize
NameError: name 'pront' is not defined The kind of error and its cause
Did you mean: 'print'? A suggestion, when Python spots a known name that looks similar

Line 3 never ran: once a program stops with an error, the statements after it are skipped. Fix the spelling and all three lines print.

Now vary the mistake: spell print correctly but forget the quotes around a word.

missing_quotes.py
print("Ready")
print(Hello)
Ready
Traceback (most recent call last):
  File ".../day01/missing_quotes.py", line 2, in <module>
    print(Hello)
          ^^^^^
NameError: name 'Hello' is not defined

Without quotes, Hello is not text; Python treats it as a name and looks it up. It knows no name Hello, so it stops. The fix is print("Hello"). Python is also case-sensitive, meaning capital and small letters count as different: Print is a different name from print, and causes the same kind of error.

Question SyntaxError NameError
When is it found? Before anything runs When Python reaches that line
Does earlier output appear? No, nothing prints Yes, earlier lines have already run
Common causes Missing ), quote, comma; stray indent Misspelled name, missing quotes, wrong capital

As with syntax errors, older versions of Python may word these messages a little differently, and some print no “Did you mean” suggestion.

Key idea

A NameError means Python reached a line using a name it does not know. Lines before it have already run; read the last line of the traceback and the carets to find the unknown name.

Watch out

Reading only the first line of the message. The most useful line of a traceback is the last one, which says what went wrong, and the line just above the carets, which shows where. Students who stop reading at Traceback (most recent call last): miss both. Read error messages from the bottom up.

Pause and try

Question 11 · Tracing

Write everything this program shows, including the last line of the error message.

name_trace.py
print("Step 1")
print("Step 2:", 5 * 2)
print(Finished)
print("Step 3")
Check your reasoning
Step 1
Step 2: 10
Traceback (most recent call last):
  ...
NameError: name 'Finished' is not defined

The syntax is fine, so the program starts. Line 1 prints Step 1, and line 2 prints Step 2: with 10. Line 3 uses Finished without quotes, so Python looks for a name Finished, finds none, and stops with a NameError. Line 4 never runs, so Step 3 never appears.

Reread 1.9 Reading a NameError if your output differed.

Question 12 · Multiple choice

A program’s first two lines are correct print statements. Line 3 has a mistake. In which case do the first two lines still print?

  1. Line 3 is missing its closing ).
  2. Line 3 starts with two spaces.
  3. Line 3 is Print("Done").
  4. Line 3 is missing its closing quote.
Check your reasoning

C. Print("Done") follows the syntax rules, so the program runs; it stops at line 3 with a NameError because Print (capital P) is not a name Python knows. Lines 1 and 2 have already printed by then.

  • A is wrong: a missing ) is a SyntaxError, found before anything runs.
  • B is wrong: a stray indent is an IndentationError, also found before anything runs.
  • D is wrong: an unclosed string is a SyntaxError too.

Reread 1.9 Reading a NameError and its comparison table if you chose differently.

Wrap-up · 1 of 7

Putting it together

Maya is making a sign for her school’s bake sale. Follow her through three runs; each stage uses a different part of today’s lesson.

Attempt 1 (1.6, 1.8). Maya starts with a comment saying what the program is for, then the sign’s lines:

bake_sale_attempt1.py
# Bake sale sign
print("BAKE SALE TODAY")
print("Muffins left:", 30 - 12
prnt("Cookies left:", 48 - 20)
print("All money goes to the library")
  File ".../day01/bake_sale_attempt1.py", line 3
    print("Muffins left:", 30 - 12
         ^
SyntaxError: '(' was never closed

Nothing prints, not even BAKE SALE TODAY, because a syntax error stops the whole file before it runs. The caret points at line 3’s (, which has no ). Maya adds the ).

Attempt 2 (1.5, 1.9). Now the syntax is fine, so the program starts running from the top:

bake_sale_attempt2.py
# Bake sale sign
print("BAKE SALE TODAY")
print("Muffins left:", 30 - 12)
prnt("Cookies left:", 48 - 20)
print("All money goes to the library")
BAKE SALE TODAY
Muffins left: 18
Traceback (most recent call last):
  File ".../day01/bake_sale_attempt2.py", line 4, in <module>
    prnt("Cookies left:", 48 - 20)
    ^^^^
NameError: name 'prnt' is not defined. Did you mean: 'print'?

Lines 2 and 3 ran (line 1 is a comment), then line 4 stopped the program. Reading the message from the bottom up, Maya sees the misspelling and Python’s suggestion.

Attempt 3 (1.4). With print spelled correctly, every line runs:

bake_sale.py
# Bake sale sign
print("BAKE SALE TODAY")
print("Muffins left:", 30 - 12)
print("Cookies left:", 48 - 20)
print("All money goes to the library")
BAKE SALE TODAY
Muffins left: 18
Cookies left: 28
All money goes to the library
Attempt Kind of problem Found What printed
1 SyntaxError Before running Nothing
2 NameError While running The first two lines
3 None Runs to the end All four lines
Wrap-up · 2 of 7

Vocabulary

Term Definition Example
program A list of instructions for a computer hello.py
Python interpreter The program that reads and runs Python code What python starts
code editor An app for writing program files VS Code
terminal A window where you type commands and read text replies Where you type python hello.py
REPL Python’s interactive mode: read, evaluate, print, loop The >>> prompt
expression Code that Python works out to a value 2 + 3
script A saved .py file that Python runs from top to bottom hello.py
function / calling A named instruction that does one job / using it, with parentheses print(...)
argument A value handed to a function inside its parentheses "Hi" in print("Hi")
string / string literal Text in quotes / a string typed directly into the code "Hello"
statement One complete instruction print("Done")
comment / commenting out Text after # that Python ignores / turning a line off with # # one loaf
syntax The rules for how code must be written Every ( needs a )
indentation Spaces at the start of a line; part of Python’s syntax Spaces before print("Hi")
error message / traceback The interpreter’s report when it cannot continue / the report of where a running program stopped Traceback (most recent call last):
SyntaxError A broken syntax rule, found before anything runs '(' was never closed
IndentationError A syntax error caused by wrong indentation unexpected indent
NameError A name Python does not know, found when that line runs name 'pront' is not defined
case-sensitive Capital and small letters count as different Print is not print
Wrap-up · 3 of 7

Summary

  • The Python interpreter runs Python code. python --version in a terminal checks that it is installed.
  • The REPL (>>>) shows the value of each expression at once; a script is a saved .py file run with python name.py, and it shows only what you print.
  • print displays its arguments separated by spaces; text in quotes is copied exactly, and expressions without quotes are worked out first. Comments start with # and are ignored.
  • Statements run one at a time, top to bottom, in the order written. In Python, indentation is part of the syntax, so for now every statement starts at the left edge.
  • A SyntaxError (including an IndentationError) is found before anything runs, so nothing prints. A NameError happens when Python reaches an unknown name, after earlier lines have run. Read error messages from the bottom up.
Wrap-up · 4 of 7

Practice

Do these in your day01 folder. Type each program yourself, run it, and only then open the answer.

Question 13 · Short answer

Name and address. Write a script that prints your name, then a three-line address, using one print per line. (Use a made-up address if you prefer.)

Check your reasoning

One possible solution:

address.py
print("Jordan Lee")
print("27 Willow Street")
print("Apartment 3")
print("Brookfield")
Jordan Lee
27 Willow Street
Apartment 3
Brookfield

Each line is one statement calling print with one string, so the program prints four lines, top to bottom, in the order written. Your text will differ; what matters is four print lines, quotes around every piece of text, and every line starting at the left edge.

Reread 1.4 Printing Text and Numbers if your program reported an error or printed the wrong text.

Question 14 · Short answer

REPL calculator. Start the REPL and use it as a calculator for five expressions. Use all four operators (+, -, *, /) and at least one pair of parentheses. Predict each answer before you press Enter.

Check your reasoning

One possible session (for example, adding up items, minutes in a day, and the average of three scores):

>>> 12 + 30 + 7
49
>>> 60 * 24
1440
>>> 100 - 37
63
>>> 45 / 9
5.0
>>> (8 + 6 + 10) / 3
8.0
  • 60 * 24 is the number of minutes in a day.
  • 45 / 9 and (8 + 6 + 10) / 3 both use /, so their answers show a decimal point (5.0, 8.0) even though they divide evenly.
  • In (8 + 6 + 10) / 3 the parentheses make Python add first; without them, only the 10 would be divided by 3.

Reread 1.2 The REPL: Python as a Calculator if a result surprised you.

Question 15 · Short answer

Break it on purpose. Make three copies of your name-and-address program. Break each one a different way: remove a closing quote, misspell print, and add spaces at the start of a line. Run each, and for each one write down the kind of error, the line number, and whether anything printed first.

Check your reasoning

Here is each break applied to the sample solution. Only the key lines of each message are shown; your terminal also shows the file name, the line of code, and a caret.

Missing closing quote on line 2:

address_broken_quote.py
print("Jordan Lee")
print("27 Willow Street)
print("Apartment 3")
print("Brookfield")
SyntaxError: unterminated string literal (detected at line 2)

A SyntaxError on line 2. Nothing printed, not even Jordan Lee, because syntax is checked before anything runs.

Misspelled print on line 3:

address_broken_name.py
print("Jordan Lee")
print("27 Willow Street")
Print("Apartment 3")
print("Brookfield")
Jordan Lee
27 Willow Street
Traceback (most recent call last):
  ...
NameError: name 'Print' is not defined. Did you mean: 'print'?

A NameError on line 3 (capital P). Lines 1 and 2 printed first, because the program was running when it reached the unknown name.

Stray indent on line 4:

address_broken_indent.py
print("Jordan Lee")
print("27 Willow Street")
print("Apartment 3")
    print("Brookfield")
IndentationError: unexpected indent

An IndentationError on line 4. Nothing printed, because it is a kind of syntax error.

Your line numbers depend on where you broke your program. The pattern should match: syntax and indentation errors print nothing; a NameError prints the lines before it.

Reread 1.8 Reading a SyntaxError and 1.9 Reading a NameError if your results differed.

Wrap-up · 5 of 7

Review questions

Question 16 · Multiple choice

A file answer.py contains just one line: 6 * 7. What appears when you run python answer.py?

  1. 42
  2. 6 * 7
  3. Nothing
  4. NameError: name 'answer' is not defined
Check your reasoning

C. The script works out 42, but a script shows only what you print, so nothing appears.

  • A is wrong: 42 is what the REPL would show, because the REPL prints every expression’s value. A script does not.
  • B is wrong: there are no quotes and no print, so the characters are never displayed.
  • D is wrong: answer is the file’s name, not a name used in the code; the line follows every rule and runs without error.

Reread 1.3 Writing and Running a Script if you chose differently.

Question 17 · Tracing

Write exactly what this program prints, including any blank line.

review_trace.py
# Movie night plan
print("Movie night")
print("Snacks:", 3 + 4)  # popcorn and juice
# print("Cancelled")
print()
print("Tickets:", 2 * 9)
print("2 * 9")
Check your reasoning
Movie night
Snacks: 7

Tickets: 18
2 * 9
Line What happens
1 Comment, skipped
2 Prints Movie night
3 Works out 3 + 4, prints Snacks: 7; the comment is ignored
4 Commented out, so Cancelled never prints
5 print() prints a blank line
6 Works out 2 * 9, prints Tickets: 18
7 "2 * 9" is a string, so it prints 2 * 9

Reread 1.4 Printing Text and Numbers and 1.6 Comments: Notes Python Ignores if your output differed.

Question 18 · Debugging

This program should print Total: 9. Instead it shows the message below. Use the caret and the message to find the mistake, and write the fix.

review_missing_comma.py
print("Total:" 4 + 5)
  File ".../day01/review_missing_comma.py", line 1
    print("Total:" 4 + 5)
          ^^^^^^^^^^^^^^
SyntaxError: invalid syntax. Perhaps you forgot a comma?
Check your reasoning

The carets cover both the string "Total:" and the expression 4 + 5, and the message suggests a missing comma. Two arguments to print must be separated by a comma; without one, Python cannot tell where the first argument ends, so the line breaks the syntax rules. Add the comma:

review_missing_comma_fixed.py
print("Total:", 4 + 5)
Total: 9

This message is new, but it reads the same way as the others: line number, carets, then the last line. invalid syntax is Python’s general message for a broken rule, and the second sentence is a suggestion, like “Did you mean”.

Reread 1.4 Printing Text and Numbers and 1.8 Reading a SyntaxError if you missed it.

Question 19 · Multiple choice

Program P and program Q each have four lines. They differ only in line 3.

program_p.py
print("A")
print("B")
pritn("C")
print("D")
program_q.py
print("A")
print("B")
print("C"
print("D")

Which statement is true?

  1. Both print A and B, then stop with an error.
  2. P prints A and B then stops; Q prints nothing.
  3. P prints nothing; Q prints A and B then stops.
  4. Both print nothing.
Check your reasoning

B. P’s line 3 misspells print as pritn. That follows the syntax rules, so P runs, prints A and B, and stops at line 3 with NameError: name 'pritn' is not defined. Q’s line 3 is missing ), a SyntaxError found before anything runs, so Q prints nothing.

  • A is wrong: it treats both mistakes as found while running. A missing ) is found before running.
  • C is wrong: it has the two kinds of error swapped.
  • D is wrong: P’s mistake is not a syntax error, so P starts running and prints its first two lines.

Reread the comparison table in 1.9 Reading a NameError if you chose differently.

Question 20 · Short answer

Ravi runs a ten-line script. It prints four lines and then shows a NameError for line 5. Ravi says, “Line 5 is the only mistake, so once I fix it the program will work.” Is Ravi right? Explain what the error does and does not tell him about lines 1–4 and lines 6–10.

Check your reasoning

Model answer: Not necessarily. Because the program started, the whole file passed the syntax check, and lines 1–4 ran without errors (though they could still print the wrong thing). But the program stopped at line 5, so lines 6–10 never ran. They could contain their own NameErrors, which Python will report only when it reaches them. Ravi should fix line 5, run the program again, and compare all the output with what it should print.

A complete answer must:

  • say that the program stopping at line 5 means lines 6–10 never ran, so their mistakes have not been checked by running yet, and
  • say that lines 1–4 ran without errors and the file has no syntax errors, while noting that running without an error does not prove the output is right.

Reread 1.9 Reading a NameError and 1.5 Python Reads Top to Bottom if your reasoning differed.

Wrap-up · 6 of 7

Go further

The official Python Tutorial’s first chapters cover why Python is worth learning and how to start the interpreter and the REPL: Whetting Your Appetite and Using the Python Interpreter.

Wrap-up · 7 of 7

Reflection

Check each statement. If the answer is “not yet,” reread the linked subsection.

  • I can check which version of Python is installed from the terminal. Reread
  • I can use the REPL as a calculator and leave it. Reread
  • I can create a .py file and run it from the terminal. Reread
  • I can predict what print shows with and without quotes. Reread
  • I can trace a program from top to bottom. Reread
  • I can write a comment and comment out a line. Reread
  • I can explain why a stray indent stops a whole program. Reread
  • I can find the mistake a SyntaxError is pointing at. Reread
  • I can read a NameError and say which lines ran before it. Reread