### Midterm 1

• Midterm 1 will be held in 105 North Gate from 5-6 on Monday the 28th. Yes, it's in the same time and place as your regular lecture.
• The test is open book and open notes The test will cover everything up to that point, including some recursion
• There won't be a lecture the week before the midterm (the 21st)
• Nate will have office hours from 10:30-noon on the day of the midterm
• There will be a review session at some point on either Saturday the 26th or Sunday the 27th, and it will take place some time between 10 and 2.
• You have a practice exam in your reader, and we will be posting more stuff on the course portal
• It is probably best if you sit down and try to work the entire practice test in an hour, just so you'll get a feeling for what CS 3 midterms are like

### Recursion

• Recursion is one of the key topics in this class
• Yes, it's hard, but mostly in the "developing a whole new way to think" sort of way
• The book and lab offer a bunch of different ways to think about recursion -- the important thing is to find one that works for you
• The first recursion lab jumps right into recursion and assumes you have read the book. Make sure you read Chapter 11 before you start lab!
• So what is recursion?
• It's when a procedure calls itself to solve a problem!
• What?
• Here's an example: Let's say you have a sentence like (I like cs3) and you want to count all of the words. One way to do it would be to count the first word (that's 1) and then count all of the rest of the sentence. It would look something like this:
1. Count I. That's on word. Then count (like cs3).
2. Count like. That's two words. Then count (cs3)
3. Count cs3. That's three words. Then count ().
4. The empty sentence has no words, so we're done. The total is three.
• There are four key parts to recursive problems. Not every part will be obvious in every problem, but you should still make a note of them. They are:
1. The base case. This tells you when you stop. A good way to find a base case is to ask yourself, "What's the simplest possible case of this problem?"
2. Do a little bit of work. The secret to recursion is only doing what you absolutely have to right now, and passing the rest of the work off on someone else.
3. Now do all the rest of the work (recursion). This is where your procedure calls itself again on what is left of the problem.
4. Combine your little bit of work and all the rest of the work. This might not be a part of every recursive problem.

### Recursion Problems

First, let's try writing count. We already know the plan, which is to count the first word and then count the rest. We start with the easy part:

`(define (count sent)`
What next? Well, I always start recursion by figuring out how I stop. This is the base case. What's the simplest possible sentence to count? That would be the empty sentence.
```(define (count sent)
(if (empty? sent)
0```
Now let's do a little bit of work. What would that be? How about counting the first word? That gives us 1. Then we do the rest of the work, which is (count (bf sent)). In other words, we count everything after the first word of the sentence. Finally, we combine the 1 for the first word and the (count (bf sent)) for all the other words. How? We add them together:
```(define (count sent)
(if (empty? sent)
0
(+ 1 (count (bf sent)))))```
Do you believe this works? Why should you? Let's test it out.
1. We start with (count '(I love cs3)). The sentence isn't empty, so we do (+ 1 (count (bf sent))).
2. Now we have (+ 1 (count '(love cs3))). We can't do the + until we figure out the underlined part, though.
3. Now we do the underlined part. Since the sentence isn't empty, we do the (+ 1 (count (bf sent))) line again. That leads us to (+ 1 (+ 1 (count '(cs3)))).
4. We do the underlined part again. Since the sentence isn't empty, we do the (+ 1 (count (bf sent))) line again. That leads us to (+ 1 (+ 1 (+ 1 (count '())))).
5. Since the sentence is empty, (count '()) gives us 0. Now we have (+ 1 (+ 1 (+ 1 0))), which gives us 3.

Now let's try writing a procedure that takes a sentence of numbers and returns the first even number. Let's call it find-even. How do we start? With the base case, of course. What is the base case? Well, what's the simplest possible sentence? Hmm... I'm not quite sure what that means. Another way to think about the base case is, "Can I look at my sentence and give you the answer with almost no work?" Well, if the first word in the sentence is even, I can tell you the answer right away.

```(define (find-even sent)
(if (even? (first sent))
(first sent)
```
Okay, so if we don't find the first even number right away, we have to look through the rest of the sentence. The rest of the sentence is (bf sent) and we look through it with find-even, so we get
```(define (find-even sent)
(if (even? (first sent))
(first sent)
(find-even (bf sent)))) ```
How well does this work?
1. We start with (find-even '(1 3 5 6 7 8)). The first number isn't even, so we throw it away and keep looking.
2. Now we have (find-even '(3 5 6 7 8)). The first number isn't even, so we throw it away and keep looking.
3. Now we have (find-even '(5 6 7 8)). The first number isn't even, so we throw it away and keep looking.
4. Now we have (find-even '(6 7 8)). The first number is even, so we stop and return it.
Now let's try to identify all four parts of this recursive problem. The base case is easy. We already did that. What about "Do a little bit of work?" Personally, I'd say that checking to see if the first word is even is doing a little bit of work. In this case, it also happens to be the base case. That's fine. What about "Do all the rest of the work?" That's (find-even (bf sent)). Finally, what about "Combine the little bit of work with all the rest of the work?" Hmm... I don't see that one. Why? Well, we aren't building something. We're looking for something. That means we don't really have anything to combine (build).

Now let's try returning all of the even numbers in a sentence. This is very different from finding the first number. Instead of looking for one number, we are building a sentence. Let's call this procedure all-evens. Once again, we start with the base case. Can we think of the simplest sentence that we could possibly give all-evens? What about the empty sentence? There aren't any numbers in it.

```(define (all-evens sent)
(cond (empty? sent) 0)
```
Now we need to see if we've found an even number. We could do that with (even? (first sent)).
```(define (all-evens sent)
(cond ((empty? sent) 0)
((even? (first sent))
```
What do we do if we actually find an even number? We need to put it into a sentence.
```(define (all-evens sent)
(cond ((empty? sent) 0)
((even? (first sent))
(se (first sent)
```
What else should we put in the sentence? All of the other even numbers, of course! How do we find them? That's what all-evens is for.
```(define (all-evens sent)
(cond ((empty? sent) 0)
((even? (first sent))
(se (first sent) (all-evens (bf sent))))
```
So if the sentence isn't empty and the first word isn't even, the first word must be odd. What do we do in this case? Well, we don't put the first word in the sentence. We just go on and look for some even words.
```(define (all-evens sent)
(cond ((empty? sent) 0)
((even? (first sent))
(se (first sent) (all-evens (bf sent))))
(else (all-evens (bf sent)))))
```