Day 25 - Transition to Python 1
TODO: actually show how to RUN pytest tests.
Functions, Types, and Conditionals in Python vs. Pyret
1. Introduction (10 minutes)
- Motivation:
- Explain that we’ve learned the basics in Pyret—expressions, functions, and data (including structured and conditional data).
- Today we “transition” to Python, which—while conceptually similar—uses different notation and conventions.
- Learning Goals:
- Recognize notational differences in function definitions and type annotations.
- Understand how return values are specified in Python.
- Compare conditionals in Pyret and Python.
- Do Now:
- Show a simple Pyret function (e.g., a gadget cost calculator) and show how it changes into Python.
2. Functions, Types, and Returning Values
- Example: Calculating Gadget Cost
- Pyret Version:
fun gadget-cost(num-gadgets :: Number, label :: String) -> Number:
doc: ```Each gadget costs 0.50,
plus 0.05 per label character```
num-gadgets * (0.50 + (string-length(label) * 0.05))
end - Python Version:
def gadget_cost(num_gadgets: int, label: str) -> float:
"""Each gadget costs 0.50 plus 0.05 per label character"""
return num_gadgets * (0.50 + (len(label) * 0.05))
- Pyret Version:
- Discussion Points:
- Notice
def
vs.fun
and underscores vs. hyphens. - Python uses a single colon for type annotations and requires an explicit
return
statement. - Python uses indentation instead of explicit end keywords.
- Notice
- Do Now:
- Ask: “What would happen if you omit the return statement in Python? (Hint: Try a small experiment.)”
3. Conditionals in Python
- Example: Shipping Cost on an Order
- Pyret (for review):
fun add-shipping(order-amt :: Number) -> Number:
if order-amt == 0:
0
else if order-amt <= 10:
order-amt + 4
else if order-amt < 30:
order-amt + 8
else:
order-amt + 12
end
end - Python Version:
def add_shipping(order_amt: float) -> float:
"""Increase order price by shipping cost"""
if order_amt == 0:
return 0
elif order_amt <= 10:
return order_amt + 4
elif order_amt < 30:
return order_amt + 8
else:
return order_amt + 12
- Pyret (for review):
- Do Now:
- Have students identify how
elif
in Python corresponds to Pyret’selse if
.
- Have students identify how
- Interactive Exercise:
- Ask students to write a Python function that computes a “discounted price” based on a condition (e.g., if the order is over $50, apply a 10% discount; otherwise, no discount).
NOTE: do we need pytest.approx? I guess we should talk about numerics, Pyret is arbitrary precision, which is pretty important.
4. Testing and Examples
- Pyret’s where: Blocks vs. Python’s Testing with pytest:
- Pyret Example:
fun gadget-cost(num-gadgets :: Number, label :: String) -> Number:
num-gadgets * (0.50 + (string-length(label) * 0.05))
where:
gadget-cost(1, "hi") is 0.55
gadget-cost(10, "tech") is 6.00
end - Python Example Using pytest:
import pytest
def gadget_cost(num_gadgets: int, label: str) -> float:
return num_gadgets * (0.50 + (len(label) * 0.05))
def test_gadget_cost():
assert gadget_cost(1, "hi") == pytest.approx(0.55)
assert gadget_cost(10, "tech") == pytest.approx(6.00)
- Pyret Example:
- Discussion:
- Python does not have “where:” blocks; tests are written separately.
- Note that type annotations in Python are not enforced at runtime.
5. Wrap-Up (10 minutes)
- Recap:
- Reviewed how expressions, functions, and conditionals are written in Python versus Pyret.
- Highlighted key notational differences and the importance of the return statement in Python.