Python Basicsยถ
Revised June 2026
Python is an open-source, high-level programming language that is widely considered one of the best first languages to learn. It supports multiple programming paradigms โ including procedural, functional, and object-oriented programming (OOP) โ and is backed by an enormous standard library and community. As of 2024, it is one of the most in-demand languages in the job market, used in web development, data science, artificial intelligence, IoT, and cybersecurity.
This course is designed to prepare you for:
๐ฏ AP Computer Science Principles (AP CSP) โ College Board performance task and exam
๐ PCEPโข โ Certified Entry-Level Python Programmer (Exam PCEP-30-02, OpenEDG Python Institute)
How to use this document: Topics are organized to build skills progressively. PCEP exam objectives are labeled
๐ PCEPand AP CSP standards are labeled๐ AP CSP. Activities and projects are marked with###.
๐ Python Pacing Guideยถ
Aug 17 โ Dec 18, 2026
Week |
Dates |
Content Focus |
Notebook Spread |
Activities / Projects |
PT / CPT In-Class Time |
Weekly Min |
|---|---|---|---|---|---|---|
1 |
Aug 17โ21 |
How Python Works; Style; Debugging; Variables & Data Types |
Spreads 1 & 2 |
โ |
โ |
216 |
2 |
Aug 24โ28 |
Variables (cont.); Operators; Numeral Systems |
Spread 3 |
Movie Ticket Eligibility Checker |
โ |
216 |
3 |
Aug 31โSep 4 |
Print Statements & Input/Output |
Spread 4 |
Hello, World! Variations |
โ |
216 |
4 |
Sep 7โ11 |
Conditional Statements |
Spread 5 |
Grade Calculator |
โ |
216 |
5 |
Sep 14โ18 |
Loops |
Spread 6 |
Nested Loop Pattern Design Studio |
โ |
216 |
6 |
Sep 21โ25 |
Strings |
Spread 7 |
Receipt Formatter |
โ |
216 |
7 |
Sep 28โOct 2 |
Lists |
Spread 8 |
โ |
โ |
216 |
8 |
Oct 5โ9 |
Tuples & Dictionaries; Practice PT 1 Introduced |
Spread 9 |
Student Contact Book |
40 min (Fri) Practice |
216 |
9 |
Oct 12โ16 |
Functions; Practice PT 1 in-class work |
Spread 10 |
Math Operations Calculator; Recursion Practice โ Three Levels |
176 min (2ร88) Practice |
216 |
10 |
Oct 19โ23 |
Functions (cont.); Modules and Packages; Practice PT 1 in-class work |
โ |
Project: Random Trivia Quiz Generator |
176 min (2ร88) Practice |
216 |
11 |
Oct 26โ30 |
Exception Handling; Practice PT 1 Due (Fri) |
Spread 11 |
Safe Calculator |
88 min (1ร88) Practice |
216 |
12 |
Nov 2โ6 |
Data Structures Deep Dive; Practice PT 2 Introduced |
Spread 12 |
โ |
176 min (2ร88) Practice |
216 |
13 |
Nov 9โ13 |
OOP |
Spread 13 |
OOP Zoo (3 options) |
128 min (88+40) Practice |
216 |
14 |
Nov 16โ20 |
PCEP Exam Prep; Certification Review (Mon/Wed); Practice PT 2 Due (Fri) |
โ |
โ |
40 min (Fri) Practice |
216 |
15 |
Nov 23โ27 |
THANKSGIVING โ No School |
โ |
โ |
โ |
โ |
16 |
Nov 30โDec 4 |
AP CSP CPT โ Brainstorming Workshop |
Spread 15 |
CPT Brainstorming: students develop an original program idea |
216 min Official CPT |
216 |
17 |
Dec 7โ11 |
AP CSP CPT โ Writing Code, Recording Video, Developing PPR Responses |
โ |
Official CPT Program (original idea, in progress) |
216 min Official CPT |
216 |
18 |
Dec 14โ18 |
AP CSP CPT โ Final Coding/Submission; CPT Due (Fri, Dec 18); End-of-Course Reflection |
Spread 16 |
Official CPT Program (original idea, due) |
216 min Official CPT |
216 |
Practice PT 1 & 2 are formative โ students write a full program to an actual College Boardโstyle CPT prompt so theyโve rehearsed the task before the real one, but this time is not counted toward the AP CPTโs official minimum. Practice PT 1 total โ 480 min (Weeks 8โ11). Practice PT 2 total โ 344 min (Weeks 12โ14).
Per AP College Board CPT requirements, the official CPT must be an original student idea. Students may not submit Practice PT 1, Practice PT 2, or any other program theyโve already completed as their CPT โ the program developed during Weeks 16โ18 must be new. The Final Project Options (A/B/C) in the curriculum may still be offered as optional starting frameworks/scaffolds, but each studentโs actual CPT submission โ the idea, the implementation, and the individual creative work behind it โ must be their own original work developed within the official CPT window.
Official AP CSP CPT (the actual, submitted Create Performance Task) happens entirely in December: Week 16 = brainstorming/planning an original idea, Week 17 = coding + video + PPR written responses, Week 18 = final coding, submission (due Fri, Dec 18), and course wrap-up โ all three are full 5-day weeks. Total Official CPT Time: 216 + 216 + 216 = 648 min (โ10.8 hrs) โ clears the 9-hour College Board minimum with room to spare, entirely within December, even after setting aside time on the last day for End-of-Course Reflection.
Python Style Guidelinesยถ
๐ Click to expand PEP 8 Guidelines
PEP 8 Guidelines is the official style guide for Python code. Following these standards is required on all assignments and is tested on the PCEP exam.
๐ PCEP 1.2 โ Pythonโs logic and structure; indentation; PEP-8 recommendations
๐ PCEP 1.3 โ Naming conventions; implementing PEP-8
All Projects and Assignments Must Include a Header Block:
# Assignment: Program [number]: [Assignment Title]
#
# Author: [Your Name]
# Partner: [Partner's Name]
#
# Course Name: [Course Name]
# Instructor: [Instructor Name]
# Due Date: [Due Date and Time]
#
# Description: [Describe the program's goal, IN DETAIL.]
#
# Language: Python 3.x
# Ex. Packages: [List any external packages used]
#
# Deficiencies: [Known problems, or state there are none.]
1. Use Descriptive Variable and Function Names
Guideline: Use
snake_casenames that clearly describe their purpose.Example:
# Good total_cost = price * quantity # Bad x = p * q
2. Use Consistent Indentation (4 Spaces)
Guideline: Use four spaces per indentation level; do not use tabs.
Example:
def calculate_area(radius): return 3.14 * radius ** 2
3. Limit Line Length to 79 Characters
Improves readability on all devices and screen sizes.
4. Use Blank Lines to Separate Code Sections
Two blank lines between top-level functions/classes; one blank line between class methods.
5. Use Docstrings to Document Functions and Classes
Example:
def calculate_area(radius): """Calculate the area of a circle given its radius.""" return 3.14 * radius ** 2
6. Use Spaces Around Operators
result = (a + b) * (c - d) # Good
result=(a+b)*(c-d) # Bad
7. Avoid Excessive Nesting โ break complex logic into smaller functions.
8. Use List Comprehensions for Simple Operations
squares = [x ** 2 for x in range(10)] # Good
9. Handle Exceptions Properly โ use specific exception types, never bare except.
10. Use Meaningful Constants Instead of Magic Numbers
TAX_RATE = 0.15
total_cost = price * (1 + TAX_RATE)
11. Avoid Global Variables โ use function parameters or class attributes.
12. Use is for Comparison to None
if value is None: # Good
if value == None: # Bad
13. Organize Imports Properly โ standard library โ third-party โ local modules.
14. Use Type Annotations (Python 3.5+)
def calculate_total(cost: float, tax_rate: float) -> float:
return cost * (1 + tax_rate)
Debugging Strategiesยถ
๐ AP CSP: CRD-2.J โ Identify and correct errors in algorithms and programs.
Types of Errors
Error Type |
Description |
Example |
|---|---|---|
Syntax Error |
Code violates Python grammar rules |
Missing |
Runtime Error |
Code crashes while running |
Dividing by zero |
Logic Error |
Code runs but gives wrong output |
Using |
Debugging Strategies
Read the Error Message Carefully โ find the exact line number, identify the error type.
Trace the Program Step-by-Step โ walk through code line by line; track variable values.
Use Print Statements โ insert
print("Value of score:", score)to expose variable state.Test with Simple Inputs โ start with values where you know the expected output.
Isolate the Problem โ comment out sections; test smaller pieces individually.
Check Variables and Data Types โ confirm types with
type().Review Logic and Conditions โ check
if, loop conditions, and operator use carefully.Rubber Duck Debugging โ explain the code out loud step-by-step; mistakes often surface.
Use Incremental Development โ write and test small pieces before adding features.
Take a Break and Revisit โ fresh eyes catch simple mistakes.
Ask for Help with Evidence โ be ready to explain: what it should do, what it does, what you tried.
Student Debugging Checklistยถ
Before asking for help, confirm:
โ Read the error message carefully
โ Checked the exact line number and nearby code
โ Added print/debug statements to trace variables
โ Tested with simple, predictable inputs
โ Traced variable values step-by-step
โ Explained the code out loud (Rubber Duck Method)
Section 1 โ Computer Programming and Python Fundamentalsยถ
๐ PCEP Section 1 โ 18% of exam (7 items)
๐ AP CSP: CRD-2.A, CRD-2.B
How Python Worksยถ
๐ PCEP 1.1 โ Understand fundamental terms and definitions
Python is an interpreted language. Instead of being compiled into machine code before running, a Python interpreter reads and executes your source code line-by-line at runtime.
Concept |
Definition |
|---|---|
Source code |
The human-readable Python instructions you write |
Interpreter |
The program that reads and runs your Python code |
Compiler |
Translates entire source code to machine code before running (e.g., C, Java) |
Lexis |
The vocabulary of the language โ valid words/tokens Python recognizes |
Syntax |
The grammar rules for how code must be structured |
Semantics |
The meaning of correctly written code |
A SyntaxError means Python cannot understand your code structure. A logic error means Python understands it but does something you didnโt intend.
Python Keywords and Structureยถ
๐ PCEP 1.2 โ Understand Pythonโs logic and structure
Keywords are reserved words that Python uses for specific purposes. You cannot use them as variable names.
False None True and as assert
async await break class continue def
del elif else except finally for
from global if import in is
lambda nonlocal not or pass raise
return try while with yield
Indentation is not optional in Python โ it defines code blocks. Incorrect indentation causes a IndentationError.
# Correct indentation
if True:
print("Indented correctly") # 4 spaces
# Wrong
if True:
print("This will crash") # IndentationError
Comments are notes for humans; Python ignores them:
# This is a single-line comment
A docstring is a special string placed as the very first line inside a function, class, or module to document what it does. Unlike a # comment, Python actually stores a docstring as part of the object โ it can be viewed later with help() or .__doc__.
def area_of_rectangle(length, width):
"""Calculate and return the area of a rectangle."""
return length * width
print(area_of_rectangle.__doc__) # Calculate and return the area of a rectangle.
|
|
|
|---|---|---|
Purpose |
Note for a human reading the code |
Documentation for someone using the function |
Location |
Anywhere |
Must be the first line inside a function/class/module |
Stored by Python? |
No โ ignored by the interpreter |
Yes โ accessible via |
Rule of thumb: a comment explains a line to a fellow programmer; a docstring is the instruction manual for someone who will never open the functionโs source code.
Variables and Data Typesยถ
๐ PCEP 1.3 โ Introduce literals and variables; numeral systems
๐ AP CSP: DAT-1.A โ Explain how data can be represented using bits.
A variable is a named location in memory that stores a value. Python uses dynamic typing โ the data type is inferred from the assigned value, not declared in advance.
age = 25 # int
name = "Alice" # str
price = 9.99 # float
is_student = True # bool
result = None # NoneType
Core Data Types
Type |
Keyword |
Example |
PCEP Focus |
|---|---|---|---|
Integer |
|
|
โ |
Float |
|
|
โ |
String |
|
|
โ |
Boolean |
|
|
โ |
None |
|
|
โ |
List |
|
|
โ |
Tuple |
|
|
โ |
Dictionary |
|
|
โ |
Numeral Systems โ ๐ PCEP 1.3
Python supports writing integer literals in multiple bases:
decimal = 255 # base 10
binary = 0b11111111 # base 2 โ 255
octal = 0o377 # base 8 โ 255
hexadecimal = 0xFF # base 16 โ 255
print(binary, octal, hexadecimal) # All print: 255 255 255
Scientific Notation
Python lets you write very large or very small numbers using e notation, where e means โtimes 10 to the power of.โ This is the same idea as scientific notation in math class (1.5 ร 10โถ), just written on one line without exponents or superscripts.
1.5e6means1.5 ร 10^6โ move the decimal point 6 places right โ1,500,000.02.5e-4means2.5 ร 10^-4โ move the decimal point 4 places left โ0.00025
big_num = 1.5e6 # 1,500,000.0
tiny_num = 2.5e-4 # 0.00025
Both
big_numandtiny_numare stored asfloattype โenotation is just a display/input shortcut, not a separate data type.
Type Casting โ converting between data types:
x = int("42") # str โ int
y = float(7) # int โ float
z = str(3.14) # float โ str
b = bool(0) # int โ bool (0 = False, anything else = True)
Floating-point accuracy:
0.1 + 0.2does not equal exactly0.3in Python due to how floats are stored in binary. This is a known limitation tested on the PCEP exam.
print(0.1 + 0.2) # 0.30000000000000004
print(round(0.1 + 0.2, 2)) # 0.3
Operatorsยถ
๐ PCEP 1.4 โ Choose operators and data types adequate to the problem
๐ AP CSP: AAP-2.F โ Use mathematical operations in algorithms.
Arithmetic Operators
Operator |
Meaning |
Example |
Result |
|---|---|---|---|
|
Exponentiation |
|
|
|
Multiplication |
|
|
|
Division (always float) |
|
|
|
Floor division |
|
|
|
Modulo (remainder) |
|
|
|
Addition |
|
|
|
Subtraction |
|
|
String Operators
"Hello" + " World" # Concatenation โ "Hello World"
"Ha" * 3 # Repetition โ "HaHaHa"
Assignment and Shortcut Operators
x = 10
x += 5 # x = x + 5 โ 15
x -= 3 # x = x - 3 โ 12
x *= 2 # x = x * 2 โ 24
x //= 4 # x = x // 4 โ 6
x **= 2 # x = x ** 2 โ 36
Operator Precedence (Highest โ Lowest)
Level |
Category |
Operators |
|---|---|---|
7 (high) |
Exponent |
|
6 |
Multiplication |
|
5 |
Addition |
|
4 |
Relational |
|
3 |
Logical |
|
2 |
Logical |
|
1 (low) |
Logical |
|
Parentheses
()always override precedence โ use them to make code intentions clear.
Relational Operators โ return True or False
Operator |
Meaning |
Example |
|---|---|---|
|
Equal to |
|
|
Not equal |
|
|
Greater than |
|
|
Less than |
|
|
Greater or equal |
|
|
Less or equal |
|
== vs. is โ ๐ PCEP 1.4 ๐ AP CSP: AAP-2.F
== and is are not interchangeable, even though both can return True/False in a comparison.
Operator |
Checks |
Question it answers |
|---|---|---|
|
Equality of value |
โDo these contain the same data?โ |
|
Identity of object |
โAre these the exact same object in memory?โ |
a = [1, 2]
b = [1, 2]
c = a
print(a == b) # True โ same values
print(a is b) # False โ two different list objects
print(a is c) # True โ c points to the same object as a
PCEP Exam Trap: Use
is/is notonly for identity checks โ most importantlyx is None(the Python standard, preferred overx == None). Use==for comparing values (numbers, strings, list contents, etc.). Small integers and short strings may sometimes evaluateisasTruedue to CPythonโs internal caching โ this is an implementation detail, not something to rely on in your own code.
Boolean / Logical Operators
True and False # False โ both must be True
True or False # True โ at least one must be True
not True # False โ reverses the boolean
Compound Boolean Expressions (expand)
age = 20
has_license = True
# AND: both must be True
is_eligible = age >= 18 and has_license # True
# OR: at least one must be True
can_enter = age >= 18 or has_vip_pass # True
# NOT: reverses the boolean
is_minor = not (age >= 18) # False
# Complex example
gets_discount = (age > 25 or is_eligible) and not has_discount_coupon
Activity: Movie Ticket Eligibility Checkerยถ
Write a program that determines whether a person can buy a discounted movie ticket, using only compound boolean expressions (and, or, not) โ no if/elif chains yet.
Requirements:
Ask the user for their age and whether they have a student ID (
yes/no).A ticket is discounted if the person is under 13, OR over 65, OR (between 13โ25 AND has a student ID).
Store the result of that full condition in a single boolean variable, e.g.
gets_discount = ..., then print"Discount applies!"or"Full price."based on its value.Add a second check: the theater is closed to anyone under 6 with no adult present โ ask a follow-up question and use
notto write the condition for โan adult is NOT present.โPrint a trace of your boolean logic as a comment above each condition, explaining what it evaluates in plain English (this mirrors how youโll need to explain conditions in your AP CSP written responses).
PCEP: 1.4 | AP CSP: AAP-2.F
Why Bitwise Operators Matter
Bitwise operators work directly on the binary representation of numbers โ the individual 0s and 1s โ rather than on the numberโs value as a whole. Most everyday Python code never needs them, but they matter for a few reasons worth knowing:
Theyโre on the PCEP exam โ youโre expected to trace what
&,|,^,~,<<, and>>do to binary values.They connect back to how computers actually store data โ ties directly to the binary/decimal/hex conversions you just learned.
They show up in real systems programming: setting individual permission flags (read/write/execute), working with network protocols, compressing data, and low-level graphics/hardware code all lean on bitwise operations because theyโre extremely fast and memory-efficient.
Shifts are a fast way to multiply/divide by powers of 2:
a << 1doubles a number,a >> 1halves it (integer division) โ a trick youโll sometimes see in performance-sensitive code.
You wonโt use these daily as a beginner, but recognizing them โ and knowing they operate on bits, not on the numberโs โeverydayโ value โ will keep you from being caught off guard by & (bitwise AND) when you meant and (logical AND), which is a common bug even experienced programmers make.
Bitwise Operators โ ๐ PCEP 1.4
a = 0b1010 # 10
b = 0b1100 # 12
print(a & b) # AND โ 8 (0b1000)
print(a | b) # OR โ 14 (0b1110)
print(a ^ b) # XOR โ 6 (0b0110)
print(~a) # NOT โ -11
print(a << 1) # Left shift โ 20
print(a >> 1) # Right shift โ 5
Print Statements and Input/Outputยถ
๐ PCEP 1.5 โ Perform Input/Output console operations
๐ AP CSP: CRD-2.B โ Implement algorithms in a programming language.
# 1. Basic print
print("Hello, World!")
# 2. f-strings (most readable โ preferred method)
name = "Alice"
age = 25
print(f"My name is {name} and I am {age} years old.")
# 3. format() method
print("My name is {} and I am {} years old.".format(name, age))
# 4. Concatenation (must convert non-strings)
print("Name: " + name + ", Age: " + str(age))
# 5. sep= and end= keyword parameters
print("A", "B", "C", sep="-") # A-B-C
print("Hello", end="! ")
print("World") # Hello! World
User Input
name = input("Enter your name: ") # always returns a string
age = int(input("Enter your age: ")) # convert to int
price = float(input("Enter price: ")) # convert to float
PCEP Exam Tip:
input()always returns astr. You must useint()orfloat()to convert it for math operations.
Activity: Hello, World! Variationsยถ
Write a program that asks the user for their name, age, and favorite color. Print a formatted sentence using each of the three print methods (f-string, format(), concatenation). Include a header block.
AP CSP: CRD-2.B | PCEP: 1.5
Section 2 โ Control Flow: Conditional Blocks and Loopsยถ
๐ PCEP Section 2 โ 29% of exam (8 items)
๐ AP CSP: AAP-2.E โ Develop algorithms using sequencing, selection, and iteration.
Conditional Statementsยถ
Control flow determines which code runs, when, and how often. Conditionals let the program make decisions.
# if
if condition:
# runs if True
# if-else
if condition:
# runs if True
else:
# runs if False
# if-elif-else
if condition1:
# ...
elif condition2:
# ...
else:
# fallback
Example: Grade Calculator
score = int(input("Enter your score: "))
if score >= 90:
print("A")
elif score >= 80:
print("B")
elif score >= 70:
print("C")
elif score >= 60:
print("D")
else:
print("F")
Nested Conditionals
if score >= 70:
if score >= 90:
print("A or A+")
else:
print("Pass")
else:
print("Fail")
๐ก Prefer
elifover deep nesting when possible โ it keeps code readable.
Activity: Grade Calculatorยถ
Write a grade calculator that accepts a numerical score and outputs:
The letter grade (AโF)
Whether the student passed or failed
A motivational message for scores below 70
Use if-elif-else and at least one nested conditional.
AP CSP: AAP-2.E | PCEP: 2.1
Loopsยถ
๐ PCEP 2.2 โ Perform different types of iterations
๐ AP CSP: AAP-2.E โ Iteration; AAP-2.K โ For loops
for Loop โ iterates over a sequence
for fruit in ["apple", "banana", "cherry"]:
print(fruit)
for i in range(5): # 0, 1, 2, 3, 4
print(i)
for i in range(1, 6, 2): # 1, 3, 5
print(i)
while Loop โ repeats while a condition is True
count = 0
while count < 5:
print(count)
count += 1
Loop Control Keywords
Keyword |
Purpose |
Example |
|---|---|---|
|
Exit loop immediately |
|
|
Skip to next iteration |
|
|
Placeholder โ does nothing |
|
|
Runs if loop ends without |
|
while-else and for-else โ ๐ PCEP 2.2
for i in range(5):
if i == 10:
break
else:
print("Loop completed without break") # This runs
Nested Loops
for i in range(1, 4):
for j in range(1, 4):
print(i * j, end="\t")
print()
Activity: Nested Loop Pattern Design Studioยถ
A single loop can only move in one direction. The moment a shape has both rows and columns โ a triangle, a diamond, a hollow box โ you need a loop inside a loop. The outer loop picks the row; the inner loop decides what happens across that row.
Warm-up โ reading a pattern like a programmer. Before writing code, answer these for the pattern below:
How many rows are there?
Row by row, what changes? (number of characters, starting character, spacing)
Is there a pattern to the pattern? (e.g., โrow
iprintsistarsโ)Is it solid (every position filled) or hollow (only a border filled)?
*
* *
* * *
* * * *
* * * * *
Guided example โ hollow rectangle:
rows = int(input("Enter the number of rows: "))
cols = int(input("Enter the number of columns: "))
for i in range(1, rows + 1):
for j in range(1, cols + 1):
if i == 1 or i == rows or j == 1 or j == cols:
print("*", end="")
else:
print(" ", end="")
print()
Discussion: What single condition controls whether the shape is solid or hollow? (The if/else inside the inner loop โ remove it and the shape becomes solid.)
The Studio Project โ Design Your Own
Design and code 4 original patterns. โOriginalโ means not shown in class, not copied from a classmate. For each pattern, choose one option from each category below (no repeating the exact same combination twice):
Category |
Options |
|---|---|
Fill type |
Solid / Hollow |
Content |
ASCII character (your choice) / Sequential numbers / Repeating digit tied to row number |
Orientation |
Grows then stays / Grows then shrinks (diamond/hourglass) / Right-aligned / Shifts diagonally (parallelogram) |
Input |
At least one of your 4 patterns must accept user input for size |
Suggested difficulty progression:
Tier 1 โ Solid, fixed growth (e.g., a solid right triangle)
Tier 2 โ Hollow (border-only conditional logic)
Tier 3 โ Numeric (a value that changes per row)
Tier 4 โ Your choice / mirrored or diagonal shape
Required process (before coding): sketch each pattern on grid paper, answer the four warm-up questions for your own design, and write pseudocode for the outer loop, inner loop, and the row-vs-column relationship โ then code it.
Deliverable: 4 working programs, each with its grid-paper sketch, pseudocode, final code, and one paragraph explaining what the outer loop controls vs. what the inner loop controls.
Rubric (8 pts per pattern, 32 pts total):
Criteria |
Points |
|---|---|
Sketch and pseudocode completed before code, and match the final output |
2 |
Pattern runs without errors and matches the intended design |
2 |
Nested loop logic is correct (not hard-coded repeated |
2 |
At least one pattern correctly uses user input to control size |
1 |
Written explanation correctly identifies the role of outer vs. inner loop |
1 |
AP CSP: AAP-2.E | PCEP: 2.2
Section 3 โ Data Collections: Lists, Tuples, Dictionaries, and Stringsยถ
๐ PCEP Section 3 โ 25% of exam (7 items)
๐ AP CSP: AAP-4.A โ Use data abstractions to manage complexity.
Stringsยถ
๐ PCEP 3.4 โ Operate with strings
๐ AP CSP: DAT-1.A
Strings are ordered, immutable sequences of characters.
greeting = "Hello, World!"
print(greeting[0]) # H (indexing)
print(greeting[-1]) # ! (negative index)
print(greeting[0:5]) # Hello (slicing)
print(greeting[::-1]) # !dlroW ,olleH (reverse)
print(len(greeting)) # 13
String Indexing Reference
string = | P | O | T | A | T | O |
pos_index: 0 1 2 3 4 5
neg_index: -6 -5 -4 -3 -2 -1
Escape Characters
print("She said \"Hello\"") # She said "Hello"
print("Line 1\nLine 2") # newline
print("Col1\tCol2") # tab
print("Backslash: \\") # \
Multi-line Strings
poem = """
Roses are red,
Violets are blue.
"""
Beginner String Methods
Method |
Description |
Example |
|---|---|---|
|
Lowercase |
|
|
Uppercase |
|
|
Remove whitespace |
|
|
Replace text |
|
|
Split into list |
|
|
Length |
|
|
Index of substring |
|
|
Count occurrences |
|
|
Starts with? |
|
|
Ends with? |
|
|
All letters? |
|
|
All digits? |
|
Activity: Receipt Formatterยถ
Write a program that formats a store receipt using string methods and escape characters.
Requirements:
Ask the user for a store name, an item name, and a price.
Use
.upper()to print the store name in all caps as a header.Use
.title()to properly capitalize the item name (e.g.,"blue notebook"โ"Blue Notebook").Use
\tto align the item name and price in two columns, and\nto add blank lines between sections.Use
\"to print a quoted โThank you for shopping with us!โ message at the bottom.Ask the user to re-enter the item name with extra spaces on purpose (e.g.,
" notebook "), then use.strip()to clean it before printing โ show the before and after to prove the method worked.Use
.replace()to apply a discount label โ replace"Price:"with"Sale Price:"in your printed line if the price is above $20.Bonus: use
.startswith()or.endswith()to check if the item name starts with a vowel, and print a fun fact if it does.
Sample interaction:
Enter store name: target
Enter item name: blue notebook
Enter price: 24.99
TARGET
Blue Notebook Sale Price: $24.99
"Thank you for shopping with us!"
PCEP: 3.4 | AP CSP: DAT-1.A
Listsยถ
๐ PCEP 3.1 โ Collect and process data using lists
๐ AP CSP: AAP-4.A โ Lists for data abstraction
A list is an ordered, mutable sequence. It is the most versatile data collection in Python.
fruits = ["apple", "banana", "cherry"]
print(fruits[0]) # apple
print(fruits[-1]) # cherry
print(fruits[1:3]) # ['banana', 'cherry']
Common List Methods
fruits.append("orange") # Add to end
fruits.insert(1, "blueberry") # Insert at index
fruits.remove("banana") # Remove by value
popped = fruits.pop() # Remove & return last item
fruits.sort() # Sort in place
fruits.reverse() # Reverse in place
print(fruits.index("apple")) # Find index
print(fruits.count("apple")) # Count occurrences
fruits2 = fruits.copy() # Clone the list
fruits.clear() # Remove all items
Iterating Through Lists
for item in fruits:
print(item)
for i, item in enumerate(fruits):
print(f"{i}: {item}")
in and not in Operators
print("apple" in fruits) # True
print("grape" not in fruits) # True
List Comprehensions
A list comprehension is a compact way to build a new list by looping over an existing sequence โ it packs a for loop (and optionally an if condition) into a single line. It always follows the same shape:
new_list = [expression for item in sequence if condition]
expressionโ what to do with each item before adding it to the new listfor item in sequenceโ the loop, exactly like a normalforloopif condition(optional) โ only include the item if this isTrue
The traditional loop version and the comprehension version produce the exact same result โ the comprehension is just shorter:
# Traditional loop
squares = []
for x in range(10):
squares.append(x ** 2)
# Equivalent list comprehension
squares = [x ** 2 for x in range(10)]
squares = [x ** 2 for x in range(10)]
evens = [x for x in range(20) if x % 2 == 0]
upper_words = [word.upper() for word in ["hi", "bye"]]
When to use which: list comprehensions are great for simple, one-line transformations. If your loop needs multiple steps,
print()statements along the way, or complex logic, a traditionalforloop is usually more readable โ donโt force a comprehension just because itโs shorter. Readability counts, per PEP 8.
Copying vs. Cloning
original = [1, 2, 3]
alias = original # NOT a copy โ both point to same list
clone = original.copy() # Independent copy
clone2 = original[:] # Also a copy (slicing)
2D Lists (Matrices)
grid = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
print(grid[1][2]) # 6 (row 1, col 2)
# Iterate a 2D list
for row in grid:
for val in row:
print(val, end=" ")
print()
Tuplesยถ
๐ PCEP 3.2 โ Collect and process data using tuples
A tuple is an ordered, immutable sequence โ values cannot be changed after creation.
coords = (40.7128, -74.0060) # GPS: New York City
rgb = (255, 128, 0)
single = (42,) # Note the comma for single-element tuple
print(coords[0]) # 40.7128
print(len(rgb)) # 3
Tuples vs. Lists
Feature |
List |
Tuple |
|---|---|---|
Ordered |
โ |
โ |
Indexed |
โ |
โ |
Mutable |
โ |
โ |
Duplicates |
โ |
โ |
Use when |
Data changes |
Data is fixed |
Lists inside Tuples and Tuples inside Lists
mixed = ([1, 2, 3], [4, 5, 6]) # tuple of lists
nested = [(1, "a"), (2, "b")] # list of tuples
Dictionariesยถ
๐ PCEP 3.3 โ Collect and process data using dictionaries
๐ AP CSP: AAP-3.B โ Use abstractions to organize data.
A dictionary stores key-value pairs. Keys must be unique and immutable. Dictionaries are ordered (Python 3.7+) and mutable.
student = {
"name": "Alice",
"age": 16,
"grade": "A"
}
print(student["name"]) # Alice
student["age"] = 17 # Update value
student["school"] = "CAMS" # Add new key
del student["grade"] # Remove key
Checking for Keys
if "name" in student:
print("Key exists!")
Dictionary Methods
student.keys() # dict_keys(['name', 'age', ...])
student.values() # dict_values(['Alice', 17, ...])
student.items() # dict_items([('name','Alice'), ...])
Iterating
for key, value in student.items():
print(f"{key}: {value}")
List of Dictionaries (real-world pattern)
students = [
{"name": "Alice", "age": 14},
{"name": "Bob", "age": 15},
{"name": "Charlie", "age": 14}
]
for s in students:
print(s["name"])
# Count students age 14
count = sum(1 for s in students if s["age"] == 14)
Activity: Student Contact Bookยถ
Build a program that stores a contact book as a list of dictionaries. Each contact has a name, phone number, and email. The user can:
Add a new contact
Search by name
Delete a contact
Display all contacts
Use a while loop for the menu and a for loop to search/display.
AP CSP: AAP-3.B, AAP-2.E | PCEP: 3.3
Section 4 โ Functions and Exceptionsยถ
๐ PCEP Section 4 โ 28% of exam (8 items)
๐ AP CSP: AAP-3.B โ Use procedures/functions to manage complexity.
Functions, Methods, and Proceduresยถ
๐ PCEP 4.1 โ Decompose the code using functions
๐ AP CSP: AAP-3.B โ Abstractions; CRD-2.G โ Call procedures.
Term |
Python Form |
Returns Value? |
Used For |
|---|---|---|---|
Function |
|
โ Yes |
Computing and returning a result |
Procedure |
|
โ No |
Side effects (printing, updating) |
Method |
Function inside a class |
โ /โ |
Behaviors belonging to an object |
# Function โ returns a value
def add(a, b):
return a + b
result = add(3, 5) # result = 8
# Procedure โ no return value
def greet(name):
print(f"Hello, {name}!")
greet("Alice") # Hello, Alice!
Parameters vs. Arguments
# 'a' and 'b' are PARAMETERS (in definition)
def multiply(a, b):
return a * b
# 5 and 3 are ARGUMENTS (passed at call)
multiply(5, 3)
Activity: Math Operations Calculatorยถ
Write a Python program called math_operations.py that performs addition, subtraction, multiplication, division, and modulo on two numbers entered by the user โ using a separate function for each operation.
Requirements:
Write five functions:
get_sum(num1, num2),get_difference(num1, num2),get_product(num1, num2),get_quotient(num1, num2), andget_modulo(num1, num2). Each function should perform one calculation andreturnthe result (noprint()inside the functions).In
main(), prompt the user for two numbers usinginput(), and convert them to the correct type (intfor whole numbers).Call each function, store the result in a variable, and print all five results using f-strings, formatted like:
Sum = 15 Difference = 5 Product = 50 Quotient = 2.00 Remainder = 0
get_quotient()should always return afloatโ usefloat()or a division with/(not//) to avoid integer division.Include a full program header block (Assignment, Author, Description, etc.) at the top, following the course style guide.
Stretch challenge: What happens if the user enters 0 as the second number for division or modulo? Add a try/except block (or an if check) so the program doesnโt crash โ print a friendly error message instead.
Teaching note: This activity mirrors a classic C-language exercise (functions returning
int/float, separate function per operation) โ a good one to point out explicitly if any students are also in a C/C++ or Java course, since the logic is identical even though the syntax (no semicolons, no type declarations, no#include) is different.
PCEP: 1.4, 1.5, 4.1 | AP CSP: AAP-2.F, AAP-3.B
Default Parameter Values โ ๐ PCEP 4.2
def greet(name, message="Hello"):
print(f"{message}, {name}!")
greet("Alice") # Hello, Alice!
greet("Bob", "Good morning") # Good morning, Bob!
Positional, Keyword, and Mixed Arguments
def describe(name, age, city):
print(f"{name}, {age}, from {city}")
describe("Alice", 16, "HB") # Positional
describe(age=16, name="Alice", city="HB") # Keyword
describe("Alice", city="HB", age=16) # Mixed
The return Keyword and None
def square(n):
return n ** 2
result = square(4) # result = 16
def do_nothing():
pass
print(do_nothing()) # None โ functions without return give None
Variable Scope and global โ ๐ PCEP 4.2
counter = 0 # global variable
def increment():
global counter # must declare to modify global
counter += 1
increment()
print(counter) # 1
Name Hiding (Shadowing): A local variable with the same name as a global hides (shadows) the global inside the function. This is a common PCEP exam trap.
x = 10
def show():
x = 99 # local x shadows global x
print(x)
show() # 99
print(x) # 10 โ global unchanged
Recursion โ ๐ PCEP 4.1
A recursive function calls itself. Every recursion needs a base case to stop.
def factorial(n):
if n == 0: # base case
return 1
return n * factorial(n - 1) # recursive case
print(factorial(5)) # 120
Call stack visualization:
factorial(5)
factorial(4)
factorial(3)
factorial(2)
factorial(1)
factorial(0) โ base case: returns 1
Activity: Recursion Practice โ Three Levelsยถ
Recursion clicks once you can identify two things in any recursive problem: the base case (when to stop) and the recursive case (how the problem gets smaller each call). Practice with three functions, in order:
Level 1 โ Countdown. Write countdown(n) that prints every number from n down to 1, then prints "Liftoff!" โ using recursion, not a loop. Identify: what is the base case? What gets smaller with each call?
Level 2 โ Sum of a list. Write list_sum(numbers) that returns the sum of all numbers in a list using recursion (hint: the base case is an empty list, which sums to 0; the recursive case is numbers[0] + list_sum(numbers[1:])).
Level 3 โ Power function. Write power(base, exponent) that calculates base ** exponent using recursion instead of the ** operator. (Base case: exponent == 0 returns 1.)
For each function, before coding, write on paper:
What is the base case, and what does it return?
What is the recursive case, and how does it move the problem toward the base case?
Trace through one full call by hand (like the
factorial(5)call stack above) and predict the output.
Stretch challenge: Add a print() inside each function showing the current callโs argument and indenting one extra level per recursive call โ this visually recreates the call stack diagram above, using your own code.
PCEP: 4.1
Modules and Packagesยถ
๐ AP CSP: AAP-2.G โ Use abstraction to manage complexity.
A module is a .py file containing reusable code. A package is a directory of related modules.
import math
import random
import datetime
print(math.sqrt(16)) # 4.0
print(random.randint(1, 10)) # random int 1โ10
print(datetime.date.today()) # today's date
Import Styles
import math # access as math.sqrt()
from math import sqrt # access as sqrt()
from math import sqrt, pi # import multiple
import numpy as np # alias
Common Standard Library Modules
Module |
Purpose |
Example |
|---|---|---|
|
Math functions |
|
|
Random numbers |
|
|
Date/time |
|
|
Operating system |
|
|
JSON data |
|
|
GUI windows |
|
Project: Random Trivia Quiz Generatorยถ
Build a trivia quiz program that pulls together modules, functions, lists, dictionaries, and string formatting โ everything youโve learned so far โ into one working project.
Requirements:
Use the
randommodule to randomly select and shuffle quiz questions each time the program runs.Use the
datetimemodule to timestamp the start and end of the quiz, and calculate/print how long the student took usingdatetime.datetime.now().Store at least 8 trivia questions as a list of dictionaries, each with keys like
"question","choices", and"answer".Write a function
ask_question(question_dict)that displays a question and its choices, collects the userโs answer, and returnsTrue/Falsefor correct/incorrect.Write a function
run_quiz(questions)that loops through all questions, tracks the score, and callsask_question()for each one.At the end, print the score as both a raw count (
"7/8 correct") and a percentage, formatted to 1 decimal place using an f-string.Import at least one module using each of the three import styles covered above (
import x,from x import y,import x as y).Include a full program header block.
Rubric (25 points total)
Criteria |
Points |
|---|---|
|
4 |
|
4 |
Questions stored as a list of dictionaries with consistent keys |
4 |
|
4 |
|
4 |
Score printed as both count and percentage (f-string formatting) |
2 |
All three import styles used correctly somewhere in the program |
2 |
Program header block, PEP 8 style, and no crashes on normal input |
1 |
Stretch challenge: Add a fourth import โ json โ to save the studentโs score to a scores.json file after each run, and load/display their best score at the start of the next run.
AP CSP: AAP-2.G, CRD-2.B
Exception Handlingยถ
๐ PCEP 4.3 โ Python Built-In Exceptions Hierarchy
๐ PCEP 4.4 โ Basics of Python Exception Handling
๐ AP CSP: CRD-2.J โ Test and debug programs.
What Is an Exception?
An exception is a runtime error that interrupts normal program flow. Without handling, it crashes the program. With try-except, you can catch and respond to errors gracefully.
Basic Syntax
try:
# code that may raise an exception
except SomeException as e:
# runs if the exception occurs
else:
# runs if NO exception occurred
finally:
# ALWAYS runs โ cleanup code
Example: Safe Division
try:
result = 10 / int(input("Enter a divisor: "))
except ValueError:
print("That wasn't a number!")
except ZeroDivisionError:
print("Can't divide by zero!")
else:
print(f"Result: {result}")
finally:
print("Operation attempted.")
Exception Hierarchy โ ๐ PCEP 4.3
BaseException
โโโ SystemExit
โโโ KeyboardInterrupt
โโโ Exception
โโโ ArithmeticError
โ โโโ ZeroDivisionError
โโโ LookupError
โ โโโ IndexError
โ โโโ KeyError
โโโ TypeError
โโโ ValueError
โโโ FileNotFoundError
PCEP Exam Tip: Order
exceptblocks from most specific to most general. Python checks them in order and runs the first match.
try:
x = int("abc")
except ValueError: # caught here โ most specific
print("Value error")
except Exception: # broader fallback
print("Some error")
Common Exceptions
Exception |
When it occurs |
|---|---|
|
Dividing by zero |
|
Wrong value type, e.g., |
|
Wrong data type in operation |
|
List index out of range |
|
Dictionary key not found |
|
File doesnโt exist |
|
Variable not defined |
Propagating Exceptions โ ๐ PCEP 4.4
def divide(a, b):
return a / b # may raise ZeroDivisionError
try:
result = divide(10, 0) # exception propagates up to here
except ZeroDivisionError:
print("Caught in caller!")
File Handling with Exceptions
try:
with open("data.txt", "r") as file:
content = file.read()
except FileNotFoundError:
print("File not found.")
except IOError:
print("Error reading file.")
Activity: Safe Calculatorยถ
Build a calculator program that:
Accepts two numbers and an operator (
+,-,*,/)Handles
ZeroDivisionErrorandValueErrorLoops until the user types
quitUses a function for each operation
Uses
try-except-else-finally
AP CSP: CRD-2.J | PCEP: 4.3, 4.4
Data Structures Deep Diveยถ
๐ AP CSP: AAP-3.A, AAP-3.B, AAP-3.C
Pythonโs built-in data structures serve different organizational needs:
Structure |
Ordered |
Mutable |
Indexed |
Duplicates |
Use When |
|---|---|---|---|---|---|
List |
โ |
โ |
โ |
โ |
General-purpose ordered collection |
Tuple |
โ |
โ |
โ |
โ |
Fixed data (coords, config) |
Set |
โ |
โ |
โ |
โ |
Unique values, set operations |
Dictionary |
โ |
โ |
By key |
โ (keys) |
Key-value lookup |
Sets
user_ids = {101, 102, 103, 101} # duplicates removed
print(user_ids) # {101, 102, 103}
a = {1, 2, 3}
b = {2, 3, 4}
print(a | b) # Union: {1, 2, 3, 4}
print(a & b) # Intersection: {2, 3}
print(a - b) # Difference: {1}
Stacks (LIFO) using Lists
A stack follows LIFO โ Last In, First Out. Think of a stack of plates: you add a new plate to the top, and you also take from the top. The most recently added item is always the first one removed. Pythonโs undo button behavior, browser back-buttons, and function call stacks (like the recursion diagram above!) all work this way.
stack = []
stack.append("action1") # push โ add to the top
stack.append("action2")
last = stack.pop() # pop โ "action2" (last one in, first one out)
Queues (FIFO) using deque
A queue follows FIFO โ First In, First Out. Think of a line at a store checkout: the first person in line is the first person served. New items are added to the back and removed from the front.
from collections import deque
queue = deque()
queue.append("first") # add to the back
queue.append("second")
first = queue.popleft() # remove from the front โ "first" (first one in, first one out)
Memory trick: LIFO = last in, first out (a stack of trays). FIFO = first in, first out (a line at the store). Both use
.append()to add, but stacks remove with.pop()(from the end) while queues remove with.popleft()(from the front).
Object-Oriented Programming (OOP)ยถ
๐ AP CSP: AAP-3.B โ Abstractions; CRD-2.B โ Implement in a language.
Why OOP? Real programs model real-world things โ students, cars, bank accounts, game characters. OOP lets us group data and behavior together in reusable, organized units called classes.
Core OOP Conceptsยถ
Key Vocabulary
Term |
Definition |
|---|---|
Class |
A blueprint/template for creating objects |
Object |
An instance (specific example) of a class |
Attribute |
A variable that belongs to a class or object |
Method |
A function that belongs to a class |
Constructor |
|
|
Refers to the current instance of the class |
Encapsulation |
Bundling data and methods together |
Inheritance |
A child class acquires attributes/methods from a parent |
Polymorphism |
Different classes can share the same method name |
Building a Classยถ
class Car:
"""Blueprint for a car object."""
def __init__(self, make, model, year):
"""Constructor โ runs automatically when object is created."""
self.make = make # instance attribute
self.model = model # instance attribute
self.year = year # instance attribute
def start_engine(self):
"""Instance method โ uses self to access attributes."""
print(f"The {self.year} {self.make} {self.model}'s engine is running.")
def stop_engine(self):
print(f"The {self.year} {self.make} {self.model}'s engine is off.")
def __str__(self):
"""Magic method โ controls how object prints."""
return f"{self.year} {self.make} {self.model}"
Creating and Using Objects
car1 = Car("Toyota", "Corolla", 2022) # create object
car2 = Car("Honda", "Civic", 2020)
car1.start_engine() # The 2022 Toyota Corolla's engine is running.
print(car2) # 2020 Honda Civic (uses __str__)
# Access attributes directly
print(car1.make) # Toyota
car1.year = 2023 # Modify an attribute
Types of Methodsยถ
class Dog:
species = "Canis familiaris" # CLASS attribute (shared by all instances)
def __init__(self, name, breed=None):
self.name = name # INSTANCE attribute (unique per object)
self.breed = breed
def bark(self): # INSTANCE method
print(f"{self.name} says Woof!")
@classmethod
def get_species(cls): # CLASS method โ operates on the class
return cls.species
@staticmethod
def is_domestic(): # STATIC method โ no instance or class needed
return True
Inheritanceยถ
Inheritance allows a child class to reuse and extend the behavior of a parent class.
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "..."
class Dog(Animal): # Dog inherits from Animal
def speak(self): # Override the parent method
return f"{self.name} says Woof!"
class Cat(Animal):
def speak(self):
return f"{self.name} says Meow!"
animals = [Dog("Rex"), Cat("Whiskers"), Dog("Buddy")]
for animal in animals:
print(animal.speak()) # Polymorphism in action
Magic / Dunder Methodsยถ
class BankAccount:
def __init__(self, holder, balance=0):
self.holder = holder
self.balance = balance
def __str__(self):
return f"Account({self.holder}, ${self.balance:.2f})"
def __len__(self):
return self.balance
def deposit(self, amount):
if amount > 0:
self.balance += amount
print(f"Deposited ${amount:.2f}. New balance: ${self.balance:.2f}")
def withdraw(self, amount):
if 0 < amount <= self.balance:
self.balance -= amount
print(f"Withdrew ${amount:.2f}. New balance: ${self.balance:.2f}")
else:
print("Insufficient funds or invalid amount.")
def get_balance(self):
return self.balance
# Usage
account = BankAccount("Alice Smith", 1000)
print(account) # Account(Alice Smith, $1000.00)
account.deposit(500)
account.withdraw(200)
account.withdraw(1500) # Insufficient funds
Activity: OOP Zooยถ
Design a Zoo simulation using OOP:
Create a base class
Animalwith attributesname,species,age, and a methoddescribe().Create at least three subclasses (e.g.,
Mammal,Bird,Reptile) that each override aspeak()method.Create a
Zooclass that holds a list ofAnimalobjects and can:add_animal(animal)show_all()โ print all animalsfind_by_species(species)โ return a list of matching animals
Create at least 5 animal objects, add them to the zoo, and demonstrate all methods.
Include __str__ and proper docstrings.
Option 2 โ Library Management System
Design a simplified library check-out system using OOP:
Create a base class
Itemwith attributestitle,id_number,checked_out(defaultFalse), and a methoddescribe().Create at least two subclasses (e.g.,
Book,Magazine) that each overridedescribe()to include a subclass-specific detail (author forBook, issue number forMagazine).Create a
Libraryclass that holds a list ofItemobjects and can:add_item(item)check_out(id_number)โ marks an item unavailable, or prints a message if already checked outreturn_item(id_number)โ marks an item available againlist_available()โ prints all items currently not checked out
Create at least 5 items, add them to the library, and demonstrate checking items in and out.
Option 3 โ RPG Character Builder
Design a role-playing game character system using OOP:
Create a base class
Characterwith attributesname,health,level, and a methodattack()that returns a damage value.Create at least three subclasses (e.g.,
Warrior,Mage,Healer) that each overrideattack()with different behavior (e.g.,Magedeals more damage but has less health;Healerโsattack()restores health to an ally instead).Create a
Partyclass that holds a list ofCharacterobjects and can:add_member(character)show_party()โ print all members and their statstotal_party_health()โ return the combined health of all members
Create at least 4 characters across different subclasses, add them to a party, and simulate a round of attacks.
Rubric for All Three Options (10 points)
Criteria |
Points |
|---|---|
Base class correctly defined with required attributes and at least one method |
2 |
At least the required number of subclasses created, each correctly inheriting from the base class |
2 |
Each subclass overrides the specified method with genuinely different behavior (not just a copy/paste) |
2 |
Container class ( |
2 |
Program includes |
2 |
AP CSP: AAP-3.B, CRD-2.B | Demonstrates: Abstraction, Inheritance, Polymorphism
AP CSP Performance Task Preparationยถ
๐ AP CSP: CRD-2 โ Program Design and Development
The AP CSP Create Performance Task (CPT) is 30% of your AP score. You write a program and submit written responses explaining it. This section helps you align your project to College Board requirements.
CPT Requirements at a Glanceยถ
Requirement |
Description |
|---|---|
Program Purpose |
Clearly state what problem your program solves |
Algorithm |
Must include sequencing, selection, AND iteration |
Abstraction |
Must use a list (or other collection) and a procedure/function |
Procedure with parameter |
A function that takes input and affects behavior |
Output |
Must produce visible output based on input |
CPT Checklist โ Does Your Program Have?ยถ
โ A clear purpose that solves a meaningful problem
โ Input from the user or a data source
โ Output that responds to the input
โ An algorithm using:
โ Sequencing (steps in order)
โ Selection (
if-elif-else)โ Iteration (
fororwhileloop)
โ A list (or collection) that stores and processes data
โ At least one student-defined function that:
โ Has a parameter that affects behavior
โ Is called at least once in the program
โ Your function implements an algorithm (not just print)
โ A second call to the function with different arguments
CPT Written Response Tipsยถ
Prompt 3a โ Program Function and Purpose:
Describe what your program does and the problem it solves
Describe what input your program accepts
Describe the output your program produces
Prompt 3b โ Data Abstraction:
Show your code that stores data in a list (or other collection)
Explain what data is in the list and how it represents information
Explain what would be harder without using a list
Prompt 3c โ Managing Complexity:
Show your function/procedure with a parameter
Explain what the parameter does and how it affects output
Explain how the function manages complexity
Prompt 3d โ Procedural Abstraction:
Identify the algorithm embedded in your function
Describe the algorithm step-by-step in plain English
Activity: CPT Brainstorming Workshopยถ
With a partner, evaluate 3 program ideas against the CPT checklist. For each idea, identify:
The input source
The list and what it stores
The function and its parameter
The algorithm (sequencing, selection, iteration)
Select the strongest idea and create a one-page project proposal.
AP CSP: CRD-2.A, CRD-2.B
Final Project Optionsยถ
Option A โ Text-Based Adventure Game (BeginnerโIntermediate)ยถ
Build a multi-room text adventure with:
Classes for
Player,Room, andItemA
listof rooms and itemsA
whileloop game engineUser-input navigation using
if-elifAt least one function with a parameter
Exception handling for invalid input
A scoring system
AP CSP Alignment: CRD-2.B, AAP-2.E, AAP-3.B, AAP-4.A
Option B โ Student Data Tracker (Intermediate)ยถ
Build a command-line tracker that:
Stores student records as a list of dictionaries
Supports add, delete, search, and update operations
Calculates class average, highest/lowest scores
Uses OOP (a
Studentclass with methods)Handles all exceptions gracefully
Optionally reads/writes to a
.jsonfile
AP CSP Alignment: CRD-2.B, AAP-3.A, AAP-3.B, AAP-3.C, AAP-4.A
Option C โ Mini Minesweeper (Advanced)ยถ
Build a simplified Minesweeper game using Python and Tkinter with OOP design.
Project Objectives
A 6ร6 grid stored as a 2D list
Random mine placement
Count adjacent mines per cell
Allow player left-clicks and right-click flagging
Score tracking for safe clicks
Move history stored in a list
Game over on mine click
Flood-fill reveal using recursion
Win/loss detection
โTry Againโ button to reset
AP CSP Alignment: AAP-2.E, AAP-4.A, CRD-2.B, CRD-2.J
AP CSP Learning Goals:
AAP-2.Eโ Algorithms with sequencing, selection, iterationAAP-4.Aโ Data abstractions (lists/2D lists) to manage complexityCRD-2.Bโ Implementing algorithms in a programming languageCRD-2.Jโ Testing and debugging
Starter Code Skeleton:
import tkinter as tk
import random
class Minesweeper:
def __init__(self, root):
self.root = root
self.root.title("<<YOUR NAME>> Minesweeper")
self.size = 6
self.mines = 6
# TODO: Create instance variables for:
# self.score, self.high_score, self.moves (list), self.flags (set)
self.grid_frame = tk.Frame(root)
self.grid_frame.pack()
self.create_board()
def create_board(self):
self.buttons = []
for r in range(self.size):
row = []
for c in range(self.size):
btn = tk.Button(self.grid_frame, width=3, height=1)
btn.grid(row=r, column=c)
btn.bind("<Button-1>", lambda e, r=r, c=c: self.click(r, c))
btn.bind("<Button-3>", lambda e, r=r, c=c: self.flag(r, c))
row.append(btn)
self.buttons.append(row)
self.place_mines()
def place_mines(self):
self.mine_locations = set()
# TODO: Randomly place self.mines mines in mine_locations
def count_mines(self, r, c):
count = 0
# TODO: Check 8 surrounding cells; count mines
return count
def click(self, r, c):
# TODO: Prevent clicking flagged or already-revealed cells
# TODO: If mine โ game_over(); else reveal number
# TODO: If count == 0 โ reveal_empty(r, c)
# TODO: Update score and moves list
pass
def reveal_empty(self, r, c):
# TODO: Recursive flood-fill to reveal adjacent empty cells
pass
def flag(self, r, c):
# TODO: Toggle flag on/off; limit flags to self.mines count
pass
def game_over(self):
# TODO: Reveal all mines; disable all buttons
pass
root = tk.Tk()
game = Minesweeper(root)
root.mainloop()
Extensions (Choose Any):
Flagging system with right-click ๐ฉ
High score tracking
Timer scoring
Difficulty levels: Easy (6ร6), Medium (8ร8), Hard (10ร10)
Win screen
Save/load high score to file
Grading Rubric (10 Points)
Criteria |
Points |
|---|---|
Mine placement algorithm works correctly |
1 |
Nearby mine counting algorithm works |
2 |
Flagging system implemented and limited |
2 |
Empty region reveal (recursion) |
2 |
Lists/sets used for tracking game data |
1 |
Program runs correctly; tested and debugged |
1 |
Reflection (text file) |
1 |
Total |
10 |
Reflection (1 page): Explain your mine-counting algorithm, how recursion works in the reveal function, and how lists are used for data abstraction.
Certification Alignment Referenceยถ
PCEP-30-02 Exam Topic Mapยถ
PCEP Objective |
Topics |
Covered In |
|---|---|---|
1.1 |
Interpreter, compiler, lexis, syntax, semantics |
Section 1 โ How Python Works |
1.2 |
Keywords, indentation, comments |
Section 1 โ Python Structure |
1.3 |
Literals, variables, numeral systems, PEP-8 |
Section 1 โ Variables & Data Types |
1.4 |
Operators, precedence, Boolean, bitwise, type casting |
Section 1 โ Operators |
1.5 |
|
Section 1 โ I/O |
2.1 |
|
Section 2 โ Conditionals |
2.2 |
|
Section 2 โ Loops |
3.1 |
Lists, indexing, slicing, methods, comprehensions, 2D lists |
Section 3 โ Lists |
3.2 |
Tuples, immutability, nesting |
Section 3 โ Tuples |
3.3 |
Dictionaries, keys/values/items, iteration |
Section 3 โ Dictionaries |
3.4 |
Strings, indexing, slicing, escaping, methods |
Section 3 โ Strings |
4.1 |
Functions, |
Section 4 โ Functions |
4.2 |
Parameters, arguments, defaults, scope, |
Section 4 โ Functions |
4.3 |
Exception hierarchy: |
Section 4 โ Exceptions |
4.4 |
|
Section 4 โ Exceptions |
AP CSP Standards Alignmentยถ
AP CSP Standard |
Description |
Covered In |
|---|---|---|
CRD-2.A |
Program design and development |
Throughout |
CRD-2.B |
Implement algorithms |
Functions, OOP, Projects |
CRD-2.G |
Call procedures |
Functions |
CRD-2.J |
Test and debug |
Debugging, Exception Handling |
AAP-2.E |
Sequencing, selection, iteration |
Control Flow |
AAP-2.F |
Mathematical operations |
Operators |
AAP-2.G |
Abstraction to manage complexity |
Functions, Modules, OOP |
AAP-2.K |
List iteration |
Lists |
AAP-3.A |
Collect and represent data |
Data Structures |
AAP-3.B |
Use abstractions to organize data |
Dictionaries, OOP, Lists |
AAP-3.C |
Analyze data to draw conclusions |
Data Structures |
AAP-4.A |
Data abstractions for complexity |
Lists, 2D Lists, Classes |
Document maintained for AP CSP and PCEP-30-02 certification alignment. Revised June 2026
Python Basicsยถ
Revised March 2026
Python is an open-source programming language that is one of the easiest programs that a person can learn for their first programming language. Python is a versatile programming language that can be used in many areas such as data analysis, science, web development, AI, and IoT. As of 2024, it is one of the most in demand programming languages in the market place. Python is a high-level programming language that offers simplicity, readability, and versatility. Python supports multiple programming paradigms and has an extensive library that simplifies coding tasks. Python has a robust community and documentation support that enables beginners to excel quickly in this language.
We will be looking at syntax and structures of Python. We will use an Integrated Development Environment to develop our code in this course.
Python Style Guidelinesยถ
Click Here
PEP 8 Guidelines is the official style guide for Python code and covers naming conventions, code layout, and indentation. These style guidelines, along with the examples and rationales, will help you write clean, readable, and maintainable code.
All Projects and assignments should have a header block for the teacher
# Assignment: Program [number]: [Assignment Title]
#
# Author: [Your Name ]
# Partner: [Partner's Name ]
#
# Course Name: [Course Name]
# Instructor: John Smith
# Due Date: [Due Date and Time]
#
# Description: [Describe the program's goal, IN DETAIL.]
#
# Language: [ Python version 18]
# Ex. Packages: [List names and sources of all external packages
# required by this program.]
#
# Deficiencies: [If you know of any problems with the code, provide
# details here, otherwise clearly state that you know
# of no unsatisfied requirements and no logic errors.]
#
1. Use Descriptive Variable and Function Names
Guideline: Use descriptive names that make the purpose of the variable or function clear.
Example:
# Good total_cost = price * quantity # Bad x = p * q
Rationale: Code is more readable when variable names clearly indicate their purpose, making it easier to understand and maintain.
2. Use Consistent Indentation (4 Spaces)
Guideline: Use four spaces per indentation level; do not use tabs.
Example:
def calculate_area(radius): return 3.14 * radius ** 2
Rationale: Consistent indentation is essential for readability and prevents syntax errors.
3. Limit Line Length to 79 Characters
Guideline: Limit all lines to a maximum of 79 characters.
Example:
# Good def display_message(message): print(f"Message: {message}") # Bad (line too long) def display_message(message): print(f"Message: {message}")
Rationale: This improves readability and ensures the code displays well on all devices, including smaller screens.
4. Use Blank Lines to Separate Code Sections
Guideline: Use two blank lines to separate top-level functions and class definitions, and one blank line to separate methods within a class.
Example:
class Animal: def speak(self): pass class Dog(Animal): def bark(self): print("Woof!")
Rationale: Blank lines help visually separate sections of code, improving readability.
5. Use Docstrings to Document Functions, Classes, and Modules
Guideline: Use triple-quoted strings (
""") for all public modules, functions, classes, and methods.Example:
def calculate_area(radius): """Calculate the area of a circle given its radius.""" return 3.14 * radius ** 2
Rationale: Docstrings provide useful explanations of code functionality, which helps future readers and collaborators.
6. Use Spaces Around Operators
Guideline: Use spaces around operators and after commas, but not directly inside parentheses.
Example:
# Good result = (a + b) * (c - d) # Bad result=(a+b)*(c-d)
Rationale: Spacing around operators makes expressions easier to read.
7. Avoid Excessive Nesting
Guideline: Break down complex logic with multiple levels of nesting into smaller functions.
Example:
# Good def process_data(data): if not data: return None cleaned_data = clean(data) return analyze(cleaned_data) # Bad def process_data(data): if data: cleaned_data = clean(data) if cleaned_data: return analyze(cleaned_data)
Rationale: Deeply nested code is harder to read and debug. Breaking code into smaller functions improves readability and reusability.
8. Use List Comprehensions for Simple Operations
Guideline: Use list comprehensions for simple operations but avoid them for complex nested operations.
Example:
# Good squares = [x ** 2 for x in range(10)] # Bad squares = [] for x in range(10): squares.append(x ** 2)
Rationale: List comprehensions are concise and often faster than equivalent for-loops for simple operations.
9. Handle Exceptions Properly
Guideline: Use specific exceptions rather than catching all exceptions with
exceptalone.Example:
# Good try: result = 10 / divisor except ZeroDivisionError: print("Cannot divide by zero.") # Bad try: result = 10 / divisor except: print("An error occurred.")
Rationale: Catching specific exceptions allows you to handle errors appropriately, making debugging easier.
10. Use Meaningful Constants Instead of Magic Numbers
Guideline: Define constants with descriptive names for โmagic numbersโ (unexplained numerical values).
Example:
# Good TAX_RATE = 0.15 total_cost = price * (1 + TAX_RATE) # Bad total_cost = price * 1.15
Rationale: Constants with meaningful names improve readability and make the code easier to modify and maintain.
11. Avoid Global Variables
Guideline: Avoid using global variables; instead, use function parameters or class attributes.
Example:
# Good def calculate_total(cost, tax_rate): return cost * (1 + tax_rate) # Bad TAX_RATE = 0.15 def calculate_total(cost): return cost * (1 + TAX_RATE)
Rationale: Global variables can lead to hard-to-track bugs and make code harder to reuse and maintain.
12. Use is for Comparison to None
Guideline: Use
isoris notwhen comparing toNone.Example:
# Good if value is None: print("No value") # Bad if value == None: print("No value")
Rationale:
isis more efficient and explicitly intended for this type of comparison, improving clarity and performance.
13. Organize Imports Properly
Guideline: Group imports into three sections in this order: standard library imports, related third-party imports, and local application-specific imports. Separate each group with a blank line.
Example:
# Good import os import sys import numpy as np import pandas as pd from my_app.utilities import helper_function
Rationale: This structure improves readability and avoids clutter.
14. Use Type Annotations (Python 3.5+)
Guideline: Use type annotations to specify expected data types for function arguments and return values.
Example:
def calculate_total(cost: float, tax_rate: float) -> float: return cost * (1 + tax_rate)
Rationale: Type annotations make it clear what types are expected, which can help prevent bugs and improve readability.
Following these guidelines helps ensure code that is easy to read, maintain, and understand across teams.
Debugging Strategiesยถ
1. Read the Error Message Carefully
Look at the exact line number and description.
Identify whether the error is a syntax error, runtime error, or logic error.
Focus first on the line mentioned, then check lines directly above it.
2. Trace the Program Step-by-Step
Walk through the program line by line.
Track variable values and program flow.
Use paper or a table to simulate what the program does.
3. Use Print Statements
Insert temporary
printstatements to display:variable values
function outputs
checkpoints in the code
This helps locate where the program behavior becomes incorrect.
Example:
print("Value of score:", score)
4. Test with Simple Inputs
Start with small, predictable test cases.
Use values where you already know the expected output.
Gradually test more complex inputs.
5. Isolate the Problem
Comment out or temporarily remove sections of code.
Test smaller pieces individually.
Determine which specific section causes the issue.
6. Check Variables and Data Types
Confirm variables contain the values you expect.
Verify correct data types (number, string, boolean, list).
Look for accidental reassignment of variables.
7. Review Logic and Conditions
Check
ifstatements and loops carefully.Verify conditions are written correctly.
Look for common mistakes:
incorrect comparison operators
misplaced parentheses
incorrect loop conditions.
8. Rubber Duck Debugging
Explain the code out loud step-by-step.
Pretend you are teaching the program to someone else.
Often the mistake becomes obvious while explaining.
9. Use Incremental Development
Write and test small pieces of code at a time.
Ensure each part works before adding more features.
10. Take a Break and Revisit
Step away briefly when stuck.
Returning with fresh eyes often reveals simple mistakes.
11. Ask for Help with Evidence
Before asking a teacher or peer, students should be able to explain:
What the program is supposed to do
What it is actually doing
What they already tried to fix it
Student Debugging Checklistยถ
Before asking for help, you should check the following:
โ Read the error message
โ Checked the line number and nearby code
โ Added print/debug statements
โ Tested with simple inputs
โ Traced variables step-by-step
โ Explained the code out loud (Rubber Ducky)
Print Statementsยถ
In Python, there are several ways to format and print strings. Each method offers a different approach to injecting variables or formatting output. Here are some popular variations:
Basic
printstatementUsing
printwith variablesUsing concatenation (
+operator)Using
format()methodUsing f-strings (formatted string literals)
Using special characters for formatting
Hereโs a Python program illustrating each of these methods:
# 1. Basic print statement
print("Hello, World!")
# 2. Using print with variables
name = "Alice"
age = 25
print("Name:", name)
print("Age:", age)
# 3. Using concatenation (with `+` operator)
city = "New York"
country = "USA"
print("Location: " + city + ", " + country)
# 4. Using format() method
greeting = "Hello"
print("Message: {}! My name is {} and I am {} years old.".format(greeting, name, age))
# 5. Using f-strings (formatted string literals)
# Introduced in Python 3.6, this is one of the most concise and popular methods for formatting.
print(f"{greeting}! My name is {name} and I am {age} years old.")
# 6. Using special characters for formatting (e.g., newline `\n`, tab `\t`)
print("Hello\nWorld!") # newline
print("Hello\tWorld!") # tab
print("Name:\t", name) # tab
print("Age:\t", age) # tab
Explanation of Each Method
Basic
printstatement: Just prints the text directly.Using
printwith variables: Allows direct printing of variables by separating values with commas. This adds a space automatically.Using concatenation: The
+operator combines strings. However, this method works only if all parts are strings, so numbers must be converted (usingstr()).Using
format()method: This method replaces{}placeholders in the string with values provided toformat(). Itโs flexible for various formatting needs.Using f-strings: These formatted string literals are enclosed with an
fprefix. Variables can be embedded directly within{}braces, making it compact and readable.Using special characters: Special characters like
\n(newline) and\t(tab) can be used to format output, particularly for line breaks and indentation.
These different print methods offer flexibility in formatting and display for different contexts.
Variables and Data Typesยถ
In Python, variables are used to store data, which can be used and manipulated throughout a program. Data types specify the kind of value a variable holds, determining what operations can be performed on it. Python automatically assigns a data type based on the value assigned to a variable.
Python Variables A variable is essentially a name given to a memory location where data is stored. In Python, you do not need to declare the data type of a variable; you just assign a value to it, and Python infers the type.
Syntax:
variable_name = value
Example:
age = 25 # age is an integer
name = "Alice" # name is a string
price = 9.99 # price is a floating-point number
is_student = True # is_student is a boolean
Python Data Types Here are the basic data types in Python, along with examples for each.
Integer (
int)Whole numbers, positive or negative, without a decimal point.
Example:
age = 25 count = -10 print(type(age)) # Output: <class 'int'>
Floating-point number (
float)Numbers with a decimal point, used for more precise calculations.
Example:
price = 19.99 temperature = -5.5 print(type(price)) # Output: <class 'float'>
String (
str)A sequence of characters, enclosed in single or double quotes.
Example:
name = "Alice" greeting = 'Hello, World!' print(type(name)) # Output: <class 'str'>
String Methodsยถ
Beginner-Friendly String Methods
Method |
Description |
Example |
|---|---|---|
|
Converts to lowercase |
|
|
Converts to uppercase |
|
|
Removes leading/trailing spaces |
|
|
Replaces parts of a string |
|
|
Splits string into list |
|
|
Returns length of string |
|
if name.lower() == "admin":
print("Welcome, admin!")
Intermediate Methods (Great with Practice)
Method |
Description |
Example |
|---|---|---|
|
Returns index of substring, or -1 |
|
|
Counts occurrences |
|
|
Checks if string starts with text |
|
|
Checks if string ends with text |
|
|
Capitalizes the first letter |
|
|
Capitalizes first letter of each word |
|
Optional for Advanced Learners
Method |
Description |
Example |
|---|---|---|
|
Checks if all characters are letters |
|
|
Checks if all characters are numbers |
|
|
Letters or numbers only |
|
|
Joins a list into a string with separator |
|
At minimum, you should know the following:
.lower().upper().strip().replace()len().split()
Indexing in Python
Definition: Indexing lets you access individual characters in a string using square brackets [].
*Note: Python uses zero-based indexing โ the first character is at position 0.
Examples:
name = "Alice"
print(name[0]) # Output: 'A' (first character)
print(name[1]) # Output: 'l'
print(name[4]) # Output: 'e' (fifth character)
Negative Indexing:
print(name[-1]) # Output: 'e' (last character)
print(name[-2]) # Output: 'c' (second to last)
Slicing in Python
Definition: Slicing lets you extract a substring using a start and end index:
string[start:end]
The start is included, but the end is excluded.
Examples:
word = "Python"
print(word[1:4]) # Output: 'yth' (characters at index 1, 2, 3)
print(word[:3]) # Output: 'Pyt' (start at 0 by default)
print(word[2:]) # Output: 'thon' (go to end)
print(word[:]) # Output: 'Python' (entire string)
With Negative Indices:
print(word[-4:-1]) # Output: 'tho' (characters from index -4 to -2)
Quick Visualization:
Character |
P |
y |
t |
h |
o |
n |
|---|---|---|---|---|---|---|
Index |
0 |
1 |
2 |
3 |
4 |
5 |
Negative |
-6 |
-5 |
-4 |
-3 |
-2 |
-1 |
Practice Programs to test your understanding:
"Mad Libs" with string concatenation
Greeting program that capitalizes user input
Word counter using .split() and len()
Simple login screen with string comparison
Boolean (
bool)Represents one of two values:
TrueorFalse.Example:
is_open = True is_available = False print(type(is_open)) # Output: <class 'bool'>
List (
list)An ordered collection of items, which can be of different data types. Lists are mutable, meaning items can be changed.
Example:
fruits = ["apple", "banana", "cherry"] numbers = [1, 2, 3, 4, 5] mixed_list = [1, "Hello", 3.5, True] print(type(fruits)) # Output: <class 'list'>
Tuple (
tuple)Similar to a list, but immutable, meaning items cannot be changed once set.
Example:
coordinates = (10, 20) dimensions = (1920, 1080) print(type(coordinates)) # Output: <class 'tuple'>
Dictionary (
dict)A collection of key-value pairs, where each key is unique. Dictionaries are mutable.
Example:
student = { "name": "Alice", "age": 20, "is_student": True } print(type(student)) # Output: <class 'dict'>
Set (
set)An unordered collection of unique items. Sets are mutable but donโt allow duplicate elements.
Example:
colors = {"red", "green", "blue"} numbers_set = {1, 2, 3, 4, 5} print(type(colors)) # Output: <class 'set'>
None Type (
NoneType)Represents the absence of a value or a null value.
Example:
result = None print(type(result)) # Output: <class 'NoneType'>
Example Program Demonstrating Python Data Types
# Integer
age = 30
print("Age:", age, "| Data type:", type(age))
# Float
height = 5.9
print("Height:", height, "| Data type:", type(height))
# String
name = "John"
print("Name:", name, "| Data type:", type(name))
# Boolean
is_active = True
print("Is Active:", is_active, "| Data type:", type(is_active))
# List
colors = ["red", "blue", "green"]
print("Colors:", colors, "| Data type:", type(colors))
# Tuple
dimensions = (1920, 1080)
print("Dimensions:", dimensions, "| Data type:", type(dimensions))
# Dictionary
person = {"name": "Alice", "age": 25}
print("Person:", person, "| Data type:", type(person))
# Set
unique_numbers = {1, 2, 3, 4, 5}
print("Unique Numbers:", unique_numbers, "| Data type:", type(unique_numbers))
# NoneType
result = None
print("Result:", result, "| Data type:", type(result))
Each variable in this example demonstrates a different data type. Using the type() function, we can easily check the data type of each variable.
Order of Operationยถ
In Python, expressions are evaluated based on a well-defined order of operations, also known as operator precedence. This hierarchy determines the sequence in which operations (arithmetic, logical, relational, etc.) are performed. Here, we will cover:
Arithmetic Operators (PEMDAS rules)
Relational Operators
Logical Operators
Operator Precedence in Python
Pythonโs precedence rules are designed to make expressions behave intuitively. Hereโs the order of precedence, from highest to lowest:
Parentheses (
())Exponentiation (
**)Arithmetic Operators: Multiplication (
*), Division (/and//), and Modulus (%)Arithmetic Operators: Addition (
+) and Subtraction (-)Relational Operators:
<,<=,>,>=,==,!=Logical Operators:
not,and,or
Understanding this precedence order and the left-to-right evaluation rule allows for correctly interpreting complex expressions in Python. Following these rules helps ensure that Python evaluates each part of an expression as intended, providing accurate and predictable results.
The following table summarizes the operator precedence from highest to lowest. A complete table for the entire language can be found in the Python Documentation.
Level |
Category |
Operators |
|---|---|---|
7 (high) |
exponent |
** |
6 |
multiplication |
*,/,//,% |
5 |
addition |
+,- |
4 |
relational |
==,!=,<=,>=,>,< |
3 |
logical |
not |
2 |
logical |
and |
1 (low) |
logical |
or |
1. Arithmetic Operators and PEMDAS
The arithmetic operators follow PEMDAS:
Parentheses: Highest precedence, used to group expressions.
Exponents: Calculated next, evaluated from right to left.
Multiplication, Division, and Modulus: Evaluated left to right.
Addition and Subtraction: Evaluated left to right.
Example:
result = 5 + 2 * (3 ** 2 - 4) / 2
print(result) # Output: 10.0
Step-by-Step Evaluation
Parentheses (
3 ** 2 - 4)3 ** 2is calculated first, giving9.Then,
9 - 4gives5.Expression becomes
5 + 2 * 5 / 2.
Multiplication and Division (
*and/left to right):2 * 5is10, so the expression is5 + 10 / 2.10 / 2results in5.0(division returns a float).Now we have
5 + 5.0.
Addition:
5 + 5.0results in10.0.
Final result: 10.0.
NOTE: Why Division Returns a Float: In Python 3, the
/operator always returns a float, even if both operands are integers. This is to provide accurate results without unexpected truncation. For integer-only results, Python offers the//operator (floor division).The
/operator preserves fractional results, which is especially helpful in complex calculations, while//discards the decimal part.Example:
python result = 7 / 2 # Output: 3.5 (float) result = 7 // 2 # Output: 3 (integer)
2. Relational (Comparison) Operators
Relational operators compare values and have lower precedence than arithmetic operators but higher precedence than logical operators. These include:
==(equal to)!=(not equal to)<,<=,>,>=(less than, greater than, and their variants)
Example:
result = 5 + 3 > 2 * 3
print(result) # Output: True
Step-by-Step Evaluation
Arithmetic Operators:
5 + 3results in8.2 * 3results in6.
Relational Operator:
The comparison
8 > 6is evaluated, resulting inTrue.
Final result: True.
3. Logical Operators
Logical operators (not, and, or) combine boolean expressions. They have the lowest precedence, so they are evaluated after arithmetic and relational operators.
Order of Precedence for Logical Operators:
not: Highest among logical operators.
and: Middle precedence.
or: Lowest precedence.
Example:
result = 3 > 2 and 5 == 5 or not (4 + 1 < 6)
print(result) # Output: True
Compound Boolean Expressions
Compound Boolean Expressions
Compound Boolean expressions are used when you need to make a decision that depends on multiple conditions being true or false. Theyโre particularly useful in programming and data queries to add complex logic to condition-checking statements.
Using AND
age = 25 has_license = True is_eligible = age >= 18 and has_license
Explanation: Here,
is_eligiblewill beTrueonly if both conditions areTrue. In this case,age >= 18andhas_licenseboth need to beTrueforis_eligibleto beTrue. Ifageis less than 18 orhas_licenseisFalse,is_eligiblewill beFalse.Using OR
temperature = 35 raining = False go_for_walk = temperature >= 20 or raining
Explanation: The variable
go_for_walkwill beTrueif eithertemperature >= 20orrainingisTrue. WithOR, only one of the conditions needs to beTruefor the overall expression to evaluate asTrue.Combining AND and OR
is_weekend = True has_free_time = False is_tired = False can_go_hiking = is_weekend and (has_free_time or not is_tired)
Explanation: In this case,
can_go_hikingisTrueif it is the weekend (is_weekendisTrue) and either there is free time (has_free_time) or the person is not tired (not is_tired). This example shows how parentheses can group parts of a compound Boolean expression to control evaluation order.Using NOT
is_student = False has_discount = not is_student
Explanation: The expression
not is_studentreverses the Boolean value ofis_student. Ifis_studentisFalse,has_discountwill beTrue. The NOT operator is useful for negating a condition.Complex Condition with Multiple AND/OR/NOT
age = 30 is_member = True has_discount_coupon = False gets_discount = (age > 25 or is_member) and not has_discount_coupon
Explanation: This expression checks if someone can get a discount. They qualify if they are older than 25 or are a member, but they should not have a discount coupon already. The expression
(age > 25 or is_member)will evaluate first, and thennot has_discount_couponwill apply, which must beTrueforgets_discountto beTrue.Nested Compound Boolean Expression
score = 80 attendance = 90 has_passed = (score >= 70 and attendance >= 80) or (score >= 60 and attendance >= 90)
Explanation: Here,
has_passedwill beTrueif either of these conditions is met:The score is at least 70 and attendance is at least 80.
The score is at least 60 and attendance is at least 90.
This kind of expression is useful when there are multiple pathways to meet a requirement.
Step-by-Step Evaluation
Parentheses (
4 + 1 < 6):4 + 1results in5.The comparison
5 < 6results inTrue.not (True)then results inFalse.
Relational Operators:
3 > 2evaluates toTrue.5 == 5evaluates toTrue.
Logical Operators:
True and TrueisTrue.Finally,
True or Falseevaluates toTrue.
Final result: True.
Combined Example with All Operators
Letโs consider an example combining arithmetic, relational, and logical operators.
result = (2 + 3 * 2) >= 7 and 4 / 2 < 3 or not (5 == 4)
print(result) # Output: True
Step-by-Step Evaluation
Parentheses (
2 + 3 * 2and5 == 4):For
2 + 3 * 2,3 * 2is evaluated first, giving6.Then,
2 + 6results in8.So
(2 + 3 * 2)becomes8.(5 == 4)results inFalse.
Arithmetic and Relational Operators:
The comparison
(2 + 3 * 2) >= 7evaluates as8 >= 7, which isTrue.4 / 2results in2.0, so2.0 < 3evaluates asTrue.
Logical Operators:
True and Trueresults inTrue.not (False)results inTrue.Finally,
True or Trueresults inTrue.
Final result: True.
Summary of Pythonโs Operator Precedence
Hereโs a quick summary of operator precedence from highest to lowest:
Parentheses
()Exponents
**Arithmetic Operators
*,/,//,%Arithmetic Operators
+,-Relational Operators
<,<=,>,>=,==,!=Logical
notLogical
andLogical
or
Modules and Packagesยถ
AP CSP Standards:
AAP-2.E: Develop algorithms using sequencing, selection, and iteration.
Example:
math.sqrt()can be part of a calculation sequence or algorithm.
AAP-2.F: Use mathematical operations in algorithms.
Example: Using arithmetic operations, powers, or square roots.
AAP-2.E: Develop algorithms using sequencing, selection, and iteration.
Example:
random.randint()used in loops or conditional logic.
AAP-2.G: Use abstraction to manage complexity in algorithms.
Example: Wrapping random logic in a function to simplify code.
AAP-3.A: Collect and represent data digitally.
Example: Parsing JSON into Python dictionaries or lists.
AAP-3.B: Use abstractions to organize and process data.
Example: Using dictionaries or lists to hold JSON data.
AAP-3.C: Analyze data to draw conclusions.
Example: Accessing JSON fields and performing calculations or counts.
In Python, modules and packages are essential organizational tools that help in managing, organizing, and reusing code. They make code more modular and allow developers to structure their projects efficiently.
Modules in Pythonยถ
A module in Python is simply a file with a .py extension that contains Python codeโvariables, functions, classes, or runnable code. Each module serves as a standalone file that you can import and use in other Python programs. Modules allow for logical organization, reduce redundancy, and make code easier to maintain and debug.
Why Modules are Used:
Code Reusability: Once written, a module can be reused in different programs.
Organization: Modules keep related code together, making it more manageable and readable.
Namespace Management: Using modules prevents naming conflicts, as each module has its own namespace.
Creating and Using a Module
Letโs create a module named math_utils.py:
# math_utils.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
To use this module, save it in your project directory and import it into your main script:
# main.py
import math_utils
result = math_utils.add(5, 3)
print(result) # Output: 8
Or, you could import only specific functions from the module:
from math_utils import add
result = add(5, 3)
print(result) # Output: 8
Packages in Pythonยถ
A package is a collection of related modules organized in a directory hierarchy. Packages allow for structuring your project logically, especially as it grows larger with multiple modules. A package is essentially a directory that contains multiple modules and an __init__.py file, which signifies to Python that the directory should be treated as a package.
Why Packages are Used:
Organization of Large Codebases: Packages help in grouping related modules, which makes larger projects more manageable.
Namespace Management: Packages can have sub-packages, which help in avoiding naming conflicts and managing large amounts of code.
Ease of Distribution: Packages can be distributed and installed using package managers like
pip, making it easier to share and use code libraries.
Creating and Using a Package
Suppose we have a package directory structure as follows:
my_package/
__init__.py
arithmetic.py
geometry.py
__init__.py: This can be an empty file or contain initialization code for the package.arithmetic.pyandgeometry.py: These are modules inside themy_packagepackage.
Letโs define functions in arithmetic.py and geometry.py:
# arithmetic.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
# geometry.py
def area_circle(radius):
import math
return math.pi * (radius ** 2)
def area_square(side):
return side * side
To use this package in your script, you can import it like this:
# main.py
from my_package import arithmetic, geometry
# Using functions from the package
print(arithmetic.add(10, 5)) # Output: 15
print(geometry.area_circle(3)) # Output: 28.27 (approx)
Common Python Modules and Packages
Python has a rich standard library with many commonly used modules and packages that are built into Python. Some of these are:
math Module: Provides mathematical functions.
Example:
import math
print(math.sqrt(16)) # Output: 4.0
datetime Module: Handles date and time manipulations.
Example:
import datetime
print(datetime.datetime.now()) # Output: Current date and time
random Module: Used for generating random numbers.
Example:
import random
print(random.randint(1, 10)) # Output: Random integer between 1 and 10
os Module: Provides functions to interact with the operating system.
Example:
import os
print(os.getcwd()) # Output: Current working directory
sys Module: Provides access to system-specific parameters and functions.
Example:
import sys
print(sys.version) # Output: Python version
re Module: Used for working with regular expressions.
Example:
import re
pattern = r"\bword\b"
text = "Find the word in this sentence."
match = re.search(pattern, text)
print(match.group()) # Output: 'word'
json Module: Used for parsing JSON data.
Example:
import json
data = '{"name": "John", "age": 30}'
parsed_data = json.loads(data)
print(parsed_data['name']) # Output: John
collections Module: Provides specialized container data types, like Counter, defaultdict, and namedtuple.
Example:
from collections import Counter
data = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
print(Counter(data)) # Output: Counter({'apple': 3, 'banana': 2, 'orange': 1})
numpy Package (external): Used for numerical computations, especially for array operations.
Example:
import numpy as np
array = np.array([1, 2, 3])
print(np.mean(array)) # Output: 2.0
pandas Package (external): Used for data analysis and manipulation.
Example:
import pandas as pd
data = {'Name': ['John', 'Jane'], 'Age': [28, 24]}
df = pd.DataFrame(data)
print(df)
tkinter Module: Used for creating graphical user interfaces (GUIs) in Python.
Example:
import tkinter as tk
# Create the main window
root = tk.Tk()
root.title("Simple Tkinter Window")
# Create a label
label = tk.Label(root, text="Enter your name:")
label.pack()
# Create an entry box
entry = tk.Entry(root)
entry.pack()
# Create a button that updates the label with the entry text
def update_label():
name = entry.get()
label.config(text=f"Hello, {name}!")
button = tk.Button(root, text="Greet Me", command=update_label)
button.pack()
# Start the GUI event loop
root.mainloop()
Summary Modules are single files with Python code, useful for organizing and reusing functions, classes, or variables.
Packages are directories containing multiple related modules and an init.py file, which make large projects more manageable and prevent naming conflicts. Using modules and packages keeps Python code modular, readable, and reusable, making it easier to structure and manage projects.
Control Flow & Conditional Statementsยถ
Control flow determines which code runs, when, and how often. It allows your program make decisions, repeat actions, or branch based on the conditions.
What Is Control Flow?
Control flow structures include:
Conditional Statements โ Decide which block of code to run
Loops โ Repeat code while a condition holds
Branching Keywords โ Jump or skip parts of the code
Conditional Statements
Used to test conditions (True or False) and run specific code blocks.
Basic if Statement
if condition:
# code runs if condition is True
Example:
age = 18
if age >= 18:
print("You're an adult.")
if-else Statement
if condition:
# if True
else:
# if False
Example:
if age >= 18:
print("Adult")
else:
print("Minor")
if-elif-else (Multiple Conditions)
if condition1:
# if condition1 is True
elif condition2:
# if condition1 is False and condition2 is True
else:
# if none are True
Example:
score = 85
if score >= 90:
print("A")
elif score >= 80:
print("B")
elif score >= 70:
print("C")
else:
print("F")
Comparison Operators
Used to form conditions.
Operator |
Meaning |
Example |
|---|---|---|
|
equal to |
|
|
not equal to |
|
|
greater than |
|
|
less than |
|
|
greater or equal |
|
|
less or equal |
|
Logical Operators
Used to combine multiple conditions.
Operator |
Meaning |
Example |
|---|---|---|
|
both must be True |
|
|
at least one must be True |
|
|
reverses a condition |
|
Nested Conditionals
Putting one conditional inside another.
if score >= 70:
if score >= 90:
print("A or A+")
else:
print("Pass")
else:
print("Fail")
๐ก Nesting too much can make code hard to read โ consider using
elifinstead when possible.
Indentation Matters in Python
Python uses indentation (usually 4 spaces) to show what code is inside the if, else, or loop block.
if is_sunny:
print("Wear sunglasses") # indented = inside
print("Have a nice day!") # outside
Control Flow Summary
Concept |
Description |
|---|---|
|
Runs code if condition is True |
|
Runs code if condition is False |
|
Adds extra conditions |
|
Compare values |
|
Combine or modify conditions |
Indentation |
Controls which code belongs to which block |
Example: Simple Login Check
username = input("Enter username: ")
if username == "admin":
print("Access granted")
else:
print("Access denied")
Loopsยถ
Loops let you repeat blocks of code. This is useful when working with lists, strings, or running a task multiple times.
Types of Loops in Python
forLoop
Used to loop through a sequence (like a list, string, or range()).
Basic Syntax:
for item in sequence:
# code to repeat
Example:
for fruit in ["apple", "banana", "cherry"]:
print(fruit)
With range():
for i in range(3):
print(i)
Output:
0 1 2
whileLoop
Repeats code while a condition is True.
Basic Syntax:
while condition:
# code to repeat
Example:
count = 0
while count < 3:
print(count)
count += 1
Loop Control Keywords
Keyword |
Purpose |
Example |
|---|---|---|
|
Exit the loop early |
|
|
Skip to the next iteration |
|
|
Placeholder that does nothing |
|
|
Runs if loop finishes without |
|
Nested Loopsยถ
A nested loop is a loop inside another loop. The inner loop completes all its iterations for each outer loop cycle.
Syntax:
for outer in outer_range:
for inner in inner_range:
# nested loop body
Example 1: Nested for Loops (Multiplication Table)
for i in range(1, 4):
for j in range(1, 4):
print(i * j, end=" ")
print() # new line after inner loop
Output:
1 2 3
2 4 6
3 6 9
Example 2: Nested Loops with Strings
words = ["hi", "hello"]
for word in words:
for letter in word:
print(letter, end=" ")
print()
Output:
h i
h e l l o
Example 3: Nested while + for
x = 0
while x < 2:
for y in range(3):
print(f"x={x}, y={y}")
x += 1
Choosing the Right Loop
Use this |
Whenโฆ |
|---|---|
|
You know how many times to loop (e.g. lists) |
|
You loop until something changes |
Nested |
You need combinations, grids, or pairs |
Summary
Keyword |
Description |
|---|---|
|
Loop through a sequence |
|
Loop while a condition is true |
|
Exit loop immediately |
|
Skip to next iteration |
|
Do nothing (placeholder) |
|
Runs if loop ends without |
Nested loop |
Loop inside another loop |
# Create a square
size = int(input("Enter the size of the square: "))
for i in range(size):
for j in range(size):
if i == 0 or i == size-1 or j == 0 or j == size-1:
print("*", end=" ")
else:
print(" ", end=" ")
print("\r")
Sample Output
Enter the size of the square: 10
* * * * * * * * * *
* *
* *
* *
* *
* *
* *
* *
* *
* * * * * * * * * *
Functions/ Methods/ Parametersยถ
In computer programming, the terms function, method, and procedure have distinct meanings, though they are often used interchangeably in casual conversation. Hereโs a breakdown of each:
Functionยถ
Definition: A function is a block of code that takes inputs (arguments), performs a specific task, and returns a value. Functions are designed to compute a value and can be used across different parts of a program.
Example: In Python, a simple function might look like this:
def add(a, b): return a + b
Methodยถ
Definition: A method is similar to a function but is associated with an object or a class in object-oriented programming (OOP). Methods operate on data contained within the object and can modify the objectโs state.
Example: In Java, a method in a class might look like this:
public class Calculator { public int add(int a, int b) { return a + b; } }
More Methodsยถ
As was stated before, methods are functions that belong to objects and are used to operate on those objects. They are similar to functions but have a special relationship with the object they belong to, known as the instance.
Letโs break down the key concepts:
Instance Methods
Most methods are called instance methods because they operate on an instance of a class (an object created from a class).
When an instance method is defined, the first parameter is usually
self, which represents the instance of the class on which the method is called. Thisselfparameter allows the method to access other attributes and methods of the same object.
class Dog: def __init__(self, name): self.name = name def bark(self): # Instance method print(f"{self.name} says Woof!") my_dog = Dog("Buddy") my_dog.bark() # Output: "Buddy says Woof!"
In this example,
bark()is an instance method that usesselfto access thenameattribute of themy_doginstance.Class Methods
Class methods are methods that operate on the class itself rather than on individual instances. They are marked with the
@classmethoddecorator.Instead of
self, they takeclsas their first parameter, which refers to the class itself, not an instance.
class Dog: species = "Canis familiaris" @classmethod def get_species(cls): return cls.species print(Dog.get_species()) # Output: "Canis familiaris"
Here,
get_species()is a class method that accesses thespeciesattribute defined on the class itself.Static Methods
Static methods are methods that donโt operate on an instance or class. They behave like normal functions but reside within a class for organizational purposes.
Static methods are marked with the
@staticmethoddecorator and donโt requireselforclsparameters.
class MathHelper: @staticmethod def add(a, b): return a + b print(MathHelper.add(5, 7)) # Output: 12
add()is a static method and does not rely on any data from an instance or the class. It simply performs a task.Special Methods (Magic Methods)
Special methods, also known as magic methods or dunder methods (short for โdouble underscoreโ), allow instances of classes to interact with built-in Python operations in unique ways.
These methods have names starting and ending with double underscores (e.g.,
__init__,__str__,__len__).
class Book: def __init__(self, title, author): self.title = title self.author = author def __str__(self): return f"{self.title} by {self.author}" my_book = Book("1984", "George Orwell") print(my_book) # Output: "1984 by George Orwell"
The
__str__()method is a magic method that defines how an object should be represented as a string.Method Chaining
Method chaining allows you to call multiple methods on the same object in a single statement. To enable this, each method must return the object itself.
class TextEditor: def __init__(self, text=""): self.text = text def add_text(self, text): self.text += text return self def make_uppercase(self): self.text = self.text.upper() return self editor = TextEditor().add_text("Hello ").add_text("World!").make_uppercase() print(editor.text) # Output: "HELLO WORLD!"
Here,
add_textandmake_uppercasereturnself, so you can chain the methods together.
Key Points to Remember
Instance Methods: Operate on individual objects and use
self.Class Methods: Operate on the class itself and use
cls.Static Methods: Do not operate on instances or the class; theyโre independent but grouped within the class.
Special Methods: Have specific purposes within Pythonโs syntax (e.g.,
__init__for initialization,__str__for string representation).
Methods make object-oriented programming in Python powerful, allowing objects to encapsulate both data and functionality.
Proceduresยถ
In Python, a procedure is a function that performs a task without returning a value. Itโs called for its side effects, such as printing text, updating a file, or modifying a global variable. It doesnโt give anything back to the caller.
Python Procedure
def greet_user():
print("Welcome to the program!")
How to call a procedure:
greet_user()
Sample Output
Welcome to the program!
Comparing Function Membersยถ
Term |
Python Form |
Returns a Value? |
Used For |
Example |
|---|---|---|---|---|
Method |
Function inside an object/class |
โ /โ Depends |
Performing actions on objects |
|
Procedure |
|
โ No |
Doing a task with side effects |
|
Function |
|
โ Yes |
Calculating and returning a result |
|
Data Structuresยถ
Python provides a variety of built-in data structures to store and organize data, each optimized for specific types of operations. Hereโs an overview of the core data structures in Python and examples of how and when each might be used in real-world applications.
AP CSP Standards
AAP-3.A: Collect and represent data digitally. Example: Use variables, lists, or dictionaries to store information.
# List of student names
students = ["Alice", "Bob", "Charlie"]
# Dictionary mapping names to ages
ages = {"Alice": 14, "Bob": 15, "Charlie": 14}
AAP-3.B: Use abstractions to organize and process data. Example: Use a list of dictionaries to manage multiple records instead of separate variables.
students = [
{"name": "Alice", "age": 14},
{"name": "Bob", "age": 15},
{"name": "Charlie", "age": 14}
]
AAP-3.C: Analyze data to draw conclusions. Example: Loop through a list or dictionary to compute averages or counts.
# Count students age 14
count = sum(1 for student in students if student["age"] == 14)
print(count) # Output: 2
AAP-2.E: Develop algorithms using sequencing, selection, and iteration. Example: Iterate over data structures to implement logic.
for student in students:
if student["age"] > 14:
print(student["name"])
AAP-2.G: Use abstraction to manage complexity in algorithms. Example: Wrap repeated operations on data structures in functions.
def count_age(students, age):
return sum(1 for student in students if student["age"] == age)
print(count_age(students, 14)) # Output: 2
1. Lists (list)
A list is an ordered, mutable collection that allows duplicate elements. Itโs the most versatile data structure in Python and can store any data type.
Real-World Example: Shopping Cart in E-commerce In an online shopping cart, each item the user adds can be stored in a list. Since the order and the ability to add/remove items matter, a list is ideal here.
shopping_cart = ["laptop", "mouse", "keyboard"]
shopping_cart.append("headphones") # Add an item
shopping_cart.remove("mouse") # Remove an item
print(shopping_cart) # Output: ['laptop', 'keyboard', 'headphones']
Why Use a List?
Best for: Ordered, changeable collections.
When to Use: Managing items in a specific order where additions and removals are frequent.
2. Tuples (tuple)
A tuple is an ordered, immutable collection, which means its values cannot be changed after creation. Tuples are often used to store related data.
Real-World Example: GPS Coordinates Tuples are ideal for storing data that shouldnโt change, such as latitude and longitude coordinates for locations.
coordinates = (40.7128, -74.0060) # New York City
print(coordinates) # Output: (40.7128, -74.0060)
Why Use a Tuple?
Best for: Fixed sets of related data.
When to Use: When you need a collection that shouldnโt be modified, like configuration data or coordinate points.
3. Sets (set)
A set is an unordered collection with no duplicate elements. Sets are useful when you need to eliminate duplicate data or perform set operations like union, intersection, and difference.
Real-World Example: Unique Users in a System In a web application, sets can store unique user IDs to ensure each user appears only once.
user_ids = {101, 102, 103, 101} # Duplicate '101' is ignored
print(user_ids) # Output: {101, 102, 103}
Why Use a Set?
Best for: Collections of unique elements.
When to Use: When duplicates need to be removed, or you need to perform set operations.
4. Dictionaries (dict)
A dictionary is an unordered collection of key-value pairs. Itโs useful for storing data that you want to look up by a unique key.
Real-World Example: Product Catalog in E-commerce Dictionaries are perfect for storing product information where each product ID maps to a productโs details.
product_catalog = {
"P001": {"name": "Laptop", "price": 1000},
"P002": {"name": "Mouse", "price": 25},
"P003": {"name": "Keyboard", "price": 50}
}
print(product_catalog["P001"]["name"]) # Output: Laptop
Why Use a Dictionary?
Best for: Key-value pair data.
When to Use: Fast lookups of values by keys, such as a database record by ID or configuration settings.
5. Stacks (list or collections.deque)
A stack follows the Last-In, First-Out (LIFO) principle. You can implement a stack using a list (with .append() and .pop() methods) or with deque from the collections module.
Real-World Example: Undo Feature in Text Editor In text editors, the undo functionality is often implemented with a stack where each user action is stored as a new item on the stack. When the user presses โundo,โ the most recent action is popped from the stack.
actions = ["type A", "type B", "type C"]
actions.append("type D") # Latest action
last_action = actions.pop() # Undo the last action
print(last_action) # Output: type D
Why Use a Stack?
Best for: Last-In, First-Out operations.
When to Use: Undo/redo features, function call tracking, and navigation history.
6. Queues (collections.deque or queue.Queue)
A queue follows the First-In, First-Out (FIFO) principle. You can implement a queue with deque from collections or Queue from queue module for thread-safe operations.
Real-World Example: Print Queue in Office In an office printer system, documents to be printed are often handled with a queue where the first document sent is printed first.
from collections import deque
print_queue = deque(["Document1", "Document2", "Document3"])
print_queue.append("Document4") # Add a document to the queue
first_document = print_queue.popleft() # Print (remove) the first document
print(first_document) # Output: Document1
Why Use a Queue?
Best for: First-In, First-Out operations.
When to Use: Task scheduling, order processing, and any process where items need to be processed in the order received.
7. Linked Lists (Custom Implementation) Python does not have a built-in linked list, but you can implement one. Linked lists are useful for dynamic memory allocation and data that frequently changes size.
Real-World Example: Music Playlist In a music player, a playlist could be implemented as a linked list where each song node points to the next song. This allows easy addition or removal of songs.
class Node:
def __init__(self, data):
self.data = data
self.next = None
class LinkedList:
def __init__(self):
self.head = None
def append(self, data):
new_node = Node(data)
if not self.head:
self.head = new_node
return
last = self.head
while last.next:
last = last.next
last.next = new_node
# Usage
playlist = LinkedList()
playlist.append("Song 1")
playlist.append("Song 2")
Why Use a Linked List?
Best for: Data that needs frequent insertion and deletion.
When to Use: Implementing playlists, managing memory in embedded systems, or when resizing overhead is a concern.
8. Heaps (heapq)
A heap is a special tree structure used to maintain a priority queue. In Python, heapq implements a min-heap by default.
Real-World Example: Priority Queue for Emergency Services In emergency dispatch, a priority queue (heap) could prioritize patients by the severity of their condition.
import heapq
emergency_queue = []
heapq.heappush(emergency_queue, (2, "Patient B")) # Priority 2
heapq.heappush(emergency_queue, (1, "Patient A")) # Priority 1 (higher)
heapq.heappush(emergency_queue, (3, "Patient C")) # Priority 3
# Remove the patient with the highest priority (lowest number)
highest_priority_patient = heapq.heappop(emergency_queue)
print(highest_priority_patient) # Output: (1, 'Patient A')
Why Use a Heap?
Best for: Priority-based operations.
When to Use: Scheduling tasks based on priority, pathfinding algorithms, and load balancing.
Summary Table
Data Structure |
Best Use Case |
Real-World Instance |
|---|---|---|
List |
Ordered collections |
Shopping cart, to-do list |
Tuple |
Immutable sets of data |
GPS coordinates, fixed configuration |
Set |
Unique elements |
Unique usernames, eliminating duplicates |
Dictionary |
Key-value mappings |
Product catalog, contact list |
Stack |
LIFO operations |
Undo in text editor |
Queue |
FIFO operations |
Print queue, task scheduling |
Linked List |
Frequent insertions/deletions |
Music playlist, dynamic data size |
Heap |
Priority-based operations |
Emergency dispatch, priority scheduling |
Choosing the right data structure depends on the specific needs of the application, such as order, mutability, uniqueness, or priority.
Lists and List Manipulationยถ
AP CSP Learning Goals
AAP-4.A: Use data abstractions to manage complexity.
For this class, we will not be using tuples, but you should be familiar with how they are used and the difference of a list.
Indexing |
Ordered |
Mutable |
Duplicate |
|
|---|---|---|---|---|
List |
|
|
|
|
Tuple |
|
|
|
|
Set |
|
|
|
|
Dictionary |
|
|
|
|
In Python, lists are indexed collections, meaning each item in a list has a specific position. Python uses zero-based indexing, which means the first element is accessed with index 0, the second with 1, and so on. Python also supports negative indexing, where -1 refers to the last item, -2 to the second-to-last, and so forth.
Example of indexing POTATO
__________________________________________________
string1 = | P | O | T | A | T | O |
pos_index # 0 1 2 3 4 5 6
neg_index # -7 -6 -5 -4 -3 -2 -1
__________________________________________________
Take a look at the program snippets below:
1. Program to Print the Index of the First Occurrence of the Letter โTโ in โPOTATOโ
This program finds the index of the first occurrence of โTโ in the word โPOTATO.โ
word = "POTATO"
index_of_T = word.index("T") # Finds the first occurrence of 'T'
print("Index of first 'T' in POTATO:", index_of_T)
Output:
Index of first 'T' in POTATO: 2
2. Program to Print All Instances (Indices) of โTโ in โPOTATOโ
This program will find and print the index of each occurrence of โTโ in the word โPOTATO.โ
word = "POTATO"
indices_of_T = [index for index, letter in enumerate(word) if letter == "T"]
print("All indices of 'T' in POTATO:", indices_of_T)
Output:
All indices of 'T' in POTATO: [2, 4]
3. Program to Print the First 3 Letters of the Word โPOTATOโ
This program extracts and prints the first 3 letters of the word โPOTATOโ using slicing.
word = "POTATO"
first_three_letters = word[:3] # Slicing to get the first three letters
print("First 3 letters of POTATO:", first_three_letters)
Output:
First 3 letters of POTATO: POT
4. Program to Print โTOPโ Using Reverse Indexing
Using reverse indexing, this program prints the letters โT,โ โO,โ and โPโ in reverse order to form โTOP.โ
word = "POTATO"
reverse_top = word[-6:-3] # Reverse indexing to get 'T', 'O', 'P'
print("TOP using reverse indexing:", reverse_top)
Output:
TOP using reverse indexing: TOP
Explanation:
word[-3]starts at end of index negative three but does not include the item within -3.word[-4]accesses the negative fourth letter in the index, โTโ.word[-5]accesses the negative fifth letter in the index, โOโ.word[-6]accesses the negative sixth letter in the index, โPโ.
NEED COMMENT ON PROGRAM INDEXs ABOVE
Accessing List Elements with Indexing
Given a list:
my_list = ["apple", "banana", "cherry", "date", "elderberry"]
my_list[0]gives"apple", the first item.my_list[1]gives"banana", the second item.my_list[4]gives"elderberry", the fifth item.
If you try to access an index outside the range, Python will raise an IndexError:
print(my_list[5]) # Raises IndexError: list index out of range
Negative Indexing
Python also allows negative indices to start counting from the end of the list:
my_list[-1]gives"elderberry", the last item.my_list[-2]gives"date", the second-to-last item.my_list[-5]gives"apple", the first item (same asmy_list[0]).
Slicing a List
Python also allows you to retrieve a subset of elements from a list using slicing. The syntax is list[start:end:step], where:
startis the index where the slice begins (inclusive).endis where the slice ends (exclusive).stepdetermines the number of steps between each item in the slice (optional).
Example of Slicing
my_list = ["apple", "banana", "cherry", "date", "elderberry"]
# Slicing from the start to the end of the list
print(my_list[1:4]) # Output: ['banana', 'cherry', 'date']
# Slicing with a step of 2
print(my_list[0:5:2]) # Output: ['apple', 'cherry', 'elderberry']
# Slicing with negative indices
print(my_list[-4:-1]) # Output: ['banana', 'cherry', 'date']
Omitting Start, End, or Step
You can omit any part of the slice syntax:
Omitting
startdefaults it to the beginning of the list.Omitting
endgoes to the end of the list.Omitting
stepdefaults it to1.
Examples of Omitting Parts of the Slice
# All elements from the start
print(my_list[:3]) # Output: ['apple', 'banana', 'cherry']
# All elements from a specific index to the end
print(my_list[2:]) # Output: ['cherry', 'date', 'elderberry']
# Entire list with a step of 2
print(my_list[::2]) # Output: ['apple', 'cherry', 'elderberry']
Using Negative Step
A negative step reverses the order, allowing you to iterate backward through the list.
Example with Negative Step
# Reverse the entire list
print(my_list[::-1]) # Output: ['elderberry', 'date', 'cherry', 'banana', 'apple']
# Every second item from the end to the beginning
print(my_list[::-2]) # Output: ['elderberry', 'cherry', 'apple']
In summary, Pythonโs list indexing is versatile, supporting positive and negative indices, as well as slicing with optional start, end, and step parameters. This flexibility allows for efficient access and manipulation of list elements.
Specifically Listsยถ
In this program, we use the most common methods that is able to manipulate a list: append, insert, remove, pop, sort, reverse, count, index, extend, and clear.
# Initializing a list
fruits = ["apple", "banana", "cherry"]
print("Initial list:", fruits)
# 1. append() - Adds an element at the end of the list
fruits.append("orange")
print("After append:", fruits)
# 2. insert() - Adds an element at the specified position
fruits.insert(1, "blueberry")
print("After insert at index 1:", fruits)
# 3. remove() - Removes the first item with the specified value
fruits.remove("banana")
print("After remove 'banana':", fruits)
# 4. pop() - Removes the element at the specified position (default is the last element)
popped_item = fruits.pop()
print("After pop:", fruits)
print("Popped item:", popped_item)
# 5. index() - Returns the index of the first element with the specified value
index_of_cherry = fruits.index("cherry")
print("Index of 'cherry':", index_of_cherry)
# 6. count() - Returns the number of elements with the specified value
fruits.append("apple")
apple_count = fruits.count("apple")
print("Count of 'apple':", apple_count)
# 7. sort() - Sorts the list in ascending order
fruits.sort()
print("After sort:", fruits)
# 8. reverse() - Reverses the order of the list
fruits.reverse()
print("After reverse:", fruits)
# 9. extend() - Adds all elements of a list to another list
more_fruits = ["mango", "pineapple", "kiwi"]
fruits.extend(more_fruits)
print("After extend with more_fruits:", fruits)
# 10. clear() - Removes all elements from the list
fruits.clear()
print("After clear:", fruits)
Explanation of the methods:ยถ
append(): Adds an item to the end of the list.insert(index, item): Inserts an item at the specified index.remove(item): Removes the first occurrence of an item from the list.pop(index): Removes and returns the item at the given index; default is the last item.index(item): Finds the index of the first occurrence of the specified item.count(item): Counts how many times an item appears in the list.sort(): Sorts the list in ascending order (in-place).reverse(): Reverses the list (in-place).extend(list): Extends the list by appending elements from another list.clear(): Removes all elements from the list.
File Handlingยถ
AP CSP Learning Goal:
AAP-2.B: Use data stored in files.
File handling in Python allows you to work with files on your computer: reading data from files, writing data to files, and appending data. Python provides built-in functions and modules to make this straightforward. Hereโs a guide to the basics of file handling in Python 3.x, with examples.
1. Opening and Closing Files
The open() function is used to open a file. It takes two main parameters:
Filename: the name of the file you want to work with.
Mode: how you want to open the file, such as for reading or writing.
Here are the common modes:
'r'- Read (default mode). Opens a file for reading. Raises an error if the file doesnโt exist.'w'- Write. Opens a file for writing. Creates a new file if it doesnโt exist or truncates the file if it exists.'a'- Append. Opens a file for appending. Creates a new file if it doesnโt exist.'r+'- Read and write. Opens a file for both reading and writing.
Itโs a good practice to close a file after youโre done working with it to free up system resources. You can do this with the close() method or by using a with statement (recommended), which automatically closes the file for you.
Example of Opening and Closing a File
# Opening a file for reading
file = open("example.txt", "r")
content = file.read()
print(content)
file.close() # Closing the file
Using a with statement:
with open("example.txt", "r") as file:
content = file.read()
print(content)
# No need to close the file, itโs automatically handled
2. Reading Files
There are several methods to read from a file:
read(): Reads the entire file as a string.readline(): Reads a single line at a time.readlines(): Reads all lines and returns them as a list of strings.
Example of Reading a File
Assuming example.txt contains:
Hello, World!
This is a text file.
# Reading the entire file
with open("example.txt", "r") as file:
content = file.read()
print(content)
# Reading line by line
with open("example.txt", "r") as file:
for line in file:
print(line.strip())
# Reading all lines as a list
with open("example.txt", "r") as file:
lines = file.readlines()
print(lines)
3. Writing to Files
To write data to a file, you can use:
write(): Writes a string to the file.writelines(): Writes a list of strings to the file.
Example of Writing to a File
# Writing to a file (overwrites if the file already exists)
with open("example.txt", "w") as file:
file.write("This is a new line.\n")
file.write("Writing to the file.")
# Writing multiple lines at once
with open("example.txt", "w") as file:
lines = ["Line 1\n", "Line 2\n", "Line 3\n"]
file.writelines(lines)
4. Appending to Files
To add data to the end of an existing file, use the 'a' mode.
Example of Appending to a File
with open("example.txt", "a") as file:
file.write("\nAppending this line to the file.")
5. Working with Binary Files
Binary files (like images or executable files) require using the 'b' mode (e.g., 'rb' for reading, 'wb' for writing).
Example of Working with Binary Files
# Reading a binary file (e.g., an image)
with open("image.jpg", "rb") as file:
data = file.read()
print(data)
# Writing to a binary file
with open("copy_image.jpg", "wb") as file:
file.write(data)
6. Using seek() and tell() for File Positioning
seek(offset, from_what): Moves the file pointer to a specific position.tell(): Returns the current position of the file pointer.
Example of Using seek() and tell()
with open("example.txt", "r") as file:
print(file.read(5)) # Read first 5 characters
print(file.tell()) # Output current file position
file.seek(0) # Go back to the beginning
print(file.read(5)) # Read first 5 characters again
Summary
Use
open()with the appropriate mode for your needs.Use
with open()to ensure files are properly closed.Use
read(),readline(), orreadlines()for reading files.Use
write()orwritelines()for writing to files.Use
seek()andtell()to navigate through files.
This covers the basics of file handling in Python!
Object-Oriented Programmingยถ
Classes/ Objectsยถ
In Python, the concepts of classes, objects, attributes, methods, and constructors are fundamental to object-oriented programming (OOP).
1. Class
A class in Python is like a blueprint for creating objects (an instance of). It defines attributes (properties) and methods (functions) that objects created from the class will have. A class encapsulates data and functions that operate on that data.
Keyword: class
Example:
class Car:
pass # Empty class definition for now
2. Object
An object is an instance of a class. Itโs a specific, individual entity created based on the blueprint (class). You can think of it as a real-world object that embodies the attributes and behaviors of its class.
Creating an Object: To create an object, you instantiate the class.
Example:
my_car = Car() # Creating an object (instance) of class Car
3. Attributes
Attributes are variables that belong to a class or an object. They represent the state or properties of an object. There are two types of attributes:
Instance Attributes: These are unique to each instance of a class.
Class Attributes: These are shared across all instances of the class.
Keyword: self
Example:
class Car:
def __init__(self, make, model, year): # Constructor to initialize attributes
self.make = make # Instance attribute
self.model = model # Instance attribute
self.year = year # Instance attribute
4. Methods
Methods are functions that belong to a class and define behaviors that the objects of the
class can perform. Methods typically take the self parameter, which refers to the current instance
of the class.
Keyword: def
Example:
class Car:
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
def start_engine(self):
print(f"The {self.year} {self.make} {self.model}'s engine is now running.")
def stop_engine(self):
print(f"The {self.year} {self.make} {self.model}'s engine is now off.")
5. Constructors
A constructor is a special method called __init__ in Python that is automatically invoked when an
object is created from a class. Itโs used to initialize the attributes of the new object.
Keyword: __init__
Example:
class Car:
def __init__(self, make, model, year): # Constructor
self.make = make
self.model = model
self.year = year
Putting It All Togetherยถ
Multiple Classes, Objects, Constructors, Methods, and Attributes
Class 1: Car
class Car:
def __init__(self, make, model, year):
self.make = make # Instance Attribute
self.model = model # Instance Attribute
self.year = year # Instance Attribute
def start_engine(self):
print(f"The {self.year} {self.make} {self.model}'s engine is now running.")
def stop_engine(self):
print(f"The {self.year} {self.make} {self.model}'s engine is now off.")
Class 2: Person
class Person:
def __init__(self, name, age, occupation):
self.name = name # Instance Attribute
self.age = age # Instance Attribute
self.occupation = occupation # Instance Attribute
def greet(self):
print(f"Hello, my name is {self.name} and I am a {self.occupation}.")
def have_birthday(self):
self.age += 1
print(f"Happy Birthday, {self.name}! You are now {self.age} years old.")
Creating Objects and Using Methods
# Creating objects (instances of classes)
car1 = Car("Toyota", "Corolla", 2022)
car2 = Car("Honda", "Civic", 2020)
person1 = Person("Alice", 30, "Engineer")
person2 = Person("Bob", 25, "Designer")
# Using methods
car1.start_engine()
car2.stop_engine()
person1.greet()
person2.have_birthday()
Output:
The 2022 Toyota Corolla's engine is now running.
The 2020 Honda Civic's engine is now off.
Hello, my name is Alice and I am an Engineer.
Happy Birthday, Bob! You are now 26 years old.
Key Vocabulary:
Class: A blueprint for creating objects.
Object: An instance of a class.
Attributes: Variables that store data associated with objects (can be instance or class attributes).
Methods: Functions that define behaviors associated with objects (usually take
selfas the first argument).Constructor: A special method
__init__that initializes attributes when a new object is created.
Creating Input for the user using OOP
class Car:
def __init__(self, make, model, year):
self.make = make # Instance Attribute
self.model = model # Instance Attribute
self.year = year # Instance Attribute
def start_engine(self):
print(f"The {self.year} {self.make} {self.model}'s engine is now running.")
def stop_engine(self):
print(f"The {self.year} {self.make} {self.model}'s engine is now off.")
class Person:
def __init__(self, name, age, occupation):
self.name = name # Instance Attribute
self.age = age # Instance Attribute
self.occupation = occupation # Instance Attribute
def greet(self):
print(f"Hello, my name is {self.name} and I am a {self.occupation}.")
def have_birthday(self):
self.age += 1
print(f"Happy Birthday, {self.name}! You are now {self.age} years old.")
# Function to create a car object based on user input
def create_car():
print("\nEnter the details for the car:")
make = input("Make: ")
model = input("Model: ")
year = int(input("Year: "))
return Car(make, model, year)
# Function to create a person object based on user input
def create_person():
print("\nEnter the details for the person:")
name = input("Name: ")
age = int(input("Age: "))
occupation = input("Occupation: ")
return Person(name, age, occupation)
# Main program to create and interact with the objects
def main():
# Create Car and Person objects based on user input
car1 = create_car()
car2 = create_car()
person1 = create_person()
person2 = create_person()
# Use the methods on the objects
car1.start_engine()
car2.stop_engine()
person1.greet()
person2.have_birthday()
# Run the main program
if __name__ == "__main__":
main()
User Input for Car: The
create_car()function asks the user for the carโs make, model, and year.User Input for Person: The
create_person()function prompts the user for the personโs name, age, and occupation.Creating Objects: The objects (
CarandPerson) are created by calling these functions, which return the new objects with the user-specified attributes.Using Methods: The methods for
CarandPersonobjects are called as before, but now with user-provided data.
Example Output:
Enter the details for the car:
Make: Ford
Model: Mustang
Year: 2021
Enter the details for the car:
Make: Chevrolet
Model: Camaro
Year: 2020
Enter the details for the person:
Name: Sarah
Age: 29
Occupation: Doctor
Enter the details for the person:
Name: John
Age: 35
Occupation: Artist
The 2021 Ford Mustang's engine is now running.
The 2020 Chevrolet Camaro's engine is now off.
Hello, my name is Sarah and I am a Doctor.
Happy Birthday, John! You are now 36 years old.
Another example and explanation of a program that demonstrates the use of classes, objects, and constructors.
A Simple Bank Account System
# Main program
if __name__ == "__main__":
# Create an instance of BankAccount
account1 = BankAccount("Alice Smith", 1000)
# Display account information
account1.display_account_info()
# Perform some transactions
account1.deposit(500)
account1.withdraw(200)
account1.withdraw(1500) # This should fail
account1.display_account_info()
""" -------------------------** Module ** ------------------------- """
class BankAccount:
"""A class representing a bank account."""
def __init__(self, account_holder, balance=0):
"""
Constructor to initialize the account holder's name and balance.
Args:
account_holder (str): The name of the account holder.
balance (float): The initial balance of the account (default is 0).
"""
self.account_holder = account_holder # Instance variable for account holder's name
self.balance = balance # Instance variable for account balance
def deposit(self, amount):
"""
Deposit money into the bank account.
Args:
amount (float): The amount to be deposited.
"""
if amount > 0:
self.balance += amount # Increase balance by the deposit amount
print(f"Deposited ${amount:.2f}. New balance: ${self.balance:.2f}")
else:
print("Deposit amount must be positive!")
def withdraw(self, amount):
"""
Withdraw money from the bank account.
Args:
amount (float): The amount to be withdrawn.
"""
if 0 < amount <= self.balance:
self.balance -= amount # Decrease balance by the withdrawal amount
print(f"Withdrew ${amount:.2f}. New balance: ${self.balance:.2f}")
else:
print("Invalid withdrawal amount!")
def get_balance(self):
"""Return the current balance of the account."""
return self.balance
def display_account_info(self):
"""Display the account holder's information and current balance."""
print(f"Account Holder: {self.account_holder}")
print(f"Current Balance: ${self.balance:.2f}")
Explanation
Main Program:
The main program creates an account, displays account information, performs deposits and withdrawals, and handles invalid transactions gracefully.
Class:
class BankAccount:defines a class namedBankAccount. A class is a blueprint for creating objects, encapsulating data and methods that operate on that data.
Constructor:
The
__init__method is a special method called the constructor. It is invoked when an object of the class is created. In this example, it initializes the account holderโs name and balance:account_holder: A string representing the name of the account holder.balance: A float representing the initial balance of the account (default is 0).
Instance Variables:
self.account_holderandself.balanceare instance variables that store the account holderโs name and balance for each instance of theBankAccountclass.
Methods:
deposit(amount): This method adds a specified amount to the account balance, ensuring the amount is positive.withdraw(amount): This method subtracts a specified amount from the balance, ensuring the withdrawal does not exceed the current balance.get_balance(): Returns the current balance of the account.display_account_info(): Displays the account holderโs information and current balance.
Objects:
account1 = BankAccount("Alice Smith", 1000): This line creates an instance (object) of theBankAccountclass with โAlice Smithโ as the account holder and an initial balance of $1000.
Copy and paste this code into a Python environment. It will create a bank account for โAlice Smith,โ allowing you to see how deposits and withdrawals affect the balance.
Below is a program that demonstrates the use of objects and classes to represent dogs. It includes constructors with no arguments, one argument, and two arguments.
class Dog:
def __init__(self, name=None, breed=None):
self.name = name
self.breed = breed
def bark(self):
return "Woof!"
def display_info(self):
if self.name and self.breed:
return f"This is {self.name}, a {self.breed} dog."
elif self.name:
return f"This is {self.name}."
elif self.breed:
return f"This is a {self.breed} dog."
else:
return "This is a dog."
# Creating an instance of Dog with no arguments
dog1 = Dog()
print(dog1.display_info()) # Output: This is a dog.
# Creating an instance of Dog with one argument
dog2 = Dog("Buddy")
print(dog2.display_info()) # Output: This is Buddy.
# Creating an instance of Dog with two arguments
dog3 = Dog("Max", "Labrador")
print(dog3.display_info()) # Output: This is Max, a Labrador dog.
# Accessing methods of the Dog class
print(dog3.bark()) # Output: Woof!
Explanation:
We define a class
Dogwith a constructor__init__which initializes the attributesnameandbreed. The constructor can take 0, 1, or 2 arguments.The
barkmethod returns a string representing the sound a dog makes.The
display_infomethod displays information about the dog based on its attributes.We create instances of the
Dogclass with different combinations of arguments to demonstrate the constructors with no arguments, one argument, and two arguments.Finally, we access methods of the
Dogclass using the created instances.
Exception Handlingยถ
Exception handling in Python allows you to manage errors that arise during program execution, helping the program to continue running or provide a more user-friendly message instead of crashing. Python uses try, except, else, and finally blocks for this purpose.
Basic Syntax of Exception Handling The basic syntax for handling exceptions in Python looks like this:
try:
# Code that may raise an exception
except SomeException as e:
# Code that runs if the specified exception occurs
else:
# Code that runs if no exceptions occur
finally:
# Code that always runs, regardless of whether an exception occurred
try: Wraps code that may raise an exception.
except: Catches and handles specific exceptions.
else: Executes code if no exception occurred.
finally: Executes code regardless of whether an exception occurred, often used for cleanup actions.
Example 1: Basic Exception Handling
Hereโs a basic example of handling a ZeroDivisionError:
try:
result = 10 / 0
except ZeroDivisionError:
print("You can't divide by zero!")
else:
print("Division successful:", result)
finally:
print("End of operation.")
Example 2: Handling Multiple Exceptions
You can handle multiple exceptions by specifying them in separate except blocks or by combining them.
try:
user_input = int(input("Enter a number: "))
result = 100 / user_input
except ValueError:
print("Invalid input! Please enter an integer.")
except ZeroDivisionError:
print("Division by zero is not allowed.")
else:
print("Result:", result)
finally:
print("Execution completed.")
Real-World Examples of Exception Handling
1. File Handling with Exceptions When working with files, itโs common to check if a file exists before attempting to read or write to it. Using exception handling here ensures that the program doesnโt crash if the file is missing.
try:
with open("data.txt", "r") as file:
content = file.read()
print(content)
except FileNotFoundError:
print("The file 'data.txt' does not exist.")
except IOError:
print("An error occurred while reading the file.")
2. Database Connection Handling In applications that connect to a database, itโs essential to handle exceptions in case the connection fails due to network issues, wrong credentials, etc.
import sqlite3
try:
connection = sqlite3.connect('my_database.db')
cursor = connection.cursor()
cursor.execute("SELECT * FROM users")
data = cursor.fetchall()
print(data)
except sqlite3.DatabaseError as e:
print("Database error:", e)
finally:
if connection:
connection.close()
3. User Input Validation In scenarios where user input is required, validation and exception handling ensure that unexpected input doesnโt crash the program.
try:
age = int(input("Enter your age: "))
if age < 0:
raise ValueError("Age cannot be negative.")
except ValueError as e:
print("Invalid input:", e)
else:
print(f"Your age is {age}")
4. Network Request Handling When making network requests (e.g., API requests), itโs good practice to handle exceptions, especially for connectivity issues, timeouts, or HTTP errors.
import requests
try:
response = requests.get("https://api.example.com/data")
response.raise_for_status() # Raises an HTTPError for bad responses (4xx or 5xx)
data = response.json()
print(data)
except requests.ConnectionError:
print("Failed to connect to the server.")
except requests.Timeout:
print("The request timed out.")
except requests.HTTPError as e:
print("HTTP error:", e)
except requests.RequestException as e:
print("An error occurred:", e)
Summary Exception handling helps manage different types of errors gracefully, enabling applications to run smoothly without abrupt failures. In real-world applications, exception handling is vital for improving reliability, especially in operations involving file access, user input, database connections, or network requests.
Lambda Functionsยถ
In Python, a lambda function is a small, anonymous function that is defined using the lambda keyword. Unlike regular functions created with def, lambda functions are written in a single line and are often used for short, simple operations that are not reused elsewhere.
Basic Lambda Syntaxยถ
lambda arguments: expression
arguments: The input(s) to the function.
expression: The operation or calculation that returns a result.
Lambda functions can take any number of arguments, but they are limited to a single expression. They are useful when you need a simple function for a short period and donโt want to formally define it with def.
1. Basic Example of a Lambda Function A simple example of a lambda function that adds 10 to a given number:
add_10 = lambda x: x + 10
print(add_10(5)) # Output: 15
2. Lambda Function with Multiple Arguments Lambda functions can accept multiple arguments, which is useful for quick calculations.
multiply = lambda x, y: x * y
print(multiply(4, 5)) # Output: 20
3. Using Lambda Functions with map()
map() applies a function to each item in an iterable (like a list). Lambda functions are frequently used with map() to simplify operations.
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
print(squared) # Output: [1, 4, 9, 16, 25]
4. Using Lambda Functions with filter()
filter() applies a function to each item in an iterable and returns only those items for which the function returns True. Lambda functions are handy for creating quick filters.
numbers = [1, 2, 3, 4, 5, 6, 7, 8]
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers) # Output: [2, 4, 6, 8]
5. Using Lambda Functions with sorted()
You can use lambda functions as the key argument in sorted() to define custom sorting logic.
names = ["John", "Paul", "George", "Ringo"]
sorted_names = sorted(names, key=lambda x: len(x))
print(sorted_names) # Output: ['Paul', 'John', 'Ringo', 'George']
6. Lambda Function in a Dictionary Lambda functions are sometimes used in dictionaries to create simple mathematical operations or other functions based on keys.
calculator = {
'add': lambda x, y: x + y,
'subtract': lambda x, y: x - y,
'multiply': lambda x, y: x * y,
'divide': lambda x, y: x / y if y != 0 else 'Division by zero'
}
print(calculator['add'](10, 5)) # Output: 15
print(calculator['divide'](10, 2)) # Output: 5.0
print(calculator['divide'](10, 0)) # Output: Division by zero
7. Using Lambda with Conditional Expressions Lambda functions can contain conditional expressions to add logic in a concise format.
max_value = lambda x, y: x if x > y else y
print(max_value(10, 20)) # Output: 20
8. Lambda in List Comprehension Lambdas can be used within list comprehensions for quick transformations.
numbers = [1, 2, 3, 4, 5]
doubled_numbers = [(lambda x: x * 2)(x) for x in numbers]
print(doubled_numbers) # Output: [2, 4, 6, 8, 10]
9. Using Lambda Functions in Higher-Order Functions Lambda functions are often used in higher-order functions (functions that take other functions as arguments). For instance, they can be used to apply custom logic in a function parameter.
def apply_operation(func, x, y):
return func(x, y)
result = apply_operation(lambda x, y: x * y, 10, 5)
print(result) # Output: 50
10. Lambda Functions for Data Manipulation in Pandas
In data science, lambda functions are commonly used with libraries like pandas for quick data transformations.
import pandas as pd
data = pd.DataFrame({
'Name': ['Alice', 'Bob', 'Charlie'],
'Age': [24, 27, 22]
})
data['AgeGroup'] = data['Age'].apply(lambda x: 'Young' if x < 25 else 'Adult')
print(data)
Summary
Lambda functions in Python provide a concise way to define simple functions without the need for formal def syntax. They are useful in scenarios where small, throwaway functions are needed, like with map(), filter(), and data processing tasks. However, lambda functions are limited to single expressions, so theyโre best for straightforward operations rather than complex logic.
Recursionยถ
Recursion is a fundamental concept in programming where a function calls itself to solve smaller instances of a problem. In Python 3.x, recursion is straightforward but needs careful handling to avoid infinite loops or exceeding the recursion limit. Letโs break it down.
How Recursion Worksยถ
Base Case: This is the condition under which the recursive function stops calling itself. Without it, recursion would go on indefinitely.
Recursive Case: This is where the function calls itself with a smaller or simpler input.
Python keeps track of each function call on the call stack, so each call has its own local variables and execution state. When a base case is reached, Python unwinds the stack, returning results back up the chain.
Example 1: Factorial
Factorial of n (denoted n!) is n * (n-1) * ... * 1.
def factorial(n):
if n == 0: # base case
return 1
else:
return n * factorial(n - 1) # recursive call
print(factorial(5)) # Output: 120
Explanation:
factorial(5)callsfactorial(4), which callsfactorial(3)โฆ untilfactorial(0).Then the stack starts returning results:
1 โ 1*1 โ 2*1 โ 3*2 โ 4*6 โ 5*24 โ 120.
Example 2: Fibonacci Sequence
Fibonacci numbers: 0, 1, 1, 2, 3, 5, 8โฆ
def fibonacci(n):
if n <= 1: # base case
return n
else:
return fibonacci(n-1) + fibonacci(n-2) # recursive calls
print(fibonacci(6)) # Output: 8
Explanation:
fibonacci(6)callsfibonacci(5)andfibonacci(4)and so on, breaking the problem into smaller subproblems.
Note: This naive Fibonacci recursion has exponential time complexity. Iterative or memoized approaches are better for large
n.
Example 3: Sum of a List
def sum_list(lst):
if not lst: # base case: empty list
return 0
else:
return lst[0] + sum_list(lst[1:]) # recursive call on the rest of the list
print(sum_list([1, 2, 3, 4])) # Output: 10
Key Points
Python has a recursion limit (
sys.getrecursionlimit()), default ~1000. Deep recursion can causeRecursionError.Recursive functions are elegant for problems naturally defined in smaller subproblems (like trees, graphs, divide-and-conquer algorithms).
Always define a base case to prevent infinite recursion.
Recursive Call Stack for factorial(3)
factorial(3)
-> 3 * factorial(2)
-> 2 * factorial(1)
-> 1 * factorial(0)
-> 1 (base case)
Unwinding the Stack (Returning Values)
factorial(0) returns 1
factorial(1) returns 1 * 1 = 1
factorial(2) returns 2 * 1 = 2
factorial(3) returns 3 * 2 = 6
Visual Diagram
Call Stack (Top -> Bottom):
| factorial(3) | <- waiting for factorial(2)
| factorial(2) | <- waiting for factorial(1)
| factorial(1) | <- waiting for factorial(0)
| factorial(0) | <- base case reached
Each layer waits for the next recursive call to return.
Once the base case is hit, Python pops the stack and computes the result as it returns.
Mini Minesweeper Projectยถ
Project Overview
In this project, you will build a simplified version of the classic Minesweeper game using Python and Tkinter. The player will click cells in a grid trying to avoid hidden mines. Safe cells show the number of nearby mines. The player may also place flags where they believe a mine exists. You will implement the logic that makes the game work.
Project Objectives
Generate a game board - 6 ร 6 grid
Place mines randomly
Count adjacent mines
Allow player moves
Score that increases for safe clicks
List that records player moves
Game over if a mine is clicked
Reveal tiles
Determine win or loss
Try Againโ button to reset the game
AP CSP Learning Goals
AAP-2.E: Develop algorithms using sequencing, selection, and iteration.
AAP-4.A: Use data abstractions to manage complexity.
CRD-2.B: Implement algorithms in a programming language.
CRD-2.J: Test and debug programs.
Concepts Used
Lists and 2D Lists
Nested Loops
Conditional Logic
Random Numbers
Algorithms
2D Grid Using Lists: Grid structure stored as a list of lists.
Example board:
board = [
[" "," "," "],
[" ","*"," "],
[" "," "," "]
]
self.buttons[r][c]
Random Mine Placement: Places mines in random grid locations.
Example:
import random
row = random.randint(0,2)
col = random.randint(0,2)
board[row][col] = "*"
List for Tracking Moves: Stores every location the player has clicked.
self.moves = []
self.moves.append((r,c))
Score Tracking: Score increases when the player safely clicks a square.
self.score += 1
Random Mine Placement: Places mines in random grid locations.
random.randint(0, SIZE-1)
Student Project Extensions:
Add flagging system (right-click ๐ฉ)
Limit number of flags
Reveal empty regions automatically
Show high score
timer scoring system
Add win screen
save/load high score file
Change grid level of difficulty
Easy (6ร6)
Medium (8ร8)
Hard (10ร10)
Student Starter Code:
Complete sections marked TODO.
import tkinter as tk
import random
class Minesweeper:
def __init__(self, root):
self.root = root
self.root.title("<<YOUR NAME>> Minesweeper")
self.size = 6
self.mines = 6
# TODO
# Create variables for:
# score
# high score
# moves list
# flags set
self.grid_frame = tk.Frame(root)
self.grid_frame.pack()
self.create_board()
# ---------------------------------
# Create Grid
# ---------------------------------
def create_board(self):
self.buttons = []
for r in range(self.size):
row = []
for c in range(self.size):
btn = tk.Button(self.grid_frame,
width=3,
height=1)
btn.grid(row=r, column=c)
# left click
btn.bind("<Button-1>", lambda e, r=r, c=c: self.click(r,c))
# right click
btn.bind("<Button-3>", lambda e, r=r, c=c: self.flag(r,c))
row.append(btn)
self.buttons.append(row)
self.place_mines()
# ---------------------------------
# Place Mines
# ---------------------------------
def place_mines(self):
self.mine_locations = set()
# TODO
# Write code that randomly places mines
# into mine_locations
# ---------------------------------
# Count Nearby Mines
# ---------------------------------
def count_mines(self, r, c):
count = 0
# TODO
# Write algorithm that checks surrounding cells
# Return number of nearby mines
return count
# ---------------------------------
# Click Cell
# ---------------------------------
def click(self, r, c):
# TODO
# Prevent clicking flagged cells
# TODO
# Check if the cell contains a mine
# If it does -> end game
# TODO
# Otherwise show number of nearby mines
# TODO
# Update score
count = self.count_mines(r,c)
self.buttons[r][c].config(text=str(count))
# TODO
# If count == 0
# reveal surrounding cells
# ---------------------------------
# Reveal Empty Region
# ---------------------------------
def reveal_empty(self, r, c):
# TODO
# Create recursive algorithm that reveals
# surrounding cells when there are no mines nearby
pass
# ---------------------------------
# Flagging System
# ---------------------------------
def flag(self, r, c):
# TODO
# Add flag if square not revealed
# Limit number of flags
pass
# ---------------------------------
# Game Over
# ---------------------------------
def game_over(self):
# TODO
# Reveal all mines
# Disable board
pass
root = tk.Tk()
game = Minesweeper(root)
root.mainloop()
Grading Rubric (10 Points)
Criteria |
Points |
|---|---|
Mine placement algorithm works correctly |
1 |
Nearby mine counting algorithm works |
2 |
Flagging system implemented and limited |
2 |
Empty region reveal algorithm |
2 |
Use of lists/sets to track game data |
1 |
Program runs correctly and is tested/debugged |
1 |
Reflection (txt file) |
1 |
Total Points |
10 |
Reflection: 1-page explanation:
their mine counting algorithm
how recursion works in the reveal function
how lists are used for data abstraction