← Back to the Introduction to Computer Science outline The Course Maker
← Introduction to Computer Science outline
Week 2 · Chapter

Chapter 2 — Variables, Data Types & Expressions

Introduction to Computer Science Free sample edition

The module's primary reading · ~35–45 minutes · Objective 2 (use variables and the core types int, float, str, and bool; evaluate expressions with correct operator precedence, including true division, floor division, and remainder; convert between types; and read input and build output with indexing, slicing, and f-strings) · Read it first this week; the lecture, the slides, the tutorial, the quiz, and the Coding Lab all build on it.


In plain language

A program needs a way to remember a value and use it again. This week you give values names, called variables (names that hold values), and you learn that every value has a data type (the kind of value it is, such as a whole number or a piece of text). You will write expressions (combinations of values and operators that Python works out to one value) and learn the order Python uses to work them out. You will also see why dividing can give three different answers, and how to turn text into a number on purpose. As always, you predict what each line prints and then run it to check.

Why you already care about this

Your phone's step counter shows 4200 steps at lunch. You walk 800 more steps on the way to class, and the number becomes 5000. The label on the screen, "Steps," never changed; only the number under it did. A program keeps values the same way: a label, and a value that can be replaced.

Now picture a bike-share station near the library with 47 bikes and racks that hold 10 bikes each. Someone asks how many racks are full. "4.7 racks" is a true division, but nobody parks seven-tenths of a bike. The useful answers are 4 full racks and 7 bikes left over. Python can give you any of those three answers, and you have to know which operator asks for which.

This chapter teaches you to name values, sort them by type, and work out expressions the way Python does. The reading log from Week 1 grows its first real arithmetic this week, and you will use it in every section.

By the end of this chapter you will be able to:

  • store a value in a variable and predict what a reassignment changes and what it leaves alone;
  • name the four core types and check any value's type with type();
  • work out an expression with the right operator precedence, including ** and parentheses;
  • choose between true division, floor division, and the remainder for a real question;
  • convert a value from one type to another and explain why "5" + 3 stops a program;
  • predict what round() does with a half, and check a chatbot's claim about a value by running it.

Carry this line with you: a label stays put; the value under it changes.

Where we are

  • Already covered: Week 1 showed you that the computer does exactly what you wrote, how to run a print line, how operator precedence puts multiplication before addition, and how to read an error message from its last line.
  • This week: variables and assignment, the four core types, expressions with **, three kinds of division, and converting between types.
  • How they connect: every expression you traced last week now gets a name to live in, and the 5.0 that 10 / 2 printed finally gets its explanation.
  • Where we're going next: Week 3, Input, Output & Strings, asks the person at the keyboard for a value with input(), which always hands back a string, so this week's conversions become a daily tool.

Week 1 gave you two habits you need now. The first is predict, then run: say what a line prints before you run it. The second is reading the last line of an error message, which names the error type. You will meet one new type this week, TypeError. Week 1 also showed 10 / 2 printing 5.0 as a surprise; Section 4 explains it.

1. Name a value: variables and assignment

A sticky note on a jar of coins might say "Laundry." The note is a label. The coins inside can change every week, but the note stays the same, so you always know which jar to reach for. A program needs labels like that too.

A variable is a name that holds a value so a program can use that value later, such as pages_left holding 255.

You make a variable with assignment, the statement that puts the value on the right of = into the name on the left; you read = as "gets", so goal = 300 means goal gets 300.

That reading matters. In algebra, = says two sides are equal. In Python, = is an instruction: work out the right side, then store the result under the name on the left.

Worked example — the reading log learns to subtract. Last week the reading log printed one line. This week it remembers three numbers. The goal is 300 pages, and you have read 45 pages so far.

goal = 300
pages_read = 45
pages_left = goal - pages_read
print(pages_left)

Output

255

Trace it one line at a time. Line 1: goal gets 300. Line 2: pages_read gets 45. Line 3: Python looks up both names, works out 300 − 45 = 255, and pages_left gets 255. Line 4 prints the value stored in pages_left. In words: 255 pages remain before the reading goal.

Notice the order. Line 3 could not run before lines 1 and 2, because the names it uses would not exist yet. Python runs top to bottom, as Week 1 showed.

Reassignment is assigning a new value to a name that already holds one, which replaces the old value and leaves every other name exactly as it was. Here is the step counter from the opening.

steps = 4200
print(steps)
steps = steps + 800
print(steps)

Output

4200
5000

Line 3 reads oddly at first: steps = steps + 800. Read it as "steps gets steps plus 800." Python works out the right side first, 4200 + 800 = 5000, and then stores 5000 under steps. The old 4200 is gone.

Worked example — what reassignment leaves alone. Predict the last line before you read the output.

x = 5
y = x
x = 10
print(y)

Output

5

Line 2 gave y the value that x held at that moment, 5. Line 3 gave x a new value, 10. Nothing told y to change, so y still holds 5. In words: a reassignment changes one name and only that name.

Misconception check. Students often think y = x ties the two names together forever, so changing x later changes y. That is tempting because the line looks like an equation. But = is a one-time instruction: give the name on the left the value the right side has at this moment. The cure is to trace each name in its own column, line by line, and update only the name on the left of each =.

Names follow Week 1's rule about capital letters. Python is case-sensitive, so Steps and steps are two different names. If a program sets steps = 7 and then runs print(Steps), nothing prints, and the last line of the error message names NameError.

In practice (your tools). Open Python Tutor at pythontutor.com and paste in this six-line program, which swaps two values with a spare name called temp: a = 1, b = 2, temp = a, a = b, b = temp, each on its own line, then print(a, b) on a sixth line. Click the button to visualize it and step forward one line at a time. Watch each name's box in the frames panel. The output is 2 1. The spare name is needed because the moment a gets 2, its old value would be lost if you had not saved it in temp first.

Pause and choose one of these to think about before you read on:

  • (a) Think of a label in your life that stays the same while the thing under it changes, such as a playlist name or a bank balance. What would "reassignment" mean there?
  • (b) Think of a time two people each wrote down the same phone number and one of them later wrote a new number over theirs. Why did the other note stay the same?

Memory hook: a label stays put; the value under it changes.

2. Sort values by type: int, float, str, and bool

A cashier treats a price, a coupon code, and a yes-or-no question differently. You can add two prices. You cannot add a coupon code to a price, and asking "is this a member?" has only two answers. Python sorts every value the same way.

A data type is the kind of value a piece of data is, such as a whole number or a piece of text, which decides what operations Python allows on it.

This week you meet four core types:

  • int — Python's type for whole numbers with no decimal point, such as 255 or -4, which can grow as large as the computer's memory allows.
  • float — Python's type for numbers with a decimal point, such as 8.5 or 5.0, which are stored in binary and can be very slightly off for some decimals.
  • str — Python's type for text: a string such as "255" is a str even when every character in it is a digit.
  • bool — Python's type for the two truth values, True and False.

You can always ask Python which type a value is. type() is the built-in function that reports what type a value is, printing a result such as <class 'int'>.

Worked example — four values, four types. Predict each type, then check.

print(type(255))
print(type(8.5))
print(type("255"))
print(type(True))

Output

<class 'int'>
<class 'float'>
<class 'str'>
<class 'bool'>

Look closely at lines 1 and 3. Both show the digits 2, 5, 5. The quotation marks make the second one text, so its type is str. A str holds characters; it does not know that they look like a number.

Variables carry the type of the value they hold. In the reading log, type(pages_left) reports <class 'int'>, because 255 is a whole number. You will see in Section 4 that pages_left / 30 reports <class 'float'>.

Misconception check. Students often think "255" and 255 are the same thing because they look the same on screen. They are not. One is text and one is a number, and Python will treat them differently in every operation. When a value surprises you, ask type() before you guess.

The bool type is here so you can name it. True and False are its only two values, written with a capital first letter. Week 4 puts them to work in decisions.

In practice (your tools). In your browser runner, type print(type( followed by any value you are unsure about, then two closing parentheses, and press Run. The answer appears in the output panel. The official documentation at docs.python.org lists every built-in type under the Standard Library reference.

Memory hook: ask type() before you guess.

3. Work out an expression: operator precedence and powers

A recipe that says "double the sugar, then add a spoonful" gives a different result from "add a spoonful, then double it." Order changes the answer. Python has a fixed order for its operators, so it never has to guess.

An expression is a combination of values, names, and operators that Python works out to a single value, such as goal - pages_read.

Week 1 showed that * goes before +. This week adds a new operator at the top. The exponent operator is the ** operator, which raises the number on its left to the power of the number on its right and is worked out before any other arithmetic operator.

The full order, called operator precedence, has three levels for arithmetic:

  1. ** first;
  2. then *, /, //, and %, worked out left to right;
  3. then + and -, worked out left to right.

Parentheses override all of it: whatever is inside them goes first.

Worked example — a power inside a product. Predict both lines.

print(2 * 3 ** 2)
print((2 * 3) ** 2)

Output

18
36

Line 1: ** goes first, so 3 × 3 = 9, then 2 × 9 = 18. Line 2: the parentheses go first, so 2 × 3 = 6, then 6 × 6 = 36. Same numbers, and the grouping doubles the result: 36 versus 18.

Worked example — a temperature converter. A weather app turns 25 degrees Celsius into Fahrenheit with "multiply by 9, divide by 5, add 32."

celsius = 25
fahrenheit = celsius * 9 / 5 + 32
print(fahrenheit)

Output

77.0

The * and / share a level, so Python takes them left to right: 25 × 9 = 225, then 225 ⁄ 5 = 45.0. Then the + level: 45.0 + 32 = 77.0. The result is a float because / was used, which Section 4 explains. In words: 25 degrees Celsius is 77 degrees Fahrenheit, and the order Python used matches the recipe.

Powers also show off a quiet strength of Python. print(2 ** 10) prints 1024. Python integers never overflow, so print(2 ** 100) prints an exact 31-digit whole number with no rounding at all.

Misconception check. Students often read an expression left to right like a sentence, so they predict 2 * 3 ** 2 is 36. That is tempting, because 2 × 3 comes first on the page. But ** outranks *, so the power happens first and the result is 18. When you are unsure, add parentheses that say what you mean and run both versions.

In practice (your tools). Type both lines of the power example into your browser runner and run them. Then add a third line of your own with three operators, write your prediction on paper, and run it. If the run disagrees with you, paste the line into Python Tutor and step through it.

Memory hook: powers first, then times and divides, then plus and minus; parentheses beat them all.

4. Divide three ways: true division, floor division, and remainder

Back to the bike-share station: 47 bikes, racks of 10. "How many racks?" has three honest answers depending on what you need. Python has a separate operator for each one.

True division is division with /, which always gives a float, even when the two numbers divide evenly.

Floor division is division with //, which gives the quotient rounded down to the next whole number toward negative infinity.

The remainder operator is the % operator, which gives what is left over after floor division, carrying the sign of the number you divide by.

Worked example — the reading log divides 255 pages. You read 30 pages a day. How long until the goal?

goal = 300
pages_read = 45
pages_left = goal - pages_read
print(pages_left)
print(pages_left / 30)
print(pages_left // 30)
print(pages_left % 30)

Output

255
8.5
8
15

Line by line:

  1. pages_left / 30 is true division: 255 ⁄ 30 = 8.5. It answers "how many days, exactly?" Eight and a half.
  2. pages_left // 30 is floor division: 8. It answers "how many full 30-page days?"
  3. pages_left % 30 is the remainder: 15. It answers "how many pages are left after those full days?"

Check the three answers against each other: 8 × 30 = 240, and 240 + 15 = 255. The floor and the remainder together rebuild the total. In words: you need 8 full days and then 15 more pages, which is why the exact count is 8.5 days.

The same split works for the bikes. With bikes = 47, bikes // 10 prints 4 and bikes % 10 prints 7: 4 full racks and 7 bikes over. And the short pinned pair print(7 // 2, 7 % 2) prints 3 1, because 2 fits into 7 three times with 1 left.

Now the Week 1 surprise. 10 / 2 printed 5.0, not 5, because / always gives a float, even when the division comes out even. The decimal point is Python telling you the type.

Negative numbers, once. Floor division rounds toward negative infinity, not toward zero. So -7 // 2 prints -4: the exact quotient is −3.5, and the next whole number below it is −4. The remainder takes the sign of the number you divide by, so -7 % 3 prints 2. Both rules are stated in the Python Language Reference, section 6.7, on binary arithmetic operations. Caveat: you will rarely need negative floor division in this course, so treat this as something to recognize, not something to memorize.

Misconception check. Students often think // rounds to the nearest whole number, so they expect pages_left // 30 to be 9, since 8.5 rounds up. It does not round; it floors. Floor division always moves down, so 8.5 becomes 8. If you want the exact answer, use /; if you want full groups, use //; if you want the leftover, use %.

In practice (your tools). Type the reading-log program into your browser runner and run it. Then change the daily pace from 30 to 40 in all three division lines, predict all four outputs on paper, and run again. Check your floor and remainder by multiplying back, the way the worked example did.

Memory hook: / for exact, // for full groups, % for leftovers.

5. Convert between types on purpose

A shop's card reader sees the characters "12" on a printed tag. A person sees twelve dollars. The reader has to be told to treat those characters as a number before it can add tax. Python works the same way, and it never makes that choice for you.

Type conversion is turning a value of one type into another with a built-in function such as int(), float(), or str().

When you skip the conversion, Python stops. A TypeError is the error type Python reports when an operation is applied to a value of the wrong type, such as adding a string to a number.

Worked example — a string meets a number. Predict before you run.

print("5" + 3)

Output

TypeError

Nothing printed. Python saw a string on one side of + and a whole number on the other. Should it add or join? Rather than guess, it raised a TypeError, and the last line of the error message names that type. This is a runtime error: the program started, and this line stopped it.

Now convert first, two different ways.

print(int("5") + 3)
print("5" + str(3))

Output

8
53

Line 1: int("5") turns the text "5" into the whole number 5, then 5 + 3 = 8. Line 2: str(3) turns the number 3 into the text "3", and + joins the two strings into 53. In words: you choose the type, and the type chooses what + does.

Truncation is cutting off the decimal part of a number without rounding it, the way int(3.9) gives 3. So print(int(3.9)) prints 3, not 4. And float(255) prints 255.0, the same amount written as a float.

One more pinned surprise: "3" * 4 prints 3333. With a string and a whole number, * repeats the string; it does not multiply.

Misconception check. Students often think "5" + 3 is 8, because a person reading it would add. That is tempting, but Python does exactly what you wrote, not what you meant: one side is text, so it refuses. The cure is to convert on purpose, with int() when you want arithmetic and str() when you want to join text.

In practice (your tools). In your browser runner, run print("5" + 3) and scroll to the last line of the error panel; it begins with TypeError. Then fix it with int() so it prints 8, and fix it again with str() so it prints 53. Next week, input() will hand you text every time, so this fix becomes a habit.

Memory hook: Python never guesses a type; you convert on purpose.

6. Check the two float surprises with a run

A bus-arrival sign that shows 2.5 buses would look broken, and some numbers in Python look broken at first too. Two float behaviors catch nearly every new programmer, and both are worth predicting before you run them.

The first is rounding. Round-half-to-even is the rule round() follows for a number exactly halfway between two whole numbers: it picks the even neighbour, so round(2.5) is 2 and round(3.5) is 4.

Worked example — rounding a half. Predict both numbers before you read the output.

print(round(2.5), round(3.5))

Output

2 4

Both inputs end in .5, so each sits exactly halfway between two whole numbers. For 2.5 the neighbours are 2 and 3, and 2 is even. For 3.5 the neighbours are 3 and 4, and 4 is even. In words: a half goes to the even side, whichever direction that is.

The second surprise is that some decimals cannot be stored exactly. A float is kept in binary, and 0.1 has no exact binary form, much as one third has no exact decimal form.

print(0.1 + 0.2 == 0.3)

Output

False

Here == asks whether two values are equal, and Week 4 teaches it fully. The sum 0.1 + 0.2 lands a tiny distance from 0.3, so the comparison prints False. Limitation: this course never asks you to memorize the exact digits a float prints; it asks you to know that tiny errors happen and to avoid testing floats for exact equality.

Worked example — checking a chatbot's claim. Suppose you ask a chatbot what print(round(2.5)) displays, and it answers 3, explaining that halves always round up. That sounds right from school arithmetic. Run it.

print(round(2.5))

Output

2

The run printed 2. The chatbot described a rounding rule that Python does not use, so its explanation contradicts what the code prints. You caught it the only reliable way: by running the code.

Misconception check. Students often think round() always sends a half up, because that is the rule many people learned first. Python sends a half to the even neighbour instead. Do not argue with the rule from memory; run round() on a half and read the output.

In practice (your tools). Ask your approved chatbot to predict round(3.5) and round(4.5). Write its answers down, then run both in your browser runner. To see the rule in writing, open docs.python.org, go to the Standard Library reference, and find round() on the built-in functions page.

Honesty note: floats are a deep topic, and this chapter covers only the two behaviors you will meet in this course. The readings page offers a floating-point explainer and a short video for more.

Memory hook: the chatbot proposes; the run decides.

Key terms

  • variable — A name that holds a value so a program can use that value later, such as pages_left holding 255. (first used: 1. Name a value: variables and assignment)
  • assignment — The statement that puts the value on the right of = into the name on the left; you read = as "gets", so goal = 300 means goal gets 300. (first used: 1. Name a value: variables and assignment)
  • reassignment — Assigning a new value to a name that already holds one, which replaces the old value and leaves every other name exactly as it was. (first used: 1. Name a value: variables and assignment)
  • data type — The kind of value a piece of data is, such as a whole number or a piece of text, which decides what operations Python allows on it. (first used: 2. Sort values by type: int, float, str, and bool)
  • int — Python's type for whole numbers with no decimal point, such as 255 or -4, which can grow as large as the computer's memory allows. (first used: 2. Sort values by type: int, float, str, and bool)
  • float — Python's type for numbers with a decimal point, such as 8.5 or 5.0, which are stored in binary and can be very slightly off for some decimals. (first used: 2. Sort values by type: int, float, str, and bool)
  • str — Python's type for text: a string such as "255" is a str even when every character in it is a digit. (first used: 2. Sort values by type: int, float, str, and bool)
  • bool — Python's type for the two truth values, True and False. (first used: 2. Sort values by type: int, float, str, and bool)
  • type() — The built-in function that reports what type a value is, printing a result such as <class 'int'>. (first used: 2. Sort values by type: int, float, str, and bool)
  • expression — A combination of values, names, and operators that Python works out to a single value, such as goal - pages_read. (first used: 3. Work out an expression: operator precedence and powers)
  • exponent operator — The ** operator, which raises the number on its left to the power of the number on its right and is worked out before any other arithmetic operator. (first used: 3. Work out an expression: operator precedence and powers)
  • true division — Division with /, which always gives a float, even when the two numbers divide evenly. (first used: 4. Divide three ways: true division, floor division, and remainder)
  • floor division — Division with //, which gives the quotient rounded down to the next whole number toward negative infinity. (first used: 4. Divide three ways: true division, floor division, and remainder)
  • remainder operator — The % operator, which gives what is left over after floor division, carrying the sign of the number you divide by. (first used: 4. Divide three ways: true division, floor division, and remainder)
  • type conversion — Turning a value of one type into another with a built-in function such as int(), float(), or str(). (first used: 5. Convert between types on purpose)
  • TypeError — The error type Python reports when an operation is applied to a value of the wrong type, such as adding a string to a number. (first used: 5. Convert between types on purpose)
  • truncation — Cutting off the decimal part of a number without rounding it, the way int(3.9) gives 3. (first used: 5. Convert between types on purpose)
  • round-half-to-even — The rule round() follows for a number exactly halfway between two whole numbers: it picks the even neighbour, so round(2.5) is 2 and round(3.5) is 4. (first used: 6. Check the two float surprises with a run)

Summary

  • A variable is a name for a value; = means "gets," and a reassignment changes only the name on its left.
  • Every value has a type: int, float, str, or bool, and type() tells you which.
  • Python works out ** first, then times and divides, then plus and minus; parentheses go first of all.
  • / gives the exact answer as a float, // gives full groups, and % gives the leftover.
  • Python never mixes text and numbers on its own: convert with int(), float(), or str().
  • int() cuts off decimals, round() sends a half to the even side, and 0.1 + 0.2 == 0.3 is False.

Check your understanding

Work these before looking at the answers — they are ungraded, and the answers (with reasoning) are at the bottom of the page.

  1. A campus print shop packs 17 posters into tubes of 5 (an illustrative example). Predict what print(17 // 5, 17 % 5) displays, and say what each number means for the posters.
  2. Predict what print(4 + 6 / 2) displays, including whether the result is an int or a float.
  3. A café app stores a price as price = "12" and then runs print(price + 3). What happens, and how would you change the second line so it prints 15?
  4. Trace this program and predict its output: a = 8, then b = a, then a = a + 2, then print(a, b).

Answers (worked reasoning — read after attempting)

  1. It prints 3 2. Floor division: 5 fits into 17 three full times, so 17 // 5 is 3, meaning 3 full tubes. Remainder: 3 × 5 = 15, and 17 − 15 = 2, so 17 % 5 is 2 posters left over. Check: 15 + 2 = 17.
  2. It prints 7.0. The / goes before the +, so 6 ⁄ 2 = 3.0 first, then 4 + 3.0 = 7.0. The result is a float because / always gives a float, even though 6 divides evenly by 2.
  3. The second line raises a TypeError, because price holds the string "12" and Python will not add a string to a number. Nothing prints. Change the line to print(int(price) + 3): int(price) turns "12" into the whole number 12, and 12 + 3 = 15.
  4. It prints 10 8. Line 1: a gets 8. Line 2: b gets the value a holds right now, 8. Line 3: a gets 8 + 2 = 10, and b is untouched. So a is 10 and b is still 8.

Next up in this module: the Readings & Resources page, the lecture tutorial, the practice set, and the quiz — and next week, input() hands you a string every time, so the conversion rule becomes a daily habit.

Built with The Course Maker · samples.thecoursemaker.com