Practice 2 — Functions & Conditionals
Skills: 0, 1, 2
Reading: the Notes sections of Class 3, Class 4, and Class 5
Calculating Distance -- Test First
- Have each student or group select two landmarks (using Google Maps) that are approximately 1 mile apart according to "measure distance" function (right/ctrl click to use it). They should record the latitude and longitude for each point.
- Students define their chosen points. For example:
(Students should use the coordinates they find.)
POINT_A_LAT = 42.3505
POINT_A_LON = -71.1054
POINT_B_LAT = 42.3430
POINT_B_LON = -71.1020
Write a Helper Function: deg_to_rad**
- The FCC approximation formula we will use to calculate
distance use trigonometric functions, and Python's (from the
mathlibrary) require angles to be in radians, whereas latitude & longitude are in degrees. - Have students write a function to convert from degrees to radians. Remember, 2
PI is the same as 360 degrees. The constant
math.picomes from Python'smathlibrary (so putimport mathat the top of your file).
Developing FCC Constants
- Students should define a reference latitude using the average of their points
POINT_A_LATandPOINT_B_LAT. - Now, students should compute two constants,
KPDLATandKPDLON. Reference page 3 of https://www.govinfo.gov/content/pkg/CFR-2016-title47-vol4/pdf/CFR-2016-title47-vol4-sec73-208.pdf, notingMLis the reference latitude just defined, and be sure to convert to radians before using themath.cosfunction.
Building the Distance Function
- Given the following function header:
define a function to calculate the distance. The key is that north-south distance is the difference of latitudes multiplied by
def dist(lat1: float, lat2: float, lon1: float, lon2: float) -> float:
"""Calculates the distance between two coordinates using FCC approximation"""KPDLATand the east-west distance is the difference in longitudes multiplied byKPDLON, and then the pythagorean theorem can get the actual distance.
Writing a Test Case
- At the beginning, we found two points that we chose to be 1 mile apart --
let's write a test using those points:
import pytest
def dist(lat1: float, lat2: float, lon1: float, lon2: float) -> float:
"""Calculates the distance between two coordinates using FCC approximation"""
...
def test_dist():
assert dist(POINT_A_LAT, POINT_B_LAT, POINT_A_LON, POINT_B_LON) == pytest.approx(1, abs=0.1) - Numeric calculations using decimal numbers will often have small
inaccuracies, so tests will work better if they test that the output is not
equal, but rather, within a certain bound of the expected value.
pytest.approxcan be given a bound, aspytest.approx(expected, abs=N), whereNis some number. This checks that the output is1 +- 0.1, i.e., that it is greater than0.9and less than1.1. - Run the test -- what do you see?
Discovering the Bug
- If our FCC formulas produce a result based on our constants, why might the computed value be different from 1?
- If tests fail, either the code is wrong or the tests are wrong. Which is the case here?
- What is the value that is produced? (Approximately 1.609). What is the relationship between 1.609 and 1?
- Once you figure out the bug, go back and fix the issue in the code! Re-run to confirm that the bug has been fixed.
Wrap-Up
- Breaking the problem into parts (helper function, constants, raw computation) helped manage complexity.
- Test cases (e.g., using real-world data -- two points chosen to be 1 mile apart) revealed the a bug (unit mismatch).
- In 1999, a space probe was lost because of failure to correctly convert between units! https://en.wikipedia.org/wiki/Mars_Climate_Orbiter