Syntax, Values & Types
Most languages use curly braces {} and semicolons to mark code blocks. Python uses something you can't
see: whitespace. Getting it wrong produces mysterious errors until you know the rule, so it's worth
meeting head-on - then we'll cover the handful of value types Python is built from.
The big surprise: indentation is structure
What it actually is. In Python, a line's indentation - how many spaces it's pushed in from the
left - groups lines into a block. Where other languages write { ... }, Python says "these lines are
indented under that line, so they belong to it." Indentation isn't decoration; it's the grammar.
A block of code that runs only when a condition is true (if proper is Phase
4 - focus on the shape for now):
= 30
What just happened: The line ending in : opens a block. The two indented lines run only when
temperature > 25; the last print, back at the left margin, is outside the block and always runs.
Since 30 > 25, all three lines print:
It's warm
Wear a t-shirt
Done checking
📝 Terminology. The : and the indented lines under it form a block (also called a suite).
Standard is 4 spaces per level - don't mix tabs and spaces, and let your editor insert four on Tab.
⚠️ IndentationError and TabError. Because spacing is the structure, getting it wrong is a real
error, not a style nitpick. Indent a line that shouldn't be, or mix tabs with spaces, and Python refuses
to run:
File "warm.py", line 3
print("It's warm")
^
IndentationError: unexpected indent
This confuses everyone at first. Fix: make every line in the block start at the same column, spaces only - set your editor to "insert spaces for tabs" and it'll handle this for you.
💡 Key point. You don't indent because it looks nice - the indentation is how you tell Python which lines belong together. Read it the way you'd read braces in other languages.
Variables - names pointing at values
What it actually is. A variable is a name attached to a value so you can refer to it later. Create
one with = - read it as "let this name refer to this value," not as math equality.
=
= 36
What just happened: name = "Ada" made name refer to the text "Ada"; age = 36 made age refer
to 36. Each print looked up what the name points at and showed it:
Ada
36
Re-point a name at a new value any time - that's the whole idea of a variable:
= 10
= + 5
What just happened: score + 5 was computed first using the current value of score (10), giving
15; then score = re-pointed the name at that value, so it prints 15. The name didn't "change" - you
pointed it somewhere new.
The core types
Every value in Python has a type - what kind of thing it is. You'll use five constantly. Ask any
value its type with the built-in type():
What just happened: type() reports each value's type:
<class 'int'>
<class 'float'>
<class 'str'>
<class 'bool'>
<class 'NoneType'>
What each is for:
int- a whole number, no decimal point:36,0,-7. No size limit; grows as large as memory allows.float- a number with a decimal point:3.14,2.0,-0.5. Short for floating-point, how computers store fractional numbers.str- a string: text in quotes."hello",'Ada'. Single or double both work; pick one and be consistent.bool- a boolean:TrueorFalse(capitalized - Python is picky). The type of any yes/no answer, like a comparison's result.None- a special value meaning "nothing here / no value yet." Its type isNoneType; there's only ever oneNone. You'll meet it as the default result of functions that don't return anything.
📝 Terminology. A string is a sequence of characters - text. The quotes aren't part of the value; they just tell Python "the text starts here and ends there."
Dynamic typing - names don't have a fixed type
What it actually is. Some languages require declaring "this variable holds an integer," and it can only ever hold integers. Python doesn't work that way: a name can point at one type now and a different type later - the value has a type, the name is just a label.
= 42
=
What just happened: x first pointed at an int, then got re-pointed at a str. Python allows this
freely, so it prints two different types:
<class 'int'>
<class 'str'>
This is called dynamic typing: flexible and quick to write, but nothing stops you from putting the wrong kind of value in a name - you only find out when something breaks later. Keep each variable holding one kind of thing to avoid most of that pain.
f-strings - putting values into text
You'll constantly build strings out of fixed text plus values. The clean, modern way is an f-string:
a string prefixed with f, where anything inside { } is replaced by that expression's value.
=
= 36
What just happened: The f before the quote marks an f-string. Python evaluated {name} and {age}
and dropped their values straight into the text:
Ada is 36 years old
Any expression can go inside the braces, not only a bare name:
= 4
What just happened: Python computed price * 2 (8) and slotted the result in:
Two coffees cost 8 dollars
💡 Key point. Reach for f-strings whenever you mix text and values - readable, fast, modern. (Older
code uses "%s" % x or .format(); you'll see those around but don't need to write them.)
Two number traps that bite beginners
⚠️ = vs == - assignment vs comparison. A single = assigns (points a name at a value); a
double == compares two values and returns a boolean. Mixing them up is a common early mistake:
= 5
What just happened: x = 5 assigned. x == 5 asked "is x equal to 5?" - True - and x == 6 asked
the same about 6 - False:
True
False
Say it in your head as you type: = is "set to," == is "is equal to?"
⚠️ Integer vs float division - / always gives a float. / always produces a float, even when
the numbers divide evenly. For whole-number division, use //:
What just happened: / gave floats (note 4.0, not 4). // did floor division - divide, discard
the remainder, giving a whole number. % (modulo) gave the remainder:
3.5
4.0
3
1
This surprises people coming from languages where / on two integers stays an integer - in Python, /
always means a decimal. Use // for the whole part, % for what's left over (handy for "is this number
even?" - n % 2 == 0).
Recap
- Indentation is structure. A
:opens a block; indented lines under it belong to it. Use 4 spaces, never tabs - getting it wrong is a realIndentationError. - A variable is a name pointing at a value;
=means "let this name refer to," re-pointable any time. - Five everyday types:
int(whole),float(decimal),str(text),bool(True/False),None(no value).type(x)tells you which. - Python is dynamically typed - a name can hold and change type. Flexible, but keep each name to one kind of thing.
- f-strings (
f"{name} is {age}") slot values into text; reach for them by default. =assigns,==compares./always yields afloat; use//for whole-number division,%for the remainder.
Next: the lists, tuples, dicts, and sets you'll use to hold collections of things.
← Phase 1: Install & Your First Program · Guide overview · Phase 3: Collections →
Before the quiz: without looking back, say (or jot down) the core idea of this phase in your own words.
Check your understanding 3 questions
1. In Python, what marks where a block of code begins and ends?
2. What does `7 / 2` produce in Python, and how do you get whole-number division?
3. What does dynamic typing mean in Python?