An updated (Rev 1) of slope_field.py to add a few user selected diffyQs. Note: selecting the max number of points (axes -4 to +4 = 81 points seems to run the Numworks calculator “out of memory” when the diffyQ is: dy/dx = sin(x)/y. No error is thrown but the display is blank. YMMV.
from matplotlib.pyplot import * from math import * # The user will input a minimum value for the x axis. # The user input should be an integer between -4 and -2 # The x and y axes will be set equal to each other at +- this value # Note: at -4 a 9 point x 9 point slope field is produced. # Currently, any slope field wih > 81 (9x9) points = out of memory. # The user will also choose from a selection of predetmined functions # to use for the display of the slope field, # By John Cantlin 1-16-2021 with help from Logan Burch. # obtain and validate user input for the axes def valid_axis(_a): if(-4 <= _a <= -2) and (isinstance(_a,int)): return "Good" else: print("x axis min: int -4 to -2") return False x_axis_good = False x_axis_min = int(input("Enter x axis min -4 to -2: ")) x_axis_good = valid_axis(x_axis_min) while not x_axis_good: x_axis_min = int(input("Enter x axis min -4 to -2: ")) x_axis_good = valid_axis(x_axis_min) # set the x-y axes min/max to equal (symmetric) +- values y_axis_min = x_axis_min x_axis_max = abs(x_axis_min) y_axis_max = abs(x_axis_min) print("x-axis: ", x_axis_min, " to ", x_axis_max) print("y-axis: ", y_axis_min, " to ", y_axis_max) # create a list of x and corresponding y lattice point coordinates usingaxes max/min x = list(range(x_axis_min, x_axis_max + 1, 1)) # range(start, stop. step) y = list(range(x_axis_min, x_axis_max + 1, 1)) # range(start, stop. step) print("x: ", x) print("y: ", y) wait = input("Press Enter to continue.") # obtain and validate the user selection for the function to display print("Enter function number:") print("1: dy/dx=x+y") print("2: dy/dx=x-y") print("3: dy/dx=xy") print("4: dy/dx=x/y") print("5: dy/dx=sin(x)/y") # use text labels to echo selection to user and for graph label # put a dummy string in position 0 so list indices match item selected dydxstr = ["dummystr", "dy/dx=x+y", "dy/dx=x-y", "dy/dx=xy", "dy/dx=x/y", "dy/dx=sin(x)/y"] def valid_selection(_s): if(1 <= _s <= 5) and (isinstance(_s,int)): return "Good" else: print("Enter int 1 to 4.") return False fselect_good = False fselect = int(input("Enter function number: ")) fselect_good = valid_selection(fselect) while not fselect_good: fselect = int(input("Enter function number: ")) fselect_good = valid_selection(fselect) print("Plot ", fselect, ": ", dydxstr[fselect]) # define the selected derivative function of y in terms of x and y # that is used for the slope field, include the label used for the graph if (fselect == 1): def dydx(_x,_y): # define the derivative as a function of x and y m = _x + _y # find slope m for given x and y, do not divide by zero return m elif (fselect == 2): def dydx(_x,_y): # define the derivative as a function of x and y m = _x - _y # find slope m for given x and y, do not divide by zero return m elif (fselect == 3): def dydx(_x,_y): # define the derivative as a function of x and y m = _x * _y # find slope m for given x and y, do not divide by zero return m elif (fselect == 4): def dydx(_x,_y): # define the derivative as a function of x and y try: m = _x / _y # define the derivative as a function of x and y return m except ZeroDivisionError: if(_x == 0 and _y == 0): m = 0 return m else: m = 1000 # cheating a little here since m is actually undefined return m elif (fselect == 5): def dydx(_x,_y): # define the derivative as a function of x and y try: m = sin(_x) / _y # define the derivative as a function of x and y return m except ZeroDivisionError: if(_x == 0 and _y == 0): m = 1 return m else: m = 0 return m else: pass # create list of x, y pairs Note: x and y lists are equal length x_y = [] # initialize empty list of x, y pairs xm = [] # initialize empty list of x midpoint values ym = [] # initialize empty list of y midpoint values # create nested list of lists of all ordered pairs then extract xm and ym lists for i in range(len(x)): for j in range(len(y)): x_y.append((x[i], y[j])) for i in range(len(x_y)): xm.append(x_y[i][0]) # select all x midpoint values for i in range(len(x_y)): ym.append(x_y[i][1]) # select all y midpoint values wait = input("Press Enter to continue.") # create x and y axes, extend by 1 in each direction so the slope lines are visible axis((x_axis_min-1,x_axis_max+1,y_axis_min-1,y_axis_max+1)) # axis(Xmin,Xmax,Ymin,Ymax) axis("on") # mathplotlib: turn axes "on" grid(False) # mathplotlib: turn grid "off" # mathplotlib: draw arrows(x,y,dx,dy) where (x,y) start and (x + dx, y + dy) is end # i.e. arrows(xs=xm-dx, ys=ym-dy, 2dx, 2dy) # where length of arrow is set to 2d where d is set to 1/8 = 0.125 # and dx = 2d/root(1+m^2), dy = m*dx d = 0.250 # initial value of half the length of each line segment xs = [] # initialize empty list of xm starting x coordinate for arrows ys = [] # initialize empty list of xm starting y coordinate for arrows m = [] # initialize empty list of m at each value of xm dx = [] # initialize empty list of dx at each value of xm dy = [] # initialize empty list of dy at each value of xm for i in range(len(xm)): m.append(dydx(xm[i],ym[i])) # call dydx to calculate m for each (xm,ym) ordered pair for i in range(len(xm)): # calculate dx for each for each (xm,ym) ordered pair dx.append((d)/(sqrt(1 + pow(m[i],2)))) # calculate dx for each xs for i in range(len(xm)): # calculate dy for each (xm,ym) ordered pair dy.append(m[i] * dx[i]) # calculate dy for each xs for i in range(len(xm)): xs.append(xm[i] - dx[i]) # xs = starting x values of arrows ys.append(ym[i] - dy[i]) # ys = starting y values of arrows print("length of lines: ", 2*d) print("slope m at each (xm,ym): ", m) wait = input("Press Enter to continue.") # draw arrows starting at each (xs,ys) ordered pair and moving by 2dx and 2dy for i in range(len(xs)): arrow(xs[i],ys[i],2*dx[i],2*dy[i],color="red",head_width = 0.05) text(x_axis_min,y_axis_max,dydxstr[fselect]) # label graph in upper-left with derivative function show() # mathplotlib show display