Python Programming — Alpha School

Lesson 2: Variables, Types, and Control Flow

🎧 Listen to this lesson

A program that only prints fixed text is a poster, not a tool. Real programs remember values, ask questions, make decisions and repeat actions. This lesson adds those four powers: variables to store values, types to know what kind of value you hold, input() to ask the user things, and control flow — if statements and loops — to decide and repeat.

Variables: names for values

A variable is a name that points to a value: score = 0 creates the name score referring to the number 0. The = sign here is assignment, not a maths equals sign: it means "store the value on the right in the name on the left". You can reassign a name whenever you like, and Python tracks four core types:

TypeMeaningExample
intwhole numbers42, -7, 0
floatdecimal numbers3.14, 2.0, -0.5
strtext (string)"hello", 'Ada'
booltrue/falseTrue, False
age = 15
name = "Ada"
height = 1.62
print(type(age), type(name), type(height))

Output: <class 'int'> <class 'str'> <class 'float'>. Python is dynamically typed: a name can be reassigned to a different type later (age = "fifteen" is legal, if unwise). Choose names that describe the value — score beats s, and total_price beats tp — because code is read far more often than it is written.

Asking the user: input() and converting types

input("prompt") displays a prompt, waits for the user to type, and gives your program what they typed — always as a string, even if they typed digits. That single fact causes more beginner bugs than any other, so convert deliberately with int() or float() when you need numbers:

name = input("What is your name? ")
age = int(input("How old are you? "))
print(f"{name}, next year you'll be {age + 1}.")

If the user types Ada and 15, the output is Ada, next year you'll be 16. The f-string (the f before the quotes) lets you embed values inside text with curly braces: {name} is replaced by the variable's value, and {age + 1} by the result of a calculation. Without the conversion, age + 1 would try to add a number to the string "15" and crash with a TypeError — the fix is never to argue with the error but to convert at the moment of input.

Making decisions: if, elif, else

Programs branch with if. The block under each condition is defined by indentation — four spaces — not by brackets:

score = 85
if score >= 90:
    print("Grade A")
elif score >= 80:
    print("Grade B")
else:
    print("Keep practising")

This prints Grade B: Python tests conditions from the top and runs the first block whose condition is true. Conditions are built from comparisons (== equal, != not equal, <, >, <=, >=) and logic operators: and (both must be true), or (at least one), not (flip it). Watch the classic trap: = assigns, == compares. Writing if score = 90: is a SyntaxError — Python refuses to guess whether you meant assignment or comparison.

Key idea. Key idea: input() always returns a string. Convert with int() or float() immediately, or every calculation later in the program inherits the bug.

Repeating: while and for loops

A while loop repeats while its condition stays true — use it when you do not know in advance how many repetitions you need:

count = 3
while count > 0:
    print(count)
    count = count - 1
print("Blast off!")

Output: 3, 2, 1, Blast off! — each on its own line. The line count = count - 1 is the loop's engine: without it, count never changes, the condition never fails, and you get an infinite loop (press Ctrl+C to escape one). A for loop repeats over a known sequence, usually range(): range(5) gives 0, 1, 2, 3, 4 (five values, starting at 0); range(1, 11) gives 1 to 10. Inside a loop, break exits immediately and continue skips to the next round.

Worked example 1 — the number-guessing game

This game uses everything above: a variable, a while loop, an if/elif/else, and input conversion.

secret = 7
guess = int(input("Guess a number 1-10: "))
while guess != secret:
    if guess < secret:
        print("Too low!")
    else:
        print("Too high!")
    guess = int(input("Try again: "))
print("Correct! The secret was", secret)

Trace with guesses 3, 9, 7: the first guess 3 is not 7, so the loop runs; 3 < 7 prints Too low!; the guess is re-read inside the loop — delete that line and the loop can never end, because guess would stay 3 forever. Guess 9 prints Too high!; guess 7 fails the != test, the loop exits, and the final line prints Correct! The secret was 7. Improvement ideas once it works: count the attempts, or pick a new secret each game with random.randint(1, 10) from the random module (Lesson 12).

Worked example 2 — a grade classifier with a loop

Combining the grade chain with a for loop processes a whole class list in one run:

scores = [95, 82, 71, 58, 90]
for score in scores:
    if score >= 90:
        letter = "A"
    elif score >= 80:
        letter = "B"
    elif score >= 70:
        letter = "C"
    elif score >= 60:
        letter = "D"
    else:
        letter = "F"
    print(score, "->", letter)

Output:

95 -> A
82 -> B
71 -> C
58 -> F
90 -> A

Step by step: the for loop hands each value to score in turn; the if-chain assigns letter; the print shows the pair. Notice the list [95, 82, 71, 58, 90] — square brackets hold a list, which Lesson 5 explores properly. Also notice the chain checks from the top: 90 lands in "A" because >= 90 is tested before >= 80. If you reversed the order, every score would stop at the first true test and 95 would be graded "B" — in an if-chain, order is logic.

Common mistakes

  • Comparing with = instead of ==. if x = 5: is a SyntaxError; if x == 5: is the comparison you meant. The error message is doing you a favour.
  • Forgetting to convert input. age = input("Age? ") then age + 1 raises TypeError: can only concatenate str (not "int") to str or a close cousin. Convert at the input line: age = int(input("Age? ")).
  • The endless loop. If a while loop's condition can never become false — usually because the variable it tests is never updated inside the loop — the program runs forever. When it happens, Ctrl+C, then check which line was supposed to change the variable.
  • range off-by-one. range(1, 10) stops at 9: the end value is always excluded. To include 10, write range(1, 11).
  • Inconsistent indentation. Mixing tabs and spaces, or indenting one line of a block differently, raises IndentationError. Set your editor to insert 4 spaces and never mix.
Try it. Try it: Write a program that asks for a test score and prints its letter grade (A 90+, B 80+, C 70+, D 60+, F below). Then write a for loop that prints the 7-times table from 7 x 1 to 7 x 12, one line per entry, like 7 x 3 = 21.

Real-World Challenge

The task. A cinema sells tickets by age: under 5s are free, ages 5–12 pay 6.00, ages 13–17 pay 8.50, adults pay 12.00, and seniors (65+) pay 7.00. Write a program that asks for one person's age and prints their ticket price. The program must never crash on a sensible age, and negative ages should get a polite error message instead of a price.

Worked solution.

age = int(input("What is your age? "))
if age < 0:
    print("That age does not make sense - please run me again.")
elif age < 5:
    price = 0.00
elif age <= 12:
    price = 6.00
elif age <= 17:
    price = 8.50
elif age < 65:
    price = 12.00
else:
    price = 7.00
if age >= 0:
    print(f"Your ticket costs ${price:.2f}")

How it works. The chain is ordered so each boundary is tested once: a 10-year-old fails age < 5, passes age <= 12, and pays 6.00 — the output is Your ticket costs $6.00, where :.2f inside the f-string brace formats the float to exactly two decimal places. An age of 65 falls through every earlier test into the final else and pays the senior price. The first branch guards the nonsense case: for a negative age the program prints the polite message, and the if age >= 0 around the last line makes sure no price is printed. Test it at every boundary: 4, 5, 12, 13, 17, 18, 64, 65 — boundary values are where pricing bugs hide, a habit Lesson 7 formalises.

Extension. Ask how many tickets the person is buying and apply a group discount: 4 or more tickets get 10% off the total. Print both the undiscounted total and the final price, each with :.2f, and test with 4 adult tickets (48.00 before discount, 43.20 after).

Going further — ordering conditions and short circuits

An if-chain is evaluated top to bottom and the first true branch wins, so the order of conditions is a design decision, not a detail. Put the most specific cases first and the general ones last; a general condition placed early will swallow cases meant for later branches and they will never run. Tiered pricing shows the pattern — each band is checked exactly once, in order:

age = 15
student = True
if age < 5:
    price = 0
elif age <= 12:
    price = 6
elif student:
    price = 8
else:
    price = 12
print(price)

Output: 8 — the visitor is too old for the child bands, so evaluation falls through to the student discount before reaching the full-price default. Swap the student and age <= 12 branches and a 10-year-old student would pay 8 instead of 6: same conditions, different order, different program. Python also short-circuits compound conditions: in a and b, if a is False the right side never runs; in a or b, a True left side ends the evaluation. That is not trivia — it lets you write guards like if items and items[0] == target: where the second test is only safe because the first already proved the list non-empty. Order, in conditions as in code generally, is meaning.

🎬 Watch & Learn

Prefer video? These searches surface top tutorials on this lesson's topic:

💪 Practice Zone

Try these yourself — hints are included, answers are not. Run your code in any Python environment.

  1. Tip calculator — Store a restaurant bill in a variable bill. Compute an 18% tip and print the bill, the tip, and the total.
    Hinttip = bill * 0.18, then total = bill + tip. Try bill = 42.50.
  2. Even or odd — Ask the user for a whole number with input(), then print even or odd.
    HintConvert with int() first, then use the % (remainder) operator: n % 2 == 0 means even.
  3. Grade classifier — Ask for a test score (0–100) and print the letter grade: A (90+), B (80+), C (70+), D (60+), F (below 60).
    HintUse if / elif / else and check the highest boundary first.
  4. Type detective — Predict the type of each, then verify with type(): "42", 42, 4.2, True, input("x: ").
    Hintinput() always returns a string — even if the user types digits.

🌍 Real World

Every app that makes a decision uses this lesson: a banking app checks if balance >= price before approving your purchase, and a fitness app picks your workout with if/elif/else on your goal. Variables and conditionals are the decision-making machinery inside nearly all software.

Keep reading to complete this lesson