Assignment 3: Composing functions
This assignment is due on Wednesday, 1/24 at 11:59 PM. Submit it using the handin server as assignment a3.
1Preparation
In your textbookturn to Fixed-Sized Datachapter.
In Functions and Programs read first Functionsthen Composing Functions.
You should also be familiar with using the design recipe with two kinds of data definition, Enumerations and Intervals.
2 Year, Monthand Day
You will design functions that make use of dates as conventionally written in English. The following data definitions will be used throughout the assignment, and more will be introduced as they are needed.
; A Year is a non-negative integer ; A Month is one of: ; January ; February ; March ; April ; May ; June ; July ; August ; September ; October ; November ; December ; A Day is an integer in the range 1 to 31 inclusive
Note that in general, it will be your job to create the data definitions. However, for this assignment we will provide the data definitions so that you may focus on the subsequent steps in the design recipe.
3 calendar
The goal of this section is to design a program which allows a user armed with relevant information about a date to generate an image displaying that date.
Analyzing this goal, we realize that written dates have a format and a choice of format needs to be made along the way. This decision gave rise to two additional data definitions:
; A MonthFormat is one of: ; long ; short ; A DateOrder is one of: ; MDY ; DMY
We will provide additionally the next 1-2 steps of the design recipe. In this assignment, most of your work will be in carrying out steps 4 and 5. (And what are these?)
; calendar : Year Month Day -> Image ; returns an image of a date on a background
Now, notice that calendarwould need carry out a number of operations to transform its input into an image. And more importantly, some of these operations have yet to be defined. Defining them all at once in the body of calendarwould result at best in a complicated function definition; at worst, in a broken or buggy definition which is hard to improve.
So instead we design helper functions which will be called in the body of calendar.
; format-month : Month MonthFormat -> String ; abbreviates Month to three letters or not ( define ( format-month m f ) ) ( check-expect ( format-month November long ) November ) ( check-expect ( format-month November short ) Nov )
You will find the substring function useful here. Look it up in the documentation.
Use format-monthto design the following function:
; year-month-day->date : Year Month Day DateOrder MonthFormat -> String ; produces a date as a string ; given: 1936 November 12 MDY long expect: November 12, 1936 ; given: 1936 November 12 MDY short expect: Nov 12, 1936 ; given: 1936 November 12 DMY long expect: 12 November 1936 ; given: 1936 November 12 DMY short expect: 12 Nov 1936 ( define ( year-month-day->date y m d o f ) )
For year-month-day->dateand the function stubs below, be sure to write unit tests with check-expectusing the examples given (as well as any other examples you see fit to devise).
You will find the string-append function useful here. Look it up in the documentation.
Once you have designed year-month-day->date, make a choice of date format and design calendar.
(If you are looking for some visual inspiration, do an image search online for the Modernist painter On Kawara.)
4 days-between
The goal of this section is to design a program which enables its user to calculate the number of days between two dates. As above, it would be prudent to decompose this task into subtasks to be carried out by helper functions.
To simplify, we assume that a year has 365 days.
; year-month-day->days : Year Month Day -> Number ; returns the number of days elapsed since January 1, 0 ; given: 0 January 1 expect: 0 ; given: 2017 August 28 expect: 736444
; month->days-in-year : Month -> Number ; returns the days elapsed in the year ; given: January expect: 0 ; given: September expect: 243
; days-between : Year Month Day Year Month Day -> Number
Be sure to complete the purpose statement and devise examples/tests for days-between.
5 time-passing
In this section, the goal is to design a program which produces a simple animation of calendar. With each tick of animate, a day will pass. Lastly, the animation will be initialized to a date of your choosing.
Take a moment to reflect on this problem and where the difficulty lies. In a sense, we would like to feed calendarto animate, relax and watch the show. However, calendartakes three arguments and none of these is the number of days elapsed since 1 Jan, 0000.
So we cannot simply compose animateand calendar. But we can design functions which allow us to connect the two. To start with, we will design a function days->year:
; days->year : Number -> Year ; takes days since 1 Jan 0 and returns the year ; given: 364 expect: 0 ; given: 365 expect: 1 ; given: 736305 expect: 2017 ; given: (year-month-day->days 1999 December 31) expect: 1999
Notice that the last example is a witness to an important property of days->year: taken together with analogous functions into Month and into Day, we would have constructed a (left)inverseto year-month-day->days.
Also notice that days->yearcan be used to supply the Year argument to calendar.
; DaysInYear is an integer falling into one of 12 intervals: ; [0,31) ; [31,59) ; [59,90) ; [90,120) ; [120,151) ; [151,181) ; [181,212) ; [212,243) ; [243,273) ; [273,304) ; [304,334) ; [334,365) ; interpretation: the number of elapsed days ; since the first day of the year ; DaysInMonth is an integer in [0,31) ; interpretation: the number of elapsed days ; since the first of the month
Both days->monthand days->dayshould be defined using helpers.
; days-in-year->month : DaysInYear -> Month ; takes days since the first of the year and returns the month ; given: 0 expect: January ; given: 31 expect: February ; given: 242 expect: August ; days->month : Number -> Month ; takes days since 1 Jan 0 and returns the month ; given: 59 expect: March ; given: 364 expect: December ; given: 736445 expect: August ; given: (year-month-day->days 1999 December 31) expect: December
; days-in-year->days-in-month : DaysInYear -> DaysInMonth ; takes days since the first of the year ; and returns days since the first of the month ; given: 0 expect: 0 ; given: 59 expect: 0 ; given: 364 expect: 30 ; days->day : Number -> Day ; takes days since 1 Jan 0 and returns the day of the month ; given: 0 expect: 1 ; given: 59 expect: 1 ; given: 736324 expect: 30 ; given: (year-month-day->days 1999 December 31) expect: 31
Hint: Although the input is an Enumeration, it is not necessary to use condto write days-in-year->days-in-month. Instead, define a composite function with days-in-year->monthand month->days-in-year.
Finally, we are ready to build our animation.
( define init-year ) ( define init-month ) ( define init-day ) ; init-time : Number ; days since init-month init-day, init-year ; given: init-month := December ; init-year := 1999 ; init-day := 31 ; expect: 729999 ( define init-time ) ; time-passing : Number -> Image ; takes days t since 1 Jan 0, advances t by init-time ; and returns a calendar image of the corresponding date ( define ( time-passing t ) )
Your final program should produce a running animation.
Reviews
There are no reviews yet.