[Tutor] Better structure?
Kent Johnson
kent37 at tds.net
Wed Feb 2 23:07:22 CET 2005
I would at least introduce some functions. For example each case of your command handling loop could
be broken out into a separate function. If there is a lot of shared state between the functions then
make them all class methods and put the shared state in the class. Maybe all the drawing commands
should be in a class with xaxis, yaxis, radiusaxis, radiusaxis2 at least as member fields.
Kent
Jacob S. wrote:
> I think this thing is screaming for better structure, but previous
> attempts at using oop for it have failed.
> I think Derintegral is okay, I'm focusing on FunctionGrapher5.py--but
> you can comment on both.
> (To Johan Nilsson: I haven't had time to implement Simpson's rule
> instead of Reimann's sum yet... but I have gotten it to work faster
> anyway.)
> I will probably expand the code yet... Add extra things like find area
> between curve and x axis in interval [a,b]...
> Any suggestions are greatly appreciated. If you want the code to work on
> your machine, you'll need to have my Derintegral.py sys.path, obviously.
>
> #### Start of FunctionGrapher5.py ###################
> from __future__ import division
> from visual import *
> import Derintegral
> import os, random
> from math import *
> ja = 0
>
> scenexdefault = 375
>
> def start():
> for objects in scene.objects:
> objects.visible = 0
> scene.title = "Function Grapher by Jacob, Inc."
> scene.x = scenexdefault
> scene.visible=1
> scene.exit=0
> scene.userspin = 0
> scene.range=(10,10,1)
> scene.background=(1,1,1)
> global xaxis
> global yaxis
> xaxis = curve(pos=[(100,0,0),(-100,0,0)],color=color.black)
> yaxis = curve(pos=[(0,100,0),(0,-100,0)],color=color.black)
> global radiusaxis
> global radiusaxis2
> radiusaxis = curve(pos=[(-100,-100),(100,100)],color=color.black)
> radiusaxis2 = curve(pos=[(-100,100),(100,-100)],color=color.black)
> radiusaxis.visible = 0
> radiusaxis2.visible = 0
>
> start()
> d = 1
> print """\
> List of Commands:
> clear
> quit
> remove lines
> return lines
> gotl # (Graph One Tangent Line) w/optional x coordinate
> gatl # (Graph All Tangent Lines) w/optional step
> gonl # (Graph One Normal Line) w/optional x coordinate
> ganl # (Graph All Normal Lines) w/optional step
>
> Function Syntax:
> [y,x,or r] = function [range] ["s" followed by float for step]
> Brackets mean that it's not required.
> So, in effect, you don't have to type a function
> """
>
> def graphit(type,f,range2,step):
> li = curve(color=color.blue)
> if type in ['y','x']:
> x = -15
> radiusaxis.visible = 0
> radiusaxis2.visible = 0
> while -15 <= x <= 15:
> if eval(range2):
> try:
> a = f(x)
> if -15 <= a <= 15:
> if type == 'y':
> li.append(pos=(x,a,0))
> elif type == 'x':
> li.append(pos=(a,x,0))
> else:
> li = curve(color=color.blue)
> except:
> pass
> else:
> li = curve(color=color.blue)
> x = x+step
> elif type == 'r':
> exec "def m(t): return f(t)*cos(t)"
> exec "def n(t): return f(t)*sin(t)"
> t = 0
> while 0 <= t <= 10*pi:
> if eval(range2):
> try:
> li.append(pos=(m(t),n(t),0))
> except:
> li = curve(color=color.blue)
> t = t+step
>
>
> print 'Please type in functions in below. '
> while 1:
> lists=[]
> y = raw_input(">")
> if y == 'clear':
> scene.visible=0
> start()
> print "-"*36
> continue
> elif y == 'quit':
> scene.visible = 0
> del scene
> break
> elif y == 'remove lines':
> a = [radiusaxis,radiusaxis2,xaxis,yaxis]
> for x in a:
> x.visible = 0
> d = 0
> continue
> elif y == 'return lines':
> a = [radiusaxis,radiusaxis2,xaxis,yaxis]
> for x in a:
> x.visible = 1
> d = 1
> continue
> elif y.startswith('gatl'):
> try:
> step2 = float(y.lstrip("gatl "))
> except:
> step2 = 0.5
> x = -20
> while -20 <=x<= 20:
> try:
> der = Derintegral.diffatpt(f,x)
> if abs(der)<=25:
> if type == 'y':
>
> curve(pos=[(-15,eval("der*(-15-x)+f(x)")),(15,eval("der*(15-x)+f(x)"))],color=color.red)
>
> else:
>
> curve(pos=[(eval("der*(-15-x)+f(x)"),-15),(eval("der*(15-x)+f(x)"),15)],color=color.red)
>
> except:
> pass
> x = x + step2
> continue
> elif y.startswith('ganl'):
> try:
> step2 = float(y.lstrip("ganl "))
> except:
> step2 = 0.5
> x = -20
> while -20 <=x<= 20:
> try:
> der = Derintegral.diffatpt(f,x)
> if abs(der)<=25:
> if type == 'y':
>
> curve(pos=[(-15,eval("(-1/der)*(-15-x)+f(x)")),(15,eval("(-1/der)*(15-x)+f(x)"))],color
> = color.red)
> else:
>
> curve(pos=[(eval("(-1/der)*(-15-x)+f(x)"),-15),(eval("(-1/der)*(15-x)+f(x)"),15)],color
> = color.red)
> except:
> pass
> x = x + step2
> continue
> elif y.startswith('gotl'):
> try:
> x = float(y.lstrip('gotl '))
> except:
> x = float(raw_input('What x coordinate do you want the
> tangent line at? '))
> der = Derintegral.diffatpt(f,x)
> try:
> if abs(der)<= 25:
> if type == 'y':
>
> curve(pos=[(-15,eval("der*(-15-x)+f(x)")),(15,eval("der*(15-x)+f(x)"))],color=color.red)
>
> else:
>
> curve(pos=[(eval("der*(-15-x)+f(x)"),-15),(eval("der*(15-x)+f(x)"),15)],color=color.red)
>
> except:
> pass
> continue
> elif y.startswith('gonl'):
> try:
> x = float(y.lstrip('gonl '))
> except:
> x = float(raw_input('What x coordinate do you want the
> tangent line at? '))
> der = Derintegral.diffatpt(f,x)
> try:
> if abs(der)<= 25:
> if type == 'y':
>
> curve(pos=[(-15,eval("(-1/der)*(-15-x)+f(x)")),(15,eval("(-1/der)*(15-x)+f(x)"))],color=color.red)
>
> else:
>
> curve(pos=[(eval("(-1/der)*(-15-x)+f(x)"),-15),(eval("(-1/der)*(15-x)+f(x)"),15)],color=color.red)
>
> except:
> pass
> continue
> elif y.startswith('getpt'):
> y = y.lstrip("getpt ")
> if y:
> m = float(eval(y))
> else:
> m = float(eval(raw_input("f(?) ")))
> try:
> print f(m)
> except ValueError:
> print "Math Domain Error"
> continue
> elif y == 'regraph':
> graphit(type,f,range2,step)
> continue
> if y.count(" = ") == 1:
> y = y.split(" = ")
> type = y[0].lower()
> y = y[1]
> y = y.replace("y","x")
> if type == 'r':
> defaultrange = '0<=t<=5*pi'
> y = y.replace('x','t')
> if d == 1:
> radiusaxis.visible = 1
> radiusaxis2.visible = 1
> else:
> defaultrange = '-15<=x<=15'
> else:
> type = 'y'
> defaultrange = '-15<=x<=15'
> y = y.split(" ",1)
> tempfunct = y.pop(0)
> if y:
> y = y[0]
> if y.count('st'):
> if y.startswith('st'):
> y = y.lstrip('st')
> step = float(y)
> else:
> y = y.split(" ")
> step = float(y.pop().lstrip('st'))
> y = " ".join(y)
> range2 = defaultrange
> else:
> range2 = y
> step = 0.005
> else:
> range2 = defaultrange
> step = 0.005
> y = tempfunct
> range2 = range2.replace('and','or')
> range2 = range2.replace(',','<=x<=')
> try:
> exec "def f(x): return %s" % y
> except:
> continue
> graphit(type,f,range2,step)
> ###### End of FunctionGrapher5.py ###########
>
> #### Start of Derintegral.py ##########
> from __future__ import division
> import psyco
> psyco.full()
> from math import *
>
>
> def diffatpt(funct,pt):
> """Return the derivative of a function at a specific point. """
> sminc = 1e-10
> x = pt+sminc
> y2 = funct(x)
> x2 = x
> x = pt-sminc
> y1 = funct(x)
> x1 = x
> slope = (y2-y1)/(x2-x1)
> return slope
>
> def defintegral(fofx,x,max1):
> total = 0
> step = 1e-5
> exec "def f(x): return %s" % fofx
> while x <= max1:
> try:
> total = total+f(x)
> except:
> pass
> x = x+step
> return abs(total*step)
> ######End of Derintegral.py ##########
>
>
> Like I said, any comments appreciated.
> Jacob Schmidt
> _______________________________________________
> Tutor maillist - Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor
>
More information about the Tutor
mailing list