Functional Problem Solving (CSC 151 2015S) : Assignments

Exam 2: Color and Control


Assigned: Tuesday, 2 March 2015

Due: The due dates for various tasks are as follows.

Preliminaries

Exam format

This is a take-home examination. You may use any time or times you deem appropriate to complete the exam, provided you return it to me by the due date.

This examination has a prologue that must be completed by the Sunday evening before the exam is due. The prologue is intended to help you get started thinking about the examination. The prologue is required. Failure to fill in the prologue by the designated time will incur a penalty of five points on the examination.

This examination has an epilogue that must be completed by the evening after the exam is due. The epilogue is intended to help you reflect carefully on the examination. The epilogue is required. Failure to fill in the epilogue will incur a penalty of five points on the exam.

There are eight problems on this examination. Each problem is worth the same number of points, except for problem 1, which is worth 0 points. Although each remaining problem is worth the same amount, problems are not necessarily of equal difficulty.

Read the entire exam before you begin.

We expect that someone who has mastered the material and works at a moderate rate should have little trouble completing the exam in a reasonable amount of time. In particular, this exam is likely to take you about four hours, depending on how well you've learned the topics and how fast you work. You should not work more than five hours on this exam. Stop at five hours and write “There's more to life than CS” on the cover sheet of the examination and you will earn at least the equivalent of 70% on this exam, provided you recorded the time spent on each problem, filled in the prologue by the specified deadline, filled in the epilogue, and arranged for a meeting with me within one week of receiving your graded exam. You may count the time you spend on the prologue toward those five hours, but not the time you spend on the epilogue.. With such evidence of serious intent, your score will be the maximum of (1) your actual score or (2) the equivalent of 70%. The bonus points for errors and recording time are not usually applied in the second situation, but penalties (e.g., for failing to number pages) usually are.

You should not count time reviewing readings, laboratories, or assignments toward the amount of time you spend on the exam or on individual problems.

We would also appreciate it if you would write down the amount of time each problem takes. Each person who does so will earn two points of extra credit for the exam. Because we worry about the amount of time our exams take, we will give two points of extra credit to the first two people who honestly report that they have completed the exam in four hours or less or have spent at least four hours on the exam. In the latter case, they should also report on what work they've completed in the four hours. After receiving such notices, we may change the exam.

Academic Honesty

This examination is open book, open notes, open mind, open computer, open Web. However, it is closed person. That means you should not talk to other people about the exam. Other than as restricted by that limitation, you should feel free to use all reasonable resources available to you.

As always, you are expected to turn in your own work. If you find ideas in a book or on the Web, be sure to cite them appropriately. If you use code that you wrote for a previous lab or homework, cite that lab or homework as well as any students who worked with you. If you use code that you found on the course Web site, be sure to cite that code. You need not cite the code provided in the body of the examination.

Although you may use the Web for this exam, you may not post your answers to this examination on the Web. And, in case it's not clear, you may not ask others (in person, via email, via IM, via IRC, by posting a please help message, or in any other way) to put answers on the Web.

Because different students may be taking the exam at different times, you are not permitted to discuss the exam with anyone until after I have returned it. If you must say something about the exam, you are allowed to say “This is among the hardest exams I have ever taken. If you don't start it early, you will have no chance of finishing.” You may also summarize these policies. You may not tell other students which problems you've finished. You may not tell other students how long you've spent on the exam.

You must include both of the following statements on the cover sheet of the examination.

  1. I have neither received nor given inappropriate assistance on this examination.
  2. I am not aware of any other students who have given or received inappropriate assistance on this examination.

Please write, sign, and date each statement. Note that the statements must be true; if you are unable to sign either statement, please talk to me at your earliest convenience. You need not reveal the particulars of the dishonesty, simply that it happened. Note also that “inappropriate assistance” is assistance from (or to) anyone other than Professor Rebelsky.

Exams can be stressful. Don't let the stress of the exam lead you to make decisions that you will later regret.

Presenting Your Work

You must present your exam to me in two forms, physically and electronically.

For the physical copy, you must write all of your answers using the computer, print them out, number the pages, staple them together (except for the cover sheet), and hand me the printed copy. For your benefit and for ours, we are doing blind grading on this examination, so you have been assigned a number to use on your exam. Please make sure that your number appears at the top of every page. You should turn in a separate cover sheet along with your stapled and printed answers. The cover sheet should include (1) the two hand-written academic honesty statements (individually signed and dated, if it is appropriate for you to sign each), (2) your name, and (3) your assigned number. If you choose to invoke the “there's more to life than computer science” option, then you must indicate that option on the cover sheet, and you should indicate it only on the cover sheet.

The code and comments in your printed copy must use a fixed-width (a.k.a., monospaced or fixed-pitch) font; depending on what platform you use, viable candidates include Monospace, Courier, Courier New, Monaco, DejaVu Sans Mono, Free Mono, Liberation Mono, and Lucida Sans Typewriter. Failure to format your code with a monospace font will result in a penalty. You may read the instructions on printing for more details on how to create readable output.

You must also submit the code for your examination at http://bit.ly/151-2015S-exam2. Ideally, you would put all of the code for the exam in a single Racket file. However, if you have created separate files for the separate parts of the exam, you can just paste them one after another when you submit, provided you put a clear separator, such as ; PROBLEM 2, between sections.

In both cases (physical and electronic), you should put your answers in the same order as the problems. Failure to number the printed pages will lead to a penalty. Failure to turn in both versions may lead to a much worse penalty.

While your electronic version is due at 10:30 p.m. Thursday, your physical copy will be submitted in class on Friday. It is presumed the physical copy matches the electronic copy. Any discrepancies (other than formatting) will be considered a misrepresentation of your work and referred to the Committee on Academic Standing.

In many problems, we ask you to write code. Unless we specify otherwise in a problem, you should write working code and include examples that show that you've tested the code informally (by looking at what value you get for various inputs) or formally (by using the Rackunit testing framework). In addition to the examples provided in the exam, you should also provide additional examples. Do not include resulting images; we should be able to regenerate those.

Unless we tell you otherwise, you should assume that you need to document every primary procedure with the six Ps. If you write helper procedures (and it's often a good idea to write helper procedures), you need only document those with a sentence or two that gives their purpose. (We would prefer that you use the 6P style, but won't require it.)

Just as you should be careful and precise when you write code and documentation, so should you be careful and precise when you write prose. Please check your spelling and grammar. Because we should be equally careful, the whole class will receive one point of extra credit for each error in spelling or grammar you identify in the preliminaries and problems on this exam. We will limit that form of extra credit to five points.

We will give partial credit for partially correct answers. We are best able to give such partial credit if you include a clear set of work that shows how you derived your answer. You ensure the best possible grade for yourself by clearly indicating what part of your answer is work and what part is your final answer.

Getting Help

I may not be available at the time you take the exam. If you feel that a question is badly worded or impossible to answer, note the problem you have observed and attempt to reword the question in such a way that it is answerable. If it's a reasonable hour (8am-10pm), feel free to try to call me (cell phone (text only) - 641-990-2947).

I will also reserve time at the start of classes the week the exam is due to discuss any general questions you have on the exam.

Problems

Problem 1: Close Colors

THIS PROBLEM IS NO LONGER REQUIRED!

Topics: Integer-encoded RGB colors, predicates

As Matt Kluber, our colleague in studio art, notes, there are a lot of different colors available in the RGB spectrum (2^24, or about 16 million). It turns out that many of us lack the visual acuity to distinguish colors with similar red, green, and blue components.

Let's define a metric for similarity of RGB colors. In order to say whether or not two colors are similar, we should know the “distance” between those colors. You may know that for two points on the plane, the distance between those two points is the plane (x1,y1) and (x2,y2) is the square root of the sum of the squares of the differences between those points. In Scheme, we'd write that as follows:

(define plane-distance
  (lambda (x1 y1 x2 y2)
    (sqrt (+ (square (- x1 x2)) (square (- y1 y2))))))

Write, but do not document, a procedure, (irgb-close? irgb1 irgb2 closeness-metric) that takes two colors and a real number as parameters and returns true (#t) if the two colors have a distance less than the number, and returns false (#f) otherwise.

> (irgb-close? (irgb 0 0 0) (irgb 0 0 0) 10)
#t
> (irgb-close? (irgb 10 10 10) (irgb 25 25 25) 16)
#f
> (irgb-close? (irgb 10 25 10) (irgb 25 10 25) 32)
#t
> (irgb-close? (irgb 100 100 100) (irgb 100 100 115) 16)
#t
> (irgb-close? (irgb 100 100 100) (irgb 100 100 115) 14)
#f

Problem 2: Tricolor Images

Topics: Integer-encoded RGB colors, code reading, conditionals, local bindings

In printing, and in some forms of op-art from the 1960's, one takes an image developed in a much larger color space and represents it using a much smaller color space, perhaps with as few as two colors. The following procedure takes an image and three colors, and makes a new version of the image by replacing each color in the image by the closest of those three colors.

(define tricolor
  (lambda (image color1 color2 color3)
    (image-variant 
     image
     (lambda (color)
        (let ([distance1 
               (sqrt (+ (square (- (irgb-red color) 
                                   (irgb-red (color->irgb color1))))
                        (square (- (irgb-green color) 
                                   (irgb-green (color->irgb color1))))
                        (square (- (irgb-blue color) 
                                   (irgb-blue (color->irgb color1))))))]
              [distance2
               (sqrt (+ (square (- (irgb-red color) 
                                   (irgb-red (color->irgb color2))))
                        (square (- (irgb-green color) 
                                   (irgb-green (color->irgb color2))))
                        (square (- (irgb-blue color) 
                                   (irgb-blue (color->irgb color2))))))]
              [distance3
               (sqrt (+ (square (- (irgb-red color) 
                                   (irgb-red (color->irgb color3))))
                        (square (- (irgb-green color) 
                                   (irgb-green (color->irgb color3))))
                        (square (- (irgb-blue color) 
                                   (irgb-blue (color->irgb color3))))))])
          (cond 
            [(= distance1 (min distance1 distance2 distance3))
             (color->irgb color1)]
            [(= distance2 (min distance1 distance2 distance3))
             (color->irgb color2)]
            [else
             (color->irgb color3)]))))))

As you may have noted, there are many problems with the definition of tricolor. It is repetitious in that we see similar code written again and again and again. It is also inefficient in that we recompute values again and again and again.

You can see the effects of these redundancies when we try to run it even on a small image.

> (time (tricolor (image-new 10 10) "red" "orange" "blue"))
cpu time: 312 real time: 6217 gc time: 0
1
> (define sample 
    (image-show (image-compute 
                 (lambda (col row)
                   (irgb (mod (* col 29) 255)
                         (mod (* (+ col row) 17) 255)
                         (mod (* row 31) 255)))
                 10 10)))
2
> (time (tricolor sample "black" "blue" "red"))
cpu time: 320 real time: 6255 gc time: 0
3
> (time (tricolor (image-new 20 20) "black" "white" "grey"))
cpu time: 1248 real time: 23280 gc time: 0
4

If even a 20x20 image takes us about 24 seconds, it will take an interminable amount of time on our kitten, which is 200x300.

Rewrite tricolor to eliminate redundancies. Your first priority should be to eliminate repeated computation; once the code computes a value once, it should not have to compute it again. Your second priority should be to eliminate repeated code; if there are two pieces of code that look similar, find a way to make them a single piece of code. You will find that local bindings with let and let* will help with both activities. Your third priority will be to make it concise and clear.

The most important set of changes will make a huge improvement in the running time. The remainder will primarily affect concision, elegance, and readability. Here's an example showing the running time after making one important change. (We include the example to show just how significant the change is.)

> (time (tricolor (image-new 20 20) "black" "white" "grey"))
cpu time: 8 real time: 46 gc time: 0
5
> (time (tricolor kitten "red" "black" "yellow"))
cpu time: 548 real time: 960 gc time: 0
7

In this problem, you are updating an existing procedure. Hence, you do not need to write the 6P-style documentation.

Problem 3: Blended Rings

Topics: Computing images, color blends, computing circles, conditionals

In the reading on building images from functions, you learned how to compute an image of circles using the distance of each image pixel from a center point. We can use that idea for not only circles, but also rings. For a ring, rather than using a color for all points within a given radius, we use a color for all points between two given radii.

In the lab on computing images, you figured out how to generalize a linear blend from one color component to another. In particular, you saw how to make a horizontal blue blend from any amount of blue to any other amount of blue.

In this problem, we will combine those two ideas.

Write, but do not document, a procedure, (radial-red-blended-ring inner-radius outer-radius initial-red final-red), that draws a 200x200 image with a ring of the specified inner radius and outer radius, centered at (100,100). The color at the inner radius should be (irgb initial-red 0 0). The color at the outer radius should be (irgb final-red 0 0). There should be a smooth blend within the ring. Pixels inside the ring should be colored white. Pixels outside the ring should be colored grey.

(radial-red-blended-ring 50 100 0 255) (radial-red-blended-ring 25 90 192 64) (radial-red-blended-ring 105 120 128 255)

Hint: Your computation of the red component should look very similar to horiz-blue-blend. However, instead of transitioning from column zero to width, the calculation will span a distance (from the center) of inner-radius to outer-radius.

Hint: Locally bind the distance of a given pixel from the center and use that distance both in a conditional test and in the calculation for the color's red component.

Hint: In writing such a procedure, you may find the euclidean-distance procedure from the reading helpful. (If you incorporate it into your exam, please be sure to cite its source.)

Problem 4: Defining rac and rdc

Topics: Core list operations, documentation.

You know that car and cdr are two basic operations for extracting the first element of a list and all but the first element of a list. Surprisingly, Scheme doesn't have procedures for getting the last and all but the last element from a list. (Okay, it's not so surprising: The underlying implementation of lists makes implementing car and cdr quick and straightforward. But the implementation makes getting the last element much less efficient.) But that's okay, we can implement them. Let's say we want to write two procedures, rac, which extracts the last element of a list, and rdc, which extracts a list containing all but the last element of the list.

For example,

> (rac (list 3 1 4))
4
> (rac (iota 20))
19
> (rdc (list 3 1 4))
'(3 1)
> (rdc (iota 20))
'(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18)

Write 6P-style documentation for rdc. Make sure that you specify the preconditions as carefully as possible. What does the input have to look like? Will the procedures accept empty lists? Singleton lists? Long lists?

Make equally sure that you specify the postconditions carefully. You want to make sure that someone who is unclear on the purpose does not accidentally write a procedure that sometimes returns the wrong value (e.g., the empty list or the cdr).

Problem 5: Implementing rac and rdc

Topics: Core list operations, concision, higher-order procedures (e.g., composition, sectioning)

Implement rac and rdc as concisely as you can. You should be able to implement rac with five words, including define and rac, plus a few parentheses. You should be able to implement rdc almost as concisely.

You do not need to document rac. You should have already documented rdc in the previous problem.

Note: You may not use the alternate mechanism of define procedures of the form (define (rac lst) ...), but you may find other ways to avoid writing lambda.

Note: You will receive most of the credit for a correct solution, even if it is not as concise as it is possible.

Problem 6: Classifying Colors

Topics: Colors, unit testing

Consider the procedure (irgb-classify icolor), that takes integer-encoded RGB color as input and returns the symbol 'reddish when the red component is larger than both the green and blue components, 'greenish when the green component is larger than both the red and blue components, 'blueish when the blue component is larger than both the red and green components, and 'otherish when none of those conditions holds.

> (irgb-classify (irgb 255 0 0))
'reddish
> (irgb-classify (irgb 0 32 0))
'greenish
> (irgb-classify (irgb 10 15 30))
'blueish
> (irgb-classify (irgb 128 128 128))
'otherish

Write a comprehensive test suite for irgb-classify.

Since you'll need something to test, here's an incorrect implementation. Amazingly, it gives the right answers for all of the examples above.

(define irgb-classify
  (lambda (icolor)
    (if (= (irgb-red icolor) (irgb-blue icolor) (irgb-green icolor))
        'otherish
        (if (> (irgb-red icolor) 128)
            'reddish
            (if (> (irgb-green icolor) (irgb-blue icolor))
                'greenish
                'blueish)))))

Your tests should not just catch the many errors in this implementation, but should be designed to catch errors in any implementation.

Note: As is usually the case in testing, you should think about a variety of cases. Consider different relationships between the red, green, and blue components and make sure you test them all. About a dozen should suffice, provided they are different.

Note: I am likely to run your tests on incorrect code that reflects some of the errors that novices are likely to make, and will expect you to catch errors in the incorrect code. I am unlikely to run your tests on maliciously designed code, but it would be nice if your tests also caught errors in such code if I did.

Note: For testing, you need to pick concrete values to test. For example, here's one of the checks I might do for a color in which blue dominates.

(check-equal? (irgb-classify (irgb 190 190 200)) 
              'blueish
              "blue dominates, red and green are equal and large")

Problem 7: Classifying Colors, Continued

Topics: Colors, conditionals

Correctly implement the irgb-classify procedure described in the prior problem. You need not document irgb-classify.

Problem 8: Sophisticated Selections

Topics: Lists, concision, higher-order procedures (map).

In a recent assignment, you wrote a procedure, (image-sample image x-coords y-coords), that gets the color at each (x,y) pair, makes a shape in that color, and then renders the shape at the same location in a new image.

As we saw in class, we can achieve interesting effects by automatically generating long lists of x and y coordinates. There are a variety of lists that are possible to generate. Solve one of the following two problems in generating coordinates.

Problem 8a: Zig-Zag Selections

Here's one opportunity: Given a width and a height, we can make a zig-zag shape by having the x coordinates increase linearly from 0 to (width-1) and the y coordinates decrease linearly from (height-1) to 0 for the first third of the width, then increase linearly from 0 to (height-1) for the second third, and then decrease linearly from (height-1) to 0 again for the final third. (That is, the line will go up/down/up, with each segment 1/3 of the width of the image.)

Write, but do not document, a procedure, (zigzag-y-coords width height), that computes the y coordinates for the previously described zig-zag. For extra credit, do not use conditionals or append.

It's difficult to get the numbers perfect. Hence, the way you calculate the values can be such that you don't quite reach 0 or (height-1) at the inflection points, as in the following example.

> (zigzag-y-coords 20 20)
'(19 16 13 10 7 4 1 2 5 8 11 14 17 18 15 12 9 6 3 0)

Here's how we might use that procedure to achieve an interesting effect from our kitten image.

>  (image-sample kitten 
                 (iota (image-width kitten)) 
                 (zigzag-y-coords (image-width kitten) 
                                  (image-height kitten)))

Here's what the kitten looks like if we overlay that sample.

Note: In my solution, I made the slope of the line 3*(height-1)/(width-1), or the opposite of that. You may find find that slope appropriate, or you might use 3*height/width.

Problem 8b: Sinusoidal Selections

Here's one slightly more interesting approach: Given a width and a height, we can have the x coordinates increase linearly from 0 to (width-1) and the y coordinates make a sine wave that ranges between 0 and height-1.

Write, but do not document, a procedure, (sinusoidal-y-coords width height), that computes the y coordinates for one cycle of a sine wave, in the manner shown.

> (sinusoidal-y-coords 20 5)
'(2
  1.381966011250105
  0.8244294954150537
  0.3819660112501051
  0.09788696740969294
  0.0
  0.09788696740969272
  0.3819660112501051
  0.8244294954150535
  1.381966011250105
  1.9999999999999998
  2.6180339887498953
  3.175570504584946
  3.618033988749895
  3.9021130325903073
  4.0
  3.9021130325903073
  3.618033988749895
  3.1755705045849467
  2.6180339887498953)
> (map (o inexact->exact round) (sinusoidal-y-coords 20 100))
'(50 34 20 9 2 0 2 9 20 34 49 65 79 90 97 99 97 90 79 65)

Here's how we might use that procedure to achieve an interesting effect from our kitten image.

>  (image-sample kitten 
                 (iota (image-width kitten)) 
                 (sinusoidal-y-coords (image-width kitten) 
                                      (image-height kitten)))

Here's what the kitten looks like if we overlay that sample.

Some Questions and Answers

Here we will post answers to questions of general interest. Please check here before emailing your questions!

General Questions

What is a general question?
A question that is about the exam in general, not a particular problem.
Do the two sections have the same exam?
Yes.
Does our exam need to be in the body of the email, or will you accept attachments?
Neither. You should submit via Web form.
Can we still invoke the “There's more to life” clause if we spend more than five hours on the exam?
Yes. However, we really do recommend that you stop at five hours unless you are very close to finishing. It's not worth your time or stress to spend more effort on the exam. It is, however, worth your time to come talk to us, and perhaps to get a mentor or more help (not on this exam, but on the class). There's likely some concept you're missing, and we can help figure that out.
What do you mean by “implement”?
Write a procedure or procedures that accomplish the given task.
Do we have to make our code concise?
You should strive for readable and correct code. If you can make it concise, that's a plus, but concision is secondary to readability and correctness. Long or muddled code is likely to lose points, even if it is correct.
Much of your sample 6P-style documentation has incomplete sentences. Can we follow that model? That is, can we use incomplete sentences in our 6P-style documentation?
Yes, you can use incomplete sentences in 6P-style documentation.
You tell us to start the exam early, but then you add corrections and questions and answers. Isn't that contradictory? Aren't we better off waiting until you've answered the questions and corrected any errors?
That's one of the reasons I give extra credit to those who work on the exam early. But you're also better able to get your questions answered early (or at least I think you are). Later questions will generally be told “See the notes on the exam”.
Is there a way to see our prologues?
I have not figured out how to make Google Docs give you your own data back. If you want your prologue, email me and I'll send it to you. In the future, you should probably answer the prologue questions in a separate document and then copy and paste into the Google Form.
How do we know what our random number is?
You should have received one on Tuesday. If you need a new one, there's a stack in the back of our classroom.
When we print the exam, do you prefer one problem per page (one on the front of the page, one on the back, unless more is needed)? If not, is it okay to have a blank line between each problem?
I prefer that you use less paper. A few blank lines between problems, and perhaps a comment like ; --------- PROBLEM 2 -------------
To show we’ve tested the code informally, would you just like us to just post the inputs we used to test the procedure? If so, how should we list those?
Copy and paste the interactions pane into the appropriate place in the definitions pane. Select the text. Under the Racket menu, use "Comment out with semicolons."

Problem 1

Can you explain why (irgb-close? (irgb 10 10 10) (irgb 25 25 25) 16) is false? It seems like each pair of components differs by only 15, and 15 is less than 16. [2015-03-04]
The metric we're using is one close to that for distance in the plane. In that case, we use (sqrt (+ (square (- x1 x2)) (square (- y1 y2)))). In this case, we want to do something similar with the components (that is, take the square root of the sum of the squares of the differences)..
> (sqrt (+ (square 15) (square 15) (square 15)))
25.98076211353316

Problem 2

I'm getting much slower times for the initial version than you got. Is that okay? [2015-03-05]
Yes. I may have used a slightly faster computer.
It's interminable to run this on a 20x20 image. What should I do? [2015-03-05]
Use a 10x10 or 5x5 image to start with.
Do we have to document tricolor? [2014-03-08]
No.
Any hints? [2014-03-08]
Sure. First, color->irgb is very slow. Do that computation as few times as possible. Second, anything that happens within the inner lambda happens for every pixel. In a 300x400 image, that 120,000 computations. If you don't need something recomputed every time, don't compute it every time.
Any more hints? [2014-03-08]
The value procedure that we've used a number of times is useful for seeing when you do repeated work. Try calling it at various points in your program to see how many computations you are doing and whether all of them are necessary. (E.g., if you keep computing the same value, you should find a way to compute it only once.)
(define value
  (lambda (val)
    (write val)
    (newline)
    val))

Problem 3

My code isn't working. Do you have a suggestion about what I should do? [2015-03-08]
I find it very useful to experiment with sample values by hand. For example, try whatever formula you come up with initial-red of 0, final-red of 100, inner-radius of 25, outer-radius of 75, and the points (0,25), (0,30), (0,50), (0,60), and (0,75). The red values should be 0, 10, 50, 70, and 100. Once you're sure the formula works on that range, try something different, such as initial-red of 220, a final-red of 120, an inner radius of 50, an outer radius of 250, and the points (0,50), (0,70), (0,150), and (0,250).
My code is very slow. Is that a problem? [2015-03-11]
Your code should not be slow. Most of the times I've seen slow code for this problem, it's because people are using color->irgb or something similar, and are calling that procedure for most of the pixels in the image. Since color->irgb is very slow, doing it as many as 40,000 times makes your procedure unbearably slow.

Problem 4

Do we only have to document rdc and not rac? [2015-03-04]
You only have to document rdc. I don't think you or I will gain much if you also document rac.

Problem 5

Any hints? [2014-03-08]
Pretend you're making an anonymous procedure and then name it. You've learned at least three ways of making anonymous procedures. lambda is one of them. But there are at least two others.

Problem 6

Why are there no questions and answers on problem 6? [2015-03-09]
I don't know.

Problem 7

Do we have to document irgb-classify? [2014-03-08]
No.

Problem 8

Why do you give extra credit on 8a for avoiding conditionals? [2015-03-04]
I think it's harder to do without conditionals, but it will be a more elegant (and probably more general) solution without conditionals.
For problem 8b, shouldn't the sine curve go the other way? [2015-03-07]
I want it to go up, then down, then up. So you are correct that the normal sine curve would be the opposite of that. You should adapt your code to meet the given view.

Errata

Here you will find errors of spelling, grammar, and design that students have noted. Remember, each error found corresponds to a point of extra credit for everyone. We usually limit such extra credit to five points. However, if we make an astoundingly large number of errors, then we will provide more extra credit. (And no, we don't count errors in the errata section or the question and answer sections.)

  • Two of the examples in irgb-close? used (100 100 115) instead of (irgb 100 100 115). [AL and EE, 1 point]
  • The broken irgb-classify used equal? instead of =. [AL, 1 point]
  • Sam is confused about the difference between “increase” and “decrease” on problem 8a. [EE, 1 point]
  • The sample code for classifying colors gives 'red rather than 'reddish. [EE, 1 point]
  • Because of the way DrRacket shows fractions, it looks like there are more than 20 values in the zig-zag. [DL and HL, 1 point]

Citations

Some of the problems on this exam are based on (and at times copied from) problems on previous exams for the course. Those exams were written by Janet Davis, Rhys Price Jones, Samuel A. Rebelsky, John David Stone, Henry Walker, and Jerod Weinman. Many were written collaboratively, or were themselves based upon prior examinations, so precise credit is difficult, if not impossible.

Some problems on this exam were inspired by conversations with our students and by correct and incorrect student solutions on a variety of problems. We thank our students for that inspiration. Usually, a combination of questions or discussions inspired a problem, so it is difficult and inappropriate to credit individual students.

The photograph of the kitten was released for public use at http://public-photo.net/displayimage-2485.html. It appears that site is now down.