# Laboratory: Simple Lists

*Summary:* We explore Scheme’s *list* structures. Lists permit us to
group data and process those data as a group. We also explore the procedures
that we can use with lists, such as `map1`

and `reduce`

.

## Useful procedures and notation

### Standard list notation

`'(val1 val2 ... valn)`

- a list of `n`

values.

### Creating lists

`(list exp1 exp2 ... expn)`

- create a list by evaluating each of the
expressions and then joining together their values.

`(make-list n val)`

- make a list of `n`

copies of `val`

.

`(iota n)`

- create a list of all the natural numbers strictly less
than `n`

(starting with `0`

).

### Manipulating lists

`(map1 fun lst)`

- apply the function to each element of the list.
`(map1 fun (list val1 val2 ... valn))`

gives you
`(list (fun val1) (fun val2) ... (fun valn))`

.

`(reduce fun lst)`

- reduce the list to a single value by repeatedly
replacing each pair of neighboring values with the result of applying
`fun`

to that pair of values.

`(map fun lst1 lst2)`

- create a new list by applying the function to
corresponding pairs of elements from the two lists.

### Sorting

`(sort nums <)`

- reorder the elements in a list of real numbers from smallest to largest.

`(sort nums >)`

- reorder the elements a list of real numbers from largest to smallest.

`(sort strings string-ci<?)`

- reorder the elements in a list of strings from
alphabetically first to alphabetically last.

`(sort strings string-ci>?)`

- reorder the elements in a list of strings from
alphabetically last to alphabetically first.

### Other list operations

`(length lst)`

- Determine how many elements are in a list.

`(reverse lst)`

- Create a new list with the elements in the opposite
order.

`(append lst1 lst2)`

- Join two lists together.

`(take lst n)`

- Build a new list consisting of the first `n`

elements
of `lst`

.

`(drop lst n)`

- Build a new list consisting of all but the first `n`

elements of `lst`

.

`(index-of val lst)`

- Determine how many values need to be dropped
from `lst`

to reach `val`

.

### Combining procedures

`(o f g)`

- Create a new procedure that applies `g`

and then applies `f`

to the result.

`(o f g h)`

- Create a new procedure that applies `h`

, then `g`

to the
result of `h`

, then `f`

to the result of `g`

.

## Preparation

a. If you have not done so already, you may want to open a separate tab or window in your browser for the reading on simple lists.

b. We will be updating the `csc151`

library throughout the semester.
Using the **Install Package** or **Package Manager** menu item,
make sure that you update our library to the latest version.
Use https://github.com/grinnell-cs/csc151.git.

c. In your definitions window, require the relevant portions of the
`csc151`

library.

```
(require csc151/lists)
(require csc151/hop)
(require csc151/numbers)
```

d. Add the following to your definitions pane.

```
; A list of movie ratings for The Large Illness
(define large-illness-ratings
(list 7 4 0.2 -3 6 5.5 5 6 -1.5 54/7 0))
; Some words
(define story-beginning
(list "Once" "upon" "a" "time" "in" "a" "land" "not" "so" "far" "away"))
; Some names
(define names
(list 'millicent 'octavius))
; Tuitions at various schools
(define tuitions
(list 40000 10000 23000 50000 42000 55000 2000 30000 20000 100000))
```

e. Add the names of about six other people (e.g., your group and the two groups nearest you) to the list of names.

## Exercises

### Exercise 1: Reviewing the self check

a. Predict the results of evaluating each of the following expressions.

```
(list 2 1)
(make-list 1 2)
(make-list -1 2)
(map - (iota 2))
(map - (iota 2) (list 2 1))
(map iota (list 2 1))
```

b. Check your predictions with DrRacket.

### Exercise 2: Averaging ratings

Write a set of instructions that allow you to compute the average
rating given *The Large Illness*.

### Exercise 3: Rounding ratings

The ratings associated with *The Large Illness* include both whole numbers
and fractional numbers. Suppose that “those on high” decide that only
whole-number ratings are permitted.

a. Write an instruction that rounds each rating to the nearest integer.
(Hint: You’ll want to use `map1`

and `round`

.)

b. Write an instruction that rounds each rating down.

c. Write an instruction that rounds each rating up.

d. Determine the effects of each strategy on the average rating.

### Exercise 4: Restoring ratings

a. Suppose we discover that a jealous competitor has artificially reduced
the ratings of *The Large Illness* by a bit. Write an expression
that lets us update the ratings by adding 1 to each rating.

b. Perhaps the ratings were more serverely impacted. Write an expression that lets us update the ratings by adding 2 to each rating.

c. Or perhaps it’s in between those two. Write an expression that let us update the ratings by adding 1.5 to each rating.

*Hint*: In the prior two instances, you could use `map1`

and a
single list because you could use the `increment`

procedure
from `csc151/numbers`

(or the composition of that procedure
with itself). But you do not yet know a procedure that adds
1.5 to its parameter. What can we do? Use `map`

with two lists,
rather than `map1`

with one list. (You will need to figure out
what the second list is.)

d. Suppose that we also discover that the jealous competitor has added
negative signs to some ratings. Write an expression that first removes
those negatives signs (e.g., by computing the absolute value) and then
adds 1 to each score. Note that you can use `increment`

(from
`csc151/numbers`

) to add 1 to a value.

e. If you used more than one call to `map1`

in the your solution to the
prior sub-exercise, come up with a solution that uses only one call to
`map1`

.

### Exercise 5: Rethinking ratings

As you may have noted, some of the ratings are very strange, indeed. Write an expression that converts any rating less than 0 to 0 and any rating greater than 6 to 6.

How will you do that? If you think back to the previous
lab, we found that `(min (max val lower) upper)`

gives us `val`

if it is between `lower`

and `upper`

and otherwise
bounds smaller values. You’ll need to convert that to an appropriate
sequence of calls to `map`

or something similar.

### Exercise 6: Sorting out sorting

a. Write an expression to sort the ratings from lowest to highest.

b. Write an expression to sort the ratings from highest to lowest.

c. Write an expression to alphabetically sort the words in the story beginning.

d. Write an expression to alphabetically sort the names. Note that the names are symbols, so you will need to do some conversion.

### Exercise 7: Removing ratings

a. Using `sort`

, `index-of`

, and `drop`

, write an expression to remove the
ratings that are less than 0. You can assume that at least one rating
is 0.

b. Do the same thing, but without the assumption that at least one rating
is 0. (Hint: You can use `append`

to make the list more like the one
we want.)

### Exercise 8: Average tuitions

a. Write an expression to compute the average tuition at schools that charge
more than $25,000 per year. Use `tuitions`

for the list of tuitions.

Your code should work no matter what values are in tuitions.

b. Suppose tuitions are going up by 10%. Write an expression to compute
the average tuition at schools that charge more than $25,000 *after* the
increase.

## For Those with Extra Time

### Extra 1: Inconsistent subtraction, revisited

Consider the following list.

```
(define ones (make-list 10 1))
```

a. How many different values do you think you can get from `(reduce - ones)`

?

b. Check your prediction experimentally.

### Extra 2: Everything else

If you find that you have extra time, explore any of the procedures not covered in the exercises above.