Quiz: Variables, Types, and Expressions

Test your understanding before moving on. Target: 70% or higher to proceed confidently.


Section 1: Multiple Choice (1 point each)

1. Which of the following BEST describes a variable in Python?

  • A) A box that holds a value
  • B) A name tag attached to an object in memory
  • C) A permanent label that cannot change
  • D) A reserved location in RAM with a fixed size
Answer **B)** A name tag attached to an object in memory. *Why B:* Python variables are references (name tags) to objects. Multiple names can point to the same object, and names can be reassigned to different objects. *Why not A:* The "box" model is misleading — it implies the variable contains the value, rather than pointing to it. *Why not C:* Variables can be reassigned (rebound) to different objects at any time. *Why not D:* Python manages memory dynamically; variables don't have fixed sizes or reserved locations. *Reference:* Section 3.1.2

2. What is the output of the following code?

x = 10
y = x
x = 20
print(y)
  • A) 20
  • B) 10
  • C) 30
  • D) Error
Answer **B)** 10 *Why B:* When `y = x` executes, `y` becomes a name tag pointing to the same object as `x` (the integer 10). When `x` is reassigned to 20, the `x` name tag moves, but `y` still points to 10. *Why not A:* `y` doesn't "track" `x`. It points to the object `x` pointed to at the time of assignment. *Reference:* Section 3.1.2, Productive Struggle

3. What does type(42.0) return?

  • A) <class 'int'>
  • B) <class 'float'>
  • C) <class 'str'>
  • D) <class 'number'>
Answer **B)** `` *Why B:* The presence of a decimal point makes `42.0` a float, even though its mathematical value is a whole number. *Why not A:* `42` (without the decimal) would be an int, but `42.0` is a float. *Why not D:* Python doesn't have a generic `number` type. *Reference:* Section 3.3.2

4. What is the result of 17 // 5?

  • A) 3.4
  • B) 3
  • C) 4
  • D) 2
Answer **B)** 3 *Why B:* `//` is floor division — it divides and rounds down to the nearest integer. 17 / 5 = 3.4, rounded down = 3. *Why not A:* That's the result of true division (`/`), not floor division (`//`). *Why not C:* Floor division rounds *down*, not up. *Reference:* Section 3.4.2

5. What is the result of 17 % 5?

  • A) 3.4
  • B) 3
  • C) 2
  • D) 5
Answer **C)** 2 *Why C:* `%` is the modulo operator — it returns the remainder. 17 ÷ 5 = 3 remainder 2. *Why not B:* 3 is the quotient (floor division result), not the remainder. *Reference:* Section 3.4.1

6. Which of the following is an ILLEGAL Python variable name?

  • A) _count
  • B) my_var2
  • C) 2nd_item
  • D) CONSTANT
Answer **C)** `2nd_item` *Why C:* Variable names cannot start with a digit. *Why not A:* Names can start with an underscore. *Why not B:* Names can contain digits, just not start with them. *Why not D:* All-caps names are valid (used by convention for constants). *Reference:* Section 3.2.1

7. What does this code output?

a = "3"
b = "5"
print(a + b)
  • A) 8
  • B) "8"
  • C) 35
  • D) Error
Answer **C)** `35` *Why C:* Both `a` and `b` are strings. The `+` operator concatenates strings, so `"3" + "5"` produces `"35"`. *Why not A or B:* Python doesn't auto-convert strings to numbers. String `+` is concatenation, not addition. *Reference:* Section 3.5.1

8. What is the value of int(7.9)?

  • A) 7
  • B) 8
  • C) 7.9
  • D) Error
Answer **A)** 7 *Why A:* `int()` truncates (drops the decimal part) — it does NOT round. So `int(7.9)` is 7, not 8. *Why not B:* `round(7.9)` would give 8, but `int()` truncates. *Reference:* Section 3.7.1

9. Which f-string correctly displays the variable price = 1234.5 as $1,234.50?

  • A) f"${price}"
  • B) f"${price:.2f}"
  • C) f"${price:,.2f}"
  • D) f"${price:2f,}"
Answer **C)** `f"${price:,.2f}"` *Why C:* The `,` adds a thousands separator and `.2f` formats to 2 decimal places. *Why not A:* No formatting — would display `$1234.5`. *Why not B:* Missing the comma separator — would display `$1234.50`. *Why not D:* Invalid format specifier syntax. *Reference:* Section 3.8.2

10. What does bool("") return?

  • A) True
  • B) False
  • C) ""
  • D) Error
Answer **B)** `False` *Why B:* Empty strings are "falsy" in Python. `bool("")` returns `False`. *Why not A:* Only non-empty strings are truthy. *Reference:* Section 3.7.4

Section 2: Short Answer (2 points each)

11. What is the difference between = and == in Python? Give a one-line example of each.

Answer `=` is the **assignment** operator — it binds a name to a value. `==` is the **comparison** operator — it tests whether two values are equal and returns a boolean. Examples: - `x = 5` — assigns the value 5 to the name `x` - `x == 5` — evaluates to `True` if `x` is 5, `False` otherwise *Reference:* Sections 3.1.1 and 3.6.1

12. Explain why input() always returns a string, and write one line of code that correctly reads an integer from the user.

Answer `input()` reads text from the keyboard. Since the user could type anything (numbers, letters, symbols), Python treats all keyboard input as a string by default. It's your job to convert it to the type you need.
age = int(input("Enter your age: "))
*Reference:* Section 3.7.2

13. Write an f-string that displays the variable gpa = 3.85714 rounded to 2 decimal places.

Answer
f"GPA: {gpa:.2f}"
This displays: `GPA: 3.86` (note: `.2f` rounds, it doesn't just truncate). *Reference:* Section 3.8.2

14. What does += do? Rewrite count += 1 without using augmented assignment.

Answer `+=` adds the right-hand value to the variable and reassigns the result. It's shorthand for:
count = count + 1
*Reference:* Section 3.9

Section 3: Code Tracing (2 points each)

15. Trace through this code and write the final output:

a = 5
b = 3
c = a + b
a = a * 2
b = c - a
print(f"a={a}, b={b}, c={c}")
Answer Step by step: - `a = 5` → a is 5 - `b = 3` → b is 3 - `c = a + b` → c is 8 - `a = a * 2` → a is 10 - `b = c - a` → b is 8 - 10 = -2 Output: `a=10, b=-2, c=8` *Reference:* Sections 3.1, 3.4

16. What is the output of this code?

x = "Hello"
y = 3
print(x * y)
print(len(x * y))
Answer
HelloHelloHello
15
`x * y` repeats the string "Hello" three times, producing "HelloHelloHello" (15 characters). *Reference:* Sections 3.5.2, 3.5.3

17. What is the output? If there's an error, identify it and explain.

price = "19.99"
tax = 0.08
total = price * (1 + tax)
print(f"Total: ${total:.2f}")
Answer **Error:** `TypeError: can't multiply sequence by non-int of type 'float'` `price` is a string (`"19.99"`). You can multiply a string by an integer (for repetition), but not by a float. The fix is: `price = float("19.99")` or `price = 19.99`. *Reference:* Section 3.7 (Debugging Walkthrough)

Section 4: Conceptual Questions (3 points each)

18. After this code runs, do a and b point to the same object? How would you verify this in Python?

a = 42
b = 42
Answer Yes, they likely point to the same object due to Python's integer caching (Python caches small integers, typically -5 to 256). You can verify with:
print(id(a) == id(b))  # True
# or
print(a is b)           # True
However, this is an implementation detail (CPython optimization). The name tag model says `a` and `b` are two names that happen to point to the same integer object. You should not write code that depends on this caching behavior. *Reference:* Section 3.10

19. A student writes this code and is confused by the output:

print(0.1 + 0.2 == 0.3)

The output is False. Explain why, and suggest a better way to compare floating-point numbers.

Answer Floating-point numbers are stored in binary, and `0.1` and `0.2` cannot be represented exactly in binary. So `0.1 + 0.2` evaluates to `0.30000000000000004`, which is not exactly equal to `0.3`. A better approach is to check if the difference is very small:
abs(0.1 + 0.2 - 0.3) < 1e-9   # True
Or use Python's `math.isclose()` function (covered in later chapters):
import math
math.isclose(0.1 + 0.2, 0.3)   # True
*Reference:* Section 3.3.2 (Pitfall box)

20. Explain why learning the name tag model in Chapter 3 (even though it seems to predict the same behavior as the box model for integers and strings) is important preparation for Chapter 8 (lists). Use the list_a/list_b example from section 3.10.4 in your answer.

Answer With immutable types like `int` and `str`, the name tag model and box model predict the same behavior because you can never modify the object itself — you can only rebind the name. But with mutable types like lists, two names pointing to the same object means changes through one name are visible through the other:
list_a = [1, 2, 3]
list_b = list_a         # Both point to the SAME list
list_a.append(4)        # Modify the list in place
print(list_b)           # [1, 2, 3, 4] — "surprise" if you use the box model
The box model would predict `list_b` is still `[1, 2, 3]` (a copy in its own box). The name tag model correctly predicts that since both names point to the same object, and the object was mutated, both names see the change. *Reference:* Section 3.10.4

Scoring Guide

Section Points Available
Section 1 (MC, 10 questions) 10
Section 2 (Short Answer, 4 questions) 8
Section 3 (Code Tracing, 3 questions) 6
Section 4 (Conceptual, 3 questions) 9
Total 33

Passing score: 70% = 23/33

If you scored below 70%, review sections 3.1-3.4 and 3.7-3.8 before proceeding to Chapter 4.