Laboratory 2 will be collected from your GitLab repository on Thursday, April 8, 2021 at 11:59pm.
Preliminaries
We have pre-seeded your repositories with a template file named
lab2.rkt
in a directory called lab2
. To get started,
update your local repository.
cd cs151
git pull
assuming that cs151
is the name of your local repository.
At this point, if you do a ls
command, you should see a directory
named lab2
(in addition to the include
and lab1
directories).
Open the lab2.rkt
file in DrRacket.
Once you have opened your lab2.rkt
file with DrRacket, go to the
Language menu, then select "Choose Language…", and then choose
"Determine language from source" from the popup menu on the lower
left edge of the application window.
You will notice that the lab2.rkt
file contains the following code:
#lang typed/racket
;; CMSC15100 Spring 2021
;; Lab 2
;; <YOUR NAME HERE>
;; List your collaborators in a comment
;; include CS151-specific definitions
(require "../include/cs151-core.rkt")
;; include testing framework
(require typed/test-engine/racket-tests)
;; YOUR CODE HERE
;; run tests
;;
(test)
You should replace "<YOUR NAME HERE>
with your name and the code that you write
for this lab will replace the "YOUR CODE HERE" comment.
Description
This week, you will practice working with conditional expressions, function definitions, and program design by implementing some common useful operations on calendar dates.
Note that, unless otherwise specified, you may assume that function arguments are valid.
We define a formula for computing the day of the week below. The formula only works for the 20th and 21st centuries, so your dates will be restricted to that range.
First write a function is-leap-year?
of type
(Integer -> Boolean)
to compute whether or not a year is a
leap year. Leap years are not simply every fourth year. The precise
rule is as follows:
A year is a leap year if it is divisible by 4 and not divisible by 100, or if it is divisible by 400.
For the time being, you do not need to account for negative years; you
may assume your function is given only nonnegative arguments. Since the
is-leap-year?
function requires testing the divisibility of one integer
by another, you should consider first writing a helper function that
implements the divisibility test.
Note
|
TIP:
TypedRacket provides the function |
Second, using the is-leap-year?
function, write a function
days-in-month
that given a year and month (months are represented
by integers from 1 to 12), returns the number of days in the month.
It should have the signature
(: days-in-month : Integer Integer -> Integer)
We would like to reject dates like September 31, 2021, or, for that matter, September 32, 2021. Write a function as specified to determine whether a given year, month, day combination represents a valid date.
(: valid-date? : Integer Integer Integer -> Boolean)
The arguments are (in order) the year, month, and day. Thus, to check if March 32, 2020 is valid, we evaluate
(valid-date? 2020 3 32)
Besides checking that a calendar date exists, this function should
also check that it is between the years 1900 and 2099 inclusive, and
return #f
if it is not.
We now give the formula for computing the days of the week. We first define a "month adjustment" as follows:
Month | Adjustment |
---|---|
Jan |
0 for leap years, 1 otherwise |
Feb |
3 for leap years, 4 otherwise |
Mar |
4 |
Apr |
0 |
May |
2 |
Jun |
5 |
Jul |
0 |
Aug |
3 |
Sep |
6 |
Oct |
1 |
Nov |
4 |
Dec |
6 |
The day of the week formula is this. Let \(y\), \(m\), and \(d\), be the year, month, and day of a given date, and let \(\mathit{adj}\) be the "month adjustment" (per the table above) for the given month and year. Then let \(n\) be the following:
where \(\lfloor\frac{y}{4}\rfloor\) is the integer quotient of \(y\)
divided by 4. (For example, \(\lfloor\frac{401}{4}\rfloor\) is 100). You
should use the Typed Racket operation exact-floor
to compute the
\(\lfloor\cdot\rfloor\) operator in your code.
Let \(w\) be the remainder of \(n\) divided by 7. Then
if \(w = 0\), the day is Sunday; if \(w = 1\),
the day is Monday; …; and if \(w = 6\), the day is Saturday.
Write the function
(: day-of-week : Integer Integer Integer -> String)
which takes a date specified as year, month, and day, and returns
the abbreviated name of the week day (i.e., "Sun"
, "Mon"
,
"Tue"
, "Wed"
, "Thu"
, "Fri"
, or "Sat"
).
You should use a helper function that computes day of the week (as
described above) and a helper that maps the integer representation of
a day to its string name.
For the present, assume the function is not given a bogus date, even though you have written a date verifier.
Note
|
TIP:
Explore the terminal command |
Finally, write a function to generate a convenient string representation of a date.
(: date->string : Integer Integer Integer -> String)
The date string should have the following form:
"Mon Oct 5, 2015"
. You should furthermore return the
string "[invalid date]"
for nonexistent or out-of-range
dates. Some examples follow:
> (date->string 2000 1 1)
"Sat Jan 1, 2000"
> (date->string 1980 7 8)
"Tue Jul 8, 1980"
> (date->string 2013 10 9)
"Wed Oct 9, 2013"
> (date->string 2013 9 32)
"[invalid date]"
To implement date->string
, you will need to use the Racket functions
string-append
and number->string
. Note that
string-append
, like +
, *
and many other Racket operations,
is of variable arity: it
consumes 0 or more arguments. All of the arguments
to string-append
must be strings.
You should also write a helper function month->string
to handle the conversion
of month numbers to strings.
Notes
Every function must be preceded by a type signature and a
purpose, and be followed by check-expect
tests.
Make sure to include enough tests so that you can be confident
that your code does not have a bug.
On these points, we do not differentiate between
"helper functions" and "main functions" — all functions should have type signature, purpose comment,
and tests.
Submission Instructions
The assignment must be pushed to the GitLab server by Thursday, April 8, 2021 at 11:59pm; we do not accept late work. Remember that to submit your work you will have to add and commit it to your local repository, and then push your changes to the server. You can verify that your work has been submitted by using the web interface to the server.
We strongly recommend pushing your code after you write and test each function; do not wait to the last minute to discover that you cannot commit your work for some reason!!
Also, remember to include, in comments, the names of the other students you worked with during the lab meeting.