# The Zen of Python - Python's guiding principles
import thisIS4010: AI-Enhanced Application Development
Week 3: Python Basics & Control Flow - Interactive Companion Notebook
Instructor: Brandon M. Greenwell
Course: IS4010: AI-Enhanced Application Development
Week: 3 - Python Basics & Control Flow
๐ฏ Learning Objectives
By the end of this interactive session, you will be able to:
- Master Python fundamentals: Variables, data types, user input, and string formatting
- Build interactive programs: Collect and process user input effectively
- Apply control flow: Use conditionals (if/elif/else) and loops (while/for) to control program execution
- Work with the random module: Generate random numbers for games and simulations
- Write professional code: Follow Python naming conventions and documentation standards
- Set up automated testing: Use pytest and GitHub Actions for continuous integration
- Create engaging applications: Build a Mad Libs generator and number guessing game
๐ ๏ธ Prerequisites
- Python 3.10+ installed
- VS Code with Python extension
- Basic understanding of running Python scripts
- Completed Labs 1-2
๐ Resources
Welcome to Python! ๐
A Brief History of Python ๐
- Born on Christmas 1989: Guido van Rossum started Python as a hobby project during the Christmas holidays
- Named after Monty Python: Not the snake! Guido was reading Monty Pythonโs Flying Circus scripts
- First release (1991): Python 0.9.0 featured classes, functions, and exception handling
- Philosophy: โThere should be one obvious way to do itโ - emphasis on readability and simplicity
- Modern dominance: Now one of the worldโs most popular programming languages
Why Python Matters Today ๐
- Readability first: Code is read more often than written - Python prioritizes human understanding
- Versatility: Web development, data science, AI/ML, automation, scientific computing
- Huge ecosystem: Over 400,000 packages available on PyPI
- Industry adoption: Powers Instagram, Spotify, Netflix, and most AI research
- Perfect learning language: Gentle learning curve, powerful capabilities
- Career relevance: Consistently ranks as one of the most in-demand programming languages
Session 1: Python Fundamentals & Data Types
Understanding Variables ๐ฆ
Think of a variable as a labeled box where you store information:
- Assignment: Use the equals sign (
=) to put data into variables - Naming matters: Choose descriptive names that explain what the data represents
- Python convention: Use
snake_casefor variable names (words separated by underscores) - Memory insight: Variables are actually references to objects in memory
Python Naming Conventions ๐ท๏ธ
- Variables and functions:
snake_case-user_name,calculate_total,is_valid - Constants:
SCREAMING_SNAKE_CASE-MAX_ATTEMPTS = 3,PI = 3.14159 - Classes:
PascalCase-StudentRecord,BankAccount - Modules:
lowercaseorsnake_case-math,user_authentication
# Good variable names (descriptive and clear)
student_name = "Grace Hopper"
birth_year = 1906
is_computer_pioneer = True
course_grade = 95.7
print(f"Student: {student_name}")
print(f"Born: {birth_year}")
print(f"Pioneer: {is_computer_pioneer}")
print(f"Grade: {course_grade}")
# Poor variable names (avoid these!)
n = "Grace Hopper" # What is 'n'?
x = 1906 # What does 'x' represent?
# These work but are hard to understand when reading code laterVariable Assignment Patterns ๐
# Multiple assignment
name, age, grade = "Alice", 20, "A"
print(f"{name} is {age} years old and has grade {grade}")
# Tuple unpacking from function return
def get_student_info():
return "Bob", 21, 3.8
student_name, student_age, gpa = get_student_info()
print(f"{student_name}: Age {student_age}, GPA {gpa}")
# Chained assignment
x = y = z = 0
print(f"x={x}, y={y}, z={z}")
# Augmented assignment operators
score = 85
score += 10 # Same as: score = score + 10
score *= 2 # Same as: score = score * 2
print(f"Final score: {score}")Core Data Types ๐งฉ
Python has four fundamental data types:
str(string): Text data, enclosed in quotes ('or")int(integer): Whole numbers, positive or negativefloat(floating-point): Numbers with decimal pointsbool(boolean): Truth values (TrueorFalse)
Python uses dynamic typing - it figures out the type automatically!
# Python automatically determines types
student_name = "Ada Lovelace" # str
student_id = 12345 # int
gpa = 3.95 # float
is_honors_student = True # bool
graduation_year = None # NoneType
# Check types using the type() function
print(f"{student_name} is type: {type(student_name)}")
print(f"{student_id} is type: {type(student_id)}")
print(f"{gpa} is type: {type(gpa)}")
print(f"{is_honors_student} is type: {type(is_honors_student)}")
print(f"{graduation_year} is type: {type(graduation_year)}")Strings: Working with Text ๐
Strings are sequences of characters used for text:
# Different ways to create strings
name1 = 'Alan Turing'
name2 = "Alan Turing" # Equivalent to single quotes
quote = """Computing machinery and intelligence
was published in 1950 by Alan Turing.""" # Triple quotes for multi-line
print(quote)
# Escape sequences
message = "Hello\nWorld\t!" # \n = newline, \t = tab
print(message)
file_path = "C:\\Users\\Documents\\file.txt" # \\ for backslash
print(file_path)# Useful string methods
name = " alan turing "
print(f"Original: '{name}'")
print(f"Stripped and titled: '{name.strip().title()}'")
print(f"Uppercase: '{name.upper()}'")
print(f"Lowercase: '{name.lower()}'")
print(f"Replace: '{name.replace('alan', 'Alan')}'")
# String immutability - strings can't be changed in place
# name[0] = 'B' # This would raise a TypeError!๐ฏ Your Turn: String Practice
Practice working with strings:
# TODO: Create a variable with your full name (use mixed case)
my_name = ""
# TODO: Print your name in all uppercase
# TODO: Print your name in all lowercase
# TODO: Print your name in title case (First Letter Capitalized)
# TODO: Count how many letters are in your name (use len() function)Numbers: Integers and Floats ๐ข
# Integer examples
students_enrolled = 150
temperature_celsius = -5
big_number = 123456789012345678901234567890 # No limits in Python!
print(f"Students: {students_enrolled}")
print(f"Temperature: {temperature_celsius}ยฐC")
print(f"Big number: {big_number}")
# Float examples
pi = 3.14159
temperature_fahrenheit = 23.0
scientific = 1.5e6 # Scientific notation: 1,500,000
print(f"Pi: {pi}")
print(f"Temperature: {temperature_fahrenheit}ยฐF")
print(f"Scientific: {scientific}")# Arithmetic operations
print("Regular division:")
print(f"17 / 3 = {17 / 3}") # 5.666666666666667
print("\nFloor division:")
print(f"17 // 3 = {17 // 3}") # 5 (integer division)
print("\nModulo (remainder):")
print(f"17 % 3 = {17 % 3}") # 2 (remainder)
print("\nExponentiation:")
print(f"2 ** 10 = {2 ** 10}") # 1024
# Type conversions
age_str = "21"
age_int = int(age_str) # Convert string to integer
print(f"\nConverted '{age_str}' to {age_int}")
pi_str = str(3.14159) # Convert float to string
print(f"Converted 3.14159 to '{pi_str}'")๐ฏ Your Turn: Number Practice
# TODO: Calculate the area of a circle with radius 5
# Formula: area = ฯ * rยฒ
# Use 3.14159 for ฯ
radius = 5
pi = 3.14159
# Your calculation here
# TODO: Calculate your age in days (approximate)
# Assume 365 days per year
age_in_years = 20 # Change this to your age
# Your calculation here
# TODO: Convert temperature from Celsius to Fahrenheit
# Formula: F = (C * 9/5) + 32
celsius = 25
# Your calculation hereGetting User Input ๐ฌ
The input() function lets you collect information from users:
- Always returns strings - Even if user types numbers
- Type conversion needed - Use
int()orfloat()for numeric input - Clear prompts - Help users understand what to enter
# Simple string input
name = input("What is your name? ")
print(f"Hello, {name}!")
# Numeric input with conversion
age_str = input("What is your age? ")
age = int(age_str) # Convert to integer
print(f"Next year you'll be {age + 1}")
# One-liner for numeric input
grade = float(input("Enter your grade (0-100): "))
print(f"Your grade: {grade}%")String Formatting: Making Output Beautiful โจ
Python offers several ways to format strings, but weโll focus on f-strings (the modern, preferred method):
name = "Katherine Johnson"
salary = 75000.50
accuracy = 0.99999
# f-string examples (Python 3.6+)
print(f"Employee: {name}")
print(f"Salary: ${salary:,.2f}") # $75,000.50 (thousands separator, 2 decimals)
print(f"Accuracy: {accuracy:.2%}") # 99.99% (percentage)
print(f"Name width: '{name:>30}'")
print(f"Name width: '{name:<30}'")
print(f"Name width: '{name:^30}'")
# Complex f-string expressions
items = ["apple", "banana", "cherry"]
print(f"We have {len(items)} fruits: {', '.join(items)}")
# Multi-line f-strings
report = f"""
Employee Report:
Name: {name}
Salary: ${salary:,.2f}
Performance: {accuracy:.1%}
"""
print(report)๐ฏ Your Turn: String Formatting Practice
# TODO: Create variables for a product
product_name = "Laptop"
price = 1299.99
quantity = 5
# TODO: Print the product name and price with proper formatting
# Format: "Product: Laptop - $1,299.99"
# TODO: Calculate and print the total cost
# Format: "Total for 5 units: $6,499.95"
# TODO: If there's a 10% discount, show the new price
# Format: "After 10% discount: $1,169.99"Mad Libs Preview: Putting It Together ๐ญ
Letโs preview the Mad Libs generator youโll build in Lab 03. This demonstrates: - Function parameters - String formatting with f-strings - NumPy-style docstrings - Writing testable code
def generate_mad_lib(adjective, noun, verb):
"""
Generates a short story using the provided words.
This function demonstrates string formatting and function design
by creating a Mad Libs-style story from user-provided words.
Parameters
----------
adjective : str
An adjective to use in the story (e.g., "silly", "brave", "colorful").
noun : str
A noun to use in the story (e.g., "cat", "computer", "adventure").
verb : str
A past-tense verb to use in the story (e.g., "jumped", "crashed", "danced").
Returns
-------
str
A formatted story string that incorporates all three input words.
Examples
--------
>>> generate_mad_lib("silly", "cat", "jumped")
"The silly cat jumped over the fence and landed in a puddle."
"""
# Example implementation - you'll create your own in Lab 03!
story = f"The {adjective} {noun} {verb} over the fence and landed in a puddle."
return story
# Test the function
print(generate_mad_lib("silly", "cat", "jumped"))
print(generate_mad_lib("brave", "knight", "battled"))
print(generate_mad_lib("colorful", "dragon", "flew"))๐ฏ Your Turn: Create Your Own Mad Lib Function
def my_mad_lib(adjective, noun, verb):
"""
Your custom Mad Libs story.
TODO: Add a complete NumPy-style docstring
"""
# TODO: Create your own creative story using all three words
# Make it at least 10-15 words long
# Use f-string formatting
pass
# Test your function
# print(my_mad_lib("sparkly", "unicorn", "danced"))Session 2: Control Flow & Professional Testing
Conditional Logic: Making Decisions ๐ค
Programs need to make decisions based on conditions:
- Boolean expressions: Conditions that evaluate to
TrueorFalse - Code blocks: Groups of statements that execute together
- Indentation matters: Python uses whitespace to group code (not braces)
- Comparison operators:
==,!=,<,>,<=,>=
# Simple condition
temperature = 75
if temperature > 70:
print("It's warm outside!")
print("Perfect for a walk.")
# Multiple conditions with elif and else
age = 20
has_id = True
if age >= 21 and has_id:
print("Welcome to the club!")
elif age >= 18:
print("You can vote, but can't enter the club.")
else:
print("Too young for either.")Boolean Operators and Logic ๐งฎ
# Comparison operators
score = 85
grade = "B"
is_passing = score >= 60 # True
is_excellent = score >= 90 # False
is_b_grade = grade == "B" # True
print(f"Passing? {is_passing}")
print(f"Excellent? {is_excellent}")
print(f"B grade? {is_b_grade}")
# Logical operators: and, or, not
has_homework = True
studied_hard = False
can_pass = has_homework and studied_hard # False (both must be True)
should_study = not studied_hard # True (inverts the value)
might_pass = has_homework or studied_hard # True (at least one is True)
print(f"\nCan pass? {can_pass}")
print(f"Should study? {should_study}")
print(f"Might pass? {might_pass}")# Membership testing with 'in'
fruits = ["apple", "banana", "cherry"]
has_apple = "apple" in fruits # True
has_orange = "orange" not in fruits # True
print(f"Has apple? {has_apple}")
print(f"Doesn't have orange? {has_orange}")
# Complex conditions
username = "alice"
password = "secret123"
is_admin = False
if username == "alice" and password == "secret123" and not is_admin:
print("Regular user login successful")
else:
print("Login failed or admin access required")๐ฏ Your Turn: Conditional Practice
# TODO: Write a grade calculator
# Given a numeric score (0-100), determine the letter grade:
# A: 90-100, B: 80-89, C: 70-79, D: 60-69, F: 0-59
score = 85 # Change this to test different scores
# Your if/elif/else logic here
# TODO: Write a password strength checker
# A password is "strong" if it:
# - Is at least 8 characters long
# - Contains at least one number
# (Hint: use len() and any(char.isdigit() for char in password))
password = "secure123" # Change this to test
# Your password strength logic hereLoops: Repeating Actions Efficiently ๐
Loops let you repeat code without writing it multiple times:
forloops: When you know what you want to iterate overwhileloops: When you want to repeat until a condition changes- Loop control:
break(exit loop),continue(skip to next iteration)
# For loop with range()
print("Countdown:")
for i in range(5, 0, -1):
print(f"{i}...")
print("Blast off!")
# For loop with collections
students = ["Alice", "Bob", "Charlie"]
print("\nGreeting students:")
for student in students:
print(f"Hello, {student}!")# While loop example
total = 0
count = 0
print("Adding numbers until we reach 100:")
while total < 100:
total += 15
count += 1
print(f"Step {count}: Total is now {total}")
print(f"Reached {total} in {count} steps")# Loop with break and continue
print("Numbers 0-9, skipping 3 and stopping at 7:")
for i in range(10):
if i == 3:
continue # Skip 3
if i == 7:
break # Stop at 7
print(i, end=" ")
print("\nLoop ended")The range() Function: Your Loop Companion ๐
Understanding range() is essential for loops:
range(stop): Numbers from 0 to stop-1range(start, stop): Numbers from start to stop-1range(start, stop, step): Numbers from start to stop-1, incrementing by step
# Basic range patterns
print("range(5):", list(range(5))) # [0, 1, 2, 3, 4]
print("range(1, 6):", list(range(1, 6))) # [1, 2, 3, 4, 5]
print("range(0, 10, 2):", list(range(0, 10, 2))) # [0, 2, 4, 6, 8]
print("range(10, 0, -1):", list(range(10, 0, -1))) # [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
# Practical example: multiplication table
number = 7
print(f"\nMultiplication table for {number}:")
for i in range(1, 11):
print(f"{number} x {i} = {number * i}")๐ฏ Your Turn: Loop Practice
# TODO: Print all even numbers from 0 to 20
# TODO: Calculate the sum of numbers 1 to 100
# (Hint: use a for loop and accumulate the total)
# TODO: Print the first 10 squares (1ยฒ, 2ยฒ, 3ยฒ, etc.)
# TODO: Create a while loop that counts down from 10 to 1
# Print "Happy New Year!" at the endWorking with the Random Module ๐ฒ
The random module lets you generate random numbers - essential for games and simulations:
import random
# Random integer in a range (inclusive)
dice_roll = random.randint(1, 6)
print(f"You rolled a {dice_roll}")
# Random choice from a list
colors = ["red", "blue", "green", "yellow"]
chosen_color = random.choice(colors)
print(f"Random color: {chosen_color}")
# Random float between 0 and 1
random_percentage = random.random()
print(f"Random percentage: {random_percentage:.2%}")
# Shuffle a list
deck = ["A", "2", "3", "4", "5"]
print(f"Original: {deck}")
random.shuffle(deck)
print(f"Shuffled: {deck}")Number Guessing Game: Putting It All Together ๐ฏ
Letโs build a complete guessing game that demonstrates: - While loops - Conditionals - User input - Random numbers - Game logic
import random
def guessing_game():
"""
Plays a number guessing game with the user.
This interactive game demonstrates while loops, conditionals, and user input
handling. The user attempts to guess a randomly generated number between
1 and 100, receiving feedback after each guess.
"""
secret = random.randint(1, 100)
attempts = 0
print("Welcome to the Number Guessing Game!")
print("I'm thinking of a number between 1 and 100.")
while True: # Continue until user guesses correctly
guess = int(input("Enter your guess: "))
attempts += 1
if guess < secret:
print("Too low! Try again.")
elif guess > secret:
print("Too high! Try again.")
else:
print(f"Congratulations! You guessed it in {attempts} attempts!")
break # Exit the loop when correct
# Run the game (uncomment to play)
# guessing_game()๐ฏ Your Turn: Enhance the Guessing Game
Modify the game to add features:
import random
def enhanced_guessing_game():
"""
Enhanced version of the guessing game with additional features.
"""
secret = random.randint(1, 100)
attempts = 0
max_attempts = 10 # Add a maximum number of attempts
print("Enhanced Number Guessing Game!")
print(f"I'm thinking of a number between 1 and 100.")
print(f"You have {max_attempts} attempts to guess it.")
while attempts < max_attempts:
# TODO: Add the game logic here
# 1. Get user input
# 2. Increment attempts
# 3. Check if guess is correct, too high, or too low
# 4. If correct, congratulate and break
# 5. If wrong, give feedback and continue
# 6. If max attempts reached, reveal the number
pass
# Test your enhanced game
# enhanced_guessing_game()Testing with pytest ๐งช
Professional developers test their code to ensure it works correctly. Letโs learn about pytest:
Why Testing Matters
- Quality assurance: Catch bugs before they become problems
- Confidence: Make changes knowing tests will catch regressions
- Professional practice: Industry standard for serious software
- Instant feedback: Know immediately if code works correctly
- Portfolio value: Shows employers you understand professional practices
How pytest Works
- Test discovery: pytest finds files starting with
test_ - Test functions: Functions starting with
test_are automatically run - Assertions:
assertstatements check if conditions are True - Test isolation: Each test runs independently
# Example: A simple function and its test
def add_numbers(a, b):
"""Add two numbers and return the result."""
return a + b
# This is what a test looks like
def test_add_numbers():
"""Test that add_numbers works correctly."""
# Test case 1: positive numbers
result = add_numbers(2, 3)
assert result == 5, "2 + 3 should equal 5"
# Test case 2: negative and positive
result = add_numbers(-1, 1)
assert result == 0, "-1 + 1 should equal 0"
# Test case 3: zeros
result = add_numbers(0, 0)
assert result == 0, "0 + 0 should equal 0"
print("All tests passed!")
# Run the test manually in this notebook
test_add_numbers()Testing the Mad Libs Function
def test_generate_mad_lib():
"""
Tests the generate_mad_lib function to ensure it uses inputs correctly.
"""
# Test case 1: Basic functionality
adj = "silly"
noun = "cat"
verb = "jumped"
story = generate_mad_lib(adj, noun, verb)
# Verify function returns a string
assert isinstance(story, str), "Function should return a string"
# Verify all words are used in the story
assert adj in story, f"Adjective '{adj}' not found in story"
assert noun in story, f"Noun '{noun}' not found in story"
assert verb in story, f"Verb '{verb}' not found in story"
print("Mad Libs test passed!")
print(f"Story: {story}")
# Run the test
test_generate_mad_lib()๐ฏ Your Turn: Write a Test
Write a test for a grade calculator function:
def calculate_letter_grade(score):
"""Convert numeric score to letter grade."""
if score >= 90:
return 'A'
elif score >= 80:
return 'B'
elif score >= 70:
return 'C'
elif score >= 60:
return 'D'
else:
return 'F'
# TODO: Write a test function for calculate_letter_grade
def test_calculate_letter_grade():
"""Test the grade calculator."""
# TODO: Test that 95 returns 'A'
# TODO: Test that 85 returns 'B'
# TODO: Test that 75 returns 'C'
# TODO: Test that 65 returns 'D'
# TODO: Test that 55 returns 'F'
print("All grade calculator tests passed!")
# Run your test
# test_calculate_letter_grade()GitHub Actions: Continuous Integration โ๏ธ
GitHub Actions automatically runs your tests every time you push code:
How It Works
- Event trigger: You push code to GitHub
- Virtual machine: GitHub spins up a fresh Ubuntu Linux computer
- Environment setup: Installs Python and dependencies
- Test execution: Runs your test suite using pytest
- Results reporting: Shows green โ (success) or red โ (failure)
Why This Matters
- Automated quality control: Tests run automatically on every change
- Environment consistency: Tests run in a clean environment
- Collaboration safety: Prevents broken code from being accepted
- Professional workflow: Same process used by major tech companies
Your Instant Feedback System
- Green checkmark โ : All tests passing - your code works!
- Red X โ: Some tests failing - time to debug
- Actions tab: Click to see detailed test results and error messages
- Professional habit: Never merge code that fails tests
๐ฏ Putting It All Together: Lab 03 Integration
Youโve learned the essential Python fundamentals. Now apply them in Lab 03!
Lab 03 Success Strategy
Part 1: Mad Libs Generator
- Write the function: Use f-strings to create a creative story
- Use all parameters: Ensure adjective, noun, and verb all appear in your story
- Make it creative: Write an engaging, fun story (10-15 words minimum)
- Test locally: Run your function with different words before pushing
- Document well: Include a proper NumPy-style docstring
Part 2: Number Guessing Game
- Understand the flow: Generate random number, loop until correct guess
- Clear prompts: Help users understand what to do
- Proper feedback: Tell users if guess is too high or too low
- Count attempts: Track and display number of guesses
- Test thoroughly: Play your game multiple times
Part 3: Automated Testing Setup
- Create test file:
test_lab03.pywith provided tests (donโt modify) - Set up GitHub Actions:
.github/workflows/main.yml(one-time setup) - Create README: Professional documentation with CI/CD badge
- Verify tests pass: Green checkmark in GitHub Actions
- Future-proof: This setup works for all future labs!
Pre-Lab Checklist
Before starting Lab 03, ensure you understand:
Key Concepts to Remember
For Mad Libs
- Functions should NOT use
input()inside - that makes them untestable - Use parameters to receive data, return values to give data back
- F-strings are the modern way to format strings in Python
- All three words must appear in the returned story
For Guessing Game
- Use
random.randint(1, 100)for inclusive range - While loops continue until you
breakout of them - Increment attempts counter on each guess
- Give clear feedback to improve user experience
For Testing
- Tests verify your functions work correctly
- GitHub Actions runs tests automatically on push
- Green checkmark means youโre ready to submit
- This testing infrastructure serves you all semester
Good luck with Lab 03! Remember: write clean code, test thoroughly, and have fun being creative!