7 "Difference between Dates" case study
(4 activities)
7.1 Quiz: "Difference between Dates" case study(1 step)
7.1.1 (Student Assessment) Answer some questions, including some about the case study
1. Which of the following calls of the first version of the day-span procedure produces an error message? (Check all that apply.)
2. Given below are two versions of a procedure to determine whether one height measurement is greater (taller) than another. A height measurement is a two-word sentence that contains some number of feet and some number of inches; the feet and inches are accessed by the feet and inches procedures respectively.
Version 1:
(define (is-taller? height1 height2)
  (cond
    ((> (feet height1) (feet height2)) #t)
    ((< (feet height1) (feet height2)) #f)
    ((> (inches height1) (inches height2)) #t)
    (else #f) ) )

Version 2:
(define (is-taller? height1 height2)
  (> 
    (+ (* 12 (feet height1)) (inches height1))
    (+ (* 12 (feet height2)) (inches height2)) ) )
Which of the two versions above is more similar to the first version of the day-span procedure, and which is more similar to the second version of the day-span procedure? Briefly explain your answer.
3. Write a procedure named student-grade that, given a test score between 0 and 100 as argument, returns an indicator of the appropriate grade. (You should use a cond.)
  • If the score is less than 50, student-grade should return the word Fail.
  • If the score is between 50 and 80, inclusive, student-grade should return Pass.
  • If the score is greater than 80, student-grade should return the word Excellent.
Your procedure should perform as few comparisons as possible.
7.2 Work with version 1 of the case study programs.(9 steps)
7.2.1 (Evidence) Here's the version 1 code.
If you want to open this code in another window, click here
;; Return the difference in days between earlier-date and 
;; later-date. earlier-date and later-date both represent 
;; dates in 2002, with earlier-date being the earlier of 
;; the two dates.
;; Note: general-day-span is not implemented.
(define (day-span earlier-date later-date)
  (cond
    ((same-month? earlier-date later-date)
     (same-month-span earlier-date later-date) )
    ((consecutive-months? earlier-date later-date)
     (consec-months-span earlier-date later-date) )
    (else
     (general-day-span earlier-date later-date) ) ) )

;; Selector procedures for the components of a date.
(define (month-name date) (first date))
(define (date-in-month date) (first (butfirst date)))

;; Return true if date1 and date2 are dates in the same 
;; month, and false otherwise. Date1 and date2 both 
;; represent dates in 2002.
(define (same-month? date1 date2)
  (equal? (month-name date1) (month-name date2)))

;; Return the number of the month with the given name.

(define (month-number month)
  (cond
    ((equal? month 'january) 1)
    ((equal? month 'february) 2)
    ((equal? month 'march) 3)
    ((equal? month 'april) 4)
    ((equal? month 'may) 5)
    ((equal? month 'june) 6)
    ((equal? month 'july) 7)
    ((equal? month 'august) 8)
    ((equal? month 'september) 9)
    ((equal? month 'october) 10)
    ((equal? month 'november) 11)
    ((equal? month 'december) 12) ) )

;; Return true if date1 is in the month that immediately 
;; precedes the month date2 is in, and false otherwise. 
;; Date1 and date2 both represent dates in 2002.
(define (consecutive-months? date1 date2)
  (= 
    (month-number (month-name date2))
    (+ 1 (month-number (month-name date1))) ) )

;; Return the difference in days between earlier-date and 
;; later-date, which both represent dates in the same month 
;; of 2002.
(define (same-month-span earlier-date later-date)
  (+ 1
    (- 
      (date-in-month later-date) 
      (date-in-month earlier-date))  ) )

;; Return the number of days in the month named month.
(define (days-in-month month)
  (cond
    ((equal? month 'january) 31)
    ((equal? month 'february) 28)
    ((equal? month 'march) 31)
    ((equal? month 'april) 30)
    ((equal? month 'may) 31)
    ((equal? month 'june) 30)
    ((equal? month 'july) 31)
    ((equal? month 'august) 31)
    ((equal? month 'september) 30)
    ((equal? month 'october) 31)
    ((equal? month 'november) 30)
    ((equal? month 'december) 31) ) )

;; Return the number of days remaining in the month of the  
;; given date,including the current day. Date represents a 
;; date in 2002.
(define (days-remaining date)
  (+ 
    1 
    (- 
      (days-in-month (month-name date)) 
      (date-in-month date) ) ) )

;; Return the difference in days between earlier-date and  
;; later-date, which represent dates in consecutive months 
;; of 2002.
(define (consec-months-span earlier-date later-date)
  (+ 
    (days-remaining earlier-date) 
    (date-in-month later-date)))
7.2.2 (Display page) Draw a call tree.

Draw a call tree

A call tree for a program is a diagram that contains the names of all the program's procedures, with an arrow from one procedure name to another if the first procedure calls the second. Here, for example, is a call tree for version 2 of the "Difference Between Dates" code.
                         day-span
                             |
                             |
                             v
                        day-of-year
                        /    |    \
                       /     |     \
                      v      |      \
          days-preceding     |       \
                             v        \
                       month-name      v
                                    date-in-month
On paper, draw a call tree for the version 1 program, and show it to your t.a.
7.2.3 (WebScheme) Provide calls to day-span that return given values.

Provide calls to day-span

Fill in the first row of blanks below with legal dates that, when input to version 1 of day-span, produce a result of 45. Fill in the second row of blanks with legal dates that produce a result as large as possible. To see if you are right, press the arrow. If you see a green check, you got it. You will need to wait until you see the word "SchemeHandler" in the upper left corner of the page before you start. If you miss any of these, put an entry in your Extra Brain explaining the reason you missed it.
day-span call day-span result Correct?
(day-span ' ' )
???? Status icon
(day-span ' ' )
???? Status icon
7.2.4 (WebScheme) Provide another call to day-span that results in a call to day-remaining.

Provide a call to day-span

Fill in the blanks below with legal dates that, when input to version 1 of day-span , produce a call to days-remaining .
day-span call Correct?
(day-span '  '  )
Status icon
If you miss this question, put an entry in your Extra Brain explaining the reason you missed it.
7.2.5 (Display page) What's the result of giving invalid dates to day-span?
The next three questions ask about the effect of calling day-span with invalid dates—dates that have either an invalid month or an invalid date-in-month. Assume for each question that one of the dates is incorrect as indicated and the other is correctly formatted.
7.2.6 (WebScheme) Identify where an invalid month name would cause a crash.

Analyze the effect of providing a date with an invalid month name to day-span

When we evaluate (day-span '(may 1) '(jun 5)) using version 1 of the days-span procedure in our Scheme interpreter, the following message appears:
    Bad number in a comparison: (okay)
This is an error message generated by the = procedure. Please answer the following questions (after waiting for SchemeHandler to appear in the upper-left corner).
question your answer correct?
Is the okay being supplied as the first input (type 1 in the box) or the second (type 2 in the box)? Status icon
In which procedure defined in the version 1 code is the call that resulted in the error message? Status icon
Now consider the result of evaluating
    (day-span '(mey 1) '(june 5))
and answer the following questions.
question your answer correct?
Fill in the name of the procedure in the error message that results. (Which procedure produced the error message?)
 :  not a number: okay
Status icon
In which procedure defined in the version 1 code is the call that resulted in the error message? Status icon
If you miss any of these questions, put an entry in your Extra Brain explaining the reason you missed it.
7.2.7 (WebScheme) Identify where an invalid date-in-month would cause a crash.

Analyze the effect of providing a date with a nonnumeric date-in-month to day-span

Before continuing, experiment in the interpreter with calls to day-span in which one of the arguments has an invalid date-in-month, for example (january x) Alternatively, you may experiment by typing dates in the line below and clicking on the pointer.
(day-span '  '  ) 
What you should be looking for is the same information you noticed in the previous step: the name of the builtin procedure whose call directly produces a crash-- = or + in the previous step--and the name of the procedure defined in the program that contains the call. Please fill in the table below with all possibilities for these two procedures. (There are between 1 and 5.) Then click the "test-all" button to check your answers.
builtin procedure whose call produces the error procedure in day-span that calls it correct? all possibilities found?
Status icon Status icon
Status icon
Status icon
Status icon
Status icon
If you miss any of these questions, put an entry in your Extra Brain explaining the reason you missed it.
7.2.8 (Brainstorm) Explain why the two arguments might be handled differently.
You have just noticed that a call to day-span with an invalid first argument might result in a crash in one part of the program, while a call to day-span with an invalid second argument might produce a crash in a different part of the program. Why don't the two situations act the same?
7.2.9 (Brainstorm) What if the date-in-month is an invalid integer?
List all possible consequences or return values that can result from a call to day-span with one of the arguments containing an integer date-in-month that's not legal (Assume that the other argument is correctly formatted.) Here's an example.
(day-span '(january 400) '(february 3))
If an error message results, identify the procedure that produced it. Be sure to review the brainstorm responses after a while to ensure that you haven't missed any of the possibilities.
7.3 Work with version 2 of the case study programs.(6 steps)
7.3.1 (Evidence) Here's the version 2 code.
If you would like to get this code in another window, click here.
;; Selector procedures for the components of a date.
(define (month-name date) (first date))
(define (date-in-month date) (first (butfirst date)))

;; Return the number of days from January 1 to the first day 
;; of the month named month.
(define (days-preceding month)
  (cond
    ((equal? month 'january) 0)
    ((equal? month 'february) 31)
    ((equal? month 'march) 59)
    ((equal? month 'april) 90)
    ((equal? month 'may) 120)
    ((equal? month 'june) 151)
    ((equal? month 'july) 181)
    ((equal? month 'august) 212)
    ((equal? month 'september) 243)
    ((equal? month 'october) 273)
    ((equal? month 'november) 304)
    ((equal? month 'december) 334) ) )

;; Return the number of days from January 1 to the given 
;; date, inclusive.  Date represents a date in 2002.
(define (day-of-year date)
  (+ 
    (days-preceding (month-name date)) 
    (date-in-month date)) )

;; Return the difference in days between earlier-date and 
;; later-date. Earlier-date and later-date both represent 
;; dates in 2002, with earlier-date being the earlier of 
;; the two.
(define (day-span earlier-date later-date)
  (+ 
    1 
    (- 
      (day-of-year later-date) 
      (day-of-year earlier-date) ) ) )
7.3.2 (WebScheme) Produce a call to day-span that returns a given value.

Provide a call to day-span

Fill in the blanks below with legal dates that, when input to version 2 of day-span , produce a result as large as possible. To see if you are right, press the arrow. If you see a green check, you got it. You will need to wait until you see the word "SchemeHandler" in the upper left corner of the page before you start. If you miss this, put an entry in your Extra Brain explaining the reason you missed it.
day-span call day-span result Correct?
(day-span ' ' )
???? Status icon
7.3.3 (WebScheme) What's the result of giving invalid dates to day-span?

Analyze the effect of providing an invalid date to day-span version 2

Before continuing, experiment in the interpreter with calls to day-span in which one of the arguments has an invalid month name, for example (mike 31) Alternatively, you may experiment by typing dates in the line below and clicking on the pointer.
(day-span '  '  ) 
What you should be looking for is the same information you noticed in earlier experiments: the name of the builtin procedure whose call directly produces a crash, and the name of the procedure defined in the program that contains the call. Please fill in the table below with all possibilities for these two procedures. (There are between 1 and 3.) Then click the "test-all" button to check your answers.
builtin procedure whose call produces the error procedure in day-span that calls it correct? all possibilities found?
Status icon Status icon
Status icon
Status icon
Now do the same for a date with an invalid date-in-month, for example, (may x) There are between 1 and 3 possibilities for the crash location.
builtin procedure whose call produces the error procedure in day-span that calls it correct? all possibilities found?
Status icon Status icon
Status icon
Status icon
If you miss any of these questions, put an entry in your Extra Brain explaining the reason you missed it.
7.3.4 (WebScheme) Implement wraparound-day-span.

Implement wraparound-day-span

One may find through experimenting that supplying date arguments that are legal but out of order (i.e. with the later date as the first argument) does not crash the program. Here is a table of sample calls.
day-span call result
(day-span '(may 2) '(may 1)) 0
(day-span '(may 3) '(may 1)) -1
(day-span '(may 1) '(april 1)) -29
(day-span '(december 31) '(january 1)) -363
It would be nice if the program could handle these dates "correctly", that is, by "wrapping around" from one year to the next. We ought to be able to ask a more general procedure named, say, wraparound-day-span to handle dates in either order. Given dates in order, wraparound-day-span should just return what day-span returns. Given dates out of order, it should interpret the second argument as being a date in the next year, and return an appropriate result. Examples:
wraparound-day-span call result
(wraparound-day-span '(may 1) '(may 1)) 1
(wraparound-day-span '(april 30) '(may 1)) 2
(wraparound-day-span '(january 1) '(december 31)) 365
(wraparound-day-span '(may 2) '(may 1)) 365
(wraparound-day-span '(may 3) '(may 1)) 364
(wraparound-day-span '(may 1) '(april 1)) 336
(wraparound-day-span '(december 31) '(january 1)) 2
Fill in the blanks in the procedure framework below to complete the implementation of the wraparound-day-span procedure. Click on the hand to run the tests in the table above. There are many ways to solve this problem, but most will not fit in the space provided. It's important for you to find a short way that fits in the blanks.
framework run tests result
(define (wraparound-day-span date1 date2) 
(if
(day-span date1 date2) ; dates are in order
) )
Status icon
wraparound-day-span call desired result your result
(wraparound-day-span '(may 1) '(may 1)) 1 ????
(wraparound-day-span '(april 30) '(may 1)) 2 ????
(wraparound-day-span '(january 1) '(december 31)) 365 ????
(wraparound-day-span '(may 2) '(may 1)) 365 ????
(wraparound-day-span '(may 3) '(may 1)) 364 ????
(wraparound-day-span '(may 1) '(april 1)) 336 ????
(wraparound-day-span '(december 31) '(january 1)) 2 ????
If you miss any of these, put an entry in your Extra Brain explaining the reason you missed it.
7.3.5 (Brainstorm) Find a bug.
Your little brother or sister changes a single word, integer, or symbol in the second version of the day-span program, with the result that the call
(day-span '(february 1) '(march 1))
returns 30 instead of the correct answer 29. List two different causes of the bug, that is, substitutions of a single word, integer, or symbol that would produce the behavior described. (We think there are at least three.)
7.3.6 (Brainstorm) Describe how you found the two bug possibilities.
Describe how you figured out, in the previous step, where the bugs might be.
7.4 Homework(5 steps)
7.4.1 (Display page) Provide comments for the last homework's discussions
Go back to the last homework discussion assignment Comment on seeing "bad" solutions. Give at least one thoughtful response to another student's answer.
7.4.2 (Display page) Write day-span to handle leap years.
Produce two versions of day-span that work for dates in a leap year. Name them leap-day-span and put them into the files LY1-day-span.scm and LY2-day-span.scm in your hwk5 directory. (You will need to create the hwk5 directory). Both versions should assume that the arguments are legal dates in a leap year (e.g. 2000), with the first argument coming at or before the second argument as in the case study programs. When you want to add new features to a program that is already written, you have two choices. Your first choice is to edit part(s) of the existing the code. This works well if you understand all of the details about how the code works. Your second choice is to leave the original code alone and write new code that reuses the old code. This works well if you don't understand the details of how the old code works, as long as you know how to use the old code.
  • For the first version, you should edit the old code. Rename the good day-span procedure (from Appendix B of the case study) to leap-day-span and modify one or more of its helper procedures. The structure of the program should be the same as the program described in the case study; that is, a call to leap-day-span should result in calls to day-of-year, days-preceding, etc. in the same way as a call to the original day-span does.
  • For the second version, you should keep the old code the same and write new code that reuses old code to get the right result. Don't modify the original day-span at all. Instead, your leap-day-span should send its arguments to the existing day-span and decide separately whether or not to add 1 (for February 29) to the value it returns.
Both versions of leap-day-span should use the good version of the day-span code (version 2). You can find that in Appendix B of the case study. Include a set of convincing tests in your solution files. This assignment is due the beginning of next lab.
7.4.3 (Display page) Identify three possible causes of a bug.
Your pesky younger brother or sister changes a single word, integer, or symbol in the first version of the day-span program, with the result that the call
    (day-span '(january 1) '(february 1))
returns 1 instead of the correct answer 32. List three different potential causes of the bug, that is, substitutions of a single word, integer, or symbol that would produce the behavior described. Also explain why each of your substitutions would cause the bug. Put your list of possible bugs and your explanations in a file named bug.possibilities in your hwk5 directory. We think there are at least four possibilities for the changed word, integer, or symbol.
7.4.4 (Display page) Don't forget to submit the homework
When you have completed all three files, submit them. Remember:
  1. The files will have to be named exactly as specified in the lab.
  2. You submit the files from unix.
  3. You will need to be inside the hwk5 directory (you can type cd ~/hwk5 to ge there).
  4. Submit the files with a hearty "submit hwk5".
7.4.5 (Discussion Forum) Devise three exam questions.
Devise three exam questions that would evaluate a student's understanding of the case study and the case study code. Next lab, you will be asked to (politely) suggest improvements to the questions of two of your classmates.
8 Review of the first two weeks.
(2 activities)
8.1 Summary(2 steps)
8.1.1 (Display page) Big ideas
We covered quite a bit of territory in the first two weeks. You may have spent most of your time learning how to format Scheme code, how to use emacs, how to use unix, and so forth. But, there are several big ideas that we've introduced in the first four days, and we'll come back to these again and again over the course of the semester.

Big ideas

  • How scheme evaluates input
  • Words and sentences
  • Conditionals, predicates, and boolean values
  • Testing
  • Writing good code (choosing good names, writing comments, using helper procedures)
8.1.2 (Display page) The programs and files that you created

Programs (and files) that you have worked on

Day 1:
  • square
  • sales-tax (sales.scm)
  • discount-price (sales.scm)
  • selling-price (sales.scm)
  • day-of-year
  • fifteen,
  • identity, and others for homework
  • additional files in the Emacs tutorial
Day 2:
  • inch-count (measurements.scm)
  • height (measurements.scm)
  • FR-date (FR-date.scm)
  • insert-and, for homework
Day 3:
  • next-higher-even (if-tests.scm)
  • non-crashing-first (if-tests.scm)
  • smaller (if-tests.scm)
  • inches-in-range (measurements.scm)
  • sign
  • seq-type, reorganization
  • exactly-one?, two different versions
  • legal? (legal2.scm). Also, homework was to add tests
  • game-result, for homework
Day 4:
  • comfort-level, in the quiz
  • valid-date? (legal-date.scm), reorganization
  • answer (answer.scm), for homework
8.2 Review problems(4 steps)
8.2.1 (Display page) You may not want to do these now...
The following are problems designed to help you review the first two weeks of materials in the course. It might be wise to save some of these for a later date (say, while studying for midterm 1). Plus, there is a good chunk of materials on the Differences between Dates case study for you to work on!
8.2.2 (Display page) Practice with these "tricky" questions...

Review of Days 1-4, Self Test

Below are four links. Each will take you to another page with some questions and, after you answer, explanations on why your answer is correct or incorrect.

8.2.3 (Display page) What comes between?

From CS3 spring 2006 Midterm 1

Problem X. (A: 3 points, B: 3 points, C: 4 points) What comes between?

Write a procedure called between? which takes three numbers as arguments, and returns true if and only if the second argument is between and not equal to the first and the third:

(between? 5 6 7) --> #t

(between? 7 6 5) --> #t


Part A: Write between? without using if or cond.



Part B: Write between? without using and or or.



Part C: Write a suite of test cases for between?. Make sure you test the possible sets of parameters exhaustively as possible, in order to test different ways the code could be written.

Also, make sure you describe what the result of the call should be!

8.2.4 (Display page) What comes between? (solutions and standards)
What comes between? was an exam question from an earlier CS3 semester. Check here (pdf) for solutions and standards given out then.