diff --git a/symboCalc.py b/symboCalc.py new file mode 100644 index 0000000000000000000000000000000000000000..fb8f50cb6b1be339f5cda2fdf9fdbbe4428e4f60 --- /dev/null +++ b/symboCalc.py @@ -0,0 +1,138 @@ +# Jack Eckert + +# dependencies +from abc import ABC, abstractmethod +import math + +# abstract base class for functions + +# arg is the argument of the function, which by default is the identity function represented +# by the string 'x'. Any string will work and acts as a marker to allow the program to identify +# the identity function. + +# coef is the coefficient of the function, should always be an integer or float and by default +# is one. +class BaseFunction(ABC): + def __init__(self, coef=None, arg=None): + if coef == None: + self.__coefficient = 1 + else: + self.__coefficient = coef + + if arg == None: + self.__argument = 'x' + else: + self.__argument = arg + + def getArg(self): + return self.__argument + + def setArg(self, new): + self.__argument = new + + def getCoef(self): + return self.__coefficient + + def setCoef(self, new): + self.__coefficient = new + + # used to consolidate an outside constant (k) into the function's coefficient + def integrateCoef(self, k): + self.__coefficient *= k + + def __str__(self): + if self.getCoef() == 1: + coefficientString = '' + else: + coefficientString = round(self.getCoef(), 3) + return coefficientString + + def __repr__(self): + return str(self) + + @abstractmethod + def derive(self): + pass + +# power function, i.e. a function raised to a constant power. +class Power(BaseFunction): + def __init__(self, coef=None, arg=None, exp=1): + super().__init__(coef, arg) + self.__exponent = exp + + def getExp(self): + return self.__exponent + + def setExp(self): + return self.__exponent + + def __str__(self): + coefficientString = super().__str__() + + # parentheses formatting + if not(isinstance(self.getArg(), str)): + argumentString = f"({self.getArg()})" + else: + argumentString = self.getArg() + + # exponent formatting + if self.getExp() == 1: + return f"{coefficientString}{argumentString}" + + return f"{coefficientString}{argumentString}^{self.getExp()}" + + def derive(self): + # base framework for the derivative, n * f(x)^(n - 1) + if self.getExp() == 1: + shell = self.getCoef() + else: + shell = Power(self.getCoef() * self.getExp(), self.getArg(), self.getExp() - 1) + + # base derivative, or chain rule if the argument is a different function + if isinstance(self.getArg(), str): + return shell + else: + return (self.getArg().derive(), shell) + + + +# exponential function, i.e. a constant raised to a function power. +class Exponential(BaseFunction): + def __init__(self, coef=None, arg=None, base=math.e): + super().__init__(coef, arg) + if base != math.e: + if isinstance(self.getArg(), str): + self.setArg(Power(math.log(base))) + else: + self.integrateCoef(math.log(base)) + self.__base = base + + def getBase(self): + return self.__base + + def setBase(self, new): + self.__base = new + + def __str__(self): + coefficientString = super().__str__() + return f"{coefficientString}exp({self.getArg()})" + + def derive(self): + if isinstance(self.getArg(), str): + return self + else: + return (self.getArg().derive(), self) + +class Sin(): + + + +# TODO +class Equation(): + def __init__(self, eqList): + pass + +# Testing +if __name__ == "__main__": + eq1 = Exponential(arg=Power(exp=2)) + print(eq1.derive()) \ No newline at end of file