Post 3: Python Syntax Fundamentals & Language Features
Welcome to the third post in my Python learning journey. In the first two posts, we installed Python and set up a proper development environment. Now it’s time to dive into the language itself. This post covers the fundamental building blocks of Python code that I’ve been learning.
We’ll explore:
- Variables and basic data types
- Operators and expressions
- Control flow with conditionals and loops
- List comprehensions and lambdas
- Iterators and generators
- Error handling with try/except
This post is a bit longer than the previous ones, but these fundamentals form the foundation of everything else in Python, so it’s worth taking the time to understand them.
1. Variables and Basic Data Types
Python is dynamically typed, meaning you don’t need to declare variable types explicitly. Coming from Excel formulas where everything just works, I found this quite intuitive.
1.1 Variables and Assignment
Variables in Python are created when you first assign a value to them:
# Creating variables
name = "Alex"
age = 35
hourly_rate = 45.50
is_python_fun = True
Variable names:
- Can contain letters, numbers, and underscores
- Cannot start with a number
- Are case-sensitive (
rate
andRate
are different variables) - Should follow the
snake_case
convention (lowercase with underscores)
1.2 Basic Data Types
Python has several built-in data types:
Numbers
# Integers (whole numbers)
count = 10
negative_number = -5
# Floating-point (decimals)
pi = 3.14159
discount_rate = 0.15
# Complex numbers
complex_number = 3 + 4j # Not often used in business applications
Strings
# Text enclosed in quotes (single or double)
first_name = "John"
last_name = 'Doe'
# Multi-line strings use triple quotes
address = """123 Main Street
Anytown, CA 12345"""
# String concatenation
full_name = first_name + " " + last_name # "John Doe"
# f-strings (Python 3.6+) - my preferred way to format strings
greeting = f"Hello, {first_name}! You are {age} years old."
Booleans
# True or False values
is_active = True
has_paid = False
# Boolean operations
is_valid_customer = is_active and has_paid # False
can_contact = is_active or has_paid # True
is_not_active = not is_active # False
None Type
# Represents absence of value (similar to NULL in databases)
result = None
1.3 Type Conversion
Python can convert between types:
# String to number
age_str = "35"
age_num = int(age_str) # 35 as integer
price_float = float("45.50") # 45.5 as float
# Number to string
count_str = str(10) # "10" as string
# Check type of a variable
print(type(age_num)) # <class 'int'>
2. Operators and Expressions
Python supports various operators for calculations and comparisons.
2.1 Arithmetic Operators
a = 10
b = 3
addition = a + b # 13
subtraction = a - b # 7
multiplication = a * b # 30
division = a / b # 3.3333... (always returns float)
floor_division = a // b # 3 (integer division, rounds down)
modulus = a % b # 1 (remainder of division)
exponent = a ** b # 1000 (10 raised to power of 3)
2.2 Comparison Operators
a = 10
b = 3
equal = a == b # False
not_equal = a != b # True
greater_than = a > b # True
less_than = a < b # False
greater_or_equal = a >= b # True
less_or_equal = a <= b # False
2.3 Assignment Operators
# Simple assignment
x = 10
# Combined operators
x += 5 # Same as x = x + 5 (x becomes 15)
x -= 3 # Same as x = x - 3 (x becomes 12)
x *= 2 # Same as x = x * 2 (x becomes 24)
x /= 4 # Same as x = x / 4 (x becomes 6.0)
3. Control Flow
Control flow determines the order in which code executes based on conditions and loops.
3.1 Conditional Statements (if/elif/else)
Python uses indentation (whitespace) to define code blocks:
age = 25
if age < 18:
print("Minor")
elif age < 65:
print("Adult")
else:
print("Senior")
Multiple conditions:
income = 75000
years_employed = 3
if income > 50000 and years_employed >= 2:
print("Loan approved")
elif income > 30000 or years_employed >= 5:
print("Further review needed")
else:
print("Loan denied")
3.2 Loops
For Loops
For loops iterate over sequences (lists, strings, etc.):
# Loop through a list
expenses = [1200, 450, 700, 95]
total = 0
for expense in expenses:
total += expense
print(f"Total expenses: ${total}") # Total expenses: $2445
# Loop with a range
for i in range(5): # 0, 1, 2, 3, 4
print(i)
# Loop with index and value using enumerate
for index, value in enumerate(expenses):
print(f"Expense {index+1}: ${value}")
While Loops
While loops execute as long as a condition is true:
count = 0
while count < 5:
print(count)
count += 1 # Don't forget this or you'll create an infinite loop!
# Break and continue
number = 0
while True: # Infinite loop
number += 1
if number == 3:
continue # Skip the rest of this iteration
if number == 6:
break # Exit the loop entirely
print(number) # Prints 1, 2, 4, 5
4. List Comprehensions and Lambdas
These are more advanced features that make Python code concise and expressive.
4.1 List Comprehensions
List comprehensions provide a compact way to create lists:
# Traditional way
numbers = [1, 2, 3, 4, 5]
squares = []
for n in numbers:
squares.append(n * n)
print(squares) # [1, 4, 9, 16, 25]
# With list comprehension
squares = [n * n for n in numbers]
print(squares) # [1, 4, 9, 16, 25]
# With conditional filtering
even_squares = [n * n for n in numbers if n % 2 == 0]
print(even_squares) # [4, 16]
4.2 Dictionary and Set Comprehensions
Similar syntax works for dictionaries and sets:
# Dictionary comprehension
number_to_square = {n: n * n for n in numbers}
print(number_to_square) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# Set comprehension (eliminates duplicates)
values = [1, 2, 2, 3, 4, 4, 5]
unique_values = {v for v in values}
print(unique_values) # {1, 2, 3, 4, 5}
4.3 Lambda Functions
Lambdas are small anonymous functions defined with the lambda
keyword:
# Traditional function
def add(a, b):
return a + b
# Equivalent lambda function
add_lambda = lambda a, b: a + b
print(add(2, 3)) # 5
print(add_lambda(2, 3)) # 5
Lambdas are often used with functions like map()
, filter()
, and sorted()
:
# Map applies a function to each item in an iterable
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x * x, numbers))
print(squared) # [1, 4, 9, 16, 25]
# Filter creates a list of elements for which a function returns True
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers) # [2, 4]
# Sorted with a custom key function
employees = [
{"name": "Alice", "salary": 60000},
{"name": "Bob", "salary": 50000},
{"name": "Charlie", "salary": 75000}
]
sorted_by_salary = sorted(employees, key=lambda emp: emp["salary"])
print(sorted_by_salary) # Sorts employees by salary
5. Iterators and Generators
These features help process data efficiently, especially when working with large datasets.
5.1 Iterators
An iterator is an object that can be iterated (looped) over. Python’s for
loops work with iterators:
# Lists, tuples, dictionaries, and sets are all iterable
numbers = [1, 2, 3]
for num in numbers: # numbers.__iter__() is called implicitly
print(num)
You can create your own iterator:
# Manual iteration with iter() and next()
numbers = [1, 2, 3]
iterator = iter(numbers)
print(next(iterator)) # 1
print(next(iterator)) # 2
print(next(iterator)) # 3
# print(next(iterator)) # Would raise StopIteration exception
5.2 Generators
Generators are functions that return an iterator using the yield
keyword:
def count_up_to(max):
count = 1
while count <= max:
yield count
count += 1
# Using the generator
counter = count_up_to(5)
print(next(counter)) # 1
print(next(counter)) # 2
# Or in a loop
for number in count_up_to(3):
print(number) # Prints 1, 2, 3
Generators are memory-efficient because they generate values on-demand rather than storing the entire sequence in memory. This is especially useful for large datasets.
6. Error Handling with try/except
Python uses exceptions to handle errors gracefully:
# Basic try/except
try:
result = 10 / 0 # Division by zero raises an exception
print(result)
except ZeroDivisionError:
print("Cannot divide by zero!")
# Handling multiple exception types
try:
number = int(input("Enter a number: "))
result = 100 / number
print(result)
except ValueError:
print("That's not a valid number!")
except ZeroDivisionError:
print("Cannot divide by zero!")
# Try/except/else/finally
try:
file = open("data.txt", "r")
content = file.read()
except FileNotFoundError:
print("File not found!")
else:
# Runs if no exception occurred
print(f"File content: {content}")
finally:
# Always runs, regardless of exception
if 'file' in locals() and not file.closed:
file.close()
print("File closed!")
Practice Exercise: Financial Calculator
Let’s apply what we’ve learned to build a simple financial calculator:
Create a program that:
- Asks the user for their monthly income and expenses
- Calculates their monthly savings
- Projects savings over time with compound interest
- Handles invalid inputs gracefully with try/except
Here’s a starter template:
def calculate_savings_projection(monthly_savings, annual_interest_rate, years):
# Convert annual interest rate to monthly and decimal
monthly_rate = annual_interest_rate / 100 / 12
months = years * 12
# Project savings
total = 0
for month in range(1, months + 1):
total = total + monthly_savings # Add monthly contribution
interest = total * monthly_rate # Calculate interest
total = total + interest # Add interest to total
# Print yearly totals
if month % 12 == 0:
print(f"Year {month // 12}: ${total:.2f}")
return total
try:
income = float(input("Enter your monthly income: $"))
expenses = float(input("Enter your monthly expenses: $"))
monthly_savings = income - expenses
if monthly_savings <= 0:
print("Your expenses exceed your income. No savings to project.")
else:
interest_rate = float(input("Enter annual interest rate (%): "))
years = int(input("Enter number of years to project: "))
print(f"\nMonthly savings: ${monthly_savings:.2f}")
print(f"Projecting growth over {years} years at {interest_rate}% annual interest:")
final_amount = calculate_savings_projection(monthly_savings, interest_rate, years)
print(f"\nFinal savings after {years} years: ${final_amount:.2f}")
except ValueError:
print("Please enter valid numbers only.")
What’s Next?
Now that we’ve covered the syntax fundamentals, the next post will dive into Python’s core data structures in more detail. We’ll explore lists, tuples, dictionaries, and sets—and when to use each one.
Stay tuned for Post 4: Core Data Structures!
*This post is part of my journey learning Python. I’m a chartered accountant exploring programming to enhance my analytical toolkit. If you have questions or spot any errors, please reach out