Introduction to Programming
Primitive Logo Operators
In this lesson, you will learn about a new kind of procedure called an operator. Operators produce an output. You'll use some of the most commonly used operators, Logo's built-in math stuff.
Most operators take inputs; they do something with the inputs to produce the output, e.g., the sum operator adds its two inputs together and the result is the output.
Operators can be combined to form expressions. Due to jLogo's prefix operator notation, constructing expressions can be a bit confusing at first. Plumbing Diagrams let you visualize the expressions, so you'll learn how to draw them.
An operator is a procedure that produces an output which is used somewhere you need an input.
To make what I'm talking about clearer, I'm going to use what Brian Harvey calls plumbing diagrams in his book Computer Science, Logo Style. Plumbing diagrams consist of boxes representing procedures. If a procedure is defined to have inputs, there are openings in the top of the box, one for each input. If the procedure produces an output, there is an opening out the bottom of the box. Figure 7.1 shows a command with an input, and an operator with one input and an output.
|
|
| Figure 7.1 | |
Figure 7.2 shows the plumbing diagrams for a Logo command and a Logo operator, both of which you've not seen yet. print displays its input in the CommandCenter of the TG applet (or the TG application). random expects an input which should be a positive integer and produces an output which is greater than or equal to zero and is less than the input.
|
|
| Figure 7.2 | |
As an example, invoking random with an input of 5 will cause it to output one of the integers: 0, 1, 2, 3, or 4. You can see this by combining println (which takes an input) with random. Here are 3 examples of using println, two of which include using random.
println 5
"5" is displayed in the CommandCenter.
println quotient 65536 64
"1024" is displayed in the CommandCenter. println can be
abbreviated pr.
repeat 5 [ pr random 5 ]
4is displayed in the CommandCenter.
Use the following TG applet to try stuff out for yourself.
| TurtleGraphics Applet |
Beware! If you use an operator, its output needs somewhere to go. Try leaving out the println command, e.g.,
random 8
You'll get an error message: "I don't know what to do with output from
random 8."
Operators can have more than one input but can only produce one output. As an example, the sum operator takes two inputs and outputs the value of the sum of the two inputs. Figure 7.3 shows the plumbing diagrams for a generic operator with two inputs and the sum operator.
|
|
| Figure 7.3 | |
Table 7.1 contains the most common math operators. Try out each of them with the println command.
| Procedure | Inputs | Description | Example |
| DIFFERENCE | number1 number2 | Subtract number2 from number1 | difference 15 7 |
| PRODUCT | number1 number2 | Multiply number1 by number2 | product 10 6 |
| QUOTIENT | number1 number2 | Divide number1 by number2 | quotient 12 4 |
| RANDOM | number | Produce an integer greater-than or equal-to zero AND less-than number | random 100 |
| SUM | number1 number2 | Add number1 and number2 | sum 3 4 |
| Table 7.1 | |||
One thing that may appear strange to you at first is the way the name of the operation comes first, followed by its inputs. But, if you think about it, jLogo is consistant - all of its procedures work this way. First you have something that you want done, then comes the thing or things it will use as input. With a little experience (some practice), you'll get used to this way of doing things.
Here is a procedure that computes the area of a rectangle and displays it.
to printRectArea :height :width
println product :height :width
end
In the field of programming languages, when an operator precedes its
operands it is called prefix notation. Most programming
languages (including Logo which jLogo is based on) have what's called
infix notation for common operations, e.g., "3 + 2"
and "12 / 3." As you can see, the operator is placed
between the operands. But, jLogo is a subset of Logo and one of
the things I left out (for a few reasons) is the infix operators.
Take, for example, computing the circumference and area of a circle, given its radius.
to printCircleCircum :radius
println product 2 product 3.14159 :radius
end
to printCircleArea :radius
println product 3.14159 product :radius :radius
end
And here are the corresponding plumbing diagrams.
|
|
| Figure 7.4 | |
(a) 22, 87, 15, 40
(b) 93, 31, 72, 18, 6
(c) 63, 11, 57, 84, 49, 25
|
|
| Figure 7.5 | |
The first image consists of hundreds of colored boxes. The boxes are all the same size, but their locations and colors have been chosen randomly. The second image is similar, but the sizes of the boxes vary from twenty turtle steps on a side to one hundred turtle steps on a side, in twenty step increments. The sizes were chosen randomly.
As always, our steps in writing computer programs starts with:
1. Understanding the Problem
And to help with this, I've written down everything I know about
the problem.
Invoking random with an input of 16 will get it to output an integer in the range of 0 through 15.
As an example, if I need a random number in the range of -10 through 10 (inclusive), I can use the following expression.
difference random 21 10
This is a lot of information about the problem we are solving. It should be enough for us to move on to the next step in writing a computer program:
2. Devising a Plan
The plan is best expressed as pseudo-code. The first
piece of art, with equal-sized boxes, is pretty simple.
1. repeat the following sub-steps a number of times
1.1. set the color of the turtle's pen to some random value
1.2. move the turtle to a random location
1.3. draw a solid box
Or, I prefer to use procedural abstraction, so I'll write three procedures:
1. main which does some initial stuff then invokes a
procedure named randomBox a bunch of times
2. randomBox which sets the pen to a random color
and then invokes solidBox
The next step in our process of writing a computer program is
3. Carrying out the Plan
This means writing the jLogo procedures. To get started,
I type in a simple version of a procedure I wrote for the last
lesson which draws a solid square of a specified size.
to solidBox :size
setpensize 1
repeat :size [fd :size bk :size rt 90 fd 1 lt 90 ]
end
Next, I'll add a new procedure that builds on top of it; I'm going
to call it randomBox. It's always nice to get code entered,
so I'll type in a partially functional version of it.
to randomBox
; setpencolor <some random value>
penup
; setx <some random value>
; sety <some random value>
pendown
solidBox 100
end
What's nice about this is that we can verify that we have a program
that at least partially works. It is always easier to find problems
when you incrementally develop your programs. In the code above, the
parts of randomBox that I still need to figure out have been entered
as comments. In jLogo, comments start with a semicolon
character (';') and continue through the end of the line. Once I have
what I know how to do working, I'll replace the comments, one at a time,
with code that accomplishes what the comment says. Try
your version of the program out. You should be able to invoke
randomBox and end up with a solid box displayed.
Once your program is working, you can convert the comment lines into working source code, one comment at a time.
First, based upon what we know (written down above in the first step of the programming process), we draw a plumbing diagram for changing the color of the turtle's pen to some random color (Figure 7.6).
|
| Figure 7.6 |
In this diagram, we have the literal 16 as an input to the random operator, which produces an output (a number in the range of 0 through 15, inclusive) that is then supplied as an input to the setpencolor command.
Now, convert this plumbing diagram into source code and replace the corresponding comment line in randomBox with your code.
Test it by invoking randomBox a few times. If your changes are working, you should now be getting a box that's a different color each time you invoke randomBox. Remember that it is possible to get the same color two times in a row - the numbers coming out of the random operator are truely random.
Once you have this working, move on to the comment lines for the setx and the sety commands. Again, we start with plumbing diagrams (Figure 7.7).
|
|
| Figure 7.7 | |
Now convert the first of the plumbing diagrams (for the setx command) to source code and replace its corresponding comment line. Again, after you've redefined randomBox with your changes, test it out by invoking it a few times. Is the box appearing in a different place horizontally? If not, review the changes you've made; look at what you've typed in closely. If it's working, make changes for the sety command and test them.
When you have randomBox working, put it to work by invoking it in a repeat command. We covered the syntax of the repeat command back in the lesson on iteration. Clear the screen and paint a couple of hundred of boxes...
|
| Figure 7.8 |
Modify your program to use setxy instead of the separate invocations of setx and sety.
|
| Figure 7.9 |
Convert this plumbing diagram into source code and produce a collage similar to that in Figure 7.5.
to solidBox :size
setpensize 1
repeat :size [fd :size bk :size rt 90 fd 1 lt 90 ]
end
The way solidBox draws the box (one line of :size pixels at
a time, repeated :size times) was necessary because you didn't know
how to compute the midpoint of the box (quotient :size 2).
Write a new version of solidBox that draws a box with one single movement of the turtle.
|
| Figure 7.10 |
Notice how the houses are similar, but have different heights and widths. And, looking closer, you'll notice that the taller the house, the taller the door is and the wider the house is, the wider the window is. So, the objective is to modify the DrawHouse procedure you wrote in the Defining Your Own Commands lesson such that it has inputs for the height and width of the front of the house.
Start off simply. Plan out how you can achieve the end result by making a series of changes. For example, when I first wrote the street program, I started by extending my house program so that it drew a street of identical houses as shown in Figure 5.2.
|
| Figure 7.11 |
Once I had this working, I moved on add the :height and :width inputs to my DrawHouse and DrawFront procedures. When I tested this, I could get the front of the house to change - but the roof wasn't right and the door and window looked funny. So, one by one, I fixed the corresponding procedures for drawing the roof, drawing the door, and finally drawing the window.
If you have access to the TG application, make a copy of your house program, renaming it street. Load it into the TG application and extend it so that it draws the street.
If you do not have access to the TG application, here is the applet for you to use. Hopefully, you wrote down your house program and you have it handy. You can modify your copy on paper first or as you type the commands back in. Programming first with paper and pencil and then typing your code into the applet is the way we used to program back in the early days of computers...
|
| Figure 7.12 |
|
| Figure 7.13 |
| New jLogo Procedures Used In This Lesson | |||
| Name | Input | Description | Example |
| DIFFERENCE |
number1 number2 |
Outputs the result of subtracting number2 from number1 | DIFFERENCE 15 7 |
|
PRINTLN PR |
thing | Displays thing in the CommandCenter. The line is then finished off by moving the cursor to the start of the next line. | PRINTLN MOUSEX |
| PRODUCT |
number1 number2 |
Outputs the result of multiplying number1 by number2 | PRODUCT 10 6 |
| QUOTIENT |
number1 number2 |
Outputs the result of dividing number1 by number2 | QUOTIENT 12 4 |
| RANDOM | number | Outputs some integer greater-than or equal-to zero AND less-than number | RANDOM 100 |
| SETXY |
number1 number2 |
Moves the turtle to the specified number1,number2 (X,Y) coordinate. If the turtle's pen is down, it draws a straight to the point. | SETXY 100 -50 |
| SUM |
number1 number2 |
Outputs the result of adding number1 and number2 | SUM 3 4 |