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.
If you finish early, create a plumbing diagram for this
instruction from last class:
if (or (memberp "computer :sentence) (memberp "computers :sentence) ~
(memberp "programming :sentence))~
[output "true]
Remember, the first input to if or ifelse is a true/false value and the remaining input or inputs are lists of instructions. The English sentence "if it rains, I will bring an umbrella" might look like:A few weeks ago, a student entered the following command while trying to draw a circle:
repeat 360 [forward 10 right 1]run it and see what happens.
When the turtle runs off the top of the Logo window it reappears at the bottom. Think of what else you might want the turtle to do when it tries to leave the Logo window -- maybe it should stop dead, maybe an error message should appear, or maybe it should "bounce back" into the Logo window.
The Logo operation pos outputs a list describing the turtle's position on the screen. Use the instruction show pos and some turtle motion instructions to guess the boundaries of the Logo window.
Write and test a predicate that checks to see whether the turtle is close to th e window boundary -- you probably want to use a predicate like greaterp or lessp as a helper procedure.
Now we're ready to change the way the turtle behaves near the window boundary. Ultimately we'd like to replace the forward command, but first let's just test our predicate. Below is a procedure wander with helper procedure turnaround which moves the turtle 300 steps in a random direction, reversing the turtle's direction if predicate offscreen returns a value of true.
to wander ; Procedure to test predicate offscreen repeat 300 ~ [ forward 1 wait 1 if offscreen [turnaround] ] end to turnaround ; Helper for wander which reverses the turtle's direction. setheading sum heading 180 endFeel free to replace turnaround by some other procedure if you wish the turtle to do something else near the edge of the screen.
Once procedure wander works the way you want it to, it should be fairly simple to create a procedure newforward based on wander. If you do so, test it on the instruction:
repeat 360 [newforward 10 right 1]Does it behave the way you expect?
As you probably know, there are some tasks computers are good at and some that they aren't. You should use a computer if you're trying to find a children's book with the word "apple" in the title whose author's last name starts with K. On the other hand, if you're looking for a book with a picture of an apple on the cover that describes all the things you can cook using apples, you should ask a librarian.
The computer solves the first problem by looking through a list of all children's books whose authors' names start with K for ones that have "apple" in the title. The computer can read this list much more quickly than the librarian, so this is a good task for a computer.
In general, computers are very good at doing simple, repetitive tasks -- checking each title for the word "apple", adding numbers on a spreadsheet, or producing frames for an animated movie. So far, the only tool we've seen to do the same thing over and over is repeat. Chapter 5 presents more tools for doing this.
Examples:
repeat 4 [forward 80 right 90] repeat 20 [repeat 30 [type "&] print []]
The Logo command for advances through a list of numbers (and so can advance through a numbered list). For example:
for [i 1 10] [print :i] for [i 1 10 2] [print :i] for [j 10 4 -1] [print :j] for [size 10 150 10] [forward :size right 60]Procedure for requires two inputs. The first input describes the way in which Logo will advance (or retreat) through a sequence of values, and the second input is a list of instructions to implement for each value in the sequence.
More specifically, the first input to for provides three or four values: the name of an index variable (which will be local to the for statement), a starting value for that variable, an ending value for that variable, and an optional "increment" value that tells you how much to advance (or decrease) the variable by at each step. While the start and end values are usually positive integers and the step size is usually 1, you can use any values you like here.
for [i -2.3 6.7 3.3] [print :i]Note that the for command only executes the instructions in its second input for values of the variable beteween the start and end values -- if the value of the index variable overshoots the end value, for stops before running the instructions in the second input.
Practice using the for command. One fun way to do this is by experimenting with different shapes of spirals:
for [size 10 150 10] [forward :size right 60]If you finish early, try to write an operation using for that accepts a positive integer n as an input and outputs the sum 1 + 2 + 3 + ... + n.
? help "while WHILE tfexpression instructionlist (library procedure) command. Repeatedly evaluates the "instructionlist" as long as the evaluated "tfexpression" remains TRUE. Evaluates the first input first, so the "instructionlist" may never be run at all. The "tfexpression" must be an expressionlist whose value when evaluated is TRUE or FALSE.From the help information, we learn that while requires two inputs: a true/false expression and a list of instructions. Like repeat and for, while executes those instructions over and over. Unlike repeat and for, we can't always tell by looking at the inputs to while how many times those instructions will be run.
Last class we wrote a maze game. Here's another maze game that uses while. You remain lost if you turn left and you fall in a pit if you do anything else. Copy and run it to see how it works.
to maze
local "response
make "response "left
while [equalp :response "left] ~
[print [You are lost in a scary maze. Will you go left or right?]
make "response readword]
print [You fell in a pit. You lose.]
end
Important note: The first input to while in this
example is a list. The while command evaluates the
instructions in the list repeatedly until the result
is false. This is different from the if
and ifelse commands, whose first input is usually the output
of a predicate. The first input to while is usually a
predicate and its inputs
inside square brackets.Below is a procedure that uses while to very roughly estimate the square root of a number by squaring numbers until the result exceeds the number input. I've written it as a command rather than as an operation because Logo has a perfectly good sqrt operation for when we need a square root.
to estimatesqrt local "number local "counter print [Type in a number and I will estimate its square root.] make "number readword make "counter 0 while [lessp :counter*:counter :number] [print :counter make "counter :counter+1] print (sentence [The square root of] :number [is between] :counter-1 "and word :counter ".) endTry this procedure out.
? estimatesqrt Type in a number and I will estimate its square root. 8 0 1 2 The square root of 8 is between 2 and 3. ?Can you make one simple change to the procedure to change the display to:
? estimatesqrt Type in a number and I will estimate its square root. 8 1 2 3 The square root of 8 is between 2 and 3. ?Would tildes (~) and line breaks make the while command more readable here? Try it!
Do you think you could write this procedure using for and stop? How or why not?