Day 24 - Transition to Python 1
Skills: 8
Pre-reading: 9.1.1, 9.1.2, 9.1.3, 9.1.4, 9.1.5
Setup: Install & configure VSCode following these directions: https://neu-pdi.github.io/cs2100-public-resources/setup/#vscode
Intro (20 mins)
- Today we begin our transition from Pyret to Python.
- Python and Pyret share many core ideas, but use different notation and conventions -- more significantly, the Pyret programming environment is designed to be easy to use, whereas there is more involved setup for Python.
Example: Function to compute gadget cost
- Pyret:
fun gadget-cost(num-gadgets :: Number, label :: String) -> Number:
doc: "computes cost, at $0.50 per gadget plus $0.05 per character in label"
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:
def gadget_cost(num_gadgets: int, label: str) -> float:
""" computes cost, at $0.50 per gadget plus $0.05 per character in label """
return num_gadgets * (0.50 + (len(label) * 0.05))
# Testing -- we'll come back to this
Example: Conditionals
- Pyret:
fun add-shipping(order-amt :: Number) -> Number:
doc: "adds 4 for orders <= 10 (but non-zero), 8 for orders < 30, 12 for larger orders"
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:
def add_shipping(order_amt: float) -> float:
""" adds 4 for orders <= 10 (but non-zero), 8 for orders < 30, 12 for larger orders """
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
# Testing -- we'll come back to this
Testing in Python with pytest
- In Pyret, you use
where:
blocks for examples/tests. In Python, there are multiple ways to write tests, but a simple (and widely used) mechanism is usingpytest
, where you write separate test functions usingassert
. - Example:
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) - Conventions:
- Test functions must be named starting with
test_
. - Use
assert
to check expected results. It takes a boolean expression and causes a test failure if it evaluates toFalse
. - For floating-point (any decimal in Python) results, use
pytest.approx
for comparison.
- Test functions must be named starting with
- How to run tests:
- Save your code in a file, e.g.,
gadget.py
. - In the terminal, run:
pytest gadget.py
- pytest will find and run all functions named
test_*
and report results.
- Save your code in a file, e.g.,
Class Exercises (35 mins)
-
Function Syntax Practice
- Rewrite the following Pyret function in Python:
Be sure to follow full design recipe, including a docstring and test cases.
fun greet(name :: String) -> String:
doc: "produces Hello, name!"
"Hello, " + name + "!"
where:
greet("Alice") is "Hello, Alice!"
greet("Bob") is "Hello, Bob!"
end - Now, design a Python function that takes a name and an age, and returns a string like
"Alice is 20 years old."
- Rewrite the following Pyret function in Python:
-
Conditionals
- Translate this Pyret function to Python:
fun shipping-cost(weight :: Number) -> Number:
doc: "if weight <= 1, cost is $5; if weight <= 5, cost is $10; otherwise, $20"
if weight <= 1:
5
else if weight <= 5:
10
else:
20
end
end - Design a Python function
grade_letter(score: int) -> str
that returns"A"
for scores 90 and above,"B"
for 80–89,"C"
for 70–79,"D"
for 60–69, and"F"
otherwise.
- Translate this Pyret function to Python:
-
Return Statement
- What happens if you forget the
return
statement in a Python function? Try it and observe the result.
- What happens if you forget the
Wrap-up (5 mins)
- Python and Pyret share core ideas, but differ in syntax and conventions.
- Next time: more on Python data and control structures.