Example #1
0
    def checkFunction_math(self, raw):
        """
        Returns whether a string contains a valid mathematical expression
        :param raw: string which contains mathematical expression
        :return:    boolean
        """
        try:
            f = eq.Expression(raw, ['x', 'A', 'B'])

            # TODO: need a better method for checking if functions are valid than a simple point evaluation
            #  although this works in most cases most of the time it seems.
            f(x=0, A=0, B=0)
        # Value and Type errors are thrown when the string can't be converted to a function via Equation library

        except TypeError:
            logging.error(
                "Attempted to parse text that is not a function, or with improperly labelled parameters"
            )
            return False

        # TODO: It would be nice to automatically detect any parameters, regardless of if they are labelled A or B, and

        # Zero division errors are still functions, i.e. 1/x
        except ZeroDivisionError:
            logging.warning(
                "Function defined which is unbounded at the origin")
            return True
        else:
            return True
Example #2
0
def fitnessfunction():
    s = input("Enter the equation you want to find minimum for:")
    f = Equation.Expression(s, ["x", "y"])
    range = []
    s = list(map(int, input("Enter range of values [a,b] for x:").split()))
    range.append(s)
    s = list(map(int, input("Enter range of values [a,b] for y:").split()))
    range.append(s)
    return [f, range]
Example #3
0
            def evaluate(self, value):
                # f could be defined as a class attribute but would require storing the Expression object in memory.
                # by declaring it locally it is thrown away and we only need store the text it is derived from.
                # This saves memory overhead at the cost of run-time performance in evaluating functions

                try:
                    f = eq.Expression(self.raw, ["x", "A", "B"])
                    result = f(x=value, A=self.A, B=self.B)
                except ValueError:
                    logging.error("Failed to evaluate function call")
                    return None
                else:
                    return result
Example #4
0
    def ternary(self, compound, limits):
        """ generate a search list for the ternary compound """

        vars = compound.vars
        eqs = [
            Equation.Expression(ele.comp, compound.vars)
            for ele in compound.elements
        ]

        eles = [ele.name for ele in compound.elements]
        composition_format = "{:.2f}".join(eles) + "{:.2f}"

        concentrations = np.stack(list(tri_grid(self.n, *limits)), axis=0)
        formula = [composition_format.format(*row) for row in concentrations]
        fake_df = pd.DataFrame({
            "formula": formula,
            "x": concentrations[:, 0],
            "y": concentrations[:, 1],
            "z": concentrations[:, 2]
        })
        return self.generate(fake_df)
Example #5
0
    def _calculate(self, x: str):

        # re_parser = '([^\(;]*\(.*?\)|[^;]*) ?; ?'
        # regex_split = ";(?!(?:[^(]*\([^)]*\))*[^()]*\))"
        x = x.strip()
        splitexp = "[*+%/^-](?!(?:[^(]*\([^)]*\))*[^()]*\))"
        x_exprs = re.split(splitexp, x)
        x_ops = re.findall(splitexp, x)
        splitops = SpreadSheet._split_ops(x)
        x_exprs = splitops[0]
        x_ops = splitops[1]
        if len(x_exprs) > 1 and not [i in x for i in ["<", "=", ">"]].count(True):
            for i, e in enumerate(x_exprs):
                x_exprs[i] = str(self._calculate(e))
            i = 1
            for op in x_ops:
                x_exprs.insert(i, op)
                i = i + 2
            x = "".join(x_exprs)

        if x.startswith("ABS("):
            x = x[4:-1]
            x = SpreadSheet._calculate(self, x)
            assert isinstance(x, (int, float))
            return math.fabs(x)

        elif x.startswith("FLOOR("):
            x = x[6:-1]
            x = SpreadSheet._calculate(self, x)
            assert isinstance(x, (int, float))
            return math.floor(x)

        elif x.startswith("CEILING("):
            x = x[8:-1]
            x = SpreadSheet._calculate(self, x)
            assert isinstance(x, (int, float))
            return math.ceil(x)

        elif x.startswith("SIN("):
            x = x[4:-1]
            x = SpreadSheet._calculate(self, x)
            assert isinstance(x, (int, float))
            return math.sin(x)

        elif x.startswith("COS("):
            x = x[4:-1]
            x = SpreadSheet._calculate(self, x)
            assert isinstance(x, (int, float))
            return math.cos(x)

        elif x.startswith("TAN("):
            x = x[4:-1]
            x = SpreadSheet._calculate(self, x)
            assert isinstance(x, (int, float))
            return math.tan(x)

        elif x.startswith("LOG("):
            x = x[4:-1]
            args_ = SpreadSheet._split_semicolon(x)
            assert 1 <= len(args_) <= 2
            x = args_[0]
            if len(args_) == 2:
                y = args_[1]
            else:
                y = "10"
            x, y = SpreadSheet._calculate(self, x),\
                   SpreadSheet._calculate(self, y)
            assert isinstance(x and y, (int, float))
            return math.log(x, y)

        elif x.startswith("POW("):
            x = x[4:-1]
            args_ = SpreadSheet._split_semicolon(x)
            assert len(args_) == 2
            x = args_[0]
            y = args_[1]
            x, y = SpreadSheet._calculate(self, x),\
                   SpreadSheet._calculate(self, y)
            assert isinstance(x and y, (int, float))
            return math.pow(x, y)

        elif x.startswith("IF("):
            x = x[3:-1]
            args_ = SpreadSheet._split_semicolon(x)
            assert len(args_) == 3
            x = args_[0]
            if x.__contains__('(') and not x.startswith('('):
                x = SpreadSheet._split_if(x)
                x1 = x[0]
                x2 = x[2]
                x1 = SpreadSheet._calculate(self, x1)
                x2 = SpreadSheet._calculate(self, x2)
                x = str(x1) + x[1] + str(x2)
            y = args_[1]
            z = args_[2]
            x = SpreadSheet._calculate(self, x)
            if x:
                state = SpreadSheet._calculate(self, y)
            else:
                state = SpreadSheet._calculate(self, z)
            if state == 1:
                state = "TRUE"
            elif state == 0:
                state = "FALSE"
            return state

        elif x.startswith("SUM("):
            x = x[4:-1]
            args_ = SpreadSheet._split_semicolon(x)
            sum_ = 0
            for arg in args_:
                arg = SpreadSheet._calculate(self, arg)
                assert isinstance(arg, (int, float, tuple))
                if isinstance(arg, tuple):
                    for i in range(arg[0][0], arg[1][0] + 1):
                        for j in range(arg[0][1], arg[1][1] + 1):
                            y = self._getcellat(i, j).getvalue()
                            assert isinstance(y, (int, float))
                            sum_ += y
                else:
                    sum_ += arg
            return sum_

        elif x.startswith("COUNTIF("):
            x = x[8:-1]
            args_ = SpreadSheet._split_semicolon(x)
            assert len(args_) == 2
            x = args_[0]
            y = args_[1]
            x, y = SpreadSheet._calculate(self, x),\
                   SpreadSheet._calculate(self, y)
            assert isinstance(x, tuple) and len(x) == 2
            count = 0
            for i in range(x[0][0], x[1][0] + 1):
                for j in range(x[0][1], x[1][1] + 1):
                    if self._getcellat(i, j).getvalue() == y:
                        count += 1
            return count

        elif x.startswith("AVERAGE("):
            x = x[8:-1]
            args_ = SpreadSheet._split_semicolon(x)
            sum_ = 0
            count = 0
            for arg in args_:
                arg = SpreadSheet._calculate(self, arg)
                assert isinstance(arg, (int, float, tuple))
                if isinstance(arg, tuple):
                    for i in range(arg[0][0], arg[1][0] + 1):
                        for j in range(arg[0][1], arg[1][1] + 1):
                            y = self._getcellat(i, j).getvalue()
                            assert isinstance(y, (int, float))
                            sum_ += y
                            count += 1
                else:
                    sum_ += arg
                    count += 1
            avg = sum_ / max(count, 1)
            # float("%.3f" % avg)
            return round(avg, 3)

        else:
            try:
                return float(x)
            except ValueError:
                pass
            if x.startswith(("'", '"')) and x.endswith(("'", '"')):
                return x[1:-1]
            elif x.__contains__(":"):
                return SpreadSheet.parserangeaddr(x)
            else:
                if x.startswith("(") and x.endswith(")"):
                    x = x[1:-1]
                eqstr = x
                eq = re.sub("[A-Z]+[0-9]+",
                            lambda m: self._convert(m), eqstr)
                eq = eq.replace("SIN(", "sin(")
                eq = eq.replace("COS(", "cos(")
                eq = eq.replace("TAN(", "tan(")
                eq = eq.replace("ABS(", "abs(")
                return Equation.Expression(eq)()