Monday, January 2, 2017

The Way to the Stars

Just before the holidays I was working on a Christmas tree sketch with a student at The Coder School and we needed a star for the top of the tree, because it's easier to draw than an angel. I could probably eyeball the points but as a math guy I should probably get it more or less exact.


The proportions of the pentagram and pentagon have been well researched, and it's cool how the magic number Phi comes up everywhere. But it's only the diagonals, not the x- and y-coordinates of the vertices, see?



 Would I have to use right triangles and dissect the star piece by piece?

Rotations to the Rescue


There's usually a math tool that will help, and this time it's rotation. The vertices (the "points") of a five-sided star can be seen as a set of five rotations from the center, like this:

Each rotation is 360 degrees divided by 5, which is 72 degrees. The Processing graphics package has a "vertex" function, so I just made a segment ("sz" units long, since "size" is already a keyword) and rotated it.

Radians


Most graphics packages and programming languages measure their angles in radians, not degrees, so I can still use degrees, but I just have to convert the number to radians by using the "radians" function.

def star(sz):
    fill(255,255,0) #yellow
    beginShape() #remember the vertices
    for i in range(5): #"do this 5 times"
        vertex(0,100) #make a vertex at the point(0,100)
        rotate(radians(72)) #then rotate 72 degrees
    endShape() 


Unfortunately, all I got was a blank screen. Since the "rotate" function rotates the coordinate system, it makes it impossible to save the coordinates of the vertices that way.


Polar Coordinates to the Rescue


There's another math tool which might help: polar coordinates. Instead of defining a point by its horizontal (x) and vertical (y) location, it's defined by a rotation and then a "radius" from the center of rotation, like this:



So I could define a vertex as a point that has a radius "sz" and the angle keeps going up by 72. A loop is in order!

def star3(sz):
    fill(255,255,0) #yellow
    beginShape()
    for x in range(5):
        vertex(sz*cos(radians(72*x)),sz*sin(radians(72*x)))
    endShape(CLOSE)

I was hoping the loop wouldn't mess with the vertex functionality, and here's the output:


Oops! I have to rotate twice as many degrees every vertex. Let's change the vertex line to this:

vertex(sz*cos(radians(144*x)),sz*sin(radians(144*x)))

And there's my star. Perfect!


Want to add ornaments to my tree? Click anywhere!

See the Pen Christmas Tree by Peter Farrell (@peterfarrell66) on CodePen.

Wednesday, September 7, 2016

Mathy Motivation

There's a lot of talk in math education circles about creating and maintaining student motivation and engagement in math courses which normal people find too abstract. Finding out what x is a thousand times is the opposite of what most people find motivating and the fact that something might be useful years in the future is also of limited interest.

My method is to hook students by showing them something visual and engaging (or in other STEM classes, hands-on and interactive) and they'll do a lot of work if they're sold on the result.

For example, teaching students polar coordinates in precalculus is a challenge, when they are already comfortable with the perfectly useful Cartesian (x-y) coordinate system. The Processing graphics package is a great way to approach this and other topics, because it was created by and for artists. The master of cool Processing sketches is "Bees and Bombs" creator David Whyte, who posted something like this:

See the Pen Rainbow Dots by Peter Farrell (@peterfarrell66) on CodePen.
It's a beautiful work of dynamic art, but it's also a graph of a trigonometric function in polar coordinates! If you can motivate students to try to recreate the work of art, they might learn how to use a few supposedly hard math tools along the way.

Students I've shown this to at The Coder School say, "Wow, cool!" And they're motivated to learn to make it themselves. The beginner question is, "How do we get one dot on the screen?" A valuable lesson to students is "Read the documentation!" The p5.js website has a lot of helpful explanations and examples on everything you can do with shapes and transformations.


And once you can put one dot on the screen, it's simple to get a lot of them on the screen: you use a loop. Of course, you have to rotate a bit so they're in different locations:



Now we have as many dots as we want on the screen, but they're all the same distance from the center, so they make a circle:




Trig to the rescue

How do we make them oscillate? This would be a difficult proposition, except there's a math tool that can help tremendously! Sines and cosines are usually introduced as the ratios of sides in right triangles, but by far their biggest application is modeling oscillating behavior. If we change the "ellipse" line in the code above to include a time variable, we can make the dots move in and out of the circle. This would be an excellent precalculus project for working with the equation of waves!

ellipse(0,100*cos((frameCount/15)),15,15);

Unfortunately, we want each dot to move in and out in a slightly different way, and we already have a variable for "shift" we can use. Introduce that into the code and each dot will "lag" a little behind the previous one:

ellipse(0,130+100*cos((frameCount/15)+3*shift),15,15);

It's hard to tell at first that each "dot" is simply oscillating from the center outwards. The rotation is an illusion. Students show off this project proudly, with good reason! Not only is it a cool-looking programming project, but they learned to use a bunch of math tools at the same time.

Tuesday, September 6, 2016

Teaching the Computer to Save You Time

I just talked with a math department head who said her school couldn't fit any programming into her already full math curriculum. "We're strapped for time just to get to everything in our current curriculum," she said. I would suggest that far from being one more thing to add to the pile of things you have to teach in a year, programming would actually reduce the workload and free up time for deeper exploration of topics. Let me give you an example.
A big idea in algebra (and programming) is functions. You put a number in to a function (the input, x) and you get a number out (output, y). In math notation
y = f(x)
There's a time in algebra when they stop using y and just use f(x), and it's never explained why. For example, if the function is "multiply the input by two and add 5," the function looks like this:
f(x) = 2x + 5
So if your input is 3, your output is
f(3) = 2(3) + 5 = 6 + 5 = 11
That's not so hard to do by hand, but pretty soon you start dealing with quadratics and cubics and higher. This is from an Algebra textbook:
The problems above want you to replace x in the function with the number in the parentheses and go through the arithmetic to find the output. You're expected to do this with a calculator, but if you need to input another number, you have to go through it all again! This can be done more effectively with Python. For example, the function in problem #4 translates to
The applet above is interactive! When you press the "Run" button (it looks like an arrow) Python will instantly evaluate the function for x = -7 and print the output (5) in the window on the right. You can evaluate the function for any number by typing a different number in the parentheses.
In problems involving compound interest, falling objects and cost of materials, it's the answer we're interested in, and not the student's ability to evaluate ugly functions like this by hand. Press the Run button and you'll see the answer.
In math class variables are all named with single letters, and it can get confusing. In programming it's possible (and advisable) to use more descriptive variable names, like this:
Now you can understand the formula just by reading it, and it proves the student understands what's going on in the function. Run it to solve problem #4 above.
Using programming tests your knowledge of a topic because you have to teach the computer how to solve a problem! It also tests your ability to be precise and it frees up a lot of time which students would otherwise spend evaluating the same functions over and over. That way they can get deeper into math topics.

Sunday, August 21, 2016

Pickover's OR Game

In his book Mazes for the Mind: Computers and the Unexpected, Clifford Pickover explores tons of algorithms that produce surprising results, including this one: take all the points on an x-y grid and convert the coordinates to binary. Taken digit by digit, if there's a 1 in either x OR y, the result will have a 1 in that digit. Color that x-y location according to the base 10 value of that number, mod 255 of course. (Since RGB values typically have a range of 0 - 255).

For example, for the point at (10, 45) you'd convert the x and y coordinates to binary. 10 is 1010 in binary, and 45 is 101101. Comparing the digits and filling in 1's if there's a 1 in that place in either number, you get 101111 or 47. You'd color that pixel 47, on the darker end of the 0-255 grayscale.

I have a binary converter program in my book Hacking Math Class with Python:

def convToBinary(num):
    '''converts decimal number to binary'''
    exponent = 0
    binary_number = 0
    while num >= 2 ** exponent: #Find the lowest power of 2
        exponent += 1           #the number is less than
    exponent -= 1
    for i in range(exponent + 1):
        #if num contains that power of 2
        if num - 2**exponent > -1: 
            #add that power of 10
            binary_number += 10**exponent 
            num -= 2**exponent
        exponent -= 1
    return binary_number

I created an "addZeros" function to make sure each binary number was 8 digits.

def addZeros(x):
    '''converts a binary number to
    8-digit form'''
    x = str(convToBinary(x))
    length = len(x)
    x = (8-length)*'0'+ x
    return x

In the next step I'll want to convert the number back to decimal so I wrote this:

def convToDec(num):
    '''converts num to decimal'''
    decnum = 0
    num = str(num)
    num = num[::-1] #reverse digits
    for i,v in enumerate(num):
        if v == '1':
            decnum += 2 ** i
    return decnum

Now we can make the comparison I described above, and return the decimal number that we'll give to the color argument.

def compareOr(a,b):
    '''converts 2 numbers to binary and
    compares their digits, returns a 1 in
    a place if it's 1 in a OR b'''
    result = 0
    a,b = addZeros(a),addZeros(b)
    for i in range(8):
        if a[-(1+i)] == '1' or b[-(1+i)] == '1':
            result += 10**i
    return convToDec(result)

Finally we'll draw a tiny 2x2 pixel rectangle of the calculated color. I used the bluescale:

def displayOr(x,y):
    '''displays the result of the "Or" comparison'''
    pygame.draw.rect(screen,compareOr(x,y) %254,[x,y,2,2])

I first did this in Pygame. All the code so far will run in the Python mode of Processing except the very last line. In Processing it needs to be replaced by these two lines.

    fill(0,0,compareOr(x,y) %254)
    rect(x,y,2,2)

Run the displayOr function using this nested loop for every other pixel on the screen:

for x in range(0,WIDTH,2):
    for y in range(0,HEIGHT,2):
        displayOr(x,y)

Guess what it makes?


If you guessed the Sierpinski Triangle you're right about a ton of seemingly unrelated afternoons spent playing around with math, Python, Pygame, Processing and Pickover. Pete out!

Saturday, August 20, 2016

The A is in the mAth

In my position as co-founder of the Professional Development company Make It STEM, I've been asked, "What about the A for Art?" I agree "Make it STEAM" would be a kickass company name, but as a math fanatic I feel the A is in the math.

Before you groan, let me explain.

Think about Art, and what it means to you. I'm sure you're conjuring up images of liberation, creativity and fun. Everybody does art in their own way, and that's cool. There are no rules, only tools: paint, crayons, yarn, beads, clay, marble, metal, lights, LEGO, anything goes!

That's exactly the feeling I get when I think of Math. It's all about beautiful curves and symmetry and mysterious symbols that can do magic if you know how to use them. Add to that the idea that my "Art" can be used to help understand science and lots of other fields, and it just adds to its ridiculous usefulness. Yes, some people like to promote rigid, "hard" math, but it's OK, anything goes. I realize not everybody shares my opinion.

Picture somebody saying to you, "I hate Art." You'd think they were crazy! You might ask, "What do you mean, you hate Art?" They might tell you, "Ugh, it's all about brushes, and buying brushes, and it has to be the right brushes, and you gotta wash the brushes.... I flunked a painting class because of the damned brushes. Then I took a drawing class and it was all about having this pencil or that stump and where's your sketchbook? I couldn't draw a horse that looked like a horse so I flunked that class. That meant I couldn't be a forest ranger because I couldn't pass the Art requirement. I hate Art. It makes me feel stupid."

Hopefully you'd think there's something wrong with the way we teach Art!

I think there's something wrong with the way we teach Math, so I promote a very Artsy approach to it. Math teachers want their students to be able to visualize the topics they're presenting, so I train teachers how to use computer programming to graph functions and draw geometric shapes. The Astroid is one of my favorites:

To create this design, you have to know your x-y coordinates, and how to draw lines in whatever graphics package you're using (I love Python but this time I used p5.js). Loops make the job much easier. And once you can make one astroid, you save it to an astroid function and then you can make any number of astroids, anywhere on the screen and make them rotate:



See? It's Art! And it's dynamic and interactive: move the slider on the top left of the applet to change the number of lines in each astroid. That's what happens when you use variables: you can vary things: location, size, color, number of lines...

Get creative with all the classic "math" graphics and you'll learn a lot. It's not easy, but the payoff is immense!

Sunday, May 8, 2016

Middle School Python

This past week my son was working on calculating the percent increase or decrease between a beginning and an ending value. He had written out the formula a bunch of times:

percent = (ending - beginning) / beginning * 100

Then he dutifully plugged in the values and if he didn't make any careless mistakes, he'd get the answer. I saw so much repetition that I offered to help him automate the process.

The above formula is perfect for putting straight into Python. Then all we need from the user is the beginning value and the ending value. Sounds like the parameters of a function:

def perc(beginning, ending):
    '''prints the percent increase or decrease between
    a given beginning value and ending value.'''
    percent = (ending - beginning) / beginning * 100
    return percent

This will give us a positive or negative number, but it might be a long decimal. We can make it round off to two decimal places by replacing the last line with this:

return round(percent,2)

So if it's positive, it's an increase and it it's negative it's a decrease. We might make it more user friendly by asking the user for input:

beginning = float(input("Enter the beginning value: "))
ending = float(input("Enter the ending value: "))

In Python, user input is assumed to be a string. "Float" changes it into a decimal. But now you have to change the "return" statement to a "print" statement:

print(round(percent,2))

So the output looks like this:

Enter the beginning value: 115
Enter the ending value: 73
-36.52

That might be enough, but for some students adding "percent" and "increase" or "decrease" might be helpful.

if ending - beginning > 0:
    change = 'increase'
else:
    change = 'decrease'
print(round(percent,2),"%",change)

Now the output is more descriptive.

Enter the beginning value: 21
Enter the ending value: 23
9.52 % increase

Not every Python exploration has to be rocket science! This 7th-grade math problem was perfect for automating.