Recitation 2 — Functions & Conditionals
Skills: 1
Reading: 3.2, 3.3, 3.4
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 Pyret's 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
PI
is built in to Pyret.
Developing FCC Constants
- Students should define a reference latitude using the average of their points
POINT-A-LAT
andPOINT-B-LAT
. - Now, students should compute two constants,
KPDLAT
andKPDLON
. Reference page 3 of https://www.govinfo.gov/content/pkg/CFR-2016-title47-vol4/pdf/CFR-2016-title47-vol4-sec73-208.pdf, notingML
is the reference latitude just defined, and be sure to convert to radians before using Pyret'snum-cos
function.
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
fun dist(lat1 :: Number, lat2 :: Number, lon1 :: Number, lon2 :: Number):
doc: "Calculates the distance between two coordinates using FCC approximation"KPDLAT
and 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:
fun dist(lat1, lat2, lon1, lon2):
doc: "Calculates the distance between two coordinates using FCC approximation"
...
where:
dist(POINT-A-LAT, POINT-B-LAT, POINT-A-LON, POINT-B-LON) is%(within(0.1)) 1
end - 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. Pyret's
is
can be followed by%()
and then a testing predicate can be placed within the parentheses: the most common one iswithin(N)
whereN
is some number. This checks that the output is1 +- 0.1
, i.e., that it is greater than0.9
and 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