Skip to main content

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))
  • 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.
  • 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
  • Do Now:
    • Have students identify how elif in Python corresponds to Pyret’s else if.
  • 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)
  • 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.