Homework 3:
Higher-Order Functions in Racket
Due: Monday, February 10, at 11:59 PM
Introduction
This assignment gives you your first chance to write and use higher-order functions in Racket.
Template Source File
Download
this template file
and use it as the starting point for your submission.
Please name your file homework03.rkt
!
homework03.rkt
includes a require
expression at the top. It imports the rackunit
module and enables you to write test cases for your solutions.
The template file contains several test cases for each problem.
homework03.rkt
includes a provide
expression at the top, which exports your five public functions.
This enables users to load your module and run your functions.
It also enables me to test your code using my own Rackunit tests.
With provide
, you must define all five functions. If
you don't have time to solve a problem, leave the template file's
placeholder function. It returns a legal default value for the
function.
Do Not Use...
To solve these problems, you do not need any Racket features beyond the things we have learned in class and the things discussed in this assignment.
-
Do not use a
let
expression in any function. -
Do not use an internal
define
in any function. -
Do not use explicit recursion or looping in any
function. Your solutions to Problems 3, 4, and 5 should use
higher-order functions such as
apply
andmap
to do their jobs.
Helpful Functions
You may find these Racket primitives useful on this assignment:
-
string->number
converts a string that contains a number into the equivalent number. -
max
takes any number of numeric arguments and returns the largest. -
exact->inexact
converts an exact number (an integer or a fraction) into the equivalent floating-point number. -
You may pass a two-argument function to
map
. If you do, pass two list arguments, not one.map
will pass the corresponding items in each list to the function at the same time:> (map + '(1 3) '(2 7)) '(3 10)
You do not have to use this, but you may if you think it helps.
Problems
-
For
Problem 4
of Homework 2, you wrote a
candy-temperature
function to implement a common conversion from The Joy of Cooking. However, programmers who make candy in the same city most of the time are forced to send their city's elevation as an argument to the function every time they call it. This is inconvenient.
Write a Racket function namedcandy-temperature-at
that takes one number as an argument: elevation (in feet) of a given location.candy-temperature-at
returns a function that takes one argument, a temperature (in degrees Fahrenheit) to use for a candy. The returned function returns as its value the temperature to use for that candy at the specified elevation. For example:> ((candy-temperature-at 5280) 302) ;; Denver 291.44 > (define temp-in-cf ;; Cedar Falls (candy-temperature-at 959)) > (temp-in-cf 240) ;; Cedar Falls fudge! 238.082
I have providedcheck-=
expressions for these examples. Write at least two morecheck-=
expressions to test your solution. -
For
Problem 5
of Homework 2, you wrote a function named
in-range?
that tests to see if two values are within a specified tolerance. When we work in engineering settings with such tolerances, theepsilon
value is often fixed for most of our tests. Passingepsilon
to the function every time we call it is inconvenient, but makingepsilon
a global variable creates bigger problems.
Write a Racket function namedin-range-of?
that takes one number as an argument: the epsilon to use as a tolerance.in-range-of?
returns as its value a function that takes two number arguments. The returned function returns true if the difference between its arguments is less than epsilon, and false otherwise. For example:> ((in-range-of? 0.1) 4.95 5.0) #t > ((in-range-of? 0.1) 5.0 4.95) ;; works both ways #t > (define within-0.01? (in-range-of? 0.01)) > (within-0.01? 4.95 5.0) ;; not anymore! #f > (within-0.01? 5.0 4.99) #t
I have providedcheck-true
andcheck-false
expressions for these examples. You do not have to write any more tests for this problem. -
Suppose that we have a list containing height/weight
pairs for a group of people, in inches and pounds,
respectively:
( (76 . 195) (81 . 212) (79 . 225) (78 . 206) ... )
We would like to know the average height of the people in the group.
Use higher-order functions such asmap
andapply
to define a Racket function namedaverage-height
. This function takes a list of height/weight pairs as its only argument and returns the average height of the group. For example:> (average-height '((79 . 225))) 79.0 > (average-height '((70 . 150) (62 . 100))) 66.0
Assume that we have already written a function namedaverage
that takes any number of numeric arguments and returns their average. (It is given in the template code file.) You may write other helper functions if you like, but you do not have to.
I have providedcheck-=
expressions for these examples. Write at least two morecheck-=
expressions to test your solution. -
A buddy of mine wrote a program that predicts the results of
college basketball games (pretty well, I might add). At the
end of a week, he would like to know how far his program's
predictions were from the actual results. His program has
generated a list of predicted-difference/actual-difference
pairs:
( (2 -7) (-4 -20) (7 8) (-13 2) )
This list contains four games. The first item in the list says that his program predicted Team 1 would win by 2 points, but it lost by 7 points (so, Team 2 won by 7). For that game, his program was off byabs(2 - (-7)) == abs(9) == 9
points. The third item says that his program predicted that Team 1 would win by 7 points and that it won by 8 points, so his program was off byabs(7 - 8) == abs(-1) == 1
point. A list can contain any number of these pairs.
Write a Racket function namedtotal-error
that takes one argument, a list of this form. The function returns the total of all the differences in the list. For example:> (define example '((2 -7) (-4 -20) (7 8) (-13 2))) > (total-error example) 41
I have providedcheck-=
expressions for this example in your template file. Write at least three morecheck-equal?
expressions to test your solution. -
To monitor enrollments each semester, I have a spreadsheet that
contains a list of courses with names, enrollments, and
capacities. I read the spreadsheet data into a Racket list that
looks like this:
'(("Dept" "Number" "Section" "Class Nbr" "Capacity" "Enrolled") ("CS" "1000" "1" "11546" "30" "30") ("CS" "1025" "1" "11547" "30" "30") ("CS" "1120" "1" "11557" "30" "15") ("CS" "1130" "1" "11548" "30" "18") ... )
The first item in the list is the header row in the spreadsheet. It is not part of the data.
The dean and provost frequently ask me for various summary data, such as total enrollments or remaining capacity.
Write a Racket function namedmax-open-seats
that takes such as a list as its only argument. It returns the maximum number of open seats available in any section. For example:> (define example '(...)) ; the data shown above > (min-open-seats example) 15
CS 1120 has 30 - 15 = 15 open seats. The other classes have 0, 0, and 12 open seats, respectively.
I have provided acheck-equal?
expression for this example. Write at least two morecheck-equal?
expressions to test your solution.
Deliverables
Use Save Definitions to save the file of function
definitions you create using the template you downloaded.
It will have the file extension rkt
. Be sure to use
the specified name for your file! This enables the auto-grader
to find and run your code.
By the due time and date, use the course submission system to submit the following files electronically:
-
homework03.rkt
, the source file containing your function definitions and test cases
No hard copy is required.
Be sure that your submission follows the submission requirements. Be sure to use the specified name for your file. This enables the auto-grader to find and run your code.