[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