Unit 1: Introduction; Variables, Expressions and Statements

ECE181 — Introduction To Python 6 min read

I. Foundations: Why Programming and Why Python

A programming language is a formal notation for instructing a computer to perform tasks; this unit establishes the vocabulary (identifiers, variables, operators) that every later Python construct reuses. Python was created by Guido van Rossum and first released in 1991, designed around readability and simplicity.

  • Defining properties carried forward:
    • High-level: Python abstracts away memory addresses and CPU registers, so programmers write x = 5 rather than machine code.
    • Interpreted: source runs line-by-line via the interpreter (CPython), giving immediate feedback in an interactive shell.
    • Dynamically typed: a variable's type is determined at runtime by the value bound to it, not by a prior declaration.
    • Case-sensitive: Total and total are distinct names — a convention every subsequent section assumes.

A. Need for a Programming Language

A programming language bridges human intent and machine execution because hardware understands only binary.

  • Machine vs. human gap: the CPU executes binary opcodes (e.g., 10110000); humans reason in symbols and English, so a translator is required.
  • Abstraction: high-level statements like print("Hello") compile or interpret down to many machine instructions, hiding complexity.
  • Portability: the same Python script runs on Windows, Linux, or macOS through their respective interpreters, unlike raw machine code tied to one processor.
  • Productivity: reusable constructs (loops, functions, libraries) let one line replace dozens of repetitive operations.

B. Introduction to Python as a Programming Language

Python is a general-purpose, high-level language prized for concise, English-like syntax.

  • Indentation as syntax: blocks are defined by whitespace, not braces, enforcing readable structure.
  • Interactive mode: typing >>> 2 + 3 in the shell instantly returns 5, aiding experimentation.
  • Batteries included: an extensive standard library (math, random, os) ships with the interpreter.
  • Multi-paradigm: supports procedural, object-oriented, and functional styles.

C. Programming Errors and Debugging

Errors are defects that prevent correct execution; debugging is the systematic process of locating and removing them.

  1. Syntax errors: violations of grammar caught before execution; e.g., print("hi" raises SyntaxError for the missing parenthesis.
  2. Runtime and logical errors: runtime errors (exceptions) surface during execution, such as ZeroDivisionError from 10/0; logical errors run without crashing but give wrong output, e.g., using + where * was intended.
    • Debugging techniques: tracing values with print(), reading the traceback bottom-up to find the failing line, and using a debugger to step through statements.

II. Identifiers, Variables and Assignment

A. Identifiers

An identifier is the programmer-chosen name for a variable, function, or other entity.

  • Formation rules: must begin with a letter or underscore, followed by letters, digits, or underscores — _count, value2 valid; 2value invalid.
  • No keywords: reserved words like if, class, True cannot be reused as names.
  • Case-sensitive: age and Age refer to different objects.
  • Convention: lowercase with underscores (student_name) by PEP 8 style.

B. Variables

A variable is a name bound to a value stored in memory; in Python it is a reference to an object.

  • No declaration needed: x = 10 both creates and initialises x.
  • Dynamic rebinding: x = 10 then x = "ten" is legal; the name simply points to a new object.
  • Type inspection: type(x) returns the current type, e.g., <class 'int'>.

C. Assignment Statements

An assignment statement binds the value on the right of = to the name on the left.

PYTHON
count = 0        # binds 0 to count
count = count + 1  # evaluates RHS (1), rebinds count
  • Right-to-left evaluation: the expression on the right is fully evaluated first, then stored.
  • Not equality: = is assignment; == tests equality.
  • Chained assignment: a = b = 5 binds both names to the same object.

D. Named Constant

A named constant is a variable intended never to change, signalling a fixed value.

  • Convention, not enforcement: Python has no true constants; uppercase names mark intent, e.g., PI = 3.14159.
  • Purpose: improves readability and centralises values — changing MAX_USERS = 100 in one place updates all uses.

E. Simultaneous Assignment

Simultaneous (tuple) assignment binds several names in a single statement, evaluating all right-hand values first.

PYTHON
a, b = 5, 10      # a=5, b=10
a, b = b, a       # swaps: a=10, b=5
  • Swap without temp: the right side (b, a) is built as a tuple before unpacking, so no temporary variable is needed.
  • Count must match: x, y = 1, 2, 3 raises ValueError.

III. Expressions and Data Types

A. Expressions

An expression is any combination of values, variables, and operators that evaluates to a single value.

  • Operands and operators: 3 * (a + 2) combines literals, a variable, and operators into one result.
  • Evaluation: the interpreter reduces the expression to one object, which can be assigned or printed.
  • Sub-expressions: parentheses group parts, e.g., (a + b) / 2.

B. Boolean Types

The Boolean type bool has exactly two values used for logical decisions.

  • Values: True and False, capitalised.
  • From comparisons: relational operators produce Booleans, e.g., 5 > 3 yields True.
  • Integer subclass: True == 1 and False == 0, so True + True gives 2.
  • Truthiness: empty values (0, "", [], None) are treated as False in conditions.

C. Numeric Data Types

Python provides three built-in numeric types for arithmetic values.

  • int: whole numbers of unlimited size, e.g., 42, -7.
  • float: double-precision real numbers with a decimal point or exponent, e.g., 3.14, 2e3 (=2000.0).
  • complex: numbers with real and imaginary parts, e.g., 3 + 4j, where j denotes √−1.
  • Literals: 0b101 (binary), 0o17 (octal), 0xF (hex) all yield int.

IV. Operators

A. Operators

An operator is a symbol performing a computation on operands.

  • Arithmetic: + - * / plus // (floor division), % (modulus), ** (exponent); 7 // 2 is 3, 7 % 2 is 1, 2 ** 3 is 8.
  • Relational: == != < > <= >= return Booleans.
  • Logical: and, or, not combine Boolean expressions.
  • Assignment: = and its augmented forms (below).
  • Bitwise: & | ^ ~ << >> operate on integer bit patterns.

B. Operator Precedence and Associativity

Precedence decides which operator applies first; associativity decides order among equal-precedence operators.

  • Precedence order (high to low): **, then unary -, then * / // %, then + -, then comparisons, then not, and, or.
  • Left-to-right associativity: most binary operators, so 10 - 4 - 2 is (10-4)-2 = 4.
  • Right-to-left exception: ** associates right, so 2 ** 3 ** 2 is 2 ** 9 = 512.
  • Parentheses override all: (2 + 3) * 4 forces the addition first, giving 20.

Worked example:

PYTHON
result = 2 + 3 * 4 ** 2   # ** first: 16; * : 48; + : 50
# result == 50

C. Augmented Assignment Operators

An augmented assignment combines an operation with assignment in shorthand.

  • Forms: += -= *= /= //= %= **=; x += 3 means x = x + 3.
  • Applies across types: s += "!" appends to a string; n *= 2 doubles a number.
  • Efficiency and clarity: avoids repeating the variable name, e.g., total += price.

V. Type Conversion and Rounding

An explicit conversion (casting) changes a value's type, while rounding controls precision of numeric results.

A. Type Conversion and Rounding

  • Explicit conversion: built-in functions recast values.
    • int("25") → 25; int(3.9) → 3 (truncates toward zero).
    • float(7) → 7.0; str(10) → "10".
  • Implicit conversion (coercion): Python promotes narrower to wider types automatically, so 2 + 3.0 yields 5.0 (int promoted to float).
  • Invalid casts raise errors: int("abc") raises ValueError.
  • Rounding: the round() function returns a value rounded to given digits.
    • round(3.14159, 2) → 3.14; round(2.5) → 2 and round(3.5) → 4 (banker's rounding, ties go to the nearest even).
    • Distinguish from //, which floors, and int(), which truncates: int(-2.7) is -2 but round(-2.7) is -3.