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