Variables & Values
A variable is a name that refers to a value
Variables must be defined before use
Assignment uses = and overwrites the previous value
The type belongs to the value, not to the variable
Python is dynamically typed
Data Types
Main basic types: integer, floating-point, string
Mixing incompatible types causes runtime errors
Variables may refer to values of different types at different times
Naming & Style
Variable names must follow Python naming rules
Use descriptive names
Constants are variables meant not to change
Constants are written in uppercase by convention
Readability and clarity matter
Comments
Comments explain code to humans
Ignored by the interpreter
Essential for documentation and maintainability
Arithmetic & Expressions
Python supports basic arithmetic operations
Operator precedence follows PEMDAS
Parentheses must be balanced
Division produces floating-point results
Integer division and remainder are separate operations
Mixing numeric types promotes results to floating-point
Functions
A function is a reusable block of code
Functions may require parameters
Functions may return values
Returned values can be used in expressions or assignments
Libraries & Modules
Libraries contain pre-written code
The standard library is included with Python
Code in modules must be imported before use
Different import styles change how functions are accessed
Type Conversion & Rounding
Explicit conversion is required between numbers and strings
Converting floating-point to integer truncates, not rounds
Floating-point values are approximate
Rounding errors are normal and must be handled consciously
Strings
Strings are sequences of characters
Defined using single or double quotes
Strings have a length
Strings are immutable
String Operations
Strings can be combined and repeated
Strings cannot be mixed directly with numeric types
Escape sequences represent special characters
Indexing & Slicing
Strings are indexed starting from zero
Valid indexes are within bounds
Slicing extracts substrings
Slicing does not modify the original string
Characters & Encoding
Characters are internally represented as integers
Python uses Unicode
Conversion between characters and integers is possible
Functions vs Methods
Functions are called independently
Methods belong to objects
Methods use dot notation
Both may return values
Core Principles to Remember
Define before use
Types matter
Strings cannot be modified
Imports are required
Floating-point math is not exact
Readability and correctness are equally important
Variables
Variables refer to values
Must be defined before use
Assignment replaces the old value
x=5
x = 10
Types
Type belongs to the value, not the variable
Python is dynamically typed
x=5 # int
x = 5.5 # float
x = "five" # str
Constants (Convention)
Variables that should not change
Written in uppercase by convention
MAX_SIZE = 100
Comments
Explain code to humans
Ignored by Python
# This is a comment
Numeric Types
Integers: whole numbers
Floats: numbers with decimals
Floats are approximate
a=7
b = 7.0
Arithmetic Operators
Perform calculations
Follow operator precedence
+ - * / ** // %
result = a + b * 2
Integer vs Floating Division
/ produces a float
// discards the fractional part
7/4 # float
7 // 4 # int
Remainder (Modulo)
Gives the remainder of a division
7%4
Mixing Numeric Types
Mixing int and float produces a float
Mixing numbers and strings causes errors
7 + 4.0 # OK
"7" + 4 # ERROR
Functions
Perform a task
May return a value
abs(-5)
x = abs(-5)
Libraries & Modules
External code must be imported
Built-in functions are always available
import math
[Link](16)
Type Conversion
Explicit conversion is required
int(3.9)
float(5)
str(10)
Rounding
Truncation is not rounding
Floating-point math is imprecise
round(3.14159, 2)
Floating-Point Errors
Some decimals cannot be represented exactly
Results may look incorrect
4.35 * 100
Strings
Strings are sequences of characters
Defined with single or double quotes
Strings are immutable
text = "Hello"
String Length
Length is the number of characters
len(text)
String Concatenation
Combines strings
Only works with strings
full = first + last
String Repetition
Repeats a string
"-" * 10
String ↔ Number Conversion
Required when mixing input and math
int("123")
float("3.14")
String Indexing
Index starts at 0
Access individual characters
text[0]
Index Errors
Accessing invalid indexes causes an error
text[len(text)]
String Immutability
Characters cannot be changed directly
Must create a new string
text = "H" + text[1:]
String Slicing
Extracts a portion of a string
Does not modify the original string
text[1:4]
text[:3]
text[3:]
text[::2]
Characters & Encoding
Characters are internally numbers
Python uses Unicode
ord('A')
chr(65)
Functions vs Methods
Function
len(text)
Method
[Link]()
Escape Sequences
Represent special characters inside strings
"\n"
"\""
"\\"
Input
All input from the user is read as a string
Numeric input requires explicit conversion
text = input()
number = int(input())
value = float(input())
Output
Output is printed to the console
Values can be inserted into text
print("Result:", result)
Formatted Output
Formatting controls how values appear, not their value
Used for precision, alignment, readability
f-string (preferred)
print(f"Total: {total:.2f}")
Format operator
print("Total: %.2f" % total)
if Statement
Executes code only if a condition is true
else branch is optional
if condition:
action
else:
alternative
Indentation & Blocks
Indentation defines program structure
Required for correctness
if x > 0:
print("Positive")
print("Still inside if")
Relational Operators
Compare values
Produce Boolean results
== != < <= > >=
if a == b:
pass
Assignment vs Comparison
x=5 # assignment
x == 5 # comparison
Comparing Strings
Case-sensitive
Compared character by character
if name1 == name2:
pass
Floating-Point Comparison
Never rely on exact equality
Compare using tolerance
if abs(a - b) < EPSILON:
pass
Nested if Statements
An if can appear inside another if
Used for multi-step decisions
if condition1:
if condition2:
action
Multiple Alternatives (elif)
Used when only one branch should execute
Order matters
if condition1:
pass
elif condition2:
pass
else:
pass
Boolean Values
Only two values: True, False
Often stored in variables
isValid = True
Boolean Operators
and
True only if both conditions are true
if a > 0 and b > 0:
pass
or
True if at least one condition is true
if a < 0 or b < 0:
pass
not
Inverts a Boolean value
if not valid:
pass
Short-Circuit Evaluation
Conditions evaluated left to right
Evaluation may stop early
if x != 0 and y / x > 1:
pass
Operator Precedence
Arithmetic before comparison
Comparison before Boolean logic
if x + 1 > y and z < 5:
pass
De Morgan’s Laws
not (A and B) == (not A or not B)
not (A or B) == (not A and not B)
String Membership
Test if a substring exists
if "abc" in text:
pass
if "abc" not in text:
pass
String Analysis (Methods)
Test string properties
Return Boolean values
[Link]()
[Link]()
[Link]()
[Link]()
Prefix & Suffix Testing
[Link](".txt")
[Link]("data")
Input Validation
Always check input before using it
Validate type, range, and meaning
if value <= 0:
print("Invalid input")
1. The while Loop
Repeats code while a condition is True (pre-test loop).
Used when number of iterations unknown or depends on a condition.
Must update variables used in condition → avoid infinite loops.
Count-Controlled Example
counter = 1
while counter <= 10:
print(counter)
counter += 1
Event-Controlled Example
balance = 100
target = 500
while balance <= target:
balance *= 2
Common Errors
Wrong condition → loop never executes.
Infinite loop → forget to update loop variable.
Off-by-one → start from 0 or 1, adjust < or <=.
Mixed Example (stop on sentinel)
count = 0
ok = True
while count < 10 and ok:
a = int(input("Number: "))
if a == 0:
ok = False
else:
print(f"Number {count+1}={a}")
count += 1
Boolean flag / sentinel
done = False
while not done:
value = float(input("Enter salary or -1 to finish: "))
if value < 0:
done = True
else:
print("Processing", value)
2. Common while Loop Algorithms
Sum / Average
total = 0
count = 0
val = input("Enter value: ")
while val != "":
total += float(val)
count += 1
val = input("Enter value: ")
average = total / count if count > 0 else 0
Counting Matches
negatives = 0
val = input("Enter value: ")
while val != "":
if int(val) < 0:
negatives += 1
val = input("Enter value: ")
print("Negatives:", negatives)
Find Maximum / Minimum
largest = int(input("Enter value: "))
val = input("Enter value: ")
while val != "":
if int(val) > largest:
largest = int(val)
val = input("Enter value: ")
smallest = int(input("Enter value: "))
val = input("Enter value: ")
while val != "":
if int(val) < smallest:
smallest = int(val)
val = input("Enter value: ")
Find First / Last Match
# First digit
found = False
pos = 0
while not found and pos < len(string):
if string[pos].isdigit():
found = True
else:
pos += 1
if found:
print("First digit at", pos)
# Last digit
found = False
pos = len(string) - 1
while not found and pos >= 0:
if string[pos].isdigit():
found = True
else:
pos -= 1
if found:
print("Last digit at", pos)
3. The for Loop
Iterates over containers (strings, lists, files) or ranges of numbers.
More compact than while loops for count-controlled loops.
Iterate over string
name = "Virginia"
for letter in name:
print(letter)
Counter-based for loop
for i in range(1, 10):
print(i)
Index + Value with enumerate
name = "ciao"
for i, letter in enumerate(name):
print(i, letter)
4. Nested Loops
Loop inside another loop, often for tables / grids.
for x in range(1, 4): # rows
for y in range(1, 4): # columns
print(f"Cell ({x},{y})")
5. Printing Options
sep → separator between multiple values (default: space)
end → what to print at line end (default: newline)
print("Hour", "Min", "Sec", sep=":", end="\n")
print("Hello", end="")
print("World") # prints HelloWorld
6. String Processing with Loops
Strings are sequences → iterate over characters.
Useful for counting, validating, finding matches.
Counting uppercase / vowels
uppercase = 0
for ch in string:
if [Link]():
uppercase += 1
vowels = 0
for ch in word:
if [Link]() in "aeiou":
vowels += 1
Finding all uppercase positions
sentence = input("Enter a sentence: ")
for i in range(len(sentence)):
if sentence[i].isupper():
print(i)
Validating string formats
Check characters at positions using loops.
phone = "(703)321-6753"
valid = True
if len(phone) == 13:
valid = (phone[0] == "(" and phone[4] == ")" and phone[8] == "-")
print(valid)
1. Functions as Black Boxes
Definition: A function is a named sequence of instructions.
Example: round() rounds a number to a specified number of decimal places.
Key idea: You don’t need to know how a function works internally; just how to use it.
Black box analogy:
A thermostat controls temperature without revealing how it works internally. Similarly, functions take inputs
and give outputs.
2. Calling Functions
price = round(6.8275, 2) # price = 6.83
Call: Executes the function’s instructions.
Arguments: Values passed to a function (6.8275 and 2 here).
Return value: Output produced by the function (6.83).
Execution flow: After returning a value, the program continues where it left off.
3. Function Arguments
Functions may take multiple arguments or none.
Arguments can be:
o Variables
o Literal values (e.g., 2, 3.14, 'hello')
Formal parameters are variables in the function definition that receive the argument values.
4. Return Values
Functions return one value using return.
To return multiple values, use a tuple: return (x, y).
Functions can also return nothing: return or omit return completely.
Ensure all code paths return a value to avoid None.
def cubeVolume(sideLength):
if sideLength < 0:
return 0
return sideLength ** 3
5. Implementing Functions
Steps:
1. Describe what the function does.
2. Determine inputs (parameters) and output.
3. Write pseudocode.
4. Implement in Python:
def cubeVolume(sideLength):
volume = sideLength ** 3
return volume
5. Test the function:
print(cubeVolume(2)) # 8
print(cubeVolume(10)) # 1000
6. The main Function
Recommended to define a starting function main() in Python.
Ensure the program runs only when executed directly:
def main():
result = cubeVolume(2)
print(result)
if __name__ == '__main__':
main()
__name__ is a “dunder” variable (__name__) that helps control execution.
7. Function Order
Define functions before calling them, or call them from within other functions.
Example:
def main():
result = cubeVolume(2)
print(result)
def cubeVolume(sideLength):
return sideLength ** 3
main()
8. Parameter Passing
Arguments → values passed by the caller.
Parameters → variables in the function definition that receive the values.
Only a copy of the argument is passed; modifying it inside the function does not affect the original
variable.
def addTax(price, rate):
tax = price * rate / 100
price = price + tax # Does NOT change original variable
return tax
Tip: Use a separate variable instead of modifying parameters.
9. Functions Without Return Values
Functions can print or perform actions without returning a value.
def boxString(contents):
n = len(contents)
print("-" * (n + 2))
print("!" + contents + "!")
print("-" * (n + 2))
Use return alone to exit early:
if n == 0:
return
10. Reusable Functions
Identify repetitive code and generalize it using parameters:
def readIntUpTo(high):
value = int(input(f"Enter a value between 0 and {high}: "))
while value < 0 or value > high:
print("Error: value out of range.")
value = int(input(f"Enter a value between 0 and {high}: "))
return value
11. Variable Scope
Local variables: Defined inside a function; not visible outside.
Global variables: Defined outside functions; visible everywhere.
Tip: Avoid global variables; use parameters and return values.
balance = 10000 # global
def withdraw(amount):
global balance
if balance >= amount:
balance -= amount
12. Stepwise Refinement
Break complex problems into simpler subtasks.
Example: Convert a number into English words:
o Hundreds → Tens → Teens → Ones
o Subtasks: digitName(), tensName(), teenName()
o Combine in intName(number)
Pseudocode for number conversion:
if part >= 100:
name = hundredsName(part) + " hundred"
if part >= 20:
name += tensName(part)
elif part >= 10:
name += teenName(part)
if part > 0:
name += digitName(part)
13. Programming Tips
Keep functions short; use sub-functions.
Comment functions for clarity:
## Computes the volume of a cube
# @param sideLength: length of a side
# @return: cube volume
def cubeVolume(sideLength):
return sideLength ** 3
Use stubs for incomplete functions during development.
What is a List?
A list is a versatile, dynamic data structure in Python.
Stores a variable number of elements of any type.
Elements are accessed by position (index).
Equivalent to structures in other languages: List, Sequence, Array, Vector.
Basic Properties of Lists
Lists are mutable: elements can be modified, added, or removed.
Lists can store elements of any type (integers, floats, strings, mixed).
Indexing starts at 0.
Out-of-range access triggers a runtime IndexError.
Creating a List
values = [32, 54, 67.5, 29, 35, 80, 115, 44.5, 100, 65]
Accessing and Modifying Elements
print(values[5]) # Access
values[5] = 87 # Modify
Negative indices access elements from the end:
values[-1] # Last element
values[-2] # Second to last
Lists vs. Strings
Both are sequences.
Differences:
o Lists: mutable, any type.
o Strings: immutable, characters only.
Common List Operations
Adding Elements
friends = []
[Link]("Harry")
[Link](1, "Cindy") # Insert at specific index
Removing Elements
[Link](1) # Remove by index
[Link]("Cindy") # Remove by value
Searching
if "Cindy" in friends:
print("She's a friend")
index = [Link]("Emily") # First occurrence
Combining Lists
ourFriends = myFriends + yourFriends # Concatenation
repeated = [1, 2, 3] * 4 # Replication
Other Useful Operations
len(values) # List length
sum(values) # Sum of elements
max(values) # Maximum
min(values) # Minimum
[Link]() # Sort in place
prices = list(values) # Copy list
Slices
thirdQuarter = temperatures[6:9] # Elements 6,7,8
firstHalf = temperatures[:6] # Up to 5
secondHalf = temperatures[6:] # From 6 to end
temperatures[6:9] = [45, 44, 40] # Replace slice
Loops with Lists
Using indices
for i in range(len(values)):
print(i, values[i])
Direct iteration
for element in values:
print(element)
Lists and Functions
Lists can be arguments to functions.
Functions can modify the original list (call by reference) or just read values.
def multiply(values, factor):
for i in range(len(values)):
values[i] *= factor
def squares(n):
result = []
for i in range(n):
[Link](i*i)
return result
Returning Multiple Values
Use tuples for multiple return values:
def readDate():
month = int(input("month: "))
day = int(input("day: "))
year = int(input("year: "))
return (month, day, year)
(month, day, year) = readDate()
Tuples
Immutable lists.
triple = (5, 10, 15)
Tables (2D Lists)
Lists of lists.
counts = [
[0, 3, 0],
[0, 0, 1],
[1, 0, 0]
Create large tables dynamically:
ROWS, COLUMNS = 5, 20
table = []
for i in range(ROWS):
[Link]([0] * COLUMNS)
Access with two indices: table[i][j]
Use nested loops to traverse:
for i in range(len(table)):
for j in range(len(table[0])):
print(table[i][j], end=" ")
print()
1. Text Files
Commonly used for storing information; highly portable.
Examples:
o Plain text files (Notepad)
o Python source code
o HTML files
o CSV files
2. Opening Files
2.1 Reading
infile = open("[Link]", "r")
"r" opens the file for reading.
File must exist; otherwise, an exception occurs.
Operations are performed through the file object.
2.2 Writing
outfile = open("[Link]", "w")
"w" opens for writing; existing file is emptied.
New file is created if it doesn’t exist.
2.3 Closing Files
[Link]()
[Link]()
Always close files to ensure data is saved.
3. File Modes
Mode Purpose
"r" Read
"w" Write
"a" Append
"r+" Read and Write
4. Reading from a File
4.1 Read a Line
line = [Link]()
Returns a string including the newline character \n.
Reaching EOF returns "".
Blank lines return "\n".
4.2 Read Multiple Lines
line = [Link]()
while line != "":
# process line
line = [Link]()
4.3 Convert Input
value = float(line) # Convert string to numeric
5. Writing to a File
[Link]("Hello, World!\n")
[Link](f"Number of entries: {count}\nTotal: {total:8.2f}\n")
Must explicitly write \n for new lines.
Supports formatted strings.
6. Reading Words
for line in infile:
line = [Link]()
wordList = [Link]()
for word in wordList:
word = [Link](".,?!")
print(word)
split() separates words by whitespace.
rstrip() removes trailing characters like punctuation or newline.
7. Reading Characters
char = [Link](1)
while char != "":
# process character
char = [Link](1)
8. Reading Records
8.1 One record per line
Example:
China:1330044605
India:1147995898
Use split(":") to separate fields.
8.2 Multi-line records
Example (2 lines per record):
China
1330044605
line = [Link]()
while line != "":
country = [Link]()
line = [Link]()
population = int(line)
# process record
line = [Link]()
8.3 Whole file as string
contents = [Link]()
8.4 Whole file as list
lines = [Link]()
9. Exception Handling
9.1 Raising Exceptions
if amount > balance:
raise ValueError("Amount exceeds balance")
9.2 Try-Except
try:
infile = open(filename, "r")
value = int([Link]())
except IOError:
print("File not found.")
except ValueError as e:
print("Error:", str(e))
9.3 Finally
Ensures cleanup actions are always executed:
outfile = open(filename, "w")
try:
writeData(outfile)
finally:
[Link]()
10. Best Practices
Throw exceptions early: when a method can’t handle a problem.
Catch exceptions late: only when the handler can fix it.
Use nested try blocks instead of combining except and finally in the same block.
11. File Reading Application Example
Goal: read a file with:
o First line = count of values
o Remaining lines = values
Risks: file missing, wrong format, extra values.
11.1 Outline
done = False
while not done:
try:
data = readFile(filename)
done = True
except IOError:
print("File not found.")
except ValueError:
print("File contents invalid.")
except RuntimeError as e:
print("Error:", str(e))
11.2 readFile
def readFile(filename):
inFile = open(filename, "r")
try:
return readData(inFile)
finally:
[Link]()
11.3 readData
def readData(inFile):
line = [Link]()
numberOfValues = int(line)
data = []
for i in range(numberOfValues):
line = [Link]()
value = int(line)
[Link](value)
if [Link]() != "":
raise RuntimeError("End of file expected.")
return data
1. Sets
Definition
A set is a collection of unique values.
Elements are unordered and cannot be accessed by index.
Set operations correspond to mathematical set operations.
Sets are faster than lists for operations like membership testing.
Creating Sets
# Using braces
uk_flag = {'blue', 'red', 'white'}
# Using set() to convert a sequence
names = ["Luigi", "Gumbys", "Spiny"]
cast = set(names)
Empty Set
cast = set() # cannot use {}
len(cast) # returns 0
Membership
if "Luigi" in cast:
print("Luigi is in the cast")
Accessing Elements
Sets are unordered → cannot access by index.
Use for loops:
for character in cast:
print(character)
Sorted display:
for actor in sorted(cast):
print(actor)
Adding and Removing Elements
[Link]("Arthur") # add
[Link]("Arthur") # remove if exists
[Link]("Arthur") # remove, raises exception if not exists
[Link]() # removes all
Subsets and Equality
canadian = {"Red", "White"}
british = {"Red", "White", "Blue"}
italian = {"Red", "White", "Green"}
[Link](british) # True
[Link](british) # False
british == {"Red", "White", "Blue"} # True
Set Operations
# Union
[Link](italian) # {'Red', 'White', 'Blue', 'Green'}
# Intersection
[Link](italian) # {'Red', 'White'}
# Difference
[Link](british) # {'Green'}
# Short operators
x1 | x2 # union
x1 & x2 # intersection
x1 - x2 # difference
x1 ^ x2 # symmetric difference
x1 <= x2 # subset
Tip: Sets are more efficient than lists for managing unique items.
2. Dictionaries
Definition
A dictionary stores key-value pairs.
Keys are unique, values can be repeated.
Access values using keys; dictionaries are unordered.
contacts = { "Fred": 7235591, "Mary": 3841212 }
Creating / Duplicating
contacts = dict() # empty
oldContacts = dict(contacts)
Accessing and Membership
contacts["Fred"] # 7235591
if "John" in contacts:
print(contacts["John"])
Default Values
[Link]("Tony", "missing") # returns "missing" if key not found
Adding / Modifying Items
contacts["John"] = 4578102 # add
contacts["John"] = 2228102 # modify
Removing Items
[Link]("Fred") # remove and return value
Traversing
for key in contacts: # by keys
print(key, contacts[key])
for key, val in [Link](): # more efficient
print(key, val)
for key in sorted(contacts): # sorted order
print(key, contacts[key])
Data Records
Store structured data using dictionaries:
person = {
"firstName": "John",
"lastName": "Doe",
"birthdate": 1971,
"city": "New York",
"profession": "Student"
people = [person1, person2, ...]
Example function to read records from a file:
def extractRecord(infile):
record = {}
line = [Link]()
if line != "":
fields = [Link](":")
record["country"] = fields[0]
record["population"] = int(fields[1])
return record
3. Complex Data Structures
Containers of containers allow more complex data storage.
Example: Dictionary of Sets
o Build a book index with terms as keys and sets of page numbers as values.
index = {
"example": {7, 10},
"index": {7},
"program": {7, 11}
Example: Dictionary of Lists
o Store yearly sales of ice cream flavors by store.
sales = {
"vanilla": [8580.0, 7201.25, 8900.0],
"chocolate": [10225.25, 9025.0, 9505.0]
Key idea: Use dictionaries as the primary container and sets/lists as the values to organize complex data
efficiently.