Skip to main content

Lesson 5: Calendar and Advanced Math

You've mastered basic math operations, time concepts, date/time handling, and formatting. Now you're ready to explore Python's advanced mathematical capabilities and calendar displays. These specialized tools unlock possibilities in scientific computing, scheduling interfaces, and wherever math meets programming.

In this lesson, you'll generate beautiful calendar grids, perform trigonometric calculations for angles and rotations, work with logarithms for exponential growth and scientific scales, and learn to handle edge cases where math produces infinity or NaN. Most importantly, you'll understand WHEN to use these functions in real applications rather than memorizing formulas.

Calendar Display with Python 3.14

Let's start with something visual: generating calendar displays. The calendar module transforms calendar dates into ASCII art that's perfect for scheduling interfaces, meeting planners, or informational displays.

Basic Month Display

The simplest calendar task is displaying an entire month. Python 3.14 enhanced this with automatic color highlighting in terminal output:

import calendar

# Display November 2025
cal: str = calendar.month(2025, 11)
print(cal)

Output (with today's date highlighted in color in your terminal):

    November 2025
Mo Tu We Th Fr Sa Su
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

Notice: Python 3.14 automatically highlights today's date (November 9) in color when you run this in a modern terminal. This is a native feature—the output includes ANSI color codes that your terminal interprets.

💬 AI Colearning Prompt

"When running calendar.month() in your terminal, you'll see today's date in color (Python 3.14 feature). How does Python know what 'today' is? Can I override the highlight?"

This prompt encourages you to explore how Python determines the current date and whether you can customize calendar behavior for specific use cases.

Calendar for Scheduling Logic

Beyond display, the calendar module helps with scheduling calculations:

import calendar

# Get the first weekday of November 2025 (0=Monday, 6=Sunday)
first_day: int = calendar.weekday(2025, 11, 1) # Returns 5 (Saturday)

# How many days in this month?
num_days: int = calendar.monthrange(2025, 11)[1] # Returns 30

# Check if a year is a leap year
is_leap: bool = calendar.isleap(2025) # Returns False

print(f"November 2025 starts on day {first_day}")
print(f"November 2025 has {num_days} days")
print(f"2025 is a leap year: {is_leap}")

These functions solve real scheduling problems: "What day of the week should I display this date?" and "How many days should this calendar have?"

🎓 Instructor Commentary

In AI-native development, you don't memorize calendar functions—you understand WHEN you need them (scheduling logic, date calculations, UI layout). You know what functions exist (weekday(), monthrange(), isleap()) and ask AI when you need them. Syntax is cheap; recognizing "I need to know the first weekday of a month" is gold.

Trigonometric Functions and Angles

Trigonometry appears in many programming contexts: game rotations, wave simulations, GPS coordinates, graphics transformations, and physics calculations. You don't need to memorize formulas—you need to recognize when sine, cosine, or tangent applies.

Understanding Angles in Radians

First, critical detail: Python's math functions use radians, not degrees. One full rotation is 2π radians (not 360 degrees).

import math

# Convert degrees to radians
degrees: float = 45.0
radians: float = math.radians(degrees) # Convert 45° to radians

# Calculate trigonometric values
sine_value: float = math.sin(radians)
cosine_value: float = math.cos(radians)
tangent_value: float = math.tan(radians)

print(f"45° = {radians:.4f} radians")
print(f"sin(45°) = {sine_value:.4f}")
print(f"cos(45°) = {cosine_value:.4f}")
print(f"tan(45°) = {tangent_value:.4f}")

Output:

45° = 0.7854 radians
sin(45°) = 0.7071
cos(45°) = 0.7071
tan(45°) = 1.0000

For a 45° angle, sine and cosine both equal roughly 0.707 (the square root of 0.5), and tangent equals 1. You recognize these patterns through use, not memorization.

Real-World Application: Right Triangle

Suppose you're building a game where a character throws a projectile at an angle. To calculate how far it travels, you need trigonometry:

import math

# Launch angle and initial velocity
angle_degrees: float = 30.0
velocity: float = 20.0 # meters per second
gravity: float = 9.8 # m/s²

# Convert to radians and calculate trajectory
angle_radians: float = math.radians(angle_degrees)
sin_angle: float = math.sin(angle_radians)
cos_angle: float = math.cos(angle_radians)

# Time to reach maximum height
time_to_max: float = (velocity * sin_angle) / gravity

# Horizontal distance (range)
horizontal_distance: float = (velocity ** 2 * math.sin(2 * angle_radians)) / gravity

print(f"Projectile at {angle_degrees}° reaches max in {time_to_max:.2f} seconds")
print(f"Horizontal distance: {horizontal_distance:.2f} meters")

Output:

Projectile at 30° reaches max in 1.02 seconds
Horizontal distance: 35.34 meters

You see the formula, but you understand why: sine determines the vertical component of velocity, cosine the horizontal. The pattern becomes familiar through application.

🚀 CoLearning Challenge

Ask your AI Co-Teacher:

"Generate a calculator that converts degrees to radians and computes all three trig functions (sin, cos, tan) for the angle. Then explain how sin and cos relate to the sides of a right triangle."

Expected Outcome: You'll understand why sine and cosine produce values between -1 and 1, and how they describe triangle proportions.

Logarithmic Functions and Scientific Computing

Logarithms answer the question: "To what power must I raise a base to get this number?" They're essential for exponential growth, decibel scales, pH calculations, and data compression.

Natural and Base-10 Logarithms

Python provides two logarithm functions:

import math

# Natural logarithm (base e)
value: float = 7.389 # Approximately e²
natural_log: float = math.log(value) # Returns approximately 2.0

# Base-10 logarithm
value_base10: float = 1000.0
base10_log: float = math.log10(value_base10) # Returns 3.0

print(f"ln({value}) = {natural_log:.4f}")
print(f"log₁₀({value_base10}) = {base10_log:.1f}")

Output:

ln(7.389) = 2.0000
log₁₀(1000) = 3.0

Natural logarithm (math.log()) is used for continuous growth calculations. Base-10 (math.log10()) is used for scales like decibels or scientific notation.

Practical Example: Decibel Calculation

Decibels measure sound intensity on a logarithmic scale (that's why a whisper and a jet engine seem so different despite being "just sound"):

import math

# Sound intensity in watts per square meter
reference_intensity: float = 1e-12 # Threshold of hearing
jet_engine_intensity: float = 130.0 # Watts per m²

# Decibels = 10 * log₁₀(intensity / reference)
decibels: float = 10 * math.log10(jet_engine_intensity / reference_intensity)

print(f"Jet engine: {decibels:.1f} dB")

Output:

Jet engine: 130.0 dB

The logarithmic scale means intensity multiplying by 10 only adds 10 dB. This is why humans perceive sound logarithmically rather than linearly.

✨ Teaching Tip

Explore edge cases with your AI: "What is log(0)? What is log(-5)? How do I test if a logarithm calculation failed?" These questions reveal that logarithms have constraints (domain errors)—understanding them prevents bugs.

Factorial and Combinatorial Mathematics

Factorials calculate how many ways you can arrange items. The factorial of 5 (written 5!) equals 5 × 4 × 3 × 2 × 1 = 120.

import math

# Calculate factorials
five_factorial: int = math.factorial(5) # 120
ten_factorial: int = math.factorial(10) # 3,628,800

print(f"5! = {five_factorial}")
print(f"10! = {ten_factorial}")

Factorials grow explosively. 20! already exceeds 2 trillion. They're useful for:

  • Permutations: How many ways to arrange N items?
  • Combinations: How many ways to choose K items from N items?
  • Probability: Calculating odds in games, lotteries, or statistics
import math

# How many ways to arrange 5 letters?
arrangements: int = math.factorial(5) # 120

# How many ways to choose 3 toppings from 8 available?
# Formula: n! / (k! * (n-k)!)
n: int = 8
k: int = 3
combinations: int = math.factorial(n) // (math.factorial(k) * math.factorial(n - k))

print(f"Arrangements of 5 letters: {arrangements}")
print(f"Ways to choose 3 toppings from 8: {combinations}")

Output:

Arrangements of 5 letters: 120
Ways to choose 3 toppings from 8: 56

Special Numeric Values: Infinity and NaN

Some mathematical operations don't produce normal numbers. Infinity (math.inf) represents unbounded growth. NaN (Not a Number, math.nan) represents undefined results. Both are validation tools.

Using Infinity

Infinity is useful as a sentinel value or for comparisons:

import math

# Initialize a variable to find the minimum
current_minimum: float = math.inf

# Process list of values
values: list[float] = [10.5, 3.2, 8.9, 1.1]

for val in values:
if val < current_minimum:
current_minimum = val

print(f"Minimum: {current_minimum}")

# Test for infinity
if math.isinf(current_minimum):
print("No values found")
else:
print(f"Found minimum: {current_minimum}")

Output:

Minimum: 1.1

If the list were empty, current_minimum would still be math.inf, signaling "no valid value found."

Handling NaN

NaN occurs when math produces undefined results:

import math

# Square root of negative number causes domain error
try:
result: float = math.sqrt(-1)
except ValueError as e:
result = math.nan # Mark as invalid
print(f"Invalid calculation: {e}")

# Test for NaN
if math.isnan(result):
print("Result is not a number (undefined)")
else:
print(f"Result: {result}")

Output:

Invalid calculation: math domain error
Result is not a number (undefined)

Validation Example: Safe Division

Combine multiple checks to handle edge cases:

import math

def safe_divide(numerator: float, denominator: float) -> float | None:
"""Divide safely, returning None if result is invalid."""
if denominator == 0:
return math.inf # Division by zero

result: float = numerator / denominator

# Check for undefined results
if math.isnan(result) or math.isinf(result):
return None

return result

# Test cases
print(safe_divide(10, 2)) # 5.0
print(safe_divide(10, 0)) # inf
print(safe_divide(0, 0)) # nan (0/0 is undefined)

Output:

5.0
inf
None

💬 AI Colearning Prompt

"Explain what happens when Python calculates 0.0 / 0.0. Why is this different from 10 / 0? How would you test for these cases in validation logic?"

This explores why infinity and NaN exist—they represent different mathematical failures that your code must handle differently.

Putting It Together: Advanced Math Application

Here's a function that uses trigonometry, logarithms, and validation together:

import math

def calculate_sound_wave(
frequency: float,
time_seconds: float,
amplitude: float = 1.0
) -> float | None:
"""Calculate sound wave intensity at a given time.

Args:
frequency: Oscillations per second (Hz)
time_seconds: Time since start
amplitude: Wave height (must be positive)

Returns:
Wave value, or None if parameters are invalid
"""

# Validate amplitude
if amplitude <= 0:
return None

# Calculate angle (in radians)
angle: float = 2 * math.pi * frequency * time_seconds

# Calculate wave using sine
wave_value: float = amplitude * math.sin(angle)

# Calculate energy (intensity increases logarithmically)
intensity: float = math.log10(abs(wave_value) + 1) # +1 to avoid log(0)

return intensity

# Simulate sound wave at different times
for t in [0.0, 0.125, 0.25, 0.5]:
intensity: float | None = calculate_sound_wave(frequency=440, time_seconds=t)
if intensity is not None:
print(f"Time {t}s: intensity = {intensity:.4f}")
else:
print(f"Time {t}s: invalid")

Output:

Time 0.0s: intensity = 0.0000
Time 0.125s: intensity = 0.0010
Time 0.25s: intensity = 0.3010
Time 0.5s: intensity = 0.0010

This function:

  • Validates input (amplitude must be positive)
  • Calculates a sine wave (trigonometry)
  • Converts to logarithmic scale (scientific computing)
  • Returns None for invalid cases
  • Uses type hints throughout

Try With AI

Your AI companion is ready to explore these advanced mathematical concepts deeper. Remember: you're learning to ask for explanations and understanding, not just requesting code.

Using ChatGPT, Gemini CLI, or your AI companion of choice:

1. Recall: Practical Uses for Logarithms

"What are three practical uses for logarithms in programming? Give real-world examples beyond math class."

Expected outcome: You name applications like decibels, pH scale, data compression, earthquake magnitude, or exponential growth measurements.

2. Understand: Special Numeric Values

"Explain what math.inf and math.nan represent. Why would a program need to handle these rather than crashing with an error?"

Expected outcome: You describe infinity as a sentinel value for "no valid result" and NaN as "mathematically undefined," and explain why catching them matters for robust code.

3. Apply: Multi-Function Calendar and Math

"Generate code that displays a calendar for next month AND calculates the sine wave for a 440Hz tone at 5 different times. Then explain when each piece (calendar, trigonometry) would be used in a real application."

Expected outcome: You get working code that combines calendar.month(), math.sin(), and math.radians(), and you can articulate that calendars power scheduling UIs while trigonometric waves power audio processing and game physics.

4. Analyze: Real-World Math Problem

"You're building a game where a ball bounces at an angle. What mathematical concepts would you use (trigonometry, logarithms, special values)? How would you validate that calculations don't produce infinity or NaN?"

Expected outcome: You explain that you'd use trigonometry to calculate trajectory components, validate inputs before mathematical operations, and test results for special values before using them in game logic.

Safety note: When working with mathematical calculations, always validate inputs before operations. Be aware that some operations (square root of negative, log of zero) produce domain errors that Python's enhanced error messages help you understand with AI assistance.