Unit 1: Introduction; Variables, Expressions and Statements
1. Computational Thinking and the Python Language Philosophy
Computers are fundamentally deterministic electronic calculating machines built from billions of nanoscale transistors that manipulate binary voltages (logic 0 and 1). Because binary machine language is illegible to human cognition and prone to error, programming languages bridge human logic and electronic hardware execution.
Python, created by Dutch programmer Guido van Rossum in the late 1980s and officially released in 1991, was designed around the guiding philosophy that "readability counts." Formally codified in The Zen of Python (PEP 20), the language emphasizes clean, concise syntax, minimal boilerplate, and consistent semantic behavior:
- Beautiful is better than ugly.
- Explicit is better than implicit.
- Simple is better than complex.
- Readability counts.
CODEHUMAN PROGRAMMER TRANSLATION ENGINE CPU EXECUTION +-------------------+ +--------------------+ +--------------+ | Python Source | Compile | Python Bytecode | Interpret | Host CPU | | File: script.py | ---------->| File: script.pyc | ---------->| Architecture | | (Readable Text) | | (CPython PVM) | | (x86 / ARM) | +-------------------+ +--------------------+ +--------------+
Execution Model: The CPython Pipeline
While colloquially described as an "interpreted language," standard Python (CPython) utilizes a two-tier execution pipeline:
- Source Parsing and Compilation: When a script is executed, CPython parses the human-readable
.pytext file into an Abstract Syntax Tree (AST) and compiles it into an intermediate, platform-neutral representation known as Bytecode (.pycfiles stored in__pycache__). - Virtual Machine Interpretation: The compiled bytecode instructions are then executed sequentially by the Python Virtual Machine (PVM), an execution engine written in C that interprets opcodes (e.g.,
LOAD_CONST,BINARY_ADD,STORE_FAST) into native CPU machine instructions. - Contrast with Compiled Languages (C/C++, Rust):
- Compiled languages translate source code directly into target-specific machine binaries prior to execution. They achieve near-instant execution speed but require recompilation for every OS/CPU architecture.
- Interpreted/Bytecode languages (Python) offer cross-platform portability and interactive REPL experimentation at the cost of interpretive execution overhead.
2. Identifiers, Keywords, and the Object Reference Model
Lexical Identifiers and Naming Rules
An identifier is a user-defined token used to name program entities such as variables, functions, classes, modules, and objects.
In Python, identifier creation is strictly governed by lexical rules:
- Character Set: May consist of alphanumeric characters (uppercase letters
A-Z, lowercase lettersa-z, digits0-9) and the underscore character (_). - Initial Character: Must begin with a letter or an underscore. An identifier can never start with a numeric digit (e.g.,
2speedis illegal, whereasspeed_2is valid). - Punctuation & Special Symbols: Whitespace and punctuation characters (
$,@,%,-,!) are forbidden. - Case Sensitivity: Identifiers are strictly case-sensitive.
voltage,Voltage, andVOLTAGErepresent three completely distinct memory references. - Reserved Keywords: Cannot match any of Python's reserved language keywords (such as
for,while,def,class,if,else,import,return,None,True,False).
python# Valid Identifiers
sensor_reading = 42
_internal_clock = 1000
MotorSpeed2 = 180.5
# Invalid Identifiers
# 2fast = 10 --> SyntaxError: invalid decimal literal
# user-name = "Alex" --> SyntaxError: cannot assign to expression
# class = 5 --> SyntaxError: invalid syntax (class is a reserved keyword)
The Name-Binding (Object Reference) Memory Model
Unlike languages such as C or Java where a variable is a typed, fixed-size memory container into which values are stored, in Python, variables are names (tags) bound to heap-allocated objects.
CODETRADITIONAL C MODEL: Fixed memory box [ int x ] ===> [ Memory Address 0x1040 contains integer bits: 00000101 ] PYTHON DYNAMIC REFERENCE MODEL: Name bound to an object Name 'x' --------------------+ | v +----------------------+ | int Object | | Type: <class 'int'> | | Value: 5 | | Ref Count: 1 | | Address: id(5) | +----------------------+
- When you write
x = 5, Python creates an integer object5on the heap and binds the identifier namexto that object. - If you subsequently write
x = "Hello", Python does not force the string"Hello"into an integer memory space. Instead, it creates a newstrobject on the heap and re-binds the tagxto point to the new string object. - The built-in function
id(obj)returns the unique integer memory identity of the referenced object. - The built-in function
type(obj)returns the class type of the object.
pythona = 250
b = a
print(id(a) == id(b)) # True: both identifiers bind to the exact same object
a = 500
# 'a' is re-bound to a new integer object 500; 'b' still points to 250
print(b) # 250
3. Fundamental Primitive Data Types
Python provides four foundational primitive scalar data types:
CODEPYTHON CORE PRIMITIVE DATA TYPES | +-----------------------+-----------------------+ | | NUMERIC NON-NUMERIC | | +-----+-----+ +-----+-----+ | | | | int float bool str (Arbitrary (IEEE-754 (True or (Unicode Precision) Double) False) Text)
1. Integers (int)
- Represent positive and negative whole numbers including zero (
... -2, -1, 0, 1, 2 ...). - In Python 3, integers have arbitrary precision (limited only by available host RAM). There is no integer overflow; values can grow to thousands of digits without wrapping around like 32-bit/64-bit integer registers in C.
- Integer literals can be specified in binary (
0bor0B), octal (0oor0O), or hexadecimal (0xor0X):pythondec = 42 bin_val = 0b101010 # 42 hex_val = 0x2A # 42
2. Floating-Point Numbers (float)
- Represent real numbers containing decimal points or scientific exponential notation (
1.25,-0.0034,6.022e23). - Implemented internally using the C
doubletype conforming to the IEEE-754 standard for binary double-precision (64-bit) floating-point arithmetic:- 1 sign bit
- 11 exponent bits
- 52 fraction/significand bits (pprox 15 ext{ to }17 significant decimal digits of precision).
- The Floating-Point Representation Pitfall: Many base-10 fractional decimals cannot be represented exactly in binary floating-point representation:
In engineering calculations, always compare floats using tolerance thresholds (pythonprint(0.1 + 0.2) # 0.30000000000000004 print(0.1 + 0.2 == 0.3) # False!math.isclose(a, b, rel_tol=1e-9)) rather than direct equality==.
3. Booleans (bool)
- Subclass of
intrepresenting truth values: exactly two built-in singleton instances exist:TrueandFalse. - In numeric evaluations,
Truebehaves identically to integer1, andFalsebehaves identically to integer0:pythonprint(True + True) # 2 print(False * 100) # 0 print(isinstance(True, int)) # True
4. Strings (str)
- Immutable sequences of Unicode characters enclosed in single quotes (
'...'), double quotes ("..."), or triple quotes ('''...'''or"""..."""for multi-line text). - Once created, individual characters within a string cannot be modified in place:
python
s = "Python" # s[0] = 'J' --> TypeError: 'str' object does not support item assignment
4. Operators, Precedence, and Semantic Evaluation
An operator is a special symbol that performs specific mathematical, logical, or relational computations on one or more operands. An expression is a syntactic combination of literals, variables, and operators that evaluates to a concrete value.
CODE+------------------------+------------------------------------+---------------------------------------+ | Category | Operators | Description & Behavior | +------------------------+------------------------------------+---------------------------------------+ | Arithmetic | +, -, *, /, //, %, ** | Addition, Subtraction, Multiplication,| | | | Float Division, Floor Division, | | | | Modulus (Remainder), Exponentiation | +------------------------+------------------------------------+---------------------------------------+ | Comparison | ==, !=, <, <=, >, >= | Value Equality, Inequality, Ordering | +------------------------+------------------------------------+---------------------------------------+ | Identity | is, is not | Memory Object Identity (id(a) == id(b))| +------------------------+------------------------------------+---------------------------------------+ | Membership | in, not in | Sequence / Collection Containment | +------------------------+------------------------------------+---------------------------------------+ | Logical | and, or, not | Boolean Conjunction, Disjunction, | | | | Inversion (with Short-Circuiting) | +------------------------+------------------------------------+---------------------------------------+ | Bitwise | &, |, ^, ~, <<, >> | Bitwise AND, OR, XOR, NOT, Shifts | +------------------------+------------------------------------+---------------------------------------+ | Assignment | =, +=, -=, *=, /=, //=, %=, **= | Binding and Compound In-Place Mutation| +------------------------+------------------------------------+---------------------------------------+
Deep Dive: Division Operators (/, //, %)
- True Division (
/): Always returns afloat, even when two integers divide evenly:pythonprint(10 / 2) # 5.0 (float) print(7 / 2) # 3.5 (float) - Floor Division (
//): Divides two numbers and rounds the quotient down to the nearest mathematical integer (towards negative infinity):pythonprint(7 // 2) # 3 print(-7 // 2) # -4 (rounds toward negative infinity, NOT towards zero!) - Modulus Operator (
%): Yields the remainder of division, obeying the fundamental identity:
pythonprint(7 % 2) # 1 print(-7 % 2) # 1, because -7 - (-4 * 2) = -7 - (-8) = 1
Operator Precedence Hierarchy (Highest to Lowest)
When an expression contains multiple operators, evaluation order is dictated by the formal operator precedence table:
CODEPRECEDENCE LEVEL OPERATOR ASSOCIATIVITY ---------------- -------------------------------- ------------- 1. Highest ( ) Parentheses, [ ] Indexing Left-to-right 2. ** Exponentiation RIGHT-TO-LEFT 3. +x, -x, ~x (Unary +, -, Bitwise NOT)Right-to-left 4. *, /, //, % Left-to-right 5. +, - Left-to-right 6. <<, >> Left-to-right 7. & (Bitwise AND) Left-to-right 8. ^ (Bitwise XOR) Left-to-right 9. | (Bitwise OR) Left-to-right 10. ==, !=, <, <=, >, >=, is, in Left-to-right (Chained) 11. not Right-to-left 12. and Left-to-right 13. Lowest or Left-to-right
Exponentiation Right-to-Left Associativity Example
pythonresult = 2 ** 3 ** 2
print(result) # 512
Short-Circuit Logic Evaluation (and, or)
Python's logical operators and and or do not necessarily evaluate to True or False; instead, they return the exact operand that determined the truth value, evaluated strictly left-to-right:
A and B: IfAis falsy, Python halts evaluation immediately and returnsAwithout evaluatingB. IfAis truthy, it evaluates and returnsB.A or B: IfAis truthy, Python halts evaluation immediately and returnsAwithout evaluatingB. IfAis falsy, it evaluates and returnsB.
python# Guard pattern against ZeroDivisionError
x = 0
result = (x != 0) and (100 / x > 2)
print(result) # False (100 / x is never evaluated, avoiding ZeroDivisionError!)
name = "" or "Default User"
print(name) # 'Default User'
5. Type Casting, Truthiness, and Precision Rounding
Explicit Type Conversion
int(x): Converts valid string literals or floats to an integer. Truncates floats towards zero (int(3.9)yields3,int(-3.9)yields-3).float(x): Converts integer or valid string to 64-bit IEEE-754 float.str(x): Converts any object into its standard string representation.bool(x): Evaluates the "truthiness" of an object.
The Truthiness Concept
In Python, all objects can be tested for truth value inside conditional expressions. The following objects evaluate to Falsy:
- Constants:
None,False - Zero numeric values:
0,0.0,0j,Decimal(0),Fraction(0, 1) - Empty sequences and collections:
""(empty string),()(empty tuple),[](empty list),{}(empty dict),set()
All other objects evaluate to Truthy.
Rounding Mechanics: Banker's Rounding
The built-in round(number, ndigits) function implements round-half-to-even (Banker's Rounding) to eliminate statistical skew in cumulative sums:
- When a number is equidistant between two integers (ending in
.5), it rounds to the nearest even integer:pythonprint(round(2.5)) # 2 (rounds down to even 2) print(round(3.5)) # 4 (rounds up to even 4) print(round(4.5)) # 4 (rounds down to even 4) - Contrast with
math.floor()(always rounds down towards ) andmath.ceil()(always rounds up towards ).
6. Formatted Console Input and Output
The input() Function
The input([prompt]) built-in function halts execution, reads a line of text entered by the user from standard input (sys.stdin), and returns it strictly as a str (string):
pythonraw_age = input("Enter your age: ") # User enters: 20
# age = raw_age + 5 --> TypeError: can only concatenate str (not "int") to str
age = int(raw_age) + 5 # Correct: explicitly cast to integer
The print() Function Parameters
print(*objects, sep=' ', end=' ', file=sys.stdout, flush=False)
sep: String inserted between items (defaults to a single space' ').end: String appended at the end of the line (defaults to newline' ').
pythonprint("2026", "10", "15", sep="-") # Output: 2026-10-15
print("Processing data", end="... ")
print("Done!") # Output: Processing data... Done!
Formatted String Literals (F-Strings)
Introduced in Python 3.6 (PEP 498), f-strings evaluate embedded expressions inside curly braces at runtime:
pythonvoltage = 3.1415926
current = 0.025
resistance = voltage / current
# Syntax: {expression:format_specifier}
print(f"Measured Voltage: {voltage:.2f} V") # Measured Voltage: 3.14 V
print(f"Computed Resistance: {resistance:>10.1f} Ohms")# Computed Resistance: 125.7 Ohms
print(f"Binary Representation: {42:#010b}") # Binary Representation: 0b00101010
7. Step-by-Step Solved Problem Walkthroughs
Problem 1: Complex Expression Precedence Evaluation
Statement: Determine the step-by-step evaluation, intermediate values, and final result of the following Python expression:
pythonresult = 15 - 3 * 2 ** 3 // 4 + 14 % 5
Step-by-Step Derivation:
- Exponentiation (
**): Evaluated first with highest precedence:
Expression becomes:15 - 3 * 8 // 4 + 14 % 5 - Multiplication, Floor Division, Modulus (
*,//,%): These have equal precedence and evaluate left-to-right:- First
3 * 8 = 24
Expression:15 - 24 // 4 + 14 % 5 - Next
24 // 4 = 6
Expression:15 - 6 + 14 % 5 - Next
14 % 5 = 4(since )
Expression:15 - 6 + 4
- First
- Addition and Subtraction (
-,+): Evaluated left-to-right:15 - 6 = 99 + 4 = 13
Final Value: 13 (Integer).
Problem 2: Logical Short-Circuit and Truthiness Tracing
Statement: Given the following Python statements, determine the exact output printed to the console:
pythona = 0
b = 25
c = "Sensor Active"
d = []
res1 = a or b and c
res2 = d and b or "Fallback"
res3 = not a and (b > 10)
print(f"res1={res1!r}, res2={res2!r}, res3={res3!r}")
Step-by-Step Derivation:
- Evaluating
res1 = a or b and c:andhas higher precedence thanor.- First evaluate
b and c:bis25(truthy), sob and cevaluates toc("Sensor Active"). - Now evaluate
a or "Sensor Active":ais0(falsy), soorproceeds to and returns"Sensor Active". res1 = "Sensor Active".
- Evaluating
res2 = d and b or "Fallback":- First evaluate
d and b:dis[](empty list, falsy). Due to short-circuiting,d and bhalts and returns[]. - Now evaluate
[] or "Fallback":[]is falsy, soorreturns"Fallback". res2 = "Fallback".
- First evaluate
- Evaluating
res3 = not a and (b > 10):not a:ais0(falsy), sonot 0evaluates toTrue.b > 10:25 > 10evaluates toTrue.True and Trueevaluates toTrue.res3 = True.
Output:
res1='Sensor Active', res2='Fallback', res3=True
8. Common Traps, Pitfalls, and Best Practices
- Confusion Between Equality (
==) and Identity (is):==checks value equality (whether two objects hold equivalent contents).ischecks memory object identity (whether two identifiers point to the identical address in memory:id(a) == id(b)).
pythonx = [1, 2, 3] y = [1, 2, 3] print(x == y) # True: identical contents print(x is y) # False: two distinct list objects allocated on heap! - The Mutable Default Trap & Chained Assignment:
- Chained assignment
a = b = []binds both namesaandbto the same list instance. Mutatinga.append(1)will invisibly mutateb!
- Chained assignment
- Integer Division in Negative Numbers:
- In Python,
//rounds towards .-7 // 2is-4, NOT-3as in C or Java.
- In Python,
- Variable Swapping Idiom:
- Avoid temporary variable idioms (
temp = a; a = b; b = temp). Use tuple unpacking:
pythona, b = b, a - Avoid temporary variable idioms (
9. Formula Cheat-Sheet and Quick Reference
CODE+------------------------------------+---------------------------------------------------------------+ | Construct / Rule | Syntax & Behavior | +------------------------------------+---------------------------------------------------------------+ | Floor Division Formula | q = x // y (Quotient rounded towards -infinity) | | Modulus Remainder Formula | r = x % y = x - (x // y) * y | | Exponentiation Associativity | a ** b ** c == a ** (b ** c) (Evaluated Right-to-Left) | | Short-Circuit Conjunction | a and b (Returns 'a' if falsy; else returns 'b') | | Short-Circuit Disjunction | a or b (Returns 'a' if truthy; else returns 'b') | | Banker's Rounding | round(2.5) -> 2 ; round(3.5) -> 4 (Rounds to nearest even) | | Multiple Assignment Unpacking | x, y, z = 1, 2, 3 | | Tuple Value Swapping | a, b = b, a | | Memory Identity Inspection | id(object) (Unique integer memory address in CPython) | | Class Type Verification | isinstance(obj, ClassInfo) (Preferred over type(obj) == Cls) | | F-String Alignment & Precision | f"{val:>10.2f}" (Right-align 10 width, 2 decimal places) | +------------------------------------+---------------------------------------------------------------+