Thursday, May 26, 2011

Calculus program

I brought up the problem of coming up with calculus exercises previously. Out of laziness, I used Python and the Sympy package. The following program needs to be modified, so the weighting scheme is actually better.

Right now it produces a specified number of complicated exercises, some of them are not even solvable (the integral exercises needs to be reconsidered). But it's fun regardless!

It's dawned on me that it would be better if it had default options, so one could just hit [enter] to get to the daily dose of calculus. I'll revise the code to produce exercises that vary in difficulty and have this option added...

At any rate, here's the code:

#!/usr/bin/python

from sympy import *
from sympy.abc import x # so x is a variable, we'll work with fns of it
import random


# returns a nonzero integer constant from -10 to 10
def constant():
    return random.randrange(-10,10,1)

# This method will generate a polynomial with random integer
# coefficients of a specified degree.
def polynomial(deg=7):
    if deg==0:
        return constant()
    elif deg>0:
        return (x**deg)*constant()+polynomial(deg-1)
    elif deg<0:
        return (x**deg)*constant()+polynomial(deg+1)

# There are 13 special functions:
# arccos, arcsin, arctan, cos, cosh, cot, coth, exp, ln,
# sin, sinh, sup, tan, tanh 
specialFn = {0 : acos,
             1 : asin,
             2 : atan,
             3 : cos,
             4 : cosh,
             5 : cot,
             6 : coth,
             7 : exp,
             8 : ln,
             9 : sin,
             10 : sinh,
             11 : tan,
             12 : tanh }

# Need to fix this method, which should produce exercises 
# depending on the weight
def term(weight=30):
    if weight<=0:
        return constant()
    if random.randrange(0,10,1)%3==0:
        tmp = specialFn[random.randrange(0,12,1)]
        return term(weight-10)+tmp(polynomial(3+(weight%4)))
    elif random.randrange(0,10,1)%3==0:
        return term(2*weight/3)**term(weight/2)
    else:
        return term(weight-5)+polynomial()

# when printing stuff out, be sure to use "latex(...)"
numDeriv = raw_input("How many derivative exercises do you want? ")
numInt = raw_input("How many integral exercises do you want? ")

try:
    numDeriv=int(numDeriv)
    numInt=int(numInt)
except ValueError:
    print "Sorry, invalid input."

# print out the exercises
print "\n"

if numDeriv>0:
    print "Calculate the derivatives of the following functions:"
    print "\n"
    for i in xrange(numDeriv):
        print latex(term(), inline=False)
    print "\n"

if numInt>0:
    print "Calculate the following integrals:"
    print "\n"
    for i in xrange(numDeriv):
        print latex(Integral(term(),x), inline=False)
    print "\n"

TODO: rewrite this so there is a better notion of "weight" to the problem. That is, the difficulty rating is more appropriate.

TODO: rewrite this so it produces a .tex file, which has two sections (problems and solutions), and the problems section has various subsections (e.g. "Derivatives," "Integrals," etc.).

No comments:

Post a Comment