# Assignment 3: Procedures and Lists

- Due
- Tuesday, 12 September 2017 by 10:30pm
- Summary
- For this assignment, you will write procedures for manipulating numbers and lists of data.
- 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**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. - Warning
- So that this assignment is a learning experience for everyone, we may spend class time publicly critiquing your work.

## Problem 1: Nearest multiple

*Topics:* Numeric computation, Writing your own procedures

We have found that the procedures `round`

, `ceiling`

, and `floor`

have come in particularly handy while we are cleaning our data to be whole numbers. However, these procedures are only capable of rounding numbers to whole numbers. Sometimes it is helpful to round to the nearest multiple of 10, or the nearest multiple of 100.

Write a procedure `(nearest-multiple val n)`

that rounds the parameter `val`

to the nearest multiple of `n`

.

Here are some example calls to the procedure.

```
> (nearest-multiple 32.7 10)
30.0
> (nearest-multiple 35.6 10)
40.0
> (nearest-multiple 10 3)
9
> (nearest-multiple -14 5)
-15
```

## Problem 2: Computing letter grades

*Topics:* Numeric computation, Characters, Writing your own procedures

Throughout the semester, I need to convert numeric scores on assignments to letter grades. In this problem you will help me automate this process.

a. Write a procedure `(score->grade score)`

that computes the letter grade for a score on an assignment. The `score`

is always between 0 and 100 points and a score of 81…100 should return the character for ‘A’; 61..80 should be for ‘B’; 41…60 should be ‘C’; 21…40 should be ‘D’; and 0…20 should be ‘F’ (or ‘E’, if you have difficulty getting ‘F’).

Here are some example calls to the procedure.

```
> (score->grade 33.3)
#\D
> (score->grade 55)
#\C
> (score->grade 74)
#\B
> (score->grade 99)
#\A
```

*Hints:* The procedures `integer->char`

and `nearest-multiple`

from problem 1 may prove useful. Also note that

```
> (integer->char 65)
#\A
```

b. Write a procedure `standard-score->grade`

that behaves much like
`score->grade`

except that 90 and above is an ‘A’, anything below 90 and
at least 80 is a ‘B’, anything below 80 and at least 70 is a ‘C’,
anything below 70 and at least 60 is a ‘D’, and anything else is an F.

**Extra Credit:** for solutions that do not use `lambda`

.

## Problem 3: Lists of cycles

*Topics:* Numeric computation, Writing your own procedures, Strings, Lists

### Part A

Write a procedure `(cycle n k)`

that outputs a list of `n`

elements that only consist of the numbers 0…`k`

-1 in ascending order. If `n`

is greater than `k`

then the list starts over from 0 after the `k`

th element.

For example,

```
> (cycle 15 4)
'(0 1 2 3 0 1 2 3 0 1 2 3 0 1 2)
> (cycle 10 3)
'(0 1 2 0 1 2 0 1 2 0)
> (cycle 6 6)
'(0 1 2 3 4 5)
> (cycle 11 2)
'(0 1 0 1 0 1 0 1 0 1 0)
```

**Extra credit:** if you can do this part without using `map`

or `map1`

.

### Part B

Using your procedure from Part A, write a procedure `(cycle-char n)`

that returns a list of the first `n`

characters of the alphabet. If `n`

> 26 the sequence starts over.

For example,

```
> (cycle-char 5)
'(#\A #\B #\C #\D #\E)
> (cycle-char 26)
'(#\A #\B #\C #\D #\E #\F #\G #\H #\I #\J #\K #\L #\M #\N #\O #\P #\Q #\R #\S #\T #\U #\V #\W #\X #\Y #\Z)
> (cycle-char 30)
'(#\A #\B #\C #\D #\E #\F #\G #\H #\I #\J #\K #\L #\M #\N #\O #\P #\Q #\R #\S #\T #\U #\V #\W #\X #\Y #\Z #\A #\B #\C #\D)
```

## Problem 4: Filtering and transforming lists

*Topics:* Numeric computation, Writing your own procedures, Lists

You may recall that we are starting to think about a standard “data science” approach to data in which you clean data, filter data, transform data, and then compute one or more summaries. Let’s start thinking more about how we might write some of these procedures.

### Part A: Filtering

Write a procedure, `(restrict-to-range lst lb ub)`

that returns the elements of `lst`

that are between `lb`

and `ub`

, inclusive. You may choose to rearrange the elements. For example,

```
> (restrict-to-range (list 5 1 2 8 4 3 19 -5 2 4) 1 4)
'(1 2 2 3 4 4)
```

### Part B: Filtering

Write a procedure, `(outside-of-range lst lb ub)`

that does the opposite: Extracts the elements of `lst`

that are either less than `lb`

or greater than `ub`

.

```
> (outside-of-range (list 5 1 2 8 4 3 19 -5 2 4) 1 4)
'(-5 5 8 19)
```

### Part C: Transforming

Write a procedure, `(scale-by-max lst)`

, that divides every element of the list by the largest value in the list.

### Part D: Transforming

Write a procedure, `(scale-by-average lst)`

, that divides every element of the list by the average value in the list.

### Part E: Summary

We may be interested in how far values in a list are from some value. Let’s call the `skewness`

the value that you get when you (a) compute the positive difference of every value in the list from the min; (b) find the geometric mean of all non-zero differences; (c) compute the positive difference of every value in the list from the max; (d) find the geometric mean of all non-zero differences; and (e) add the two geometric means together. Write a procedure to compute the skewness of a list. Then find a list that has a high skewness and a list that has low skewness. What does skewness seem to represent?

*Note: You can choose another term for this.*

## 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 achieves 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).