**eProgramming in Maple, Part 1:
Functions, iteration and graphics**

Integrated, First-Year Curriculum in Science, Engineering, and Mathematics

Based on a notebook by Claude Anderson

Revised by Kurt Bryan and David Mutchler

**Format of today's session**

**Questions?**

**Overview of programming in Maple. Why Maple? Why ME!?!**

Turn to your partner or a neighbor and discuss (45 seconds):

--- What is the difference between "programming" and merely entering some Maple code to get an answer?

--- Can you think of some examples of things we have done in previous sessions or in your homework

that could be called "programming"?

Large group discussion (2 minutes):

--- Overview of programming in IFYCSEM.

--- Why we begin our programming experience with Maple.

**Vectors: what are they?**

From your calculus textbook (Larson, Hostetler, Edwards):

Many quantities in geometry and physics, such as area, volume, temperature, mass and time,

can be characterized by single real numbers ... called
**scalars**
.

Other quantities, such as force, velocity and acceleration, involve both magnitude and direction

and cannot be characterized completely by single real numbers. A directed line segment is used

to represent such a quantity... The line segment is called a
**vector **
in the plane.

A vector in the plane can be represented by many different line segments --- all pointing in

the same direction and all of the same length. ... The directed line segment whose initial point

is the origin is often the most convenient such representation.

[For such a representation, the vector] can be uniquely represented by the coordinates

of its terminal point.

Summary: vectors are very useful and you will use them LOTS this year.

In today's lab, we will draw pictures described by points (which can be thought of as vectors).

Note that:

-- You can enlarge a picture by multiplying every point in the picture by a constant.

-- You can move a picture by adding a fixed vector to every point in the picture.

You'll find this handy today. Details below about how to do such
**vector arithmetic**
.

**Functions (review)**

There are three key ideas to the use of
__functions__
in any programming language:

---
**formal parameters**

---
**actual arguments**

---
**returned values**

For example, in the following,
is the formal parameter while 3 and
are actual arguments.

`> `
**h := x -> x^2 + 5*x + 3;
h( 3 );
h( w^2 );**

By the way, note that I typed the separate lines within one execution group by using
*Shift-Enter*
(instead of just
*Enter*
) at the end of lines. You'll use this lots in today's lab, so get used to it!

Note the use of the returned value from Maple function
:

`> `
**cos( h(3) + h(2.7) ) * h(-4);**

One can have Maple functions of two (or more) variables, as we saw in previous sessions.

Here is a simple example:

`> `
**twoArgFun := (s, t) -> 2*s + 3*t;**

The names
and
are not defined globally by this definition, they are merely the parameters ("dummy arguments") of the definition of
*twoArgFun*
. To see this, evaluate the following code:

`> `
**s;
t;**

When we apply
*twoArgFun*
to the numbers 1.4 and 100 in the following example, 1.4 and 100 are called the "actual arguments". The first actual argument (1.4) is substituted for the first parameter (
*s*
) , and the second actual argument (100) is substituted for the second parameter (
*t*
).

`> `
**twoArgFun( 1.4, 100 );**

If we try to call
*twoArgFun*
with only one argument, it doesn't fit the pattern of
*twoArgFun*
's definition, so Maple can't evaluate it. Here is an example (this example causes an error message):

`> `
**twoArgFun( 6 );**

* In-class exercise 1*
: Write a Maple function

`> `

`> `
**vectorLength := (xa,ya) -> sqrt(xa^2+ya^2);
vectorLength(Pi,2);**

`> `

**Lists (review)**

There are two key ideas to
__lists__
:

--- using []s to create a list

--- using []s to obtain a particular element of a list.

For example:

`> `
**a := [x, y, 3, h];
a[2];
a[3];
a[4];
a[4] (10);**

That last example illustrates both lists and Maple functions.

If it doesn't make sense to you, ask about it now!

Another example, in which a Maple function
*returns a list*
:

`> `
**d := (x, y) -> [x^2, x*y + 8, y^2];
d(-1, 4);
d(-1, 4) [3];**

Do you understand the notation of the last item above? If not, discuss it with someone who does understand it: your partner, a classmate, a lab assistant or your instructor.

* In-class exercise 2*
: Write a Maple function

When you are done with this exercise, shout
*"I need a Red Card!"*
and someone will come check your work.

`> `
**AnotherVectorLength := b -> sqrt(b[1]^2+b[2]^2);
b := [8,1/3,6]:
AnotherVectorLength(b);**

`> `
**b[3];**

Here's something you probably have not noticed about lists: Maple can see them as vectors and Maple knows about vector arithmetic. For example:

`> `
**u := [3, 4];
v := [9, 1];
u + v;
5*u;
**

`> `

**You'll find this handy today --- remember it!**

**Sequences (review)**

Recall that the
*seq*
command creates sequences. Here's some examples:

`> `
**seq( 3*i, i = 1 .. 9 );
seq( (2*i - 1)^2, i = 2 .. 6 );
seq( Pi/(6 - k), k = 0 .. 5 );
points := [ seq( [x, sin( Pi * x / 6 )], x = 0 .. 12 ) ];
plot( points );**

* In-class exercise 3:*
Use

`> `
**points := [ seq( [x, x^2] ,x=0..6 ) ];**

`> `
**plot(points);**

`> `

`> `

Suppose that we want to generate a list of the points that divide the interval [0,
] into 8 equal intervals:

`> `
**[ seq(2 * Pi * (i / 8), i = 0 .. 8) ];**

There's nothing special about 8; we can write a Maple function that does this for any integer
:

`> `
**intervals := n -> [ seq(2 * i * Pi / n, i = 0 .. n) ];**

Warning, `i` in call to `seq` is not local

As before, don't worry about the warning message. We'll talk about its meaning when we get further into programming. You can now use this
*intervals*
function:

`> `
**intervals(7);
intervals(8);**

Now let's use the same idea to generate a list of equally spaced points around a circle with radius
. The key idea is that the coordinates of the point at angle
with the
*x*
-axis are (
). Thus:

`> `
**circlePoints := (n, r) ->
[ evalf(
seq( [r * cos(2* Pi * i / n), r * sin(2 * Pi * i / n)],
i = 0 .. n ) ) ];**

`> `
**c := circlePoints( 13, 3 );**

`> `
**plot( c );**

* In-class exercise 4:*
Use

When you are done with this exercise, shout
*"I need a Yellow Card!"*
and someone will come check your work.

`> `
**ex4 := circlePoints(10,2);**

`> `
**plot(ex4);**

`> `

`> `

`> `

**Sequences of sequences**

Later in the lab you will use sequences of sequences. Here are some examples to help you understand that idea. For each example, first decide what you think it will produce, then execute it to check your answer.

`> `
**seq( [1, j], j = 1 .. 3 );**

`> `
**seq( [k, j], j = 1 .. 3 );**

`> `
**seq( seq( [k, j], j = 1 .. 3 ),
k = 1 .. 4 );**

Notice that for each value of
*k*
(outer range), we go through all of the values of
*j*
(inner range)

`> `
**seq( seq( [j, k], j = 1 .. k ),
k = 1 .. 4 );**

`> `

**Maple graphics --- PLOT and CURVES**

So far, the only graphics we have generated have been via the high-level command
*plot*
. The pictures that it builds are based on graphics primitives like PLOT, CURVES and TEXT. We examine the basics of some of these primitives here and others in your homework. These primitives should be used when you want to draw specific pictures or enhance your function plots by adding such pictures.

*You've Gotta Draw The Line Somewhere*
. Try these commands:

`> `
**myline := CURVES( [ [3,1], [6,6], [7,3] ] );
PLOT( myline );**

`> `

The
*CURVES*
command generates a graphic primitive that defines a "curve" joining the list of points that the command is fed. The points are joined with straight line segments (connect the dots). The
*PLOT*
command (it must be in all capitals) creates the actual graph from the graphics primitives that you supply.

You can do multiple lines with the same
*PLOT*
command:

`> `
**myline1 := CURVES( [ [3,2], [5,5] ] ):
myline2 := CURVES( [ [0,3], [5,1] ] ):
PLOT( myline1, myline2);**

With
*PLOT*
, the default behavior is to draw axes unless you specify otherwise. You can specify otherwise like this:

`> `
**PLOT( myline1, myline2, AXESSTYLE(NONE) );**

* In-class exercise 5:*
Write code to draw a "house" like the one shown as Picture A in your

Use the PLOT command to draw your house, first with axes (as in the left side of Picture A), then without the axes (as in the right side of Picture A).

`> `
**house := CURVES( [ [0,2], [0,0], [3,0], [3,2], [0,2], [1.5,3], [3,2] ] );**

`> `
**PLOT( house, SCALING(CONSTRAINED), AXESSTYLE(NONE) );**

**Make sure your plots produce output **
__exactly__** like Picture A in the **
**Pictures**** handout, including the numbers. If they don't, get help NOW.**

By the way, notice that the high-level
*plot*
function (lower-case) really uses PLOT and CURVES (upper-case).

`> `
**p1 := plot( x^2, x = 2 .. 4 ):
[p1];**

`> `

(Scroll up to see that the above output starts with "PLOT" and "CURVES", as promised.)

**Putting it all together:**
* using functions with parameters to encapsulate ideas*
.

Here is a picture. You'll do a more interesting picture shortly.

`> `
**rectangle1 := CURVES( [ [1,1], [4,1], [4,3], [1,3], [1,1] ] );
PLOT( rectangle1, SCALING(CONSTRAINED), AXESSTYLE(NONE) );**

`> `

I did the
*SCALING(CONSTRAINED)*
to ensure that 1 unit in the
*x*
-direction is the same physical distance on the screen as 1 unit in the
*y*
-direction. This makes today's pictures look prettier. You'll use
*SCALING(CONSTRAINED)*
in all the pictures you draw in the rest of this lab.

Here is the same code as in
*rectangle1*
above, but this time as a
__Maple function__
of no parameters. As usual, the -> indicates that we are defining a Maple function. The ( ) in front of the -> means there are no parameters.

`> `
**rectangle2 := ( ) ->
CURVES( [ [1,1], [4,1], [4,3], [1,3], [1,1] ] );**

`> `
**PLOT( rectangle2(), SCALING(CONSTRAINED) );**

Self-test: why is it necessary to use
*rectangle2()*
in the above PLOT command instead of simply
*rectangle2*
?

By encapsulating the code into a Maple function, we have used the
**single most important concept in computer science (**
and perhaps in problem-solving in general),
* abstraction*
. We give a name ("

This brings us to a key followup idea:
* using parameters to reuse code*
. Let's convert our Maple function to permit a single parameter that specifies the length of the rectangle:

`> `
**rectangle3 := (length) ->
CURVES( [ [1, 1],
[1 + length, 1],
[1 + length, 3],
[1, 3],
[1, 1] ] );**

`> `
**PLOT( rectangle3(3), rectangle3(5), rectangle3(8),
SCALING(CONSTRAINED) );**

`> `

Similarly, we could have a Maple function that has a single parameter that specifies the amount by which to stretch the rectangle (in both directions):

`> `
**rectangle4 := (size) ->
CURVES( size * [ [1, 1], [4, 1], [4, 3], [1, 3], [1, 1] ] );
PLOT( rectangle4(3), rectangle4(5), rectangle4(8),
SCALING(CONSTRAINED) );**

`> `

Note the use of vector arithmetic in the above: multiplying size times the list multiplies it times each element in the list.

Each element is itself a list, so the multiplication works its way inside each two-element list.

Finally, add another key idea ---
* iteration*
(doing things over and over) --- and our pictures start getting hot:

`> `
**PLOT( seq( rectangle4(k), k = 1 .. 20 ),
SCALING(CONSTRAINED) );**

`> `
** **

**In-class exercise 6: ABSTRACTING a house function.**

Copy the
*house*
code you wrote earlier to write a
__Maple function__
*house1*
with no parameters that returns a graphics object representing the house. Test your function with the following command. (The TEXT graphics primitives puts the requested text at the requested place.) The output should look like Picture B in the
*Pictures*
handout.
**(If it doesn't, get help.)**

`> `
**house1 := () -> CURVES( [ [0,2], [0,0], [3,0], [3,2], [0,2], [1.5,3], [3,2] ] );**

`> `
**PLOT( house1(),
TEXT( [1.5, 0.5], "Our house is a very very very plain House"),
SCALING(CONSTRAINED) );**

`> `

By encapsulating the code into a Maple function, we have used the most important tool known to the programmer (or to the problem-solver in general),
* abstraction*
. We give a name ("

**In-class exercise 7: adding a PARAMETER to make the code more useful.**

Write another Maple function
*house2*
(copy-and-paste from
*house1*
as needed) that has a single parameter (
*roofHeight*
) that determines how big the house is. A
*roofHeight*
of 1 draws the house above (Picture B). A
*roofHeight*
of 2 draws all of the dimensions twice as big, etc. Test your function with the following command. The output should look like Picture C in the
*Pictures*
handout.
**(If it doesn't, get help.)**

One hint: using vector arithmetic simplifies the code for
*house2*
nicely.
**Use vector arithmetic if you can**
(but if you can't, that's OK).

`> `
**house2 := (roofHeight) -> CURVES( roofHeight * [ [0,2], [0,0], [3,0], [3,2], [0,2], [1.5,3], [3,2] ] );**

`> `
**PLOT( house2(1), house2(0.5), house2(3), SCALING(CONSTRAINED) );**

`> `

**When you are done with in-class exercise 7, shout **
**"I need a Green Card!"**** and someone will come check your work.**

**In-class exercise 8: adding another PARAMETER to make the code still more useful.**

We still have a problem; it would be nice if the houses could be in different locations. (My real estate agent said that location is everything in the real estate market!) Write another Maple function
*house3*
(copy-and-paste from
*house2*
as needed) that has two parameters. The first is the size as above and the second (a vector, that is, a list of two numbers) specifies the location of the lower left corner of the house.

As before, using vector arithmetic simplifies the code for
*house3*
nicely.
**Use vector arithmetic if you can**
(but if you can't, that's OK).

Test your function with the following command. The output should look like Picture D in the
*Pictures*
handout.
**(If it doesn't, get help.)**

`> `
**house3 := (roofHeight, V) ->
CURVES( roofHeight * [ [0,2], [0,0], [3,0], [3,2], [0,2], [1.5,3], [3,2] ] + [V,V,V,V,V,V,V] );**

`> `
**PLOT( house3( 2, [0,0] ), house3( 3, [7,2] ),
SCALING(CONSTRAINED) );**

`> `

**In-class exercise 9: Ega****litarian's Neighborhood --- where all houses are created equal.**

What power do we have at our disposal now that we have a house
* function*
?

Let's take it for a test drive and see what it'll do!

First, draw Picture E, a row of houses:

`> `
**PLOT( seq( house3( 1, [4*k, 0] ), k = 0 .. 8 ),
SCALING(CONSTRAINED) );**

Or we can draw Picture F, row-houses:

`> `
**PLOT( seq( house3( 1, [3*k, 0] ), k = 0 .. 8 ),
SCALING(CONSTRAINED) );**

Before we create a subdivision, we'd better work on "double iterations" (sequences of sequences) a bit. Try to predict the value of each piece of code before you evaluate it. (They are the same examples you did earlier in the session..) If you don't understand why the results are what they are, ask!

`> `
**seq( [1, j], j = 1 .. 3 );**

`> `
**seq( [k, j], j = 1 .. 3 );**

`> `
**seq( seq( [k, j], j = 1 .. 5 ),
k = 1 .. 4 );**

`> `
**seq( seq( [j, k], j = 1 .. k ),
k = 1 .. 4 );**

Next, we draw Picture G, a whole subdivision of tract-houses (make sure that this works for you):

`> `
**PLOT( seq( seq( house3( 0.5, [2*j, 2*k] ),
j = 0 .. 5 ),
k = 0 .. 4 ),
SCALING(CONSTRAINED) );**

Or Picture H, a wedge of houses. Study this one carefully; it differs from the previous command by only one letter. Try to figure out what the picture should look like. Then execute the code. If your prediction was incorrect, be sure you understand why before going on to the next one.

`> `
**PLOT( seq( seq( house3(0.5, [2*j, 2*k]),
j = 0 .. k),
k = 0 .. 4),
SCALING(CONSTRAINED) );**

Or even a picture of 25 random houses (
*rand(0 .. 99)*
generates a Maple function which provides a pseudo-random integer from 0 to 99 each time it is called).

`> `
**randomNumberProcedure := rand( 0 .. 99 );
PLOT( seq( house3( randomNumberProcedure() / 10,
[ randomNumberProcedure(),
randomNumberProcedure() ] ),
j = 1 .. 25 ),
SCALING(CONSTRAINED) );**

*Now are you convinced of how much power we gain by defining house3 as a function with parameters?*

**In-class exercise 10:****Auntie Em! Auntie Em!**

After you have successfully completed the last house function from the above exercises, evaluate the following inputs. When the plot appears, click on it to bring up the animation controls (buttons). (Get help if you don't understand what I am saying in this exercise, it is more easily shown than written.) Click on the "play" button --- pretty neat, huh?! Click the rightmost animation control button to change to "Cyclic mode" and "play" some more. Try out the other buttons too.

`> `
**houses := [ seq( PLOT( house3( 0.5,
evalf( [ 4 * cos(2 * Pi * k / 40),
4 * sin(2 * Pi * k / 40) ] )
) ),
k = 0 .. 40 ) ]:**

`> `
**with( plots ):
display( houses, insequence=true );**

`> `

Notice that the "spinning house" animation is not smooth (there's a pause) at the point where it reaches the starting point again. Can you figure out why and how to fix it?

By the way, the
*evalf*
is necessary in the above because
*display*
and
*PLOT*
(unlike
*plot*
) do not automatically convert symbolic expressions like
*Pi*
to numbers when they attempt to display the plot.

**In-class exercise 11:****Auntie Em! Auntie Em! (continued)**

Now look again at the tornado-to-Oz animation example from the previous section. Think about the
*circlePoints*
example from earlier in the session. Explain to your partner how the tornado pictures are generated. Do you follow what is going on? Do you think it would be reasonable to do this if we had not first defined a
*house*
function with parameters?

**Summary statement (so far): Maple programming = Designing and writing good functions.**

Tell your instructor or a lab assistant that you have completed this lab exercise. He will ask you to show him your pictures from
*house3*
in Exercises 8 and 9. He will then give you a cover sheet (each partner gets one) that record the competencies you earned today.

If you do not complete the lab before you leave, see your instructor for special instructions.

When you have completed this worksheet, begin working on the post-lab problems. Beginning the post-lab problems is part of this lab. You can do the post-lab problems with your partner, with someone else, or by yourself --- your choice.