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.
Below is a procedure that outputs the tangent of an angle.
to tan :angle output quotient sin :angle cos :angle endRemember that this is an operation, not a command, so to run this procedure without errors you must start your complete instruction with a command. For example:
? print tan 180 -0 ? print tan 60 1.73205080756888 ? print tan 45 1 ?For example, we might use this function to write a procedure to draw a circle with a given diameter.
to circle :diameter repeat 360 [forward product tan .5 :diameter right 1] end
A few calculations starting from a right triangle with hypotenuse of length 1 shows us that:
arcsin y = arctan( y / (sqrt(1-y2))).
Write a Logo procedure arcsin which accepts a number between -1 and 1 as input and outputs the arcsin of that number.
Choose an algebraic function whose graph has an x-intercept -- for example, f(x) = x^2 - 1 or f(x) = x^3.
Write an operation function which accepts a value :x as input and outputs the value of your function when it's evaluated at :x. Test your procedure as shown below:
? print function 1 0 ? print function 2 3 ? print function 0 -1Next, write an operation derivative which accepts one input and outputs the slope of the graph of the function at that input. Your procedure may use the derivative of the function or it may compute the slope of a secant. Test your procedure.
Once you've written your function and derivative procedures, the Logo operation improve_guess defined below should accept a guess at an x-intercept as input and output an improved guess. (The formula used to improve the guess came from solving the formula given in the figure for the variable "new".)
to improve_guess :guess output :guess - (function :guess) / (derivative :guess) endTo apply "Newton's method" to find the x-intercept, continue improving a guess until the output of function is close enough to 0 for your purposes. (Or until it's obvious that the method isn't working.) Use a global variable or instructions like:
print improve_guess improve_guess 0to see how close you can get to the value of the x-intercept of your function.
If you finish this task with time to spare, experiment with the difference between using the derivative to find the slope and using the formula for the secant line to find the slope. How small does the value of the variable "dx" have to be in order to get good results? This could be an interesting research project!
to music.quiz print [Who is the greatest musician of all time?] if equalp readlist [John Lennon] [print [That's right!] stop] print [No, silly, it's John Lennon.] endLast class we used Newton's method to improve our guess at the x-intercept of a function until we had an estimate we liked. To decide whether we liked an estimate, we plugged it back in to the function to see how close to zero the function was at that point. If we know how close is "close enough" -- say, less than .05 units away from the x-axis -- we could use Logo to check to see when our estimate is good enough. To do this we'll need instructions like if used in the quiz program.
According to the author, your choice of favorite musician is either right or wrong; there's no partial credit. For most computers, the electrical impulses which power them are either on or off; there's no partway on. Based on the states of off and on, computers are ideally well suited to handle true/false and yes/no questions. In fact, the underlying design of most computer systems is formal logic.
In Logo, a predicate is a procedure which always outputs one of two values: true or false. The predicate equalp from music.quiz is an example of a predicate.
Experiment with equalp and see how it works; use instructions like:
print equalp [John Lennon] [Lennon] print equalp 6 sum 3 3 print equalp "01 1 print equalp [a] "aWhat do you think the predicates lessp, numberp, emptyp and memberp do? Use help, the examples below, and some experimentation to find out!
print lessp 3 5 print lessp 5 3 print memberp "t "that print memberp "t [a e i o u] print emptyp butfirst "t print numberp "01
Predicates are fundamental to the workings of a computer program, but in Logo they aren't mysterious or complicated. They're just operations that output true or false. We can write our own predicates!
If you were writing a Wheel of Fortune computer game, you might need to check whether a letter is a vowel or consonant. The textbook has offers the following procedure:
to vowelp :letter output memberp :letter [a e i o u] endHere's how we might use predicate vowelp:
to chooseletter local "letterchoice print [Pick a letter] make "letterchoice readword if vowelp :letterchoice [print [You must pick a consonannt.] make "letterchoice chooseletter] output :letterchoice endWhat does this procedure do? Can you use Logo's count operation to make sure the user's choice is a single letter?
Another example in the book is the predicate oddp, which uses the operation remainder to see if a number is divisible by 2:
to oddp :number output equalp (remainder :number 2) 1 endCan you write a predicate which tells whether its input divisible by 10? What should you name this predicate?
You've already seen the edit tool and the help tool. These are the two most important tools you have for figuring out and fixing problems in Logo, but they're not your only tools.
Broken procedures are easier to fix if you know what they're doing. Procedure house had comments written into the code to indicate what each line does:
to square :sidelength repeat 4 [forward :sidelength right 90] end to house square 100 ; frame right 90 forward 50 left 90 ; move to door square 30 ; door penup forward 50 left 90 forward 20 right 90 pendown ; move to window square 15 ; window penup back 50 right 90 back 30 left 90 pendown ; move back to start endTo add a comment to a procedure, start with a semicolon (;) and follow it with your comment. (Also, try to avoid using semicolons elsewhere in your programming.)
Using comments in your procedures will help you remember what you were thinking as you wrote each line. This will help you fix procedures that don't work, it will help me understand what you were trying to do with your procedures, and it may increase your grade on the assignment (beyond just making it easier to get the right answer!)
When these three basic tools fail, Logo provides you with some fancier tools. They're cumbersome, so you might not want to use them often.
The command step requires one input which is the name of a procedure (or a list of names of procedures). When you run a procedure whose name has been given to step, Logo will print each line in the procedure before running it. This is a good thing to try if your procedure is doing something unexpected -- you can isolate the line on which the unexpected thing happens, then use a plumbing diagram to analyze that line.
? step "house ? houseTo stop stepping through a procedure, use the command unstep.
The command trace requires one input which is a procedure name or list of procedure names.
? trace "square ? houseEvery time the procedures named are run, Logo prints the instruction that uses the procedure. trace is a good tool to use if you have a complicated program and you're not sure what part of the program is causing the problem. trace is only useful for debugging procedures that use helper procedures (e.g. house, but not square or triangle.) To stop tracing a procedure, use the command untrace.
The command pause stops a procedure when it reaches a certain point and gives you a Logo prompt to use to determine what variables have what values at that point in the program. You can learn more about pause on pages 293-295 of Chapter 15.