Week 4 Lecture: Functions
Built-in Functions
- Built-in functions are pre-written code provided by Python that perform common tasks
- They save time and effort - no need to reinvent the wheel for common operations
- We’ve already used several:
print(),input(),int(),float(),str(),range() - Python has dozens of built-in functions that make programming easier
- Understanding built-in functions helps you recognize patterns for creating your own functions
Syntax:
# General syntax
result = function_name(arguments)
# Common built-in functions for numbers
max(a, b, c, ...) # Returns the largest value
min(a, b, c, ...) # Returns the smallest value
abs(x) # Returns absolute value of x
round(x) # Rounds x to nearest integer
round(x, n) # Rounds x to n decimal places
pow(base, exp) # Returns base raised to power exp
len(sequence) # Returns length of sequence
sum(sequence) # Returns sum of sequence
Problem
Problem Statement: Create a grade analysis program that processes three test scores. The program should:
- Start with three predefined test scores: score1 = 85, score2 = 92, score3 = 78
- Calculate and display the highest score among the three
- Calculate and display the lowest score among the three
- Calculate the average score and round it to 2 decimal places
- Find the absolute difference between the highest and lowest scores
- Calculate the total points if each score is raised to the power of 2 (for weighted calculation)
- Display all results in a clear format
Complete Code
# Three test scores
score1 = 85
score2 = 92
score3 = 78
# Calculate statistics using built-in functions
highest = max(score1, score2, score3)
lowest = min(score1, score2, score3)
average = (score1 + score2 + score3) / 3
rounded_average = round(average, 2)
score_range = abs(highest - lowest)
# Weighted calculation using pow
weighted1 = pow(score1, 2)
weighted2 = pow(score2, 2)
weighted3 = pow(score3, 2)
total_weighted = weighted1 + weighted2 + weighted3
print("Grade Analysis:")
print(f"Scores: {score1}, {score2}, {score3}")
print(f"Highest: {highest}")
print(f"Lowest: {lowest}")
print(f"Average: {rounded_average}")
print(f"Range: {score_range}")
print(f"Weighted total (squared): {total_weighted}")
Key Points:
max()andmin()can take multiple argumentsround()with second argument controls decimal placesabs()is useful for finding distances/differencespow()is equivalent to ** operator but as a function- Built-in functions can be combined for complex calculations
Defining Your Own Functions
- Functions are reusable blocks of code that perform specific tasks
- They help organize code, reduce repetition, and make programs easier to understand
- Functions can take inputs (parameters) and produce outputs (return values)
- The DRY principle: “Don’t Repeat Yourself” - if you write similar code twice, consider making it a function
- Functions create a layer of abstraction - use complex operations without knowing implementation details
Syntax:
def function_name(parameter1, parameter2):
# function body
# code that does something
return result # optional
defkeyword starts function definition- Function name follows Python naming conventions (lowercase with underscores)
- Parameters in parentheses (can be empty)
- Colon ends the header line
- Function body is indented
returnstatement sends value back to caller (optional)
Problem
Problem Statement: Create a temperature conversion system that can convert between Celsius and Fahrenheit. The system should:
- Define a function to convert Celsius to Fahrenheit using the formula: F = (C × 9/5) + 32
- Define a function to convert Fahrenheit to Celsius using the formula: C = (F - 32) × 5/9
- Test both functions with sample temperatures: 0°C, 100°C, 32°F, and 212°F
- Display the conversions showing both the original and converted values
Complete Code
def celsius_to_fahrenheit(celsius):
fahrenheit = (celsius * 9/5) + 32
return fahrenheit
def fahrenheit_to_celsius(fahrenheit):
celsius = (fahrenheit - 32) * 5/9
return celsius
# Test conversions
c1 = 0
f1 = celsius_to_fahrenheit(c1)
print(f"{c1}°C = {f1}°F")
c2 = 100
f2 = celsius_to_fahrenheit(c2)
print(f"{c2}°C = {f2}°F")
f3 = 32
c3 = fahrenheit_to_celsius(f3)
print(f"{f3}°F = {c3}°C")
f4 = 212
c4 = fahrenheit_to_celsius(f4)
print(f"{f4}°F = {c4}°C")
Key Points:
- Function names should describe what the function does
- Each function should do one thing well
- Functions make code reusable - call them multiple times with different values
- The return value can be stored in a variable or used directly
Expected Output:
0°C = 32.0°F
100°C = 212.0°F
32°F = 0.0°C
212°F = 100.0°C
Passing Arguments and Multiple Parameters
- Functions can accept multiple pieces of information through parameters
- Arguments are the actual values passed when calling the function
- Parameters are the variable names in the function definition
- Order matters when passing arguments (positional arguments)
- Functions can have zero, one, or many parameters
- Each parameter acts as a local variable inside the function
Syntax:
def function_name(param1, param2, param3):
# use param1, param2, param3
return result
# Calling with arguments
result = function_name(arg1, arg2, arg3)
Problem
Problem Statement: Create a geometric calculator for rectangles and triangular prisms. The calculator should:
- Define a function that calculates the area of a rectangle given width and height
- Define a function that calculates the perimeter of a rectangle given width and height
- Define a function that calculates the volume of a triangular prism given base, height of triangle, and length of prism
- Test all functions with these measurements:
- Rectangle: width=5, height=8
- Triangular prism: base=6, triangle_height=4, prism_length=10
- Display all calculated values with appropriate labels
Complete Code
def rectangle_area(width, height):
area = width * height
return area
def rectangle_perimeter(width, height):
perimeter = 2 * (width + height)
return perimeter
def triangular_prism_volume(base, triangle_height, prism_length):
# Area of triangle times length
triangle_area = 0.5 * base * triangle_height
volume = triangle_area * prism_length
return volume
# Rectangle calculations
w = 5
h = 8
area = rectangle_area(w, h)
perimeter = rectangle_perimeter(w, h)
print(f"Rectangle {w}x{h}:")
print(f" Area: {area}")
print(f" Perimeter: {perimeter}")
# Triangular prism calculation
b = 6
th = 4
pl = 10
volume = triangular_prism_volume(b, th, pl)
print(f"\nTriangular Prism (base={b}, height={th}, length={pl}):")
print(f" Volume: {volume}")
Key Points:
- Parameter names should be descriptive
- Order of arguments must match order of parameters
- Functions can perform complex calculations and return single results
- Same parameters (width, height) can be used for different calculations
Expected Output:
Rectangle 5x8:
Area: 40
Perimeter: 26
Triangular Prism (base=6, height=4, length=10):
Volume: 120.0
Return Values and Functions Without Return
returnstatement sends a value back to where the function was called- Functions can return any data type: numbers, strings, booleans, etc.
- A function stops executing when it reaches a
returnstatement - Functions without
returnstatements returnNoneby default - Some functions perform actions (like printing) instead of computing values
- You can have multiple return statements (in different branches of logic)
Syntax:
def computing_function():
result = # some calculation
return result
def action_function():
# do something (like print)
# no return statement
Problem
Problem Statement: Create a grade classification system that processes numerical scores. The system should:
- Define a function that determines the letter grade (A, B, C, D, F) for a score:
- A: 90-100
- B: 80-89
- C: 70-79
- D: 60-69
- F: below 60
- Define a function that checks if a score is passing (60 or above) and returns True/False
- Define a function that prints a formatted grade report (doesn’t return anything)
- Test with individual scores: 95, 82, 73, 65, 58
- For each score, show the letter grade, pass/fail status, and print the report
Complete Code
def get_letter_grade(score):
if score >= 90:
return "A"
elif score >= 80:
return "B"
elif score >= 70:
return "C"
elif score >= 60:
return "D"
else:
return "F"
def is_passing(score):
return score >= 60 # Returns True or False
def print_grade_report(score):
# This function performs action but doesn't return value
letter = get_letter_grade(score)
status = "PASS" if is_passing(score) else "FAIL"
print(f"Score: {score} | Grade: {letter} | Status: {status}")
# No return statement
# Test individual scores
score1 = 95
letter1 = get_letter_grade(score1)
pass1 = is_passing(score1)
print(f"Processing score {score1}:")
print(f" Letter grade: {letter1}")
print(f" Passing: {pass1}")
print_grade_report(score1)
print()
score2 = 82
letter2 = get_letter_grade(score2)
pass2 = is_passing(score2)
print(f"Processing score {score2}:")
print(f" Letter grade: {letter2}")
print(f" Passing: {pass2}")
print_grade_report(score2)
print()
score3 = 73
letter3 = get_letter_grade(score3)
pass3 = is_passing(score3)
print(f"Processing score {score3}:")
print(f" Letter grade: {letter3}")
print(f" Passing: {pass3}")
print_grade_report(score3)
print()
score4 = 65
letter4 = get_letter_grade(score4)
pass4 = is_passing(score4)
print(f"Processing score {score4}:")
print(f" Letter grade: {letter4}")
print(f" Passing: {pass4}")
print_grade_report(score4)
print()
score5 = 58
letter5 = get_letter_grade(score5)
pass5 = is_passing(score5)
print(f"Processing score {score5}:")
print(f" Letter grade: {letter5}")
print(f" Passing: {pass5}")
print_grade_report(score5)
Key Points:
- Functions can call other functions
- Boolean functions often use direct return of comparison
- Not all functions need to return values - some perform actions
- Multiple return statements allow different outputs based on conditions
- Early return can simplify logic (no need for else after return)
Expected Output:
Processing score 95:
Letter grade: A
Passing: True
Score: 95 | Grade: A | Status: PASS
Processing score 82:
Letter grade: B
Passing: True
Score: 82 | Grade: B | Status: PASS
Processing score 73:
Letter grade: C
Passing: True
Score: 73 | Grade: C | Status: PASS
Processing score 65:
Letter grade: D
Passing: True
Score: 65 | Grade: D | Status: PASS
Processing score 58:
Letter grade: F
Passing: False
Score: 58 | Grade: F | Status: FAIL
Variable Scope (Local and Global)
- Scope determines where a variable can be accessed in your code
- Local variables exist only inside the function where they’re created
- Global variables exist outside all functions and can be accessed anywhere
- Parameters are local variables
- Variables created inside a function are destroyed when the function ends
- Each function call creates a new set of local variables
- Best practice: minimize use of global variables, pass data through parameters
Syntax:
global_var = 10 # Global scope
def function():
local_var = 5 # Local scope
# Can access both global_var and local_var here
# Can only access global_var here, not local_var
Problem
Problem Statement: Create a points tracking system for a game that demonstrates scope. The system should:
- Have a global variable for the game’s high score (initially 0).
- Define a helper function
calculate_round_pointsthat calculates points for a round based on: hits (10 points each) and time_bonus (5 points per second under 30). This function should return the calculated score. - Define a function
show_statisticsthat displays the current game statistics for a given round. - Define a primary function
play_roundthat orchestrates a full round of the game. It should:- Accept the round number, hits, and time taken as parameters.
- Call
calculate_round_pointsto get the score for the round. - Update the global
high_scoreif the new score is higher. - Call the
show_statisticsfunction internally to display the results immediately after the round is processed.
- Simulate three rounds by calling
play_roundwith these values:- Round 1: 5 hits, completed in 25 seconds
- Round 2: 8 hits, completed in 20 seconds
- Round 3: 3 hits, completed in 35 seconds
- After all rounds are played, display the final high score.
Complete Code
high_score = 0 # Global variable
def calculate_round_points(hits, time_taken):
# Local variables
hit_points = hits * 10
if time_taken < 30:
time_bonus = (30 - time_taken) * 5
else:
time_bonus = 0
total_points = hit_points + time_bonus
return total_points
def show_statistics(round_num, current_points):
# Reading global variable (no 'global' keyword needed for reading)
print(f"Round {round_num} Results:")
print(f" Points this round: {current_points}")
print(f" Current high score: {high_score}")
print()
def play_round(round_num, hits, time_taken):
global high_score # Need this to modify the global variable
# Call helper function to get points
points = calculate_round_points(hits, time_taken)
# Check and update the global high score
if points > high_score:
high_score = points
print(f"NEW HIGH SCORE: {high_score}")
# Call another helper function to display results
show_statistics(round_num, points)
# Simulate game rounds with single function calls
play_round(1, 5, 25)
play_round(2, 8, 20)
play_round(3, 3, 35)
# Display the final state of the game
print(f"Final High Score after all rounds: {high_score}")
Key Points:
- Need
globalkeyword to modify global variables inside functions. - Don’t need
globalkeyword just to read global variables (as seen inshow_statistics). - Function Composition: A primary function (
play_round) can orchestrate a series of actions by calling other helper functions (calculate_round_points,show_statistics) to perform specific sub-tasks. - This design makes the main part of the script cleaner and easier to read. The complexity is encapsulated within the
play_roundfunction. - The
play_roundfunction is an “action” function; its main purpose is to perform a sequence of operations rather than returning a value. - Global variables persist between function calls, allowing the
high_scoreto be maintained across multiple rounds.
Expected Output:
NEW HIGH SCORE: 75
Round 1 Results:
Points this round: 75
Current high score: 75
NEW HIGH SCORE: 130
Round 2 Results:
Points this round: 130
Current high score: 130
Round 3 Results:
Points this round: 30
Current high score: 130
Final High Score: 130
Consolidation Problems
Problem 1: Prime Number Analyzer
Problem
Problem Statement: Create a program that analyzes prime numbers within a range. Your program should:
- Define a function
is_prime(n)that returns True if n is prime, False otherwise- A prime number is only divisible by 1 and itself
- Numbers less than 2 are not prime
- Check divisibility from 2 up to n-1
- Define a function
count_primes_between(start, end)that counts how many prime numbers exist between start and end (inclusive)- Use the is_prime function to check each number
- Return the total count
- Define a function
nth_prime(n)that finds the nth prime number- The 1st prime is 2, 2nd prime is 3, 3rd prime is 5, etc.
- Keep checking numbers until you find n primes
- Define a function
is_twin_prime(n)that checks if n and n+2 are both prime- Twin primes are pairs like (3,5), (11,13), (17,19)
- Test your functions:
- Count primes between 1 and 50
- Find the 10th prime number
- Check if 11, 15, and 29 form twin prime pairs with n+2
- Count primes between 100 and 150
- Display all results clearly
Solution
def is_prime(n):
if n < 2:
return False
for i in range(2, n):
if n % i == 0:
return False
return True
def count_primes_between(start, end):
count = 0
for num in range(start, end + 1):
if is_prime(num):
count += 1
return count
def nth_prime(n):
if n < 1:
return -1 # Invalid input
count = 0
num = 2
while count < n:
if is_prime(num):
count += 1
if count == n:
return num
num += 1
return -1
def is_twin_prime(n):
return is_prime(n) and is_prime(n + 2)
# Test the functions
print("Prime Number Analysis")
print("-" * 40)
# Count primes between 1 and 50
count1 = count_primes_between(1, 50)
print(f"Prime numbers between 1 and 50: {count1}")
# Find 10th prime
prime10 = nth_prime(10)
print(f"The 10th prime number is: {prime10}")
# Check twin primes
num1 = 11
twin1 = is_twin_prime(num1)
print(f"Is {num1} part of a twin prime pair? {twin1}")
if twin1:
print(f" Twin pair: ({num1}, {num1+2})")
num2 = 15
twin2 = is_twin_prime(num2)
print(f"Is {num2} part of a twin prime pair? {twin2}")
num3 = 29
twin3 = is_twin_prime(num3)
print(f"Is {num3} part of a twin prime pair? {twin3}")
if twin3:
print(f" Twin pair: ({num3}, {num3+2})")
# Count primes between 100 and 150
count2 = count_primes_between(100, 150)
print(f"\nPrime numbers between 100 and 150: {count2}")
Expected Output/Behavior:
Prime Number Analysis
----------------------------------------
Prime numbers between 1 and 50: 15
The 10th prime number is: 29
Is 11 part of a twin prime pair? True
Twin pair: (11, 13)
Is 15 part of a twin prime pair? False
Is 29 part of a twin prime pair? True
Twin pair: (29, 31)
Prime numbers between 100 and 150: 10
- Key Points:
- Efficiency: checking up to square root of n would be faster
- Building functions on top of other functions creates powerful abstractions
- The is_prime function is reused multiple times
- Twin primes become rarer as numbers get larger
Problem 2: Password Strength Validator
Problem
Problem Statement: Create a password validation system that checks password strength. Your program should:
- Define a function
count_uppercase(password)that counts uppercase letters in the password - Define a function
count_lowercase(password)that counts lowercase letters - Define a function
count_digits(password)that counts numeric digits - Define a function
has_special_char(password)that returns True if password contains at least one special character from: !@#$%^&* - Define a function
calculate_strength(password)that returns a strength score (0-5):- 1 point if password has at least 2 uppercase letters
- 1 point if password has at least 2 lowercase letters
- 1 point if password has at least 2 digits
- 1 point if password has special character
- 1 point if password length >= 8
- Define a function
get_strength_label(score)that returns:- “Very Weak” for score 0-1
- “Weak” for score 2
- “Medium” for score 3
- “Strong” for score 4
- “Very Strong” for score 5
- Test with these passwords (store each in a separate variable):
- password1 = “abc”
- password2 = “Hello”
- password3 = “HeLLo123”
- password4 = “Pass@123”
- password5 = “MyP@ssW0rd!”
- For each password, show the strength score and label
Solution
def count_uppercase(password):
count = 0
for char in password:
if char >= 'A' and char <= 'Z':
count += 1
return count
def count_lowercase(password):
count = 0
for char in password:
if char >= 'a' and char <= 'z':
count += 1
return count
def count_digits(password):
count = 0
for char in password:
if char >= '0' and char <= '9':
count += 1
return count
def has_special_char(password):
special_chars = "!@#$%^&*"
for char in password:
if char in special_chars:
return True
return False
def calculate_strength(password):
score = 0
if count_uppercase(password) >= 2:
score += 1
if count_lowercase(password) >= 2:
score += 1
if count_digits(password) >= 2:
score += 1
if has_special_char(password):
score += 1
if len(password) >= 8:
score += 1
return score
def get_strength_label(score):
if score <= 1:
return "Very Weak"
elif score == 2:
return "Weak"
elif score == 3:
return "Medium"
elif score == 4:
return "Strong"
else:
return "Very Strong"
# Test passwords
print("Password Strength Analysis")
print("-" * 40)
password1 = "abc"
score1 = calculate_strength(password1)
label1 = get_strength_label(score1)
print(f"Password: {password1}")
print(f" Uppercase: {count_uppercase(password1)}, Lowercase: {count_lowercase(password1)}, Digits: {count_digits(password1)}")
print(f" Strength Score: {score1}/5")
print(f" Strength Label: {label1}")
print()
password2 = "Hello"
score2 = calculate_strength(password2)
label2 = get_strength_label(score2)
print(f"Password: {password2}")
print(f" Uppercase: {count_uppercase(password2)}, Lowercase: {count_lowercase(password2)}, Digits: {count_digits(password2)}")
print(f" Strength Score: {score2}/5")
print(f" Strength Label: {label2}")
print()
password3 = "HeLLo123"
score3 = calculate_strength(password3)
label3 = get_strength_label(score3)
print(f"Password: {password3}")
print(f" Uppercase: {count_uppercase(password3)}, Lowercase: {count_lowercase(password3)}, Digits: {count_digits(password3)}")
print(f" Strength Score: {score3}/5")
print(f" Strength Label: {label3}")
print()
password4 = "Pass@123"
score4 = calculate_strength(password4)
label4 = get_strength_label(score4)
print(f"Password: {password4}")
print(f" Uppercase: {count_uppercase(password4)}, Lowercase: {count_lowercase(password4)}, Digits: {count_digits(password4)}")
print(f" Strength Score: {score4}/5")
print(f" Strength Label: {label4}")
print()
password5 = "MyP@ssW0rd!"
score5 = calculate_strength(password5)
label5 = get_strength_label(score5)
print(f"Password: {password5}")
print(f" Uppercase: {count_uppercase(password5)}, Lowercase: {count_lowercase(password5)}, Digits: {count_digits(password5)}")
print(f" Strength Score: {score5}/5")
print(f" Strength Label: {label5}")
Expected Output/Behavior:
Password Strength Analysis
----------------------------------------
Password: abc
Uppercase: 0, Lowercase: 3, Digits: 0
Strength Score: 1/5
Strength Label: Very Weak
Password: Hello
Uppercase: 1, Lowercase: 4, Digits: 0
Strength Score: 1/5
Strength Label: Very Weak
Password: HeLLo123
Uppercase: 3, Lowercase: 2, Digits: 3
Strength Score: 4/5
Strength Label: Strong
Password: Pass@123
Uppercase: 1, Lowercase: 3, Digits: 3
Strength Score: 4/5
Strength Label: Strong
Password: MyP@ssW0rd!
Uppercase: 3, Lowercase: 5, Digits: 1
Strength Score: 4/5
Strength Label: Strong
- Key Points:
- Character comparison using ASCII values
- Modular design makes it easy to add new criteria
- Each function has a single responsibility
- Could enhance by checking for consecutive characters or common patterns
Problem 3: Mathematical Function Evaluator
Problem
Problem Statement: Create a program that evaluates mathematical functions at different points. Your program should:
- Define a function
quadratic(x, a, b, c)that evaluates ax² + bx + c - Define a function
cubic(x, a, b, c, d)that evaluates ax³ + bx² + cx + d - Define a function
find_quadratic_roots(a, b, c)that finds the roots of ax² + bx + c = 0- Use the quadratic formula: x = (-b ± √(b² - 4ac)) / 2a
- Calculate discriminant = b² - 4ac
- If discriminant < 0, return “No real roots”
- If discriminant = 0, return the one root
- If discriminant > 0, calculate and return both roots
- Define a function
evaluate_at_points(func_type, x1, x2, x3, a, b, c)that:- If func_type is “quadratic”, evaluate quadratic function at x1, x2, x3
- If func_type is “linear”, evaluate ax + b at x1, x2, x3 (use c=0)
- Print the results for each point
- Test your functions:
- Evaluate quadratic 2x² + 3x - 5 at x = -2, 0, 2
- Evaluate cubic x³ - 2x² + x - 1 at x = -1, 1, 3
- Find roots of x² - 5x + 6 = 0
- Find roots of x² + 2x + 5 = 0
- Evaluate linear function 3x + 7 at x = -3, 0, 4
Solution
def quadratic(x, a, b, c):
result = a * x * x + b * x + c
return result
def cubic(x, a, b, c, d):
result = a * x * x * x + b * x * x + c * x + d
return result
def find_quadratic_roots(a, b, c):
# Calculate discriminant
discriminant = b * b - 4 * a * c
if discriminant < 0:
return "No real roots"
elif discriminant == 0:
root = -b / (2 * a)
return root
else:
# Two roots
sqrt_discriminant = pow(discriminant, 0.5)
root1 = (-b + sqrt_discriminant) / (2 * a)
root2 = (-b - sqrt_discriminant) / (2 * a)
return root1, root2
def evaluate_at_points(func_type, x1, x2, x3, a, b, c):
if func_type == "quadratic":
y1 = quadratic(x1, a, b, c)
y2 = quadratic(x2, a, b, c)
y3 = quadratic(x3, a, b, c)
print(f"Quadratic {a}x² + {b}x + {c}:")
elif func_type == "linear":
y1 = a * x1 + b
y2 = a * x2 + b
y3 = a * x3 + b
print(f"Linear {a}x + {b}:")
print(f" f({x1}) = {y1}")
print(f" f({x2}) = {y2}")
print(f" f({x3}) = {y3}")
# Test the functions
print("Mathematical Function Evaluator")
print("-" * 40)
# Evaluate quadratic 2x² + 3x - 5
print("Evaluating 2x² + 3x - 5:")
y1 = quadratic(-2, 2, 3, -5)
y2 = quadratic(0, 2, 3, -5)
y3 = quadratic(2, 2, 3, -5)
print(f" f(-2) = {y1}")
print(f" f(0) = {y2}")
print(f" f(2) = {y3}")
print()
# Evaluate cubic x³ - 2x² + x - 1
print("Evaluating x³ - 2x² + x - 1:")
c1 = cubic(-1, 1, -2, 1, -1)
c2 = cubic(1, 1, -2, 1, -1)
c3 = cubic(3, 1, -2, 1, -1)
print(f" f(-1) = {c1}")
print(f" f(1) = {c2}")
print(f" f(3) = {c3}")
print()
# Find roots
print("Finding roots of x² - 5x + 6 = 0:")
roots1 = find_quadratic_roots(1, -5, 6)
if roots1 != "No real roots":
if isinstance(roots1, tuple):
print(f" Root 1: {roots1[0]}")
print(f" Root 2: {roots1[1]}")
else:
print(f" Single root: {roots1}")
print()
print("Finding roots of x² + 2x + 5 = 0:")
roots2 = find_quadratic_roots(1, 2, 5)
print(f" Result: {roots2}")
print()
# Evaluate linear function
evaluate_at_points("linear", -3, 0, 4, 3, 7, 0)
Expected Output/Behavior:
Mathematical Function Evaluator
----------------------------------------
Evaluating 2x² + 3x - 5:
f(-2) = 3
f(0) = -5
f(2) = 9
Evaluating x³ - 2x² + x - 1:
f(-1) = -5
f(1) = -1
f(3) = 11
Finding roots of x² - 5x + 6 = 0:
Root 1: 3.0
Root 2: 2.0
Finding roots of x² + 2x + 5 = 0:
Result: No real roots
Linear 3x + 7:
f(-3) = -2
f(0) = 7
f(4) = 19
- Key Points:
- Using pow(x, 0.5) for square root since we haven’t covered math module
- Tuple return for multiple values
- Building complex calculations from simpler functions
- Type checking with isinstance (preview of advanced concepts)
This content will be available starting October 21, 2025.