Name:
[1851] Kirby Urner

Member:
107 months

Authored:
6 videos

Description:
Veteran of the OSCON, Pycon, EuroPython circuit, math teacher, programmer. ...

# Working with Stickworks [ID:305] (5/6)

## in series: Python for Math Teachers

## video tutorial by Kirby Urner, added 07/07

Name:
[1851] Kirby Urner

Member:
107 months

Authored:
6 videos

Description:
Veteran of the OSCON, Pycon, EuroPython circuit, math teacher, programmer. ...

Our authors tell us that feedback from you is a big motivator. Please take a few moments to let them know what you think of their work.

Here's a Python module you might want to use in your math classes. It works with VPython to provide simple vector graphics, as well as plotting capabilities. Students wouldn't just use the module, they'd study the source code to gain a stronger understanding of the math concepts involved ("math through programming").

""" Some infrastructure for working with Vectors and Edges, including an xyplotter generator and axes maker. By Kirby Urner, Sept 13, 2006 Updated Sept 29, 2006: make Edge color a class-level attribute add funky derivative demo refactor a bit Code: http://www.4dsolutions.net/ocn/python/stickworks.py For colorized source: http://www.4dsolutions.net/cgi-bin/py2html.cgi?script=/ocn/python/stickworks.py Some relevant discussion: http://mail.python.org/pipermail/edu-sig/2006-September/007145.html http://mail.python.org/pipermail/edu-sig/2006-September/007149.html http://mail.python.org/pipermail/edu-sig/2006-September/007150.html http://mail.python.org/pipermail/edu-sig/2006-September/007312.html """ from visual import vector, cylinder, cross, dot, diff_angle import visual class Vector (object): """ A wrapper for visual.vector that expresses a cylinder via draw(), always pegged to the origin """ radius = 0.03 def __init__(self, xyz, color=(0,0,1)): self.v = vector(*xyz) self.xyz = xyz self.color = color self.cyl = None def draw(self): """define and render the cylinder""" self.cyl = cylinder(pos = (0,0,0), axis = self.v, radius = self.radius, color = self.color) def erase(self): """toss the cylinder""" if self.cyl: self.cyl.visible = 0 self.cyl = None def __repr__(self): return 'Vector @ (%s,%s,%s)' % self.xyz # some vector ops, including scalar multiplication def diff_angle(self, other): return self.v.diff_angle(other.v) def cross(self, other): temp = cross(self.v, other.v) return Vector((temp.x, temp.y, temp.z)) def dot(self, other): return dot(self.v, other.v) def __sub__(self, other): temp = self.v - other.v return Vector((temp.x, temp.y, temp.z)) def __add__(self, other): temp = self.v + other.v return Vector((temp.x, temp.y, temp.z)) def __mul__(self, scalar): temp = self.v * scalar return Vector((temp.x, temp.y, temp.z)) __rmul__ = __mul__ def __neg__(self): return Vector((-self.v.x, -self.v.y, -self.v.z)) def _length(self): return pow(self.v.x ** 2 + self.v.y ** 2 + self.v.z ** 2, 0.5) length = property(_length) class Edge (object): """ Edges are defined by two Vectors (above) and express as cylinder via draw(). """ radius = 0.03 color = (1,0,0) def __init__(self, v0, v1, color=None): if not color==None: self.color = color self.v0 = v0 self.v1 = v1 self.cyl = None def draw(self): """define and render the cylinder""" temp = (self.v1 - self.v0).xyz self.cyl = cylinder(pos = self.v0.xyz, axis = vector(*temp), radius = self.radius, color = self.color) def erase(self): """toss the cylinder""" if self.cyl: self.cyl.visible = 0 self.cyl = None def __repr__(self): return 'Edge from %s to %s' % (self.v0, self.v1) def xyplotter(domain, f): """ domain should be an initialized generator, ready for next() triggering. f is any function of x. Consecutive Vectors trace connected edges. """ x0 = domain.next() y0 = f(x0) while True: x1 = domain.next() y1 = f(x1) e = Edge( Vector((x0, y0, 0)), Vector((x1, y1, 0)) ) e.draw() yield None x0, y0 = x1, y1 def axes(x=0,y=0,z=0): """ Draw some axes on the VPython canvas """ v0 = Vector((x,0,0)) v0.draw() v0 = Vector((-x,0,0)) v0.draw() v0 = Vector((0,y,0)) v0.draw() v0 = Vector((0,-y,0)) v0.draw() v0 = Vector((0,0,z)) v0.draw() v0 = Vector((0,0,-z)) v0.draw() def dgen(start, step): """ generic domain generator """ while True: yield start start += step def testme(): """ >>> from stickworks import testme Visual 2005-01-08 >>> testme() See: http://www.4dsolutions.net/ocn/graphics/cosines.png """ from math import cos def f(x): return cos(x) d = dgen(-5, 0.1) axes(-5,1,0) graph = xyplotter(d, f) for i in xrange(100): graph.next() def testmemore(): """ See: http://www.4dsolutions.net/ocn/graphics/pycalculus.png """ def snakeywakey(x): """ Polynomial with x-axis crossings at 3,2,-3,-7, with scaler to keep y-values under control (from a plotting point of view) """ return 0.01 * (x-3)*(x-2)*(x+3)*(x+7) def deriv(f, h=1e-5): """ Generic df(x)/dx approximator (discrete h) """ def funk(x): return (f(x+h)-f(x))/h return funk d1 = dgen(-8, 0.1) d2 = dgen(-8, 0.1) d3 = dgen(-8, 0.1) axes(-8,5,3) deriv_snakeywakey = deriv(snakeywakey) second_deriv = deriv(deriv_snakeywakey) graph1 = xyplotter(d1, snakeywakey) graph2 = xyplotter(d2, deriv_snakeywakey) graph3 = xyplotter(d3, second_deriv) Edge.color = (1,0,0) # make snakeywakey red for i in xrange(130): graph1.next() Edge.color = (0,1,0) # make derivative green for i in xrange(130): graph2.next() Edge.color = (0,1,1) # make 2nd derivative cyan for i in xrange(130): graph3.next() if __name__ == '__main__': testme()

### Got any questions?

Get answers in the ShowMeDo Learners Google Group.

### Video statistics:

- Video's rank shown in the most popular listing
- Video plays: 3 (since July 30th)
- Plays in last week: 0
- Published: 108 months ago

## Thank-yous, questions and comments

If this video tutorial was helpful please take some time to say thank-you to the authors for their hard work. Feel free to ask questions.
Let the author know **why** their video tutorial was useful - what are
you learning about? Did the video tutorial save you time? Would you like to see more?

You may also want to see our ShowMeDo Google Group to speak to our active users and authors.

## All comments excluding tick-boxed quick-comments

Excellent tutorial!

Cool! I like the use of VPython instead of the usual gnuplot/matplotlib plotting libraries.

I also like the format: Fast pace with the source attached. This way time is conserved, while an individual viewer can always pause when he gets lost, review the code, and continue.