
Chapter Outline
Chapter 2: Python Syntax and Core Concepts
Now that your development environment is ready, it’s time to get hands-on with Python syntax and core programming concepts. In this chapter, we’ll cover:
- Variables and Data Types
- Operators
- Conditional Statements
- Loops
- Functions and Modules
- A practical project: Building a simple CLI-based calculator
- Writing unit tests for your calculator
2.1 Variables and Data Types
Python Data Types
| Category | Data Type | Description | Example |
|---|---|---|---|
| Numeric | int | Integer numbers | x = 5 |
float | Floating-point (decimal) numbers | y = 3.14 | |
complex | Complex numbers (real + imaginary) | z = 2 + 3j | |
| Sequence | str | Text/string data | name = "Python" |
list | Ordered, mutable collection | fruits = ["apple", "banana"] | |
tuple | Ordered, immutable collection | coords = (10.0, 20.0) | |
range | Sequence of numbers (used in loops) | r = range(5) | |
| Mapping | dict | Key-value pairs | person = {"name": "Alice", "age": 25} |
| Set | set | Unordered, unique elements | colors = {"red", "green"} |
frozenset | Immutable set | f_colors = frozenset(["red", "green"]) | |
| Boolean | bool | Boolean value (True or False) | is_active = True |
| Binary | bytes | Immutable byte sequence | data = b'hello' |
bytearray | Mutable byte sequence | ba = bytearray([65, 66]) | |
memoryview | Memory-efficient view of binary data | mv = memoryview(ba) | |
| None Type | NoneType | Represents absence of value | result = None |
| User-defined | Custom Class | Classes defined by developers | class Dog: passd = Dog() |
Python Variables
In Python, a variable is a name that refers to a value stored in memory. Variables allow you to store, retrieve, and manipulate data in your programs.
Key Features of Python Variables
| Feature | Explanation |
|---|---|
| Dynamically Typed | You don’t need to declare the variable type explicitly. Python infers it automatically. |
| No Explicit Declaration | Simply assign a value to create a variable. |
| Reassignment Allowed | You can change the value and even the type of data a variable holds later in your code. |
| Case Sensitive | name and Name are treated as two different variables. |
Example Variable Declarations
python# Integer variableage = 25# String variablename = "Alice"# Float variableprice = 19.99# Boolean variableis_active = True
Variable Naming Rules
- Variable names can contain letters, numbers, and underscores.
- They cannot start with a number.
- No spaces allowed.
- Reserved keywords like
class,if,return, etc., cannot be used as variable names.
✅ Valid examples:
pythonuser_name = "Bob"userAge = 30_user_location = "NY"
❌ Invalid examples:
python2user = "Error" # Starts with a numberuser-name = "Error" # Contains a hyphenclass = "Error" # Reserved keyword
Dynamic Typing Example
pythonx = 10 # x is an integerx = "Hello" # x is now a stringx = 3.14 # x is now a float
Python doesn’t require you to declare the type beforehand.
Multiple Variable Assignment
pythona, b, c = 1, 2, 3# Or assign the same value to multiple variablesx = y = z = 0
Swapping Variables
Python makes it easy to swap values without a temporary variable:
pythonx, y = 5, 10x, y = y, xprint(x, y) # Output: 10 5
Type Checking:
You can check the type of a variable using:
pythonname = "Alice"print(type(name)) # Output: <class 'str'>
Notes:
- Type Checking: Use
type(x)orisinstance(x, DataType) - Type Conversion: Built-in functions like
int(),str(),float() - Further Reading: Python Standard Types - Official Docs
2.2 Operators
Like all high level programming languages, Python comes with many operators of various kinds, to work with data of different types.
Categories of Python Operators
| Category | Description |
|---|---|
| Arithmetic Operators | Perform mathematical calculations |
| Assignment Operators | Assign values to variables |
| Comparison Operators | Compare two values |
| Logical Operators | Combine conditional statements |
| Identity Operators | Compare object identity (is) |
| Membership Operators | Check existence in sequences (in) |
| Bitwise Operators | Operate at the binary level |
Arithmetic Operators
| Operator | Description | Example | Result |
|---|---|---|---|
+ | Addition | 5 + 3 | 8 |
- | Subtraction | 5 - 3 | 2 |
* | Multiplication | 5 * 3 | 15 |
/ | Division | 5 / 2 | 2.5 |
// | Floor Division | 5 // 2 | 2 |
% | Modulus (remainder) | 5 % 2 | 1 |
** | Exponentiation | 2 ** 3 | 8 |
Assignment Operators
Used to assign and modify values.
| Operator | Example | Equivalent to |
|---|---|---|
= | a = 5 | |
+= | a += 1 | a = a + 1 |
-= | a -= 2 | a = a - 2 |
*= | a *= 3 | a = a * 3 |
/= | a /= 4 | a = a / 4 |
//= | a //= 2 | a = a // 2 |
%= | a %= 3 | a = a % 3 |
**= | a **= 2 | a = a ** 2 |
Comparison (Relational) Operators
Return Boolean values.
| Operator | Description | Example | Result |
|---|---|---|---|
== | Equal | 3 == 3 | True |
!= | Not equal | 4 != 5 | True |
> | Greater than | 5 > 2 | True |
< | Less than | 3 < 1 | False |
>= | Greater than or equal | 5 >= 5 | True |
<= | Less than or equal | 4 <= 5 | True |
Logical Operators
Used to combine multiple conditions.
| Operator | Description | Example | Result |
|---|---|---|---|
and | True if both | x > 1 and x < 10 | True/False |
or | True if either | x < 0 or x > 5 | True/False |
not | Negates condition | not (x == 3) | True/False |
Identity Operators
Used to compare memory addresses, not values.
pythona = [1, 2, 3]b = ac = [1, 2, 3]print(a is b) # Trueprint(a is c) # Falseprint(a == c) # True (values are equal)
| Operator | Description |
|---|---|
is | True if same object |
is not | True if not same obj |
Membership Operators
Check whether a value is in a container.
pythonmy_list = [1, 2, 3]print(2 in my_list) # Trueprint(4 not in my_list) # True
| Operator | Description |
|---|---|
in | True if found in object |
not in | True if not found |
Bitwise Operators
Operate at the bit level.
| Operator | Symbol | Use Case |
|---|---|---|
| AND | & | a & b |
| OR | | | a | b |
| XOR | ^ | a ^ b |
| NOT | ~ | ~a |
| Left Shift | << | a << 2 |
| Right Shift | >> | a >> 2 |
Operator Precedence
Precedence determines order of execution in expressions.
| Precedence Level | Operators |
|---|---|
| Highest | () (Parentheses) |
** (Exponentiation) | |
+, - (Unary) | |
*, /, //, % | |
+, - | |
Comparison: ==, !=, <, > | |
Logical: not, and, or | |
| Lowest | = (Assignment) |
2.3 Conditional Statements
if/elif/else statements
Python uses indentation (not curly braces) for blocks of code.
pythonx = 10if x > 5:print("x is greater than 5")elif x == 5:print("x equals 5")else:print("x is less than 5")
match/case statements
Python's match statement, introduced in Python 3.10, provides structural pattern matching, offering a more concise and readable alternative to multiple if/elif/else statements for certain scenarios.
Here are examples illustrating various uses of the match statement:
- Simple Value Matching:
pythonstatus_code = 200match status_code:case 200:print("OK")case 404:print("Not Found")case 500:print("Internal Server Error")case _: # Default case, matches anything not previously matchedprint("Unknown Status")
- Matching Multiple Values with
|(OR operator):
pythonday = "Saturday"match day:case "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday":print("It's a weekday.")case "Saturday" | "Sunday":print("It's the weekend!")case _:print("Invalid day.")
- Matching with Guards (Conditional Cases):
pythonscore = 85subject = "Math"match subject:case "Math" if score >= 90:print("Excellent in Math!")case "Math" if score >= 70:print("Good in Math.")case "Science" if score >= 80:print("Great in Science!")case _:print("Needs improvement or unknown subject.")
- Matching Sequences (Lists and Tuples):
Here we're using structural pattern matching, introduced in Python 3.10.
pythoncommand = ["move", "north"]match command:case ["move", direction]:print(f"Moving in direction: {direction}")case ["attack", target, weapon]:print(f"Attacking {target} with {weapon}")case _:print("Unknown command.")
- Matching Objects (Class Instances):
pythonclass Point:def __init__(self, x, y):self.x = xself.y = yp = Point(5, 0)match p:case Point(x=0, y=0):print("Origin")case Point(x=x_val, y=0):print(f"On X-axis at x={x_val}")case Point(x=0, y=y_val):print(f"On Y-axis at y={y_val}")case Point(x=x_val, y=y_val):print(f"Point at ({x_val}, {y_val})")
- Capturing Sub-patterns and Wildcards:
pythondata = ("error", 401, "Unauthorized")match data:case ("success", value):print(f"Operation successful with value: {value}")case ("error", code, message):print(f"Error {code}: {message}")case _:print("Unrecognized data format.")
2.4 Loops
For Loop
pythonfruits = ["apple", "banana", "cherry"]for fruit in fruits:print(fruit)
While Loop:
pythoncount = 0while count < 3:print(f"Count is {count}")count += 1
Loop Control Statements:
break: Exit the loop earlycontinue: Skip to the next iteration
2.5 Functions and Modules
The def keyword is used to define a function in Python. Functions help organize and reuse your code.
pythondef add(a, b):return a + bresult = add(2, 3)print(result) # Output: 5
You can also import functions from modules (files).
Example: If you had a file math_utils.py:
math_utils.py1def multiply(a, b):2 return a * b
You can import and use it like this:
pythonfrom math_utils import multiplyprint(multiply(3, 4)) # Output: 12
2.6 Comments
Comments are lines ignored by the Python interpreter. They're used to explain what the code does, document tricky logic, or temporarily disable code.
Single-Line Comments
Use the # symbol to start a single-line comment:
python# This is a single-line commentprint("Hello, World!") # This prints a greeting
Everything after the # is ignored by Python.
Multi-Line Comments (Convention)
Python does not have a native multi-line comment syntax. Instead, we use multiple # lines:
python# This script calculates# the square of a number# and prints the result
Alternatively, you can use a triple-quoted string that isn’t assigned:
python"""This is not a true multi-line comment,but it behaves like one and is commonly usedfor documentation or disabling code temporarily."""
However, triple quotes are typically reserved for docstrings (see below).
Docstrings: Comments for Documentation
Python supports inline documentation using docstrings—strings enclosed in triple quotes at the start of a module, function, or class.
pythondef greet(name):"""This function greets the user by name."""return f"Hello, {name}"
You can access docstrings using:
pythonprint(greet.__doc__)
This is useful for auto-generating documentation with tools like Sphinx or IDE tooltips.
Example Project: CLI-Based Calculator
Let ’s build a simple command-line calculator supporting addition, subtraction, multiplication, and division.
calculator.py1def add(a, b):2 return a + b34def subtract(a, b):5 return a - b67def multiply(a, b):8 return a * b910def divide(a, b):11 if b == 0:12 raise ValueError("Cannot divide by zero")13 return a / b1415def main():16 print("Simple CLI Calculator")17 print("Operations: add, subtract, multiply, divide")1819 operation = input("Enter operation: ").strip().lower()20 try:21 num1 = float(input("Enter first number: "))22 num2 = float(input("Enter second number: "))2324 if operation == "add":25 result = add(num1, num2)26 elif operation == "subtract":27 result = subtract(num1, num2)28 elif operation == "multiply":29 result = multiply(num1, num2)30 elif operation == "divide":31 result = divide(num1, num2)32 else:33 print("Invalid operation")34 return3536 print(f"Result: {result}")3738 except ValueError as e:39 print(f"Error: {e}")4041if __name__ == "__main__":42 main()
Running the Calculator
bashpython calculator.py
Example interaction:
bashSimple CLI CalculatorOperations: add, subtract, multiply, divideEnter operation: addEnter first number: 10Enter second number: 5Result: 15.0
Writing Unit Tests for the Calculator
Now, let's create a unit test file.
File: test_calculator.py
test_calculator.py1import pytest2from calculator import add, sub, mul, div34def test_addition():5 assert add(1, 2) == 367def test_subtraction():8 assert sub(5, 2) == 3910def test_multiplication():11 assert mul(2, 3) == 61213def test_division():14 assert div(6, 2) == 31516def test_division_by_zero():17 with pytest.raises(ValueError, match="Division by zero"):18 div(2, 0)
Running Your Tests:
bashpytest
Expected Output:
bashcollected 5 itemstest_calculator.py ..... [83%]5 passed in 0.03s
The reason why the test coverage isn't 100% is because the main() function in the module wasn't tested. We could achieve 100% test coverage of the business logic by moving the arithmatic functions into a separate module, calculator_operations.py for instance, and writing tests for it.
2.7 How This Ties to Web Development Later
Understanding data types, control structures, and functions lays the groundwork for writing API routes, services, and business logic layers in frameworks like FastAPI and Django.
For example:
- The
main()function above mirrors a simple web controller - Validation logic (like checking for divide by zero) will later appear in API request validation
Conclusion
You’ve learned:
- Python variables and types
- Conditionals and loops
- Functions and modules
- How to write and test a simple calculator app
What is Next?
In Chapter 3: Working with Files and Data Serialization, we’ll cover:
- Reading and writing files
- Parsing JSON and CSV
- Practical example: Log file parser that outputs JSON
Check your understanding
Test your knowledge of Python Syntax and Core Concepts