# Chapter 6: Functions, Modules, Errors, and Testing
# Fundamentals of Python for Financial Econometrics - Functions, Modules, Errors, and Testing
# Dataset: Ceteris Lab teaching sample

# Functions, Modules, Errors, and Testing
#
# **Opening question:** How can a calculation be trusted when it is reused in several chapters or projects?

# %% Cell 2
def simple_return(start_price: float, end_price: float) -> float:
    """Return the decimal holding-period return."""
    if start_price <= 0:
        raise ValueError("start_price must be positive")
    return end_price / start_price - 1

print(simple_return(100, 105))

# **Interpretation check:** Interpretation. The tiny binary representation difference is normal. Formatting or math.isclose is appropriate when comparing floating-point values.

# %% Cell 4
import math

assert math.isclose(simple_return(100, 105), 0.05)
try:
    simple_return(0, 105)
except ValueError as err:
    print(err)

# **Interpretation check:** Interpretation. The first assertion protects the formula; the second check demonstrates that an invalid denominator is rejected.

# Verified source output
#
# ```text
# 0.050000000000000044
# ```
#
# ```text
# start_price must be positive
# ```
#
# ```text
# def simple_return(start_price: float, end_price: float) -> float:
# raise ValueError("start_price must be positive")
# print(simple_return(100, 105))
# import math
# assert math.isclose(simple_return(100, 105), 0.05)
# simple_return(0, 105)
# ```
