Python Programming
Detailed Notes — Unit I & Unit II
Based on: Al Sweigart — Automate the Boring Stuff with Python
With Programs and Examples
UNIT I — Python Basics and Flow Control
This unit covers the foundational building blocks of Python: data types, variables, expressions, and the
mechanisms that control how a program executes. It corresponds to Chapters 1 and 2 of Al Sweigart's
Automate the Boring Stuff with Python.
1. The Interactive Shell (REPL)
The Python interactive shell is a Read-Eval-Print Loop (REPL). You type an expression, Python reads
it, evaluates it, and prints the result immediately. This is ideal for experimenting and testing small
snippets without writing a full program.
• Launch: type python or python3 in your terminal/command prompt
• The >>> prompt means Python is waiting for input
• Type an expression and press Enter — Python prints the result
• It keeps track of nothing between sessions — each new session starts fresh
How to open: Windows: Start → Python 3.x | Mac/Linux: open Terminal, type python3
Example in the shell:
>>> 2 + 2
4
>>> 'Hello' + ' World'
'Hello World'
>>> 10 / 3
3.3333333333333335
>>> 2 ** 8
256
2. Data Types — int, float, str
Every value in Python has a data type. The three core types in this unit are integers, floating-point
numbers, and strings.
Integer (int)
Whole numbers, positive or negative, without a decimal point. There is no size limit in Python —
integers can be arbitrarily large.
x = 10
y = -250
big = 99999999999999999999
print(type(x)) # <class 'int'>
Floating-Point Number (float)
Numbers with a decimal point. Python uses IEEE 754 double precision for floats. Be aware of floating-
point imprecision.
pi = 3.14159
temp = -98.6
print(type(pi)) # <class 'float'>
print(0.1 + 0.2) # 0.30000000000000004 (float imprecision!)
Note: Use the round() function to handle float imprecision: round(0.1 + 0.2, 2) gives 0.3
String (str)
A sequence of characters enclosed in single quotes, double quotes, or triple quotes. Strings are
immutable — you cannot change individual characters in place.
name = 'Alice'
greeting = "Hello, World!"
multiline = '''This is
a multiline
string'''
print(type(name)) # <class 'str'>
print(len(name)) # 5
String Concatenation and Replication
The + operator joins two strings. The * operator repeats a string a given number of times. You cannot
use + to combine a string with a number — you must convert first.
# Concatenation
first = 'Hello'
second = ' World'
print(first + second) # Hello World
# Replication
print('Ha' * 3) # HaHaHa
print('-' * 40) # ----------------------------------------
# WRONG — will cause TypeError
# print('Age: ' + 25) ERROR
# CORRECT — convert int to str first
print('Age: ' + str(25)) # Age: 25
3. Variables and Assignment
A variable is a name that refers to a value stored in memory. You create a variable by assigning it a
value with the = operator. Python is dynamically typed — a variable can be reassigned to a value of a
different type.
Variable Naming Rules
• Must start with a letter or underscore (_), not a digit
• Can contain letters, digits, and underscores
• Case-sensitive: spam, Spam, and SPAM are three different variables
• Cannot be a Python keyword (if, while, for, def, class, etc.)
• Convention: use lowercase_with_underscores for variable names
spam = 42
eggs = 2.5
my_name = 'Alice'
_private = 'hidden'
# Reassignment is allowed
spam = 'now I am a string'
print(spam) # now I am a string
# Multiple assignment
a = b = c = 0
x, y, z = 1, 2, 3
print(x, y, z) # 1 2 3
4. The print() and input() Functions
print() displays output to the screen. input() pauses the program and waits for the user to type
something, then returns what was typed as a string.
# print() basics
print('Hello, World!')
print('Score:', 100) # prints: Score: 100
print('A', 'B', 'C', sep='-') # A-B-C
print('Loading', end='...') # no newline at end
# input() always returns a string
name = input('What is your name? ')
print('Hello, ' + name + '!')
# Convert input to number
age = int(input('Enter your age: '))
print('In 10 years you will be', age + 10)
5. Your First Complete Program
The following program demonstrates variables, input/output, string operations, and basic arithmetic —
all the basics of Unit I Python Basics.
# Program: Personal Info Display
print('=== Personal Info Program ===')
name = input('Enter your full name: ')
age = int(input('Enter your age: '))
city = input('Enter your city: ')
print()
print('Name: ' + name)
print('Age: ' + str(age))
print('City: ' + city)
print('Birth Year: ' + str(2025 - age))
print('-' * 30)
print('Hello ' + name + '! You live in ' + city + '.')
6. Flow Control — Introduction
Flow control determines the order in which Python executes instructions. Without it, every program
would run line by line from top to bottom. Flow control introduces branching (decisions) and loops
(repetition).
7. Boolean Values
The Boolean data type has exactly two values: True and False (capitalised). Booleans are the result of
comparison expressions and are used in all flow control statements.
is_sunny = True
is_raining = False
print(type(True)) # <class 'bool'>
# Any value can be tested as a boolean
# Falsy values: 0, 0.0, '', [], None, False
# Truthy values: everything else
print(bool(0)) # False
print(bool('')) # False
print(bool(42)) # True
print(bool('hello')) # True
8. Comparison Operators
Comparison operators compare two values and always return True or False.
Operator Meaning Example
== Equal to 5 == 5 → True
!= Not equal to 5 != 3 → True
< Less than 3 < 10 → True
> Greater than 10 > 5 → True
<= Less than or equal to 5 <= 5 → True
>= Greater than or equal to 10 >= 9 → True
x = 10
print(x == 10) # True
print(x != 5) # True
print(x > 7) # True
print(x <= 10) # True
print(x == '10') # False (int vs str)
9. Boolean Operators — and, or, not
Boolean operators combine or invert boolean expressions.
Operator Meaning Truth Table Summary
and True only if BOTH sides are True T and T = T; T and F = F; F and
F=F
or True if AT LEAST ONE side is True T or T = T; T or F = T; F or F = F
not Inverts the boolean value not True = False; not False =
True
age = 20
has_id = True
# and — both must be True
print(age >= 18 and has_id) # True
print(age >= 18 and not has_id) # False
# or — at least one must be True
print(age < 18 or has_id) # True
# not — flips the value
print(not (age > 30)) # True
# Combining multiple conditions
x = 5
print(1 < x and x < 10) # True (x is between 1 and 10)
print(x < 1 or x > 10) # False
10. if, elif, else Statements
The if statement lets Python choose which block of code to run based on a condition. elif (else if)
checks additional conditions if the previous ones were False. else runs when all conditions above it are
False.
Syntax
if condition1:
# runs if condition1 is True
elif condition2:
# runs if condition1 is False and condition2 is True
elif condition3:
# runs if condition1, condition2 are False and condition3 is True
else:
# runs if ALL conditions above are False
Important: Indentation defines the block. Python uses 4 spaces (or 1 tab) for each level.
Incorrect indentation causes IndentationError.
Program 1 — Grade Calculator
marks = int(input('Enter your marks (0-100): '))
if marks >= 90:
grade = 'A+'
result = 'Distinction'
elif marks >= 80:
grade = 'A'
result = 'First Class'
elif marks >= 70:
grade = 'B'
result = 'Second Class'
elif marks >= 60:
grade = 'C'
result = 'Pass with Merit'
elif marks >= 35:
grade = 'D'
result = 'Pass'
else:
grade = 'F'
result = 'Fail'
print('Grade:', grade)
print('Result:', result)
Program 2 — Even or Odd with Range Check
num = int(input('Enter a number: '))
if num < 0:
print('Negative number')
elif num == 0:
print('Zero')
elif num % 2 == 0:
print(str(num) + ' is a positive EVEN number')
else:
print(str(num) + ' is a positive ODD number')
Program 3 — Login System
# Simple username/password checker
correct_user = 'admin'
correct_pass = 'python123'
username = input('Username: ')
password = input('Password: ')
if username == correct_user and password == correct_pass:
print('Login successful! Welcome, ' + username)
elif username == correct_user and password != correct_pass:
print('Wrong password!')
elif username != correct_user:
print('Unknown username!')
else:
print('Login failed.')
11. The while Loop
A while loop repeatedly executes its block as long as its condition remains True. If the condition is
False from the start, the block never runs. If the condition never becomes False, you get an infinite
loop.
# Syntax
while condition:
# body — runs repeatedly while condition is True
Program 4 — Countdown Timer
import time
count = int(input('Start countdown from: '))
while count > 0:
print(count, '...')
count -= 1 # same as count = count - 1
[Link](1) # wait 1 second
print('Blastoff!')
Program 5 — Sum of N Numbers
n = int(input('How many numbers to add? '))
total = 0
count = 1
while count <= n:
num = int(input('Enter number ' + str(count) + ': '))
total += num
count += 1
print('Sum =', total)
print('Average =', total / n)
Program 6 — Number Guessing Game (while loop version)
import random
secret = [Link](1, 100)
attempts = 0
guessed = False
print('Guess the number between 1 and 100!')
while not guessed:
guess = int(input('Your guess: '))
attempts += 1
if guess < secret:
print('Too low! Try higher.')
elif guess > secret:
print('Too high! Try lower.')
else:
guessed = True
print('Correct! The number was', secret)
print('You got it in', attempts, 'attempts!')
12. break and continue Statements
break immediately exits the innermost loop it is inside. continue skips the rest of the current iteration
and jumps back to the loop condition check.
break
# break — exit loop early
print('Enter words (type QUIT to stop):')
while True: # infinite loop
word = input('> ')
if word == 'QUIT':
break # exits the while loop
print('You said:', word)
print('Goodbye!')
continue
# continue — skip current iteration
# Print only odd numbers from 1 to 10
num = 0
while num < 10:
num += 1
if num % 2 == 0: # if even...
continue # ...skip to next iteration
print(num) # only prints 1,3,5,7,9
Program 7 — ATM PIN Entry (3 attempts)
correct_pin = '1234'
max_attempts = 3
for attempt in range(1, max_attempts + 1):
pin = input('Enter PIN (attempt ' + str(attempt) + '/' +
str(max_attempts) + '): ')
if pin == correct_pin:
print('Access granted!')
break
else:
print('Wrong PIN!')
if attempt == max_attempts:
print('Card blocked after 3 wrong attempts.')
13. The for Loop and range()
A for loop iterates over a sequence. The range() function generates a sequence of integers and is
commonly used with for loops. range(start, stop, step) — stop is exclusive.
# range(stop) — starts from 0
for i in range(5):
print(i) # 0, 1, 2, 3, 4
# range(start, stop)
for i in range(1, 6):
print(i) # 1, 2, 3, 4, 5
# range(start, stop, step)
for i in range(0, 20, 5):
print(i) # 0, 5, 10, 15
# Counting down
for i in range(10, 0, -1):
print(i) # 10, 9, ..., 1
Program 8 — Multiplication Table
n = int(input('Enter a number for its multiplication table: '))
print('Multiplication Table of', n)
print('-' * 30)
for i in range(1, 11):
result = n * i
print(str(n) + ' x ' + str(i) + ' = ' + str(result))
Program 9 — Factorial Calculator
num = int(input('Enter a positive integer: '))
if num < 0:
print('Factorial not defined for negative numbers')
elif num == 0:
print('0! = 1')
else:
factorial = 1
for i in range(1, num + 1):
factorial *= i # factorial = factorial * i
print(str(num) + '! = ' + str(factorial))
Program 10 — Prime Number Checker
num = int(input('Enter a number: '))
is_prime = True
if num < 2:
is_prime = False
else:
for i in range(2, num):
if num % i == 0: # if divisible by i
is_prime = False
break # no need to check further
if is_prime:
print(str(num) + ' is a prime number')
else:
print(str(num) + ' is NOT a prime number')
14. Importing Modules
A module is a Python file containing useful functions and variables. Python has a rich standard library
of built-in modules. You import them with the import statement.
# Method 1: import module
import random
import math
import sys
# Method 2: from module import function
from random import randint
from math import sqrt, pi
# Using random module
print([Link](1, 10)) # random int between 1 and 10
print([Link](['a', 'b', 'c'])) # random item from list
print([Link]()) # float between 0.0 and 1.0
# Using math module
print([Link](144)) # 12.0
print([Link]) # 3.141592...
print([Link](4.9)) # 4
print([Link](4.1)) # 5
print([Link](5)) # 120
# Using sys module
print([Link]) # Python version info
Program 11 — [Link]() and Early Termination
import sys
print('Welcome to the program')
age = int(input('Enter your age: '))
if age < 18:
print('Sorry, you must be 18 or older.')
[Link]() # program stops here
print('Access granted. You are', age, 'years old.')
15. Landmark Program — Guess the Number (Complete)
This program from the textbook combines everything from Unit I: import, variables, while loop, for loop,
if/elif/else, comparison operators, and [Link]().
import random
def main():
print('I am thinking of a number between 1 and 20.')
secret_number = [Link](1, 20)
guesses_taken = 0
for guessesTaken in range(1, 7): # max 6 guesses
print('Take a guess.')
guess = int(input())
guesses_taken += 1
if guess < secret_number:
print('Your guess is too low.')
elif guess > secret_number:
print('Your guess is too high.')
else:
break # correct guess!
if guess == secret_number:
print('Good job! You guessed my number in ' +
str(guesses_taken) + ' guesses!')
else:
print('Nope. The number I was thinking of was ' +
str(secret_number))
main()
UNIT II — Functions and Lists
Unit II introduces two essential features: functions for code reuse and organisation, and lists for storing
collections of values. These are covered in Chapters 3 and 4 of Al Sweigart's book.
1. Defining and Calling Functions
A function is a named block of code that performs a specific task. Functions avoid repetition (DRY —
Don't Repeat Yourself) and make programs easier to read and maintain.
# Defining a function
def function_name(parameter1, parameter2):
# body of function
return value # optional
# Calling a function
result = function_name(argument1, argument2)
Program 1 — Basic Function with Parameters
def greet(name, times):
for i in range(times):
print('Hello, ' + name + '!')
greet('Alice', 3) # calls greet with Alice, 3 times
greet('Bob', 1)
Program 2 — Area Calculator Functions
def area_rectangle(length, width):
return length * width
def area_circle(radius):
import math
return [Link] * radius ** 2
def area_triangle(base, height):
return 0.5 * base * height
# Call the functions
print('Rectangle area:', area_rectangle(5, 3)) # 15
print('Circle area:', round(area_circle(7), 2)) # 153.94
print('Triangle area:', area_triangle(10, 6)) # 30.0
2. Return Values and the return Statement
A function can send a value back to the caller using return. The function immediately stops executing
when return is reached. A function can have multiple return statements (in different branches), but only
one executes per call.
def absolute_value(num):
if num < 0:
return -num
else:
return num
print(absolute_value(-5)) # 5
print(absolute_value(8)) # 8
Program 3 — Maximum of Three Numbers
def maximum(a, b, c):
if a >= b and a >= c:
return a
elif b >= a and b >= c:
return b
else:
return c
x = int(input('Enter first number: '))
y = int(input('Enter second number: '))
z = int(input('Enter third number: '))
print('Maximum is:', maximum(x, y, z))
3. The None Value
None is a special value that represents the absence of a value. Every function that does not have a
return statement implicitly returns None. It is Python's equivalent of 'nothing' or 'null'.
def say_hello():
print('Hello!') # no return statement
result = say_hello() # prints Hello!
print(result) # None
print(result == None) # True
print(result is None) # True (preferred way to check)
# print() also returns None
spam = print('Hello') # prints Hello!
print(spam) # None
4. Keyword Arguments and print()
When calling a function, you can pass arguments by name (keyword arguments). This lets you pass
them in any order and makes code more readable. The built-in print() function uses keyword arguments
for sep and end.
# print() keyword arguments
print('cat', 'dog', 'bird') # cat dog bird
print('cat', 'dog', 'bird', sep=', ') # cat, dog, bird
print('cat', 'dog', 'bird', sep='-') # cat-dog-bird
print('Loading', end='') # no newline
print('...') # continues on same line
# Custom function with keyword arguments
def make_pizza(size, crust='thin', toppings='cheese'):
print(size + ' pizza with ' + crust +
' crust and ' + toppings)
make_pizza('large') # uses defaults
make_pizza('medium', crust='thick') # override one default
make_pizza('small', toppings='pepperoni', crust='stuffed')
5. Local and Global Scope
Scope determines where a variable is accessible. Local variables exist only inside the function where
they are created. Global variables are created outside functions and accessible everywhere.
Rules of Scope
• Variables created inside a function are LOCAL — invisible outside it
• Variables created outside all functions are GLOBAL
• A function can READ a global variable without any special keyword
• A function can only MODIFY a global variable if it declares it with global
• Local and global variables can have the same name — they are separate
# Global variable
global_var = 'I am global'
def show_scope():
local_var = 'I am local' # local to this function
print(global_var) # can READ global
print(local_var)
show_scope()
print(global_var) # works fine
# print(local_var) # NameError! local_var doesn't
exist here
The global Statement
counter = 0 # global variable
def increment():
global counter # declare intent to modify global
counter += 1 # modifies the global counter
increment()
increment()
increment()
print(counter) # 3
Program 4 — Counter with Global Scope
score = 0
def add_points(points):
global score
score += points
print('Added', points, 'points. Total:', score)
def reset_score():
global score
score = 0
print('Score reset.')
add_points(10)
add_points(25)
add_points(15)
reset_score()
add_points(5)
6. Exception Handling — try / except
Runtime errors (exceptions) crash programs. try/except blocks catch errors gracefully, allowing the
program to continue or display a useful message instead of crashing.
# Without exception handling — crashes
# print(10 / 0) ZeroDivisionError
# int('hello') ValueError
# With exception handling
try:
result = 10 / 0
except ZeroDivisionError:
print('Cannot divide by zero!')
result = None
Common Exception Types
• ValueError — wrong type of value (e.g., int('hello'))
• ZeroDivisionError — dividing by zero
• TypeError — wrong data type in operation
• NameError — using a variable that doesn't exist
• IndexError — accessing a list index that doesn't exist
• FileNotFoundError — opening a file that doesn't exist
Program 5 — Safe Division Function
def safe_divide(a, b):
try:
return a / b
except ZeroDivisionError:
print('Error: Cannot divide by zero')
return None
except TypeError:
print('Error: Both arguments must be numbers')
return None
print(safe_divide(10, 2)) # 5.0
print(safe_divide(10, 0)) # Error: Cannot divide by zero / None
print(safe_divide('a', 2)) # Error: Both arguments must be numbers /
None
Program 6 — Input Validation with try/except
def get_integer(prompt):
while True:
try:
value = int(input(prompt))
return value
except ValueError:
print('Invalid input! Please enter a whole number.')
age = get_integer('Enter your age: ')
print('Next year you will be', age + 1)
7. The List Data Type
A list is an ordered, mutable collection of values enclosed in square brackets. Lists can hold items of
any type — even mixed types — and can be nested (lists within lists).
# Creating lists
fruits = ['apple', 'banana', 'cherry']
numbers = [10, 20, 30, 40, 50]
mixed = [42, 'hello', 3.14, True]
empty = []
nested = [[1, 2], [3, 4], [5, 6]]
# Accessing items — index starts at 0
print(fruits[0]) # apple
print(fruits[2]) # cherry
print(fruits[-1]) # cherry (last item)
print(fruits[-2]) # banana (second from last)
# Accessing nested list
print(nested[1][0]) # 3 (second list, first item)
8. Working with Lists — Slices, in, len
Lists support slicing (extracting a sublist), membership testing with in/not in, and length checking with
len(). Lists are mutable — you can change individual items by index.
nums = [10, 20, 30, 40, 50, 60]
# Slicing: list[start:stop] (stop is exclusive)
print(nums[1:4]) # [20, 30, 40]
print(nums[:3]) # [10, 20, 30] (from beginning)
print(nums[3:]) # [40, 50, 60] (to end)
print(nums[::2]) # [10, 30, 50] (every 2nd item)
print(nums[::-1]) # [60, 50, 40, 30, 20, 10] (reversed)
# Membership testing
print(30 in nums) # True
print(99 in nums) # False
print(99 not in nums) # True
# Length
print(len(nums)) # 6
# Modifying items
nums[0] = 100
print(nums) # [100, 20, 30, 40, 50, 60]
# Deleting items
del nums[1]
print(nums) # [100, 30, 40, 50, 60]
9. Augmented Assignment Operators
Augmented assignment operators combine an arithmetic operation with assignment. They are
shorthand and work on both numbers and strings/lists.
Operator Equivalent To Example
x += 5 x = x + 5 x=10; x+=5 → 15
x -= 3 x = x - 3 x=10; x-=3 → 7
x *= 2 x = x * 2 x=10; x*=2 → 20
x /= 4 x = x / 4 x=10; x/=4 → 2.5
x //= 3 x = x // 3 x=10; x//=3 → 3
x **= 2 x = x ** 2 x=5; x**=2 → 25
x %= 3 x = x % 3 x=10; x%=3 → 1
10. List Methods
Methods are functions attached to objects. List methods modify the list in place (except index() and
count() which just return information).
Method What it does Example
append(x) Add x to end of list [1,2].append(3) → [1,2,3]
insert(i, x) Insert x at index i [1,3].insert(1,2) → [1,2,3]
remove(x) Remove first x in list [1,2,2].remove(2) → [1,2]
pop() Remove & return last item [1,2,3].pop() → 3
pop(i) Remove & return item at i [1,2,3].pop(0) → 1
sort() Sort list in place (asc) [3,1,2].sort() → [1,2,3]
sort(reverse=True) Sort descending [1,2,3] → [3,2,1]
reverse() Reverse list in place [1,2,3] → [3,2,1]
index(x) Return index of first x [10,20,30].index(20) → 1
count(x) Count occurrences of x [1,2,2,3].count(2) → 2
copy() Return shallow copy b = [Link]()
clear() Remove all items [1,2,3].clear() → []
Program 7 — Student Marks Manager
students = []
marks = []
n = int(input('How many students? '))
for i in range(n):
name = input('Enter student ' + str(i+1) + ' name: ')
mark = int(input('Enter marks for ' + name + ': '))
[Link](name)
[Link](mark)
# Analysis
print('\n=== Results ===')
for i in range(len(students)):
print(students[i] + ': ' + str(marks[i]))
print('\nHighest marks:', max(marks))
print('Lowest marks:', min(marks))
print('Average:', sum(marks) / len(marks))
# Topper
top_index = [Link](max(marks))
print('Topper:', students[top_index])
Program 8 — Shopping Cart
cart = []
prices = []
while True:
print('\n1. Add item 2. Remove item 3. View cart 4. Checkout')
choice = input('Choice: ')
if choice == '1':
item = input('Item name: ')
price = float(input('Price: '))
[Link](item)
[Link](price)
print(item + ' added to cart')
elif choice == '2':
if len(cart) == 0:
print('Cart is empty!')
else:
item = input('Item to remove: ')
if item in cart:
idx = [Link](item)
[Link](item)
[Link](idx)
print(item + ' removed')
else:
print('Item not found in cart')
elif choice == '3':
if len(cart) == 0:
print('Cart is empty')
else:
for i in range(len(cart)):
print(cart[i] + ' - Rs.' + str(prices[i]))
elif choice == '4':
print('Total: Rs.' + str(sum(prices)))
break
11. Magic 8 Ball Program (Textbook Program)
import random
messages = [
'It is certain',
'It is decidedly so',
'Yes, definitely',
'You may rely on it',
'As I see it, yes',
'Most likely',
'Outlook good',
'Signs point to yes',
'Reply hazy, try again',
'Ask again later',
'Better not tell you now',
'Cannot predict now',
'Concentrate and ask again',
"Don't count on it",
'My reply is no',
'My sources say no',
'Outlook not so good',
'Very doubtful'
]
while True:
question = input('Ask the Magic 8 Ball (or type quit): ')
if [Link]() == 'quit':
print('Goodbye!')
break
print(messages[[Link](0, len(messages) - 1)])
12. List-like Types — Strings and Tuples
Strings and tuples behave like lists in many ways — they support indexing, slicing, len(), and in/not in.
However, they are immutable: you cannot modify them in place.
Strings as Sequences
name = 'Python'
# Indexing
print(name[0]) # P
print(name[-1]) # n
# Slicing
print(name[0:3]) # Pyt
print(name[2:]) # thon
print(name[::-1]) # nohtyP (reversed)
# Membership
print('y' in name) # True
print('z' in name) # False
# Iteration
for char in name:
print(char, end=' ') # P y t h o n
Tuples — Immutable Lists
# Tuples use parentheses (or no brackets at all)
point = (10, 20)
rgb = (255, 128, 0)
single = (42,) # comma required for single-item tuple
# All list-like operations work
print(point[0]) # 10
print(len(rgb)) # 3
print(20 in point) # True
# Immutable — cannot modify
# point[0] = 99 # TypeError!
# Tuple unpacking
x, y = point
print(x, y) # 10 20
# When to use tuples vs lists:
# Use tuples for data that should NOT change (coordinates, RGB, DB
records)
# Use lists for data that changes (shopping cart, student records)
13. References and Copies
In Python, variables do not store list values directly — they store references (memory addresses) to
where the list lives. This means assigning a list to another variable does NOT create a copy; both
variables point to the same list.
# Reference problem
a = [1, 2, 3]
b = a # b is a REFERENCE to the same list
[Link](4)
print(a) # [1, 2, 3, 4] — a was changed too!
print(b) # [1, 2, 3, 4] — same object
print(a is b) # True (same object in memory)
# How to make a true copy
import copy
c = [Link](a) # shallow copy
d = [Link](a) # deep copy (use for nested lists)
[Link](99)
print(a) # [1, 2, 3, 4] — unchanged
print(c) # [1, 2, 3, 4, 99] — only c changed
# Slice copy also works for simple lists
e = a[:] # creates a new list with same items
Key Rule: Use a[:] or [Link]() for flat lists. Use [Link]() when the list
contains other lists (nested). Without copying, accidental mutations to one variable will
affect the other.
14. Additional Programs — Lists and Functions
Program 9 — Fibonacci Sequence
def fibonacci(n):
fib = [0, 1]
for i in range(2, n):
next_val = fib[i-1] + fib[i-2]
[Link](next_val)
return fib[:n]
n = int(input('How many Fibonacci numbers? '))
result = fibonacci(n)
print('Fibonacci sequence:', result)
Program 10 — Bubble Sort
def bubble_sort(lst):
n = len(lst)
for i in range(n - 1):
for j in range(0, n - i - 1):
if lst[j] > lst[j + 1]:
# Swap
lst[j], lst[j+1] = lst[j+1], lst[j]
return lst
numbers = []
count = int(input('How many numbers to sort? '))
for i in range(count):
[Link](int(input('Enter number: ')))
sorted_list = bubble_sort([Link]())
print('Original:', numbers)
print('Sorted: ', sorted_list)
Program 11 — Contact Book
names = []
phones = []
def add_contact(name, phone):
[Link](name)
[Link](phone)
print('Contact added!')
def search_contact(name):
if name in names:
idx = [Link](name)
print('Phone:', phones[idx])
else:
print('Contact not found')
def show_all():
if len(names) == 0:
print('No contacts.')
return
for i in range(len(names)):
print(names[i] + ': ' + phones[i])
while True:
print('\[Link] [Link] [Link] All [Link]')
ch = input('> ')
if ch == '1':
add_contact(input('Name: '), input('Phone: '))
elif ch == '2':
search_contact(input('Search name: '))
elif ch == '3':
show_all()
elif ch == '4':
break
Program 12 — Caesar Cipher (Encryption)
def encrypt(text, shift):
result = []
for char in text:
if [Link]():
base = ord('A') if [Link]() else ord('a')
encrypted = chr((ord(char) - base + shift) % 26 + base)
[Link](encrypted)
else:
[Link](char) # keep spaces, punctuation
return ''.join(result)
def decrypt(text, shift):
return encrypt(text, -shift) # decrypt = encrypt backwards
message = input('Enter message: ')
shift = int(input('Enter shift (1-25): '))
encrypted = encrypt(message, shift)
decrypted = decrypt(encrypted, shift)
print('Original: ', message)
print('Encrypted:', encrypted)
print('Decrypted:', decrypted)
End of Notes — Unit I & Unit II