CSSE1001 — Week 1 Notes

Python as a Calculator

See csse1001 for course logistics — this note covers Lecture 1B’s technical content.

Today’s outline

  • The Python REPL
  • Syntax vs. semantics
  • Arithmetic expressions, order of operations, and associativity
  • Variables
  • Worked exam questions

Learning objectives

  1. Python expressions have syntax and semantics.
  2. Python can evaluate arithmetic expressions, but this requires an order of operations and rules for associativity.

The Python REPL

A REPL (read-evaluate-print loop) is an interactive environment: it reads input, evaluates it, prints the result, then loops.

>>> 2*3
6
>>>

The >>> prompt is only shown in the interactive REPL — it isn’t included when writing Python instructions into files.

Syntax vs. semantics

A programming language like Python has both:

  • Syntax — defines what it means to be a valid program.
  • Semantics — defines what a valid program actually does.

2 + 3 is syntactically correct Python and evaluates to 5. Prefix notation like + 2 3 (valid in Lisp) is not valid Python syntax:

>>> + 2 3
    + 2 3
      ^
SyntaxError: invalid syntax

Python’s language rules must be followed precisely for a program to run.

Arithmetic expressions

See python-operator-precedence-and-associativity for the full syntax/semantics rules for brackets, negation/affirmation, and the arithmetic operators (+ - * / // % **), the order-of-operations table, associativity (including why ** is right-associative), integer division, and the ^ xor gotcha.

Worked exam questions

Q: What does 2 ** 3 % 5 - 1 evaluate to? ((2 ** 3) % 5) - 1 = (8 % 5) - 1 = 3 - 1 = 2

Q: What value gets assigned to x in x = 35 * 2 % 5 ** 2? (35 * 2) % (5 ** 2) = 70 % 25 = 20 — 60% of the class answered correctly.

Variables

Values can be named — these names are called variables. Assigning a value to a variable doesn’t print anything in the REPL:

>>> width = 2
>>> height = 3
>>> area = width * height
>>> 4 * area
24

min and max

>>> max(1, 2)
2
>>> min(1, 2)
1
>>> max(5, 1, -2, 3, 2*7)
14

Exercise: second largest of three numbers

Given three distinct numbers a, b, c, write an expression for the second largest:

>>> a, b, c = -9, 19, 3
>>> a + b + c - max(a, b, c) - min(a, b, c)
3
>>> min( max(a, b), max(a, c), max(b, c) )
3
>>> max( min(a, b), min(a, c), min(b, c) )
3

Next lecture

  1. 2025-08-04-python-memory-model — Python memory model.
  2. 2025-08-04-primitive-data — Primitive data types.

Reference material

Python Operator Precedence and Associativity

Syntax vs. semantics

Each rule below has two parts:

  • Syntax — what makes the expression a valid Python program.
  • Semantics — what the expression evaluates to.

Constants and brackets

  • A constant (e.g. 2) is the most basic expression.
  • If x is a valid expression then (x) is also a valid expression — bracketed expressions get evaluated first. Whitespace inside brackets is ignored, and brackets can nest arbitrarily (((2))).
  • An unmatched closing bracket (2)) is a SyntaxError.

Negation and affirmation

  • If x is a valid expression then +x and -x are valid expressions.
  • +x is equivalent to multiplying x by 1; -x is equivalent to multiplying x by -1.
  • These can be chained (--3 is 3, +-+-+-3 is -3), but a trailing operator with nothing after it (3+) is a SyntaxError.

Arithmetic operators

If x and y are valid expressions, then all of the following are valid expressions, evaluated according to the rules of math:

Operator Meaning
x + y Addition
x - y Subtraction
x * y Multiplication
x / y Division
x // y Integer (floor) division
x % y Remainder
x ** y Exponentiation

Order of operations

From highest to lowest precedence:

Operator Description
() Parenthesis
** Exponents
-x, +x Negation, Affirmation
*, /, //, % Multiplication, Division, Integer Division, Remainder
+, - Addition, Subtraction

*, /, //, and % share a precedence level, as do + and - — see Associativity below for how ties between operators of equal precedence get resolved.

Associativity

An order of operations alone doesn’t remove all ambiguity — e.g. 1 - 2 + 3 needs a rule for whether it means (1 - 2) + 3 or 1 - (2 + 3). Python evaluates 1 - 2 + 3 as (1 - 2) + 3 = 2, so +/- are left-associative.

Operators of equal precedence are left-associative in general, except exponentiation (**), which is right-associative:

  • 3 * 1 // 2 = (3 * 1) // 2 = 1 (left-associative *///)
  • 2 ** 1 ** 0 = 2 ** (1 ** 0) = 2 (right-associative **, not (2 ** 1) ** 0 = 1)

In general, if # and @ are operators of equal precedence, a # b @ c = (a # b) @ c (left-associative case).

Division and floats

  • / always returns a float, even when the division is exact (4 / 2 is 2.0, not 2) — type(2) is int, type(2.0) is float.
  • 1 / 3 gives an approximate result (0.3333333333333333) since floats have finite precision.
  • 1 / 0 raises ZeroDivisionError; 1 / float('inf') is 0.0.

Exponentiation edge cases

  • 2 ** 3 is 8 (int); 2 ** 3.0 is 8.0 (float) — a float exponent/base produces a float result.
  • 2 ** -1 is 0.5.
  • 2 ** 0 and 0 ** 0 are both 1.

Warning: ^ is not exponentiation

The caret ^ is Python’s bit-wise xor operator, not exponentiation — e.g. 2 ^ 3 is 1 and 4 ^ 1 is 5. Using ^ where you meant ** does not raise an error, so this mistake can silently produce wrong results.

Integer division (the division algorithm)

For positive integers x and y, there is a unique quotient q and remainder r (with 0 <= r < y) satisfying x = q * y + r — “grade school” division. E.g. for x = 17, y = 3: 17 = 5 * 3 + 2, so 17 // 3 is 5 (the quotient) and 17 % 3 is 2 (the remainder), and 3 * (17 // 3) + (17 % 3) == 17.

The division algorithm can be computed directly (repeated subtraction) or recursively:

def remainder(x: int, y: int) -> int:
    ans = x
    while ans >= y:
        ans = ans - y
    return ans
def remainder(x: int, y: int) -> int:
    return x if x < y else remainder(x - y, y)

Both give remainder(17, 7) == 3.