Questions to ask yourself as you go through the design process

Asking yourself questions at each step of the design process is helpful in creating well-designed, correct solutions. But like any other skill, knowing which questions to ask takes practice. Many times, the questions have to do with data types, and often the answers to the questions are found in previous steps in the design recipe. As a model, here are the questions I would ask myself while designing the function any-cs-in-b? which we developed in class today.

Starting point: data definitions, templates, signature/purpose

We started with these data definitions, examples, templates, and signature and purpose for the function. All of this information will be used to answer subsequent questions.

;; a Course is a (make-course symbol number symbol number number)
(define-struct course(dept coursenum term sections seats))

;; Examples
(make-course 'CS 1101 'C 6 25)
(define MA2201 (make-course 'MA 2201 'A 8 30))

;; a ListOfCourse is either
;; empty, or
;; (cons Course ListOfCourse)

;; Examples
(define sched1 (cons MA2201 (cons (make-course 'CS 1101 'C 6 25) empty)))

#|
;; course-template:  Course ... -> ...
;; ...
(define (course-template acourse ...)
  (course-dept acourse)
  (course-coursenum acourse)
  (course-term acourse)
  (course-sections acourse)
  (course-seats acourse))
|#

#|
;; ListOfCourse template
;; loc-fcn:  ListOfCourse ... -> ...
;; ...
(define (loc-fcn aloc ...)
  (cond [(empty? aloc)   ]
        [(cons? aloc)    (course-template (first aloc) ...)
                         (loc-fcn (rest aloc) ...)]))
|#




;; any-cs-in-b?:  ListOfCourse -> Boolean
;; consumes a list of courses and determines whether any CS courses are offered in B-term

Questions about the test cases

The design recipe tells us that once we have a signature/purpose for a function, we need to design test cases next. When designing test cases, ask yourself these questions:

Questions about the easy parts of the function definition

Questions to ask about the cons? case...these are the questions that take some practice to master

Almost always, the hardest part of designing a function involves figuring out how to combine the pieces the template gives you into an expression that correctly solves the problem. Let's look at the cons? part of the template:

[(cons? aloc)    (course-template (first aloc) ...)
                 (any-cs-in-b? (rest aloc))]

Questions to ask about the design of the helper function

We've determined that we need to develop a helper function that consumes a Course. Use the course-template:

;; course-template:  Course ... -> ...
;; ...
(define (course-template acourse ...)
  (course-dept acourse)
  (course-coursenum acourse)
  (course-term acourse)
  (course-sections acourse)
  (course-seats acourse))

Last step: Questions to ask about using the helper

We're back to the list function, any-cs-in-b? But now we have a helper function cs-in-b? that is fully designed and tested. Here's the list template with the name of our new helper function:

;; any-cs-in-b?:  ListOfCourse -> Boolean
;; consumes a list of courses and determines whether any CS courses are offered in B-term
(define (any-cs-in-b? aloc)
  (cond [(empty? aloc) false  ]
        [(cons? aloc)    (cs-in-b? (first aloc))
                         (any-cs-in-b? (rest aloc))]))

Run the test cases on any-cs-in-b?, and we're done. Whew!