Skip to main content

Assignment 3: Getting started with Racket

Assigned
Wednesday, 30 January 2019
Due
Tuesday, 5 February 2019 by 10:30pm
Summary
In this assignment, you will write a variety of procedures to work with numbers, strings, and images.
Collaboration
You must work with your assigned partner(s) on this assignment. You may discuss this assignment with anyone, provided you credit such discussions when you submit the assignment.
Submitting
Email your answer to csc151-01-grader@grinnell.edu. The subject of your email should be [CSC151-01] Assignment 3 (Your Names) and should contain your answers to all parts of the assignment. Scheme code should be in the body of the message, not in an attachment.

Problem 1: Scoring divers, gymnasts, and similar athletes

Topics: Scheme basics, Numeric computation

As you may know, in many sports, such as diving and gymnastics, a group of judges award scores to each athlete. To improve the accuracy of the scoring, they normally drop the top and bottom score and then compute the average. (We realize that this approach is not completely accurate for some sports; there are many variants of this approach.) We’ll call this computation robust average.

In this problem, we will build a procedure that computes the score for an athlete using the robust average process. We want the output to be easily readable and meaningful, so we will do some numeric processing to convert the precise scores into something more humanly intelligible.

Suppose we have eight judges for the event and they award scores of 7, 10, 4, 7, 6, 9, 8, and 6. We can compute the sum of those eight numbers with DrRacket.

> (+ 7 10 4 7 6 9 8 6)
57

We can then eliminate the smallest score (5) and the largest score (10).

> (- 57 10 5)
42

And then we can compute the average.

> (/ 42 6)
7

Part A: Finding the robust average

i. Write a procedure, (average-5 score1 score2 score3 score4 score5), that takes five scores as input and finds the average of those five scores. You should not eliminate any scores for this procedure, just compute the average of all five values.

ii. Write a procedure, (robust-average-5 score1 score2 score3 score4 score5) that computes the robust average of five scores.

iii. Write a procedure, (robust-average-6 score1 score2 score3 score4 score5 score6) that computes the robust average of six scores.

Part B: Cleaner averages

The averaged scores you may have seen so far may not be all that pretty. For example,

> (robust-average-5 8 5 6 8 5)
6 1/3

Instead of the 6 1/3, which you might get for this contestant, we’d probably prefer 6.3, which is an approximation of 6.3333333333…, the decimal representation of 6 1/3.

You may recall that we have a number of mechanisms for rounding real numbers to integers, such as ceiling and floor. But what if we want to round not to an integer, but to only one digit after the decimal point? Racket does not include a built-in operation for doing that kind of rounding.

i. Write a procedure, (robust-decimal-average-5 score1 score2 score3 score4 score5), which attempts to round the five scores to one decimal place.

> (robust-decimal-average-5 8 5 6 8 5)
6.3

Hint: Think about how you can arrange values so that the round procedure helps.

Hint: If you include a decimal number in your computation, the result has a decimal.

Note: Because of some oddities in the way that DrRacket represents decimal numbers, you may get a small amount extra.

> (robust-decimal-average-5 8 5 6 8 5)
6.300000000000001

Note: You should feel free to use robust-average as a subroutine in writing robust-decimal-average.

ii. Of course, not all sports use only one decimal digit, so we should generalize our procedure to round to an arbitrary number of digits after the decimal point.

Write a procedure, (new-robust-decimal-average precision score1 score2 score3 score4 score5), that computes a robust average to precision decimal places.

(new-robust-decimal-average-5 0 8 5 6 8 5) 6 (new-robust-decimal-average-5 1 8 5 6 8 5) 6.3 (new-robust-decimal-average-5 2 8 5 6 8 5) 6.33 (new-robust-decimal-average-5 3 8 5 6 8 5) 6.333

Note: You should feel free to use robust-average as a subroutine in writing new-robust-decimal-average.

Note: As you write your instructions, you may find the expt function useful. (expt b p) computes bp.

Note: You may still get a small amount extra with this procedure. That is acceptable.

Problem 2: Mad Libs

Topics: Scheme basics, Strings

In your childhood, you may have encountered a “party game” called Mad Libs. In this game, the leader asks the other participants for a series of types of words and then fills them into a template for a story.

Here’s a sample template.

CSC 151 is a/an ADJECTIVE-2 class! The professor has us VERB-INTRANSITIVE all day long. I have met many ADJECTIVE-1 PLURAL-NOUN in this class. I would definitely recommend the class to POSSESSIVE SINGULAR_NOUN.

Here’s a sample use of that template.

Please give me an adjective.

Frozen.

Please give me another adjective.

Grumpy.

Please give me a singular noun.

President.

Please give me a plural noun.

Squirrels.

Please give me an intransitive verb.

What’s an intransitive verb?

An intransitive verb is a verb that does not take an object, like “sleep” or “study” or “explode”. It’s okay if the verb *can* take an object, as long as it need not take an object.

Oh. Let’s see. Dance.

Please give me a possessive.

Grinnell’s.

Great. Now I can tell you a story.

CSC 151 is a/an grumpy class! The professor has us dance all day long. I have met many frozen squirrels in this class. I would definitely recommend the class to Grinnell’s president.

Wasn’t the fun?

Part A: A simple, string-like Mad-Lib

Write a procedure (describe-csc151 adj1 adj2 singular-noun plural-noun verb-intransitive possessive) that generates a story like the previous one.

> (describe-csc151 "frozen" "grumpy" "president" "squirrels" "dance" "Grinnell's")
"CSC 151 is a/an grumpy class!  The professor has us dance all day long.  I have met many frozen squirrels in this class.  I would definitely recommend the class to Grinnell's president."

Part B: Parameterizing the template

An issue of a procedure like describe-csc151 is that we have hardcoded the template. It might be better to make the Mad Lib template a parameter to the procedure. A template might look something like the following, with * characters around the things to fill in.

; Mad Lib template: A short statement about CSC 151.
(define csc151-template
  "CSC 151 is a/an *adj2* class.  The professor has us *verbi* all day long.  I have met a/an *adj1* *noun3* and a very *adj3* *noun1*.  I would definitely recommend the class to your *noun2*.")

; Mad Lib template: A weather report
(define weather-template
  "Today in Grinnell, the weather is *adj1*.  You might say that it's sleeting *noun1*s and *noun2*s.  Our weather anchor saw a/an *adj2* *noun3* *verbi* and then *verbt* a/an *adj3* *noun1*.")

Of course, that would likely require us to decide on a fixed set of kinds of words. We’ll use three adjectives (adj1, adj2, and adj3), three nouns (noun1, noun2, and noun3), an intransitive verb (verbi), and a transitive verb (verbt).

Write a procedure, (mad-libs template adj1 adj2 adj3 noun1 noun2 noun3 verbi verbt) that takes a template and the given types of words as parameters and substitutes the words into the correct place.

> (mad-libs weather-template
            "explosive" "tired" "orange"
            "computer" "squirrel" "snowman"
            "sleep" "freeze")
"Today in Grinnell, the weather is explosive.  You might say that it's sleeting computers and squirrels.  Our weather anchor saw a/an tired snowman sleep and then freeze a/an orange computer."

> (mad-libs csc151-template
            "explosive" "tired" "orange"
            "computer" "squirrel" "snowman"
            "sleep" "freeze")
"CSC 151 is a/an tired class.  The professor has us sleep all day long.  I have met a/an explosive snowman and a very orange computer.  I would definitely recommend the class to your squirrel."

> (mad-libs csc151-template
            "problematic" "argumentative" "triskaidekaphobic"
            "octothorpe" "hash tag" "pound sign"
            "genuflect" "transcribe")
"CSC 151 is a/an argumentative class.  The professor has us genuflect all day long.  I have met a/an problematic pound sign and a very triskaidekaphobic octothorpe.  I would definitely recommend the class to your hash tag."

Note: You will find the (string-replace str from to) procedure quite helpful. You can determine through experimentation how it works.

Hint: You may find it easier to start by writing a simpler version, say one that just replaces the first two adjectives.

Part C: Generating HTML

Write a procedure, press-release, that takes between seven and ten parameters of your choice and generates a simulated press release from Grinnell in HTML format.

Here’s a simplified version of how that procedure might behave.

> (press-release "Chicago" "Student Ambassador" "Blue")
"<html><head><title>Important press release</title></head><body><h1>Grinnell announces adoption of new Blue logo</h1><p>Dateline Chicago</p><p>At a press conference today, Grinnell's Student Ambassador announced the creation of a new, Blue, logo.</p><p>Our Student Ambassador reports, <q>I know that Blue reinforces our ties to Chicago.  It also looks so much better than the mating slugs of the late 1990's.</q></p></body></html>"

Problem 3: Procedures that build and modify images

Topics: Scheme basics, Images

You have learned a variety of basic image operations. Now it’s time to put them to use.

Part A: Mirroring images

The DrRacket image documentation includes an example that shows something like a shadow for a start.

> (above
   (star 40 'solid 'firebrick)
   (scale/xy 1 1/2 (flip-vertical (star 40 'solid 'gray))))
A dark red five-pointed star with a gray shadow in front of it

As far as we can tell, it would be difficult to generalize this procedure, since there is no convenient way to recolor an existing image to gray. However, it should be possible to make a reflection of the image with a different aspect ratio.

i. Write a procedure, (reflect-vert image), that takes as input an image and adds a reflection to that image directly below the image.

> (reflect-vert (star 40 'solid 'firebrick))              
A dark red five-pointed star with a vertically flattened upside-down copy directly below it
> (reflect-vert (beside (circle 30 'solid 'blue)          
                      (circle 20 'outline 'black)         
                      (circle 10 'solid 'red)))           
Three circles in a row, each smaller than the one to the left, aligned on their centers.  A flattened version of the three circles appears below them.  We see a gap between the smaller circles.
> (beside (reflect-vert (circle 30 'solid 'blue))         
          (reflect-vert (circle 20 'outline 'black))      
          (reflect-vert (circle 10 'solid 'red)))         
Three three circles in a row, each smaller than the one to the left, aligned along their bottom.  Below them is a set of flattened versions of those circles.
> (reflect-vert (reflect-vert (star 40 'outline 'black))) 
Four five-pointed stars stacked vertically.  The top one is uniform.  The next is half the height of the first.  The next is half again the height.  And the last is the same as the second.

ii. Write a procedure, (reflect-horiz image), that takes as input an image and adds a reflection to that image directly to the right of the image.

> (reflect-horiz (star 40 'solid 'firebrick))             
Two dark red solid stars, side by side.  The first is uniform in size, the second is squashed horizontally by half.
> (reflect-horiz (reflect-vert (star 40 'outline 'black)))
Four stars in a two-by-two grid.  The top-left and bottom-right stars are uniform in size.  The top-right star is half as wide as the top-left star.  The bottom-left star is half as tall as the top-left star.  The bottom right star is half the width and height of the top-left star.  The bottom two stars are "flipped" as compared to the top stars.

iii. Create an “interesting” drawing using those two procedures and no more than three simple images,

Part B: A smiley face

Write a procedure, smiley, with at least two parameters, that generates something resembling the traditional yellow smiley face. Your parameters might specify the color of some aspect of the face, its size (width, height), the placement of features, or other aspects you consider appropriate.

Part C: Building buildings

In some ways, the construction of a complex procedure from subroutines resembles the construction of physical objects from reusable components. Suppose we wanted to make images of skyscrapers and other tall buildings. We might have rules for making floors, towers, and such.

i. Create at least three parameterized procedures that you could use in making images of skyscrapers and other buildings.

ii. Using your procedures, create a cityscape of at least three buildings.

Documentation

For this assignment (and only this assignment), you are not required to document your procedures. However, if you’d like to try to use the 6P documentation style (or even the 4P documentation style), you are certainly welcome to do so.

Evaluation

We will primarily evaluate your work on correctness (does your code compute what it’s supposed to and are your procedure descriptions accurate); clarity (is it easy to tell what your code does and how it acheives its results; is your writing clear and free of jargon); and concision (have you kept your work short and clean, rather than long and rambly).