- Midterm exam, next class!

When circumstances allow, I'll be typing up bits of my lecture notes and posting them online. These may or may not bear any resemblance to the actual lectures.

0 5 10 15 20 25

Here's a sample procedure which takes a name as input and outputs the initials in the name:

to initials.recursive :name ifelse (emptyp :name)~ [output []]~ [output sentence (first (first :name)) (initials.recursive butfirst :name)] endWhat is the stop condition? Where is the recursive call? Must the stop condition be checked before the recursive call?

When making the recursive call, we assume that `initials.recursive` can successfully output "the rest of the list" of initials. This is the "leap of faith" the author mentions.

The procedure outputs `[]` when it reaches its stop condition, and longer and longer lists as it outputs the initials from different stages of "the rest of the list". This is typical of recursion. Our factorial procedure behaved similary, outputting 1 as its stop condition and larger and larger products as the program ran to completion.

to factorial :number if equalp :number 0 [output 1] output :number * factorial (:number - 1) end(What is the stop condition? Where is the recursive call?)

Can you write a recursive procedure which accepts a positive integer *n* as input and outputs the sum of the odd integers up to *n*? What about a maze game procedure that ends after the player makes a total of three lefts or one right, assuming that lefts and rights cancel? (The player wins as soon as he or she is facing in the correct direction.)

local "score make "score 0 make "score sum :score 1(Of course, the instruction to

This is typical of programs by authors who prefer using `make` to thinking about functional programming techniques. Here is our initials procedure again, using `for` instead of recursion.

to initials.for :name local "initiallist make "initiallist [] ; This is called initializing. No pun intended. for [i 1 [count :name]] ~ [make "initiallist sentence :initiallist first item :i :name] ; The list of instructions above adds the ith initial to the list. output :initiallist endNote that here we use

There are two steps needed to accumulate values in a variable in this way:

- Initialize the variable, giving it a starting value which is often 0, 1 or the empty list. For example:
local "varname make "varname 0

- Add on to the value stored in the variable, then store the new value in the old location. For example:
make "varname :varname + :number

Here's a procedure which calculates factorials using`for`:to factorial.for :num local "fac make "fac 1 for [i 1 :num] [make "fac :fac * :i] output :fac end

Why did we`make "fac 1`and not 0 in this procedure? Where does the initialization happen? Where do we add on to the value stored in the variable?Can you write a procedure which uses

`for`to find the sum of the odd numbers from 1 to n? If so, can you write a procedure to find the sum of the first k odd numbers?Can you write a procedure which uses

`for`and accepts a list as input then prints each item in the list? Which outputs the list in reverse?### Recursion and Graphics

Look at the example of the tree on page 193 of Chapter 10. Recursive procedures can be used to draw very pretty pictures. Here we'll talk about how to write a recursive procedure to draw one based on a square pattern.The hardest part of the problem is the leap of faith. Suppose we already had a procedure that could draw a small collection of nested squares. How would we write a procedure to add one square to that collection?

What information do we need? We need the size of the new square that we're drawing, the size of the collection of squares to be drawn inside that square, and information on where to position the smaller collection of squares inside the large outer square.

We can make the size of the square we're drawing an input to our recursive procedure:

to squareview :size ; ; ; ; end

The size of the collection of squares inside the starter square will depend on the size of the starting square. After some thought, you may notice a 45-45-90 triangle at the corner of each square. If the two legs of that triangle have length :size/2, the Pythagorean theorem says that the hypotenuse must have length :size/sqrt(2).to square :size repeat 4 [forward :size right 90] end to squareview :size square :size ; ; squareview :size / (sqrt 2) end

Our procedure isn't done yet. What are we missing?- We need a stop condition. There is more than one right stop condition, but we must
be sure that that stop condition is eventually reached. Our two chief options are: stop after
we've drawn a certain number of squares, or stop when the squares get small enough. The second
option seems simpler and more aesthetically pleasing to me, so I'll choose that one.
The size of the squares is dictated by the variable

`size`, so we just stop when the squares get small enough.to squareview :size square :size if lessp :size 2 [stop] ; squareview :size / (sqrt 2) end

(What happens if we mistakenly say`if lessp 2 :size`? Why don't we need an`output`command as we did with the`factorial`program?) - We need to move the turtle into position to draw the smaller collection of squares. (If we do
this step second, we can even run the procedure to see why we need this!)
First, figure out where your turtle will be when it finishes drawing the outside square. Then figure out where it needs to move to to draw the next square.

In this example, the turtle needs to move forward

`:size`/2 distance, then turn to the right by 45° before starting the inside square.to squareview :size square :size if lessp :size 2 [stop] forward :size/2 right 45 squareview :size / (sqrt 2) end

`ht`hides the turtle. - We need a stop condition. There is more than one right stop condition, but we must
be sure that that stop condition is eventually reached. Our two chief options are: stop after
we've drawn a certain number of squares, or stop when the squares get small enough. The second
option seems simpler and more aesthetically pleasing to me, so I'll choose that one.