def gestionNewtonRaphson (expresion, expresion_derivada, punto_inicio, cifras, max_iteraciones, area_texto): area_texto.delete('1.0', 'end') parser = Parser() try: funcion = parser.parse(expresion) derivada_funcion = parser.parse(expresion_derivada) except Exception as exc: area_texto.insert('end', "Ha ocurrido un error al procesar las funciones, por favor revise los campos.\n") return try: inicio = (float)(punto_inicio) cifras_significativas = (int)(cifras) tolerancia = calcularTolerancia(cifras_significativas) maximo_iteraciones = (int)(max_iteraciones) imprimirEncabezadoTabla(['n', 'x_n', 'f(x_n)', 'f_derivada(x_n)', 'error'], area_texto) raiz = newtonRaphson(funcion, derivada_funcion, inicio, tolerancia, 0.0005, maximo_iteraciones, area_texto) area_texto.insert('end', '\n') area_texto.insert('end', "La aproximación a la raíz es: " + str(raiz) + ".") except ValueError: area_texto.insert('end', "Uno o más de los valores introducidos no son numéricos. Por favor revise los campos.\n") except IteracionesInvalidasExcepcion as exc: area_texto.delete('1.0', 'end') area_texto.insert('end', exc.mensaje + "\n") except NumeroCercanoCeroExcepcion as exc2: area_texto.insert('end', exc2.mensaje + "\n") except MetodoFallidoExcepcion as exc3: area_texto.insert('end', exc3.mensaje + "\n") except Exception as exc4: area_texto.insert('end', "Ha ocurrido un error.\n" + exc4.message)
def calculate_price(expressionString, data, numeric=True): """Calculates price based on the expression. For example, "participants.age * 12" "participants * 12" will use participants' length if it is an array. todo: base 64 encode here. """ from .defaultContext import DEFAULT_CONTEXT if ":" in expressionString: expressionString = expressionString.replace(":", DELIM_VALUE) expressionString = expressionString.replace("$", "") parser = Parser() expr = parser.parse(expressionString) context = {} for variable in expr.variables(): escapedVariable = variable.replace(".", DOT_VALUE) if escapedVariable.startswith("CFF_FULL_"): _, actual_variable = escapedVariable.split("CFF_FULL_") context[escapedVariable] = parse_number_formula( data, actual_variable.replace(DOT_VALUE, "."), False) else: context[escapedVariable] = parse_number_formula( data, escapedVariable.replace(DOT_VALUE, ".")) expressionString = expressionString.replace(variable, escapedVariable) context = dict(context, **DEFAULT_CONTEXT) price = parser.parse(expressionString).evaluate(context) if not numeric: return price return ceil(float(price) * 100) / 100
def test_custom_functions(self): parser = Parser() def testFunction0(): return 13 def testFunction1(a): return 2 * a + 9 def testFunction2(a, b): return 2 * a + 3 * b # zero argument functions don't currently work # self.assertEqual(parser # .parse('testFunction()') # .evaluate({"testFunction":testFunction0}),13) self.assertExactEqual( parser.parse('testFunction(x)').evaluate({ "x": 2, "testFunction": testFunction1 }), 13) self.assertExactEqual( parser.parse('testFunction(x , y)').evaluate({ "x": 2, "y": 3, "testFunction": testFunction2 }), 13) # Add some "built-in" functions def mean(*xs): return sum(xs) / len(xs) parser.functions['mean'] = mean def counter(initial): class nonlocals: x = initial def count(increment): nonlocals.x += increment return nonlocals.x return count parser.functions['count'] = counter(0) self.assertEqual(parser.parse("mean(xs)").variables(), ["xs"]) self.assertEqual(parser.parse("mean(xs)").symbols(), ["mean", "xs"]) self.assertEqual( parser.evaluate("mean(xs)", variables={"xs": [1, 2, 3]}), 2) self.assertExactEqual( parser.evaluate("count(num)", variables={"num": 5}), 5) self.assertExactEqual( parser.evaluate("count(num)", variables={"num": 5}), 10)
def _evaluate(cls, models, formula): """ Parse a string into an arithmetic expression. Parameters ---------- models : list List of `Layer` objects that correspond to the given variables. formula : str A string describing the arithmetic operations to perform. """ try: parser = Parser() expr = parser.parse(formula) except: return # Extract variables vars = expr.variables() # List the models in the same order as the variables sorted_models = [m for v in vars for m in models if m.name == v] if len(sorted_models) > len(vars): logging.error("Incorrect model arithmetic formula: the number " "of models does not match the number of variables.") return elif len(sorted_models) < len(vars): extras = [ x for x in vars if x not in [y.name for y in sorted_models] ] for extra in extras: matches = re.findall('([\+\*\-\/]?\s?{})'.format(extra), formula) for match in matches: formula = formula.replace(match, "") try: expr = parser.parse(formula) vars = expr.variables() except: logging.error("An error occurred.") return try: result = parser.evaluate( expr.simplify({}).toString(), dict(pair for pair in zip(vars, sorted_models))) return result except (AttributeError, TypeError) as e: logging.error("Incorrectly formatted model formula: %s", e)
def fixedpointres(request): import math from py_expression_eval import Parser #tol=float(input("Ingrese tolerancia: ")) #xa=float(input("Ingrese valor inicial: ")) #niter=float(input("Ingrese número de iteraciones: ")) #func=str(input("Ingrese la función f: ")) #fung=str(input("Ingrese función g: ")) xa = request.POST.get('x0', None) niter = request.POST.get('iter', None) tol = request.POST.get('tol', None) func = request.POST.get('func', None) fung = request.POST.get('fung', None) xa = float(xa) niter = int(niter) tol = float(tol) t = PrettyTable(['Iterations', 'xi', 'g(xi)', 'f(xi)', 'Error']) t.border = False t.header = False parser = Parser() fx = parser.parse(func).evaluate({'x': xa}) cont = 0 error = tol + 1 print("| Iter | xi | g(xi) | f(xi) | E |") while fx != 0 and error > tol and cont < niter: xn = parser.parse(fung).evaluate({'x': xa}) fx = parser.parse(func).evaluate({'x': xn}) error = abs(xn - xa) xa = xn cont = cont + 1 print(" | ", cont, " | ", xa, " | ", xn, " | ", fx, " | ", error, " | ") t.add_row([ " | " + str(cont) + " | ", str(xa) + " | ", str(xn) + " | ", str(fx) + " | ", str(error) + " | " ]) if fx == 0: print("{} es una raiz".format(xa)) else: if error < tol: print("{} es una aproximación con una tolerancia de {}".format( xa, error)) else: print("El método fracasó en {} iteraciones".format(niter)) context6 = {'vec': t} return render(request, "fixedpointres.html", context6)
def calculate(): g = [] parser = Parser() function = request.args.get('function') g1 = request.args.get('g1') g2 = request.args.get('g2') g3 = request.args.get('g3') g4 = request.args.get('g4') g5 = request.args.get('g5') x3 = request.args.get('x3') x4 = request.args.get('x4') x5 = request.args.get('x5') g1 and g.append(g1) g2 and g.append(g2) g3 and g.append(g3) g4 and g.append(g4) g5 and g.append(g5) g = [parser.parse(gi) for gi in g] startPoint = [float(request.args.get('x1')), float(request.args.get('x2'))] x3 and startPoint.append(x3) x4 and startPoint.append(x4) x5 and startPoint.append(x5) print("new run", function, g1, g2, g3, startPoint) localStepSize = float(request.args.get('localStepSize', '50')) epsilon = float(request.args.get('epsilon', '10e-3')) stepsLimit = int(request.args.get('stepsLimit', '3000')) function = parser.parse(function) if len(function.variables()) < 3: Process(target=showGraph, args=(function, g, startPoint, localStepSize, epsilon, stepsLimit)).start() cg = GaussSeidel(function, g, startPoint, localStepSize, epsilon, stepsLimit) pos = cg.getLowestPos() parameters = dict(zip(cg.variables, pos)) result = { "pos": pos, "logs": cg.logs, "f": function.evaluate(parameters), "g": [ gi.evaluate(dict(zip(sorted(function.variables()), pos))) for gi in g ] } return result
class ValidMathStr(QValidator): def __init__(self, parent=None): QValidator.__init__(self, parent) self.parser = Parser() def validate(self, string, pos): try: self.parser.parse(string) except Exception: self.parent().setStyleSheet('border: 3px solid red') # red return QValidator.Intermediate, string, pos else: self.parent().setStyleSheet('border: 3px solid green') # green return QValidator.Acceptable, string, pos
def test_custom_functions_with_inline_strings(self): parser = Parser() expr = parser.parse("func(1, \"func(2, 4)\")") self.assertEqual(expr.variables(), ['func']) expr = parser.parse("func(1, 'func(2, 4)')") self.assertEqual(expr.variables(), ['func']) parser2 = Parser(string_literal_quotes=("'")) expr = parser2.parse("func(1, \"func(2, 4)\")") self.assertEqual(expr.variables(), ['func', "\"func(2, 4)\""]) expr = parser2.parse("func(1, 'func(2, 4)')") self.assertEqual(expr.variables(), ['func'])
def test_decimals(self): parser = Parser() self.assertEqual(parser.parse(".1").evaluate({}), parser.parse("0.1").evaluate({})) self.assertEqual(parser.parse(".1*.2").evaluate({}), parser.parse("0.1*0.2").evaluate({})) self.assertEqual(parser.parse(".5^3").evaluate({}), float(0.125)) self.assertEqual(parser.parse("16^.5").evaluate({}), 4) self.assertEqual(parser.parse("8300*.8").evaluate({}), 6640) with self.assertRaises(ValueError): parser.parse("..5").evaluate({})
def result_expr(self, values): p = Parser() return p.parse(self.exp).evaluate({ 'x': values[0], 'y': values[1], 'z': values[2] })
def update_apps_verification(): print('Check the users are verified for the apps') parser = Parser() apps = {app["_key"]: app['verification'] for app in db['apps'] if app.get('verification')} for user in db['users']: verifications = get_user_verification(user['_key']) for app in apps: try: expr = parser.parse(apps[app]) variables = expr.variables() verifications.update( {k: False for k in variables if k not in verifications}) verified = expr.evaluate(verifications) except: print('invalid verification expression') continue if verified and app not in verifications: db['verifications'].insert({ 'app': True, 'name': app, 'user': user['_key'], 'timestamp': int(time.time() * 1000) }) elif not verified and app in verifications: db['verifications'].delete_match({ 'app': True, 'name': app, 'user': user['_key'] })
def evaluarExpresion(expresion: str, value=255): parser = Parser() try: response = parser.parse(expresion).evaluate({'x': value}) return response except Exception as e: return False
class TestExpressions(unittest.TestCase): def setUp(self): self.parser = Parser() self.goal_functions = [self.get_goal_function('x^2 + y ^ 3'), self.get_goal_function('sin(e)*x*y + e*y')] self.answers = [['((x^2.0)+(y^3.0))', '(x^2.0)+(y^3.0)', True], ['(((0.410781290503*x)*y)+(2.71828182846*y))', '((sin(e)*x)*y)+(e*y)', True]] self.goal_err_functions = [self.get_goal_function('x^2 + z'), self.get_goal_function('x + a + y')] def get_goal_function(self, expression): gf = GoalFunction() gf.__expression = self.parser.parse(expression) gf.__fetch_function_name() return gf def testExpressionValidation(self): for (gf, answers) in zip(self.goal_functions, self.answers): expr, validates, val_error = ExpressionValidator(gf.expression).validate() self.assertEqual(answers[0], expr.toString()) self.assertEqual(answers[1], gf.get_function_name()) self.assertTrue(validates) def testExpressionFailure(self): for gf in self.goal_err_functions: expr, validates, val_error = ExpressionValidator(gf.__expression).validate() self.assertFalse(validates)
def post_expression(): try: raw_json = request.get_json() expression = raw_json['expression'] variables = raw_json['variables'] except TypeError: return jsonify_msg('No JSON found'), 400 except KeyError: return jsonify_msg('JSON has a wrong structure'), 400 try: parser = Parser() # mathematical expression validation parsed_expression = parser.parse(expression) # "py_expression_eval" uses Exception class for all exceptions except devision by zero and overflow :( except Exception: return jsonify_msg('Error occured while parsing expression'), 400 # variables matching validation variables_set = set(parsed_expression.variables()) if variables_set != set(variables): return jsonify_msg('JSON["variables"] does not match with variables in expression'), 400 expression_id = db.put_task(expression, variables) return jsonify(expression_id[0]), 200
def is_expression_valid(expression: str, alias_list: list) -> bool: """ Check if a mathematical string expression is valid by attempting to parse it and checking if all the variables in it exist in the aliases list. Parameters ---------- expression : str String containing mathematical expression alias_list : list List of strings containing all the aliases in display Returns ------- bool True for valid expression, otherwise its false. """ parser = Parser() try: expr_var = parser.parse(expression) except Exception: return False else: return all(item in alias_list for item in expr_var.variables())
def update_index_by_variable_name_appearing_in_formula(index_by_variable_name, formula): parser_formula = Parser() try: expr = parser_formula.parse(formula) except Exception, e: print formula raise(e)
def setViaFile(cls, my_filename): dirname = os.path.dirname(__file__) wb = load_workbook(filename = os.path.join(dirname, './Rules/'+my_filename) ) ws = wb.active Distributions = [] for row in ws: Distribution = [] for enumerator, cell in enumerate(row): if cell.value == None: continue if str(cell.value).find('SUM') != -1: continue if re.search('[а-яА-ЯёЁ]|http', str(cell.value)): continue #if cell.value == "?": #print("Hey!!!!", my_filename) if cell.value == "f:": print("Hello!") i, j = cell.row, cell.col_idx str_expr = str(ws.cell(row = i, column = j + 1).value) print(str_expr) parser = Parser() expr = parser.parse(str_expr) Distribution = Distribution + [float(expr.evaluate({'x':x})) for x in range(ws.cell(row = i, column = j + 2).value, ws.cell(row = i, column = j + 3).value)] print(Distribution) break Distribution.append(cell.value) Distributions.append(Distribution) return cls(Distributions)
def calculate_worker(self, task): logger.debug('Calculate task: ', task) parser = Parser() expression_id = task['expression_id'] expression = task['expression'] variables = task['variables'] signal.signal(signal.SIGALRM, signal_handler) signal.alarm(CALCULATION_TIMEOUT) try: result = parser.parse(expression).evaluate(variables) error_code = 0 except ZeroDivisionError: result = None error_code = 1 # ZeroDivisionError except OverflowError: result = None error_code = 2 # OverflowError except TimeoutError: result = None error_code = 3 # Calculation TimeoutError except Exception as e: logger.warning( f"Unexpected error while calculating task: {task}; error: ", e) result = None error_code = 4 # UnexpectedError finally: signal.alarm(0) res = (expression_id, expression, json.dumps(variables), result, error_code) result_queue.put(res)
def gestionTrapecioConocida (expresion, a, b, trapecios, area_texto): area_texto.delete('1.0', 'end') parser = Parser() try: funcion = parser.parse(expresion) except Exception as exc: area_texto.insert('end', "Ha ocurrido un error al procesar la función, por favor revise los campos.\n") return try: lim_inferior = (float)(a) lim_superior = (float)(b) if lim_inferior < lim_superior: numero_trapecios = (int)(trapecios) integral = integracionTrapecioConocida(funcion, lim_inferior, lim_superior, numero_trapecios) area_texto.insert('end', '\n') area_texto.insert('end', "La aproximación a la integral es: " + str(integral) + ".") else: area_texto.insert('end', "El límite superior debe ser mayor al inferior, por favor revise los campos.") except ValueError: area_texto.insert('end', "Uno o más de los valores introducidos no son numéricos. Por favor revise los campos.\n") except NumeroParticionesInvalidoExcepcion as exc: area_texto.insert('end', exc.mensaje + "\n") except Exception as exc2: area_texto.insert('end', "Ha ocurrido un error.\n" + exc2.message)
class FormulaParser: exp = None raw = None parser = None def __init__(self, raw: str, vars=['x']): self.raw = raw self.parser = Parser() self.variables = vars def is_valid(self, raise_exception=False): exp = self.parser.parse(self.raw) vars = exp.variables() if len(vars) != len(self.variables): if raise_exception: raise Exception('must be only {}'.format(', '.join( [v for v in self.variables]))) return False for v in self.variables: if v not in vars: if raise_exception: raise Exception('must be only one {}'.format(v)) return False self.exp = exp return True def __call__(self, **kwargs): if not self.exp: raise Exception('cal .is_valid() first') return self.exp.evaluate(kwargs)
def gdal_mapcalc(expression, exp_val_paths, outRaster, template_rst, outNodata=-99999): """ GDAL Raster Calculator TODO: Check if rasters dimensions are equal """ import numpy as np from osgeo import gdal from py_expression_eval import Parser from glass.g.prop.img import get_nd from glass.g.wt.rst import obj_to_rst parser = Parser() EXPRESSION = parser.parse(expression) evalValue = {} noDatas = {} for x in EXPRESSION.variables(): img = gdal.Open(exp_val_paths[x]) arr = img.ReadAsArray().astype(float) evalValue[x] = arr noDatas[x] = get_nd(img) result = EXPRESSION.evaluate(evalValue) for v in noDatas: np.place(result, evalValue[v]==noDatas[v], outNodata) # Write output and return return obj_to_rst(result, outRaster, template_rst, noData=outNodata)
def parse_expression(args): """generate data from a parsed expression Parameters ---------- expression = an expression to parse vars : Each key is a the variable name and the value is a DataValue to use in the expression Returns ------- a DataValue which is the result of the expression Raises ------ AttributeError if no attribute, value pair or dict is specified. """ verbose = False #make this more robust and test it XXX expression = args["expression"] vars = args["vars"] if verbose: print("expression:", pformat(expression), "\nvars:", pformat(vars)) parser = Parser() result = parser.parse(expression).evaluate(vars) return {'value': DV.DataValue(result)}
def bisseccao(self): parser = Parser() expressao = self.funcao.get() a = float(self.aVariavel.get()) b = float(self.bVariavel.get()) epsilon = float(self.epsilon.get()) # #Seta o primeiro valor de x x = float((a + b) / 2) fA = float(parser.parse(expressao).evaluate({'x': a})) fB = float(parser.parse(expressao).evaluate({'x': b})) fX = float(parser.parse(expressao).evaluate({'x': x})) i = 1 maiorErro = True while (maiorErro): i += 1 #suplemento do excel -> steam table #Seta o primeiro valor de x if ((fA > 0 and fX > 0) or (fA < 0 and fX < 0)): a = x else: b = x #Seta o enesimo valor de x x = float((a + b) / 2) fA = float(parser.parse(expressao).evaluate({'x': a})) fB = float(parser.parse(expressao).evaluate({'x': b})) fX = float(parser.parse(expressao).evaluate({'x': x})) aux = float(b - a) if (b - a <= epsilon): maiorErro = False #joga resultado final na variavel resultado e seta o texto do resultado como sendo ela resultado = "Iteracao: " + str(i) + "\na: " + str(a) + "\nb: " + str( b) + "\nx: " + str(x) + "\nf(a): " + str(fA) + "\nf(b): " + str( fB) + "\nf(x): " + str(fX) + "\nErro: " + str(b - a) self.resultado["text"] = resultado
class Info(commands.Cog): def __init__(self, bot): self.bot = bot self.parser = Parser() @commands.command(aliases=["c", "calc"]) @commands.guild_only() async def calculate(self, ctx, *, equation): eq = (equation.replace("×", "*")).replace("÷", "/") ans = self.parser.parse(eq).evaluate({}) await ctx.send(ans) @commands.command(aliases=["ducksearch", "dsearch"]) @commands.guild_only() async def duckduckgo(self, ctx, *, query): response = requests.get( f"https://api.duckduckgo.com/?q={query}&format=json&pretty=1") result = json.loads(response.text) topics = result["RelatedTopics"] if len(topics) == 0: await ctx.send("Sorry! duckduckgo returned 0 results") else: for i in range(len(topics)): image = topics[i]["Icon"]["URL"] text = topics[i]["Text"] url = topics[i]["FirstURL"] d = discord.Embed(title="duckduckgo", description=text, color=discord.Color.blue(), url=url) d.set_image(url=f"https://duckduckgo.com/{image}") msg = await ctx.send(embed=d) emojis = [ "<:arrowleft:762542689425555486>", "<:arrowright:762542086788349964>" ] for j in emojis: await msg.add_reaction(j) async def page(i): await d.description() def check(reaction, user): return user == ctx.author and reaction.message.id == msg.id no = 0 while len(topics) > i: try: reaction, user = await self.bot.wait_for( "reaction_add", check=check, timeout=30) emoji = str(reaction.emoji) if emoji == "<:arrowright:762542086788349964>": no += 1 elif emoji == "<:arrowleft:762542689425555486>": no -= 1 await reaction.remove(user) except asyncio.TimeoutError: await msg.clear_reactions()
class Function: def __init__(self, s): self.parser = Parser() self.s = s self.expr = self.parser.parse(s) def eval(self, x): return self.expr.evaluate({'x': x})
def calculate(expression): """ This function will calculate the result of the mathematical expression :param expression: the expression to be calculated/evaluated (str) :return: the result of the calculation (float or int) """ parser = Parser() return parser.parse(expression).evaluate({})
def update_index_by_variable_name_appearing_in_formula(index_by_variable_name, formula): parser_formula = Parser() try: expr = parser_formula.parse(formula) except Exception, e: print formula raise (e)
def calibrate_pm25(self, formula): if formula: parser = ExpressionParser() expression = parser.parse(formula) context = self.get_calibration_context() self.pm25_env = expression.evaluate(context) self.pm25_calibration_formula = formula
def evaluate_rules(city, temp, n_rules): parser = Parser() for note_rule in n_rules: if parser.parse(note_rule['rule']).evaluate({"t": temp, "city": city}): return note_rule["note"] return ''
def update_index_by_variable_name_appearing_in_formula(index_by_variable_name, formula): parser_formula = Parser() expr = parser_formula.parse(formula) formula_variables = expr.variables() components = dict( (formula_variable, {'code': formula_variable}) for formula_variable in formula_variables ) index_by_variable_name.update(components) return index_by_variable_name
def test_custom_functions_substitute_strings(self): def func(var, str): if str == "custom text": return 1 return 0 parser = Parser() expr = parser.parse("func(1, \"custom text\")") self.assertEqual(expr.evaluate({"func": func}), 1)
def calculate(self, calculation): if calculation: try: # Solve formula and display it in entry # which is pointed at by display parser = Parser() self.display.text = str(parser.parse(calculation).evaluate({})) except Exception: self.display.text = "Error"
class GoalFunction: """ Class which holds a goal function to optimize """ def __init__(self, initial_function=None): self.console_logger = ConsoleLogger.get_instance() # get logger self.console_logger.log("Goal function initializing...", LoggerLevel.DEBUG) self.__expression = "" # function expression self.__function_name = "" # function simple name self.__variables = ['x', 'y'] # variables in function self.__parser = Parser() # function parser self.__correctly_parsed = True # whether the function was correctly parsed self.set_goal_function("x ^ 4 * (y + 1) ^ 2 + y ^ 4 * (x + 1) ^ 2") # set some default function if initial_function: # if to constructor was passed function self.set_goal_function(initial_function) # try to set it self.console_logger.log("Goal function initialized", LoggerLevel.DEBUG) def __fetch_function_name(self): self.__function_name = self.__expression.simplify({}).toString()[1:-1] self.console_logger.log("function fetched to: " + self.get_function_name(), LoggerLevel.ADDITIONAL) def get_function_name(self): return self.__function_name def get_expression(self): return self.__expression def is_correctly_parsed(self): return self.__correctly_parsed def set_goal_function(self, function): """sets goal function If function is not correctly set it returns false, if it is correctly set itt returns true """ try: function = function.lower() # convert input to lower case expression = self.__parser.parse(function) # try to parse expression validator = ExpressionValidator(expression, self.__variables) # get expression validator expression, validates, validation_error = validator.validate() # expression validation if not validates: self.console_logger.log("function is not validating", LoggerLevel.ERROR) self.console_logger.log(validation_error, LoggerLevel.ERROR) print validation_error raise Exception() self.__expression = expression self.__fetch_function_name() # fetch simple name from function self.console_logger.log("function: " + self.get_expression().toString(), LoggerLevel.ADDITIONAL) self.__correctly_parsed = True return True except Exception: self.__correctly_parsed = False return False
def test_custom_functions(self): parser = Parser() def testFunction0(): return 13 def testFunction1(a): return 2*a+9 def testFunction2(a,b): return 2*a+3*b # zero argument functions don't currently work # self.assertEqual(parser # .parse('testFunction()') # .evaluate({"testFunction":testFunction0}),13) self.assertExactEqual(parser .parse('testFunction(x)') .evaluate({"x":2,"testFunction":testFunction1}),13) self.assertExactEqual(parser .parse('testFunction(x , y)') .evaluate({"x":2,"y":3,"testFunction":testFunction2}),13) # Add some "built-in" functions def mean(*xs): return sum(xs) / len(xs) parser.functions['mean'] = mean def counter(initial): class nonlocals: x = initial def count(increment): nonlocals.x += increment return nonlocals.x return count parser.functions['count'] = counter(0) self.assertEqual(parser.parse("mean(xs)").variables(), ["xs"]) self.assertEqual(parser.parse("mean(xs)").symbols(), ["mean", "xs"]) self.assertEqual(parser.evaluate("mean(xs)", variables={"xs": [1, 2, 3]}), 2) self.assertExactEqual(parser.evaluate("count(inc)", variables={"inc": 5}), 5) self.assertExactEqual(parser.evaluate("count(inc)", variables={"inc": 5}), 10)
def eval_cost(self, var_value): """ The eval_cost method calculates the value of the cost formula for a given var_value: WARNING: the variable in the function MUST be f. >>> Edge(1, 2, 3, '5+5*f').eval_cost(5.0) 30.0 >>> Edge(1, 2, 3, '5+5*t').eval_cost(5.0) Traceback (most recent call last): ... Exception: undefined variable: t """ parser = Parser() exp = parser.parse(self.cost_formula) #Hardcoded variable 'f' return exp.evaluate({'f': var_value})
def _evaluate(self): expression = str(self.get_argument('expression')) operands = self.get_operands() parser = Parser() try: return parser.parse(expression).evaluate(operands) except TypeError: msg = "Type Error expression {} with operands {}" raise ValueError(msg.format(expression, operands)) except ZeroDivisionError: msg = "Zero division for expression {} with operands {}" logging.warn(msg.format(expression, operands)) return float('NaN') except Exception as e: msg = u"PyExpression error: {} for expression '{}' with opers: {}" logging.warn(msg.format(e, expression, operands)) raise
def calculateEdgesTravelTimesNew(self, stringOfActions): """ New Version THIS IS THE NEW EVALUATE FUNCTION(THE ONE ABOVE IS NOT USED ANYMORE) EACH EDGE OF THE NETWORK HAS ITS OWN COST FUNCTION NOW. """ edges_travel_times = {} #Get the flow of that edge linkOccupancy = self.driversPerLink(stringOfActions) #For each edge for edge in self.Eo: p = Parser() exp = p.parse(edge.cost_formula) #Evaluates the cost of that edge with a given flow (i.e. edge.eval_cost(flow)) edges_travel_times[edge.start + "|" + edge.end] = \ edge.eval_cost(linkOccupancy[edge.start + "|" + edge.end]) return edges_travel_times
def __check_formula_simple(self, formula_name, formula, list_of_variables): msg = "" variables_to_remove = [] #list of unused variables # get the list of terms p = Parser() list_of_terms = p.parse(formula).variables() # check consistency of the variables for v in list_of_variables: if v not in list_of_terms: variables_to_remove.append(v) #return "Variable '%s' is not part of the function!" % v print "WARNING: Variable '%s' is not part of function %s's formula!" % (v, formula_name) return msg, variables_to_remove, list_of_terms
def get_pure_depreciation_contribution(self): par = Parser() equation = self.depreciation_curve.trim() return par.parse(equation).evaluate({'x': self.target_attribute.value})
def test_plot(): from py_expression_eval import Parser parser = Parser() expr = parser.parse('x^2 + y^2') plotter = Plotter(expr, expr.toString()) plotter.plot_function_in_3D()
def get_or_construct_value(df, variable_name = None, index_by_variable = None, years = None, fill_value = numpy.NaN, verbose = False): """ Returns the DateFrame (1 column) of the value of economic variable(s) for years of interest. Years are set to the index of the DataFrame. Parameters ---------- df : DataFrame DataFrame generated by get_comptes_nationaux_data(year) variable : string or dictionary Variable to get or to construct (by applying formula). index_by_variable : dictionary Contains all economic variables indexes and formula. Variables appearing in formula of variable should be listed in index_by_variable. years : list of integers Years of interest Example -------- >>> table_cn = get_comptes_nationaux_data(2013) >>> index_by_variable = { ... 'Interets_verses_par_rdm': { ... 'code': 'D41', ... 'institution': 'S2', ... 'ressources': False, ... 'description': '' ... }, ... 'Dividendes_verses_par_rdm_D42': { ... 'code': 'D42', ... 'institution': 'S2', ... 'ressources': False, ... 'description': '' ... }, ... 'Dividendes_verses_par_rdm_D43': { ... 'code': 'D43', ... 'institution': 'S2', ... 'ressources': False, ... 'description': '' ... }, ... 'Revenus_propriete_verses_par_rdm': { ... 'code': 'D44', ... 'institution': 'S2', ... 'ressources': False, ... 'description': '' ... }, ... 'Interets_dividendes_verses_par_rdm': { ... 'code': None, ... 'institution': 'S2', ... 'ressources': False, ... 'description': 'Interets et dividendes verses par RDM, nets', ... 'formula': 'Interets_verses_par_rdm + Dividendes_verses_par_rdm_D42 + Dividendes_verses_par_rdm_D43 + Revenus_propriete_verses_par_rdm' ... } ... } >>> computed_variable_vector, computed_variable_formula = get_or_construct( ... df, 'Interets_dividendes_nets_verses_par_rdm', index_by_variable ... ) Returns a tuple, where the first element is a DataFrame (with a single column) for years 1949 to 2013 of the value of the sum of the four variables, and the second element is the formula 'Interets_verses_par_rdm + Dividendes_verses_par_rdm_D42 + Dividendes_verses_par_rdm_D43 + Revenus_propriete_verses_par_rdm' """ assert df is not None assert variable_name is not None assert years is not None df = df.copy() if index_by_variable is None: index_by_variable = { variable_name: {'code': variable_name} } variable = index_by_variable.get(variable_name, None) assert variable is not None, "{} not found".format(variable_name) formula = variable.get('formula') dico_value = dict() entry_df = look_up(df, variable, years) index = None if not entry_df.empty: result_data_frame = entry_df[['value', 'year']].copy() result_data_frame.drop_duplicates(inplace = True) result_data_frame.rename(columns = dict(value = variable_name)) result_data_frame.set_index('year', inplace = True, verify_integrity = True) result_data_frame.sort_index(inplace = True) final_formula = variable_name # For formulas that are not real formulas but that are actually a mapping elif (not formula) and entry_df.empty: result_data_frame = pandas.DataFrame(data = [fill_value] * len(years), index = years) final_formula = '' else: # When formula is a list of dictionnaries with start and end years if isinstance(formula, list): result_data_frame = pandas.DataFrame() for individual_formula in formula: assert individual_formula['start'] or individual_formula['end'] start = individual_formula.get('start', None) end = individual_formula.get('end', None) local_index_by_variable = copy.deepcopy(index_by_variable) local_index_by_variable[variable_name]['formula'] = individual_formula['formula'] actual_years = list(set(range( max(start, min(years)) if (start is not None) else min(years), min(end + 1, max(years) + 1) if (end is not None) else (max(years) + 1), ))) variable_value, final_formula = get_or_construct_value( df, variable_name, local_index_by_variable, actual_years, fill_value = fill_value) if variable_value.empty: variable_value = pandas.DataFrame({variable_name: [fill_value]}, index = actual_years) variable_value.index.name = 'year' result_data_frame = pandas.concat((result_data_frame, variable_value)) return result_data_frame, 'formula changes accross time' parser_formula = Parser() try: expr = parser_formula.parse(formula) except Exception as e: log.info('Got the following error when evaluation formula: \n {}'.format(formula)) raise(e) variables = expr.variables() for component in variables: if verbose: log.error('Component {} of the formula'.format(component)) log.error(pretty_printer(index_by_variable)) variable_value, variable_formula = get_or_construct_value( df, component, index_by_variable, years, fill_value = fill_value) if verbose: log.info(variable_value) if index is None: index = variable_value.index assert len(variable_value.index) == len(variable_value.index.unique()), \ "Component {} does not have a single valued index.\n The following values {} are duplicated".format( component, variable_value.index[variable_value.index.duplicated()]) # else: # equality_index_test = ( # numpy.sort(index.unique()) != numpy.sort(variable_value.index.unique()) # ) # try: # reindexing_condition = equality_index_test.any() # except AttributeError: # reindexing_condition = equality_index_test # if reindexing_condition: # log.info('index differs {} vs {} after getting {}'.format( # index, variable_value.index, component)) # index = index.union(variable_value.index) # log.info('Will be using union index {}'.format(index)) # formula_with_parenthesis = '(' + variable_formula + ')' # TODO needs a nicer formula output final_formula = formula.replace(component, formula_with_parenthesis) dico_value[component] = variable_value formula_modified = formula.replace("^", "**") for component, variable_value in dico_value.iteritems(): # Reindexing if variable_value.empty: # Dealing with completely absent variable log.info('Variable {} is completely missing'.format(component)) variable_value = pandas.DataFrame({component: [fill_value]}, index = index) dico_value[component] = variable_value.reindex(index = years, fill_value = fill_value).values.squeeze() data = eval(formula_modified, dico_value) # assert data is not None # assert index is not None try: result_data_frame = pandas.DataFrame( data = {variable_name: data}, index = years, ) result_data_frame.index.name = 'year' except Exception, e: log.error('FAILED') log.error(variable_name) log.error('data') log.error(data) log.error('index') log.error(index) raise(e)
def generate_graph(self, graph_file, print_edges = False, flow = 0): """ Reads the .net file and return it's infos. The infos are: function(s) node(s) arc(s) edge(s) od(s) It should be following the specification from: https://wiki.inf.ufrgs.br/Network_files_specification It returns a list of vertices(V), a list of edges(E) and a list of OD(ODlist) Tests: >>> Experiment(8, './networks/OW10_1/OW10_1.net', 1, 'OW').\ generate_graph('./networks/OW10_1/OW10_1.net') #doctest:+NORMALIZE_WHITESPACE (['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M'], ['A-B', 'B-A', 'A-C', \ 'C-A', 'A-D', 'D-A', 'B-D', 'D-B', 'B-E', 'E-B', 'C-D', 'D-C', 'C-F', 'F-C', 'C-G', 'G-C',\ 'D-E', 'E-D', 'D-G', 'G-D', 'D-H', 'H-D', 'E-H', 'H-E', 'F-G', 'G-F', 'F-I', 'I-F', 'G-H',\ 'H-G', 'G-J', 'J-G', 'G-K', 'K-G', 'H-K', 'K-H', 'I-J', 'J-I', 'I-L', 'L-I', 'J-K', 'K-J',\ 'J-L', 'L-J', 'J-M', 'M-J', 'K-M', 'M-K'], [('A', 'L', 600), ('A', 'M', 400),\ ('B', 'L', 300), ('B', 'M', 400)]) In order: The vertice list, edge list and the OD list. Vertices -> ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M'] Edges -> ['A-B', 'B-A', 'A-C', 'C-A', 'A-D', 'D-A', 'B-D', 'D-B', 'B-E', 'E-B', 'C-D', 'D-C', 'C-F', 'F-C', 'C-G', 'G-C', 'D-E', 'E-D', 'D-G', 'G-D', 'D-H', 'H-D', 'E-H', 'H-E', 'F-G', 'G-F', 'F-I', 'I-F', 'G-H', 'H-G', 'G-J', 'J-G', 'G-K', 'K-G', 'H-K', 'K-H', 'I-J', 'J-I', 'I-L', 'L-I', 'J-K', 'K-J', 'J-L', 'L-J', 'J-M', 'M-J', 'K-M', 'M-K'] OD -> [('A', 'L', 600), ('A', 'M', 400), ('B', 'L', 300), ('B', 'M', 400)] """ vertices = [] edges = [] functions = {} od_list = [] for line in open(graph_file, 'r'): taglist = string.split(line) if taglist[0] == 'function': variables = [] variables = taglist[2].replace("(", "") variables = variables.replace(")", "") variables = variables.split(",") functions[taglist[1]] = [taglist[3], variables] elif taglist[0] == 'node': vertices.append(Node(taglist[1])) elif taglist[0] == 'dedge' or taglist[0] == 'edge': constants = [] cost_formula = "" freeflow_cost = 0 constant_acc = 0 if len(taglist) > 5: i = 5 while i <= (len(taglist) - 1): constants.append(taglist[i]) i += 1 parser = Parser() ##[4] is function name.[0] is expression exp = parser.parse(functions[taglist[4]][0]) LV = exp.variables() buffer_LV = [] for l in LV: if l not in functions[taglist[4]][1]: constant_acc += 1 buffer_LV.append(l) #check if the formula has any parameters(variables) flag = False for v in functions[taglist[4]][1]: if v in LV: flag = True buffer_dic = {} i = 0 for index in range(constant_acc): buffer_dic[buffer_LV[index]] = float(constants[index]) i = 1 if not flag: freeflow_cost = exp.evaluate(buffer_dic) cost_formula = str(freeflow_cost) elif is_number(functions[taglist[4]][0]): freeflow_cost = float(functions[taglist[4]][0]) cost_fomula = functions[taglist[4]][0] else: exp = exp.simplify(buffer_dic) cost_formula = exp.toString() exp = Parser() cost_formula2 = "(" + cost_formula + ") + flow" exp = exp.parse(cost_formula2) freeflow_cost = exp.evaluate({'f': 0, 'flow': flow}) # Hardcoded edges.append(Edge(taglist[2], taglist[3], freeflow_cost, cost_formula)) if taglist[0] == 'edge': edges.append(Edge(taglist[3], taglist[2], freeflow_cost, cost_formula)) else: cost_formula = "" freeflow_cost = 0 parser = Parser() if is_number(functions[taglist[4]][0]): cost_formula = functions[taglist[4]][0] freeflow_cost = float(functions[taglist[4]][0]) else: exp = parser.parse(functions[taglist[4]][0]) cost_formula = exp.toString() cost_formula2 = "(" + cost_formula + ") + flow" exp = exp.parse(cost_formula2) freeflow_cost = exp.evaluate({'f': 0, 'flow': flow}) # hardcoded edges.append(Edge(taglist[2], taglist[3], freeflow_cost, cost_formula)) edges.append(Edge(taglist[3], taglist[2], freeflow_cost, cost_formula)) elif taglist[0] == 'od': od_list.append((taglist[2], taglist[3], int(taglist[4]))) ''' Print edges but there are too many lines to be printed!! ''' if print_edges: for e in edges: print("Edge " + str(e.start) + "-" + str(e.end) + " has length: " + str(e.length)) return vertices, edges, od_list
def test_parser(self): parser = Parser() #parser and variables self.assertEqual(parser.parse('pow(x,y)').variables(), ['x','y']) self.assertEqual(parser.parse('pow(x,y)').symbols(), ['pow','x','y']) #checking if '"a b"' could be a variable (using it in sql) self.assertEqual(parser.parse('"a b"*2').evaluate({'"a b"':2}),4) #evaluate self.assertExactEqual(parser.parse('1').evaluate({}), 1) self.assertExactEqual(parser.parse('a').evaluate({'a': 2}), 2) self.assertExactEqual(parser.parse('2 * 3').evaluate({}), 6) self.assertExactEqual(parser.parse(u'2 \u2219 3').evaluate({}), 6) self.assertExactEqual(parser.parse(u'2 \u2022 3').evaluate({}), 6) self.assertExactEqual(parser.parse('2 ^ x').evaluate({'x': 3}), 8.0) self.assertExactEqual(parser.parse('2 ** x').evaluate({'x': 3}), 8.0) self.assertExactEqual(parser.parse('-1.E2 ** x + 2.0E2').evaluate({'x': 1}), 100.0) self.assertEqual(parser.parse('x < 3').evaluate({'x': 3}), False) self.assertEqual(parser.parse('x < 3').evaluate({'x': 2}), True) self.assertEqual(parser.parse('x <= 3').evaluate({'x': 3}), True) self.assertEqual(parser.parse('x <= 3').evaluate({'x': 4}), False) self.assertEqual(parser.parse('x > 3').evaluate({'x': 4}), True) self.assertEqual(parser.parse('x >= 3').evaluate({'x': 3}), True) self.assertExactEqual(parser.parse('2 * x + 1').evaluate({'x': 3}), 7) self.assertExactEqual(parser.parse('2 + 3 * x').evaluate({'x': 4}), 14) self.assertExactEqual(parser.parse('(2 + 3) * x').evaluate({'x': 4}), 20) self.assertExactEqual(parser.parse('2-3^x').evaluate({'x': 4}), -79.0) self.assertExactEqual(parser.parse('-2-3^x').evaluate({'x': 4}), -83.0) self.assertExactEqual(parser.parse('-3^x').evaluate({'x': 4}), -81.0) self.assertExactEqual(parser.parse('(-3)^x').evaluate({'x': 4}), 81.0) self.assertExactEqual(parser.parse('2-3**x').evaluate({'x': 4}), -79.0) self.assertExactEqual(parser.parse('-2-3**x').evaluate({'x': 4}), -83.0) self.assertExactEqual(parser.parse('-3**x').evaluate({'x': 4}), -81.0) self.assertExactEqual(parser.parse('(-3)**x').evaluate({'x': 4}), 81.0) self.assertExactEqual(parser.parse('2*x + y').evaluate({'x': 4, 'y': 1}), 9) self.assertEqual(parser.parse("x||y").evaluate({'x': 'hello ', 'y': 'world'}), 'hello world') self.assertEqual(parser.parse("'x'||'y'").evaluate({}), 'xy') self.assertEqual(parser.parse("'x'=='x'").evaluate({}), True) self.assertEqual(parser.parse("(a+b)==c").evaluate({'a': 1, 'b': 2, 'c': 3}), True) self.assertEqual(parser.parse("(a+b)!=c").evaluate({'a': 1, 'b': 2, 'c': 3}), False) self.assertEqual(parser.parse("(a^2-b^2)==((a+b)*(a-b))").evaluate({'a': 4859, 'b': 13150}), True) self.assertEqual(parser.parse("(a^2-b^2+1)==((a+b)*(a-b))").evaluate({'a': 4859, 'b': 13150}), False) self.assertEqual(parser.parse("(a**2-b**2)==((a+b)*(a-b))").evaluate({'a': 4859, 'b': 13150}), True) self.assertEqual(parser.parse("(a**2-b**2+1)==((a+b)*(a-b))").evaluate({'a': 4859, 'b': 13150}), False) self.assertExactEqual(parser.parse("x/((x+y))").simplify({}).evaluate({'x':1, 'y':1}), 0.5) self.assertExactEqual(parser.parse('origin+2.0').evaluate({'origin': 1.0}), 3.0) #functions self.assertExactEqual(parser.parse('pyt(2 , 0)').evaluate({}), 2.0) self.assertEqual(parser.parse("concat('Hello',' ','world')").evaluate({}),'Hello world') self.assertExactEqual(parser.parse('if(a>b,5,6)').evaluate({'a':8,'b':3}),5) self.assertExactEqual(parser.parse('if(a,b,c)').evaluate({'a':None,'b':1,'c':3}),3) #log with base or natural log self.assertExactEqual(parser.parse('log(16,2)').evaluate({}), 4.0) self.assertExactEqual(parser.parse('log(E^100)').evaluate({}), 100.0) self.assertExactEqual(parser.parse('log(E**100)').evaluate({}), 100.0) # test substitute expr = parser.parse('2 * x + 1') expr2 = expr.substitute('x', '4 * x') # ((2*(4*x))+1) self.assertExactEqual(expr2.evaluate({'x': 3}), 25) # test simplify expr = parser.parse('x * (y * atan(1))').simplify({'y': 4}) self.assertIn('x*3.141592', expr.toString()) self.assertExactEqual(expr.evaluate({'x': 2}), 6.283185307179586) # test toString with string constant expr = parser.parse("'a'=='b'") self.assertIn("'a'=='b'",expr.toString()) self.assertIn("'a'=='b'", "%s" % expr) expr = parser.parse("concat('a\n','\n','\rb')=='a\n\n\rb'") self.assertEqual(expr.evaluate({}),True) expr = parser.parse("a==''") self.assertEqual(expr.evaluate({'a':''}),True) #test toString with an external function expr=parser.parse("myExtFn(a,b,c,1.51,'ok')") self.assertEqual(expr.substitute("a",'first').toString(),"myExtFn(first,b,c,1.51,'ok')") # test variables expr = parser.parse('x * (y * atan(1))') self.assertEqual(expr.variables(), ['x', 'y']) self.assertEqual(expr.simplify({'y': 4}).variables(), ['x']) # list operations self.assertEqual(parser.parse('a, 3').evaluate({'a': [1, 2]}), [1, 2, 3])
def __init__(self, exp): p = Parser() self.expression = p.parse(exp) self.var = self.expression.variables() self.var.sort()
def test_decimals(self): parser = Parser() self.assertExactEqual(parser.parse(".1").evaluate({}), parser.parse("0.1").evaluate({})) self.assertExactEqual(parser.parse(".1*.2").evaluate({}), parser.parse("0.1*0.2").evaluate({})) self.assertExactEqual(parser.parse(".5^3").evaluate({}), float(0.125)) self.assertExactEqual(parser.parse("16^.5").evaluate({}), 4.0) self.assertExactEqual(parser.parse(".5**3").evaluate({}), float(0.125)) self.assertExactEqual(parser.parse("16**.5").evaluate({}), 4.0) self.assertExactEqual(parser.parse("8300*.8").evaluate({}), 6640.0) self.assertExactEqual(parser.parse("1E3*2.0").evaluate({}), 2000.0) self.assertExactEqual(parser.parse("-1e3*2.0").evaluate({}), -2000.0) self.assertExactEqual(parser.parse("-1E3*2.E2").evaluate({}), -200000.0) with self.assertRaises(ValueError): parser.parse("..5").evaluate({})
class ParserTestCase(unittest.TestCase): def setUp(self): self.parser = Parser() def test_parser(self): parser = Parser() #parser and variables self.assertEqual(parser.parse('lulu(x,y)').variables(), ['lulu','x','y']) #evaluate self.assertEqual(parser.parse('2 * 3').evaluate({}), 6) self.assertEqual(parser.parse('2 ^ x').evaluate({'x': 3}), 8) self.assertEqual(parser.parse('2 * x + 1').evaluate({'x': 3}), 7) self.assertEqual(parser.parse('2 + 3 * x').evaluate({'x': 4}), 14) self.assertEqual(parser.parse('(2 + 3) * x').evaluate({'x': 4}), 20) self.assertEqual(parser.parse('2-3^x').evaluate({'x': 4}), -79) self.assertEqual(parser.parse('-2-3^x').evaluate({'x': 4}), -83) self.assertEqual(parser.parse('-3^x').evaluate({'x': 4}), -81) self.assertEqual(parser.parse('(-3)^x').evaluate({'x': 4}), 81) self.assertEqual(parser.parse('2*x + y').evaluate({'x': 4, 'y': 1}), 9) self.assertEqual(parser.parse("x||y").evaluate({'x': 'hello ', 'y': 'world'}), 'hello world') self.assertEqual(parser.parse("'x'||'y'").evaluate({}), 'xy') #functions self.assertEqual(parser.parse('pyt(2 , 0)').evaluate({}),2) self.assertEqual(parser.parse("concat('Hello',' ','world')").evaluate({}),'Hello world') #external function self.assertEqual(parser.parse('testFunction(x , y)').evaluate({"x":2,"y":3,"testFunction":testFunction}),13) # test substitute expr = parser.parse('2 * x + 1') expr2 = expr.substitute('x', '4 * x') # ((2*(4*x))+1) self.assertEqual(expr2.evaluate({'x': 3}), 25) # test simplify expr = parser.parse('x * (y * atan(1))').simplify({'y': 4}) self.assertIn('x*3.141592', expr.toString()) self.assertEqual(expr.evaluate({'x': 2}), 6.283185307179586) # test variables expr = parser.parse('x * (y * atan(1))') self.assertEqual(expr.variables(), ['x', 'y']) self.assertEqual(expr.simplify({'y': 4}).variables(), ['x']) def test_consts(self): # self.assertEqual(self.parser.parse("PI ").variables(), [""]) self.assertEqual(self.parser.parse("PI").variables(), []) self.assertEqual(self.parser.parse("PI ").variables(), []) self.assertEqual(self.parser.parse("E ").variables(), []) self.assertEqual(self.parser.parse(" E").variables(), []) self.assertEqual(self.parser.parse("E").variables(), []) self.assertEqual(self.parser.parse("E+1").variables(), []) self.assertEqual(self.parser.parse("E / 1").variables(), []) self.assertEqual(self.parser.parse("sin(PI)+E").variables(), []) def test_parsing_e_and_pi(self): self.assertEqual(self.parser.parse('Pie').variables(), ["Pie"]) self.assertEqual(self.parser.parse('PIe').variables(), ["PIe"]) self.assertEqual(self.parser.parse('Eval').variables(), ["Eval"]) self.assertEqual(self.parser.parse('Eval1').variables(), ["Eval1"]) self.assertEqual(self.parser.parse('EPI').variables(), ["EPI"]) self.assertEqual(self.parser.parse('PIE').variables(), ["PIE"]) self.assertEqual(self.parser.parse('Engage').variables(), ["Engage"]) self.assertEqual(self.parser.parse('Engage * PIE').variables(), ["Engage", "PIE"]) self.assertEqual(self.parser.parse('Engage_').variables(), ["Engage_"]) self.assertEqual(self.parser.parse('Engage1').variables(), ["Engage1"]) self.assertEqual(self.parser.parse('E1').variables(), ["E1"]) self.assertEqual(self.parser.parse('PI2').variables(), ["PI2"]) self.assertEqual(self.parser.parse('(E1 + PI)').variables(), ["E1"]) self.assertEqual(self.parser.parse('E1_').variables(), ["E1_"]) self.assertEqual(self.parser.parse('E_').variables(), ["E_"]) def test_evaluating_consts(self): self.assertEqual(self.parser.evaluate("Engage1", variables={"Engage1": 2}), 2) self.assertEqual(self.parser.evaluate("Engage1 + 1", variables={"Engage1": 1}), 2)
def test_parser(self): parser = Parser() #parser and variables self.assertEqual(parser.parse('lulu(x,y)').variables(), ['lulu','x','y']) #evaluate self.assertEqual(parser.parse('2 * 3').evaluate({}), 6) self.assertEqual(parser.parse('2 ^ x').evaluate({'x': 3}), 8) self.assertEqual(parser.parse('2 * x + 1').evaluate({'x': 3}), 7) self.assertEqual(parser.parse('2 + 3 * x').evaluate({'x': 4}), 14) self.assertEqual(parser.parse('(2 + 3) * x').evaluate({'x': 4}), 20) self.assertEqual(parser.parse('2-3^x').evaluate({'x': 4}), -79) self.assertEqual(parser.parse('-2-3^x').evaluate({'x': 4}), -83) self.assertEqual(parser.parse('-3^x').evaluate({'x': 4}), -81) self.assertEqual(parser.parse('(-3)^x').evaluate({'x': 4}), 81) self.assertEqual(parser.parse('2*x + y').evaluate({'x': 4, 'y': 1}), 9) self.assertEqual(parser.parse("x||y").evaluate({'x': 'hello ', 'y': 'world'}), 'hello world') self.assertEqual(parser.parse("'x'||'y'").evaluate({}), 'xy') #functions self.assertEqual(parser.parse('pyt(2 , 0)').evaluate({}),2) self.assertEqual(parser.parse("concat('Hello',' ','world')").evaluate({}),'Hello world') #external function self.assertEqual(parser.parse('testFunction(x , y)').evaluate({"x":2,"y":3,"testFunction":testFunction}),13) # test substitute expr = parser.parse('2 * x + 1') expr2 = expr.substitute('x', '4 * x') # ((2*(4*x))+1) self.assertEqual(expr2.evaluate({'x': 3}), 25) # test simplify expr = parser.parse('x * (y * atan(1))').simplify({'y': 4}) self.assertIn('x*3.141592', expr.toString()) self.assertEqual(expr.evaluate({'x': 2}), 6.283185307179586) # test variables expr = parser.parse('x * (y * atan(1))') self.assertEqual(expr.variables(), ['x', 'y']) self.assertEqual(expr.simplify({'y': 4}).variables(), ['x'])
class ParserTestCase(unittest.TestCase): def setUp(self): self.parser = Parser() def assertExactEqual(self, a, b): self.assertEqual(type(a), type(b)) self.assertEqual(a, b) def test_parser(self): parser = Parser() #parser and variables self.assertEqual(parser.parse('pow(x,y)').variables(), ['x','y']) self.assertEqual(parser.parse('pow(x,y)').symbols(), ['pow','x','y']) #checking if '"a b"' could be a variable (using it in sql) self.assertEqual(parser.parse('"a b"*2').evaluate({'"a b"':2}),4) #evaluate self.assertExactEqual(parser.parse('1').evaluate({}), 1) self.assertExactEqual(parser.parse('a').evaluate({'a': 2}), 2) self.assertExactEqual(parser.parse('2 * 3').evaluate({}), 6) self.assertExactEqual(parser.parse(u'2 \u2219 3').evaluate({}), 6) self.assertExactEqual(parser.parse(u'2 \u2022 3').evaluate({}), 6) self.assertExactEqual(parser.parse('2 ^ x').evaluate({'x': 3}), 8.0) self.assertExactEqual(parser.parse('2 ** x').evaluate({'x': 3}), 8.0) self.assertExactEqual(parser.parse('-1.E2 ** x + 2.0E2').evaluate({'x': 1}), 100.0) self.assertEqual(parser.parse('x < 3').evaluate({'x': 3}), False) self.assertEqual(parser.parse('x < 3').evaluate({'x': 2}), True) self.assertEqual(parser.parse('x <= 3').evaluate({'x': 3}), True) self.assertEqual(parser.parse('x <= 3').evaluate({'x': 4}), False) self.assertEqual(parser.parse('x > 3').evaluate({'x': 4}), True) self.assertEqual(parser.parse('x >= 3').evaluate({'x': 3}), True) self.assertExactEqual(parser.parse('2 * x + 1').evaluate({'x': 3}), 7) self.assertExactEqual(parser.parse('2 + 3 * x').evaluate({'x': 4}), 14) self.assertExactEqual(parser.parse('(2 + 3) * x').evaluate({'x': 4}), 20) self.assertExactEqual(parser.parse('2-3^x').evaluate({'x': 4}), -79.0) self.assertExactEqual(parser.parse('-2-3^x').evaluate({'x': 4}), -83.0) self.assertExactEqual(parser.parse('-3^x').evaluate({'x': 4}), -81.0) self.assertExactEqual(parser.parse('(-3)^x').evaluate({'x': 4}), 81.0) self.assertExactEqual(parser.parse('2-3**x').evaluate({'x': 4}), -79.0) self.assertExactEqual(parser.parse('-2-3**x').evaluate({'x': 4}), -83.0) self.assertExactEqual(parser.parse('-3**x').evaluate({'x': 4}), -81.0) self.assertExactEqual(parser.parse('(-3)**x').evaluate({'x': 4}), 81.0) self.assertExactEqual(parser.parse('2*x + y').evaluate({'x': 4, 'y': 1}), 9) self.assertEqual(parser.parse("x||y").evaluate({'x': 'hello ', 'y': 'world'}), 'hello world') self.assertEqual(parser.parse("'x'||'y'").evaluate({}), 'xy') self.assertEqual(parser.parse("'x'=='x'").evaluate({}), True) self.assertEqual(parser.parse("(a+b)==c").evaluate({'a': 1, 'b': 2, 'c': 3}), True) self.assertEqual(parser.parse("(a+b)!=c").evaluate({'a': 1, 'b': 2, 'c': 3}), False) self.assertEqual(parser.parse("(a^2-b^2)==((a+b)*(a-b))").evaluate({'a': 4859, 'b': 13150}), True) self.assertEqual(parser.parse("(a^2-b^2+1)==((a+b)*(a-b))").evaluate({'a': 4859, 'b': 13150}), False) self.assertEqual(parser.parse("(a**2-b**2)==((a+b)*(a-b))").evaluate({'a': 4859, 'b': 13150}), True) self.assertEqual(parser.parse("(a**2-b**2+1)==((a+b)*(a-b))").evaluate({'a': 4859, 'b': 13150}), False) self.assertExactEqual(parser.parse("x/((x+y))").simplify({}).evaluate({'x':1, 'y':1}), 0.5) self.assertExactEqual(parser.parse('origin+2.0').evaluate({'origin': 1.0}), 3.0) #functions self.assertExactEqual(parser.parse('pyt(2 , 0)').evaluate({}), 2.0) self.assertEqual(parser.parse("concat('Hello',' ','world')").evaluate({}),'Hello world') self.assertExactEqual(parser.parse('if(a>b,5,6)').evaluate({'a':8,'b':3}),5) self.assertExactEqual(parser.parse('if(a,b,c)').evaluate({'a':None,'b':1,'c':3}),3) #log with base or natural log self.assertExactEqual(parser.parse('log(16,2)').evaluate({}), 4.0) self.assertExactEqual(parser.parse('log(E^100)').evaluate({}), 100.0) self.assertExactEqual(parser.parse('log(E**100)').evaluate({}), 100.0) # test substitute expr = parser.parse('2 * x + 1') expr2 = expr.substitute('x', '4 * x') # ((2*(4*x))+1) self.assertExactEqual(expr2.evaluate({'x': 3}), 25) # test simplify expr = parser.parse('x * (y * atan(1))').simplify({'y': 4}) self.assertIn('x*3.141592', expr.toString()) self.assertExactEqual(expr.evaluate({'x': 2}), 6.283185307179586) # test toString with string constant expr = parser.parse("'a'=='b'") self.assertIn("'a'=='b'",expr.toString()) self.assertIn("'a'=='b'", "%s" % expr) expr = parser.parse("concat('a\n','\n','\rb')=='a\n\n\rb'") self.assertEqual(expr.evaluate({}),True) expr = parser.parse("a==''") self.assertEqual(expr.evaluate({'a':''}),True) #test toString with an external function expr=parser.parse("myExtFn(a,b,c,1.51,'ok')") self.assertEqual(expr.substitute("a",'first').toString(),"myExtFn(first,b,c,1.51,'ok')") # test variables expr = parser.parse('x * (y * atan(1))') self.assertEqual(expr.variables(), ['x', 'y']) self.assertEqual(expr.simplify({'y': 4}).variables(), ['x']) # list operations self.assertEqual(parser.parse('a, 3').evaluate({'a': [1, 2]}), [1, 2, 3]) def test_consts(self): # self.assertEqual(self.parser.parse("PI ").variables(), [""]) self.assertEqual(self.parser.parse("PI").variables(), []) self.assertEqual(self.parser.parse("PI ").variables(), []) self.assertEqual(self.parser.parse("E ").variables(), []) self.assertEqual(self.parser.parse(" E").variables(), []) self.assertEqual(self.parser.parse("E").variables(), []) self.assertEqual(self.parser.parse("E+1").variables(), []) self.assertEqual(self.parser.parse("E / 1").variables(), []) self.assertEqual(self.parser.parse("sin(PI)+E").variables(), []) def test_parsing_e_and_pi(self): self.assertEqual(self.parser.parse('Pie').variables(), ["Pie"]) self.assertEqual(self.parser.parse('PIe').variables(), ["PIe"]) self.assertEqual(self.parser.parse('Eval').variables(), ["Eval"]) self.assertEqual(self.parser.parse('Eval1').variables(), ["Eval1"]) self.assertEqual(self.parser.parse('EPI').variables(), ["EPI"]) self.assertEqual(self.parser.parse('PIE').variables(), ["PIE"]) self.assertEqual(self.parser.parse('Engage').variables(), ["Engage"]) self.assertEqual(self.parser.parse('Engage * PIE').variables(), ["Engage", "PIE"]) self.assertEqual(self.parser.parse('Engage_').variables(), ["Engage_"]) self.assertEqual(self.parser.parse('Engage1').variables(), ["Engage1"]) self.assertEqual(self.parser.parse('E1').variables(), ["E1"]) self.assertEqual(self.parser.parse('PI2').variables(), ["PI2"]) self.assertEqual(self.parser.parse('(E1 + PI)').variables(), ["E1"]) self.assertEqual(self.parser.parse('E1_').variables(), ["E1_"]) self.assertEqual(self.parser.parse('E_').variables(), ["E_"]) def test_evaluating_consts(self): self.assertExactEqual(self.parser.evaluate("Engage1", variables={"Engage1": 2}), 2) self.assertExactEqual(self.parser.evaluate("Engage1 + 1", variables={"Engage1": 1}), 2) def test_custom_functions(self): parser = Parser() def testFunction0(): return 13 def testFunction1(a): return 2*a+9 def testFunction2(a,b): return 2*a+3*b # zero argument functions don't currently work # self.assertEqual(parser # .parse('testFunction()') # .evaluate({"testFunction":testFunction0}),13) self.assertExactEqual(parser .parse('testFunction(x)') .evaluate({"x":2,"testFunction":testFunction1}),13) self.assertExactEqual(parser .parse('testFunction(x , y)') .evaluate({"x":2,"y":3,"testFunction":testFunction2}),13) # Add some "built-in" functions def mean(*xs): return sum(xs) / len(xs) parser.functions['mean'] = mean def counter(initial): class nonlocals: x = initial def count(increment): nonlocals.x += increment return nonlocals.x return count parser.functions['count'] = counter(0) self.assertEqual(parser.parse("mean(xs)").variables(), ["xs"]) self.assertEqual(parser.parse("mean(xs)").symbols(), ["mean", "xs"]) self.assertEqual(parser.evaluate("mean(xs)", variables={"xs": [1, 2, 3]}), 2) self.assertExactEqual(parser.evaluate("count(inc)", variables={"inc": 5}), 5) self.assertExactEqual(parser.evaluate("count(inc)", variables={"inc": 5}), 10) def test_decimals(self): parser = Parser() self.assertExactEqual(parser.parse(".1").evaluate({}), parser.parse("0.1").evaluate({})) self.assertExactEqual(parser.parse(".1*.2").evaluate({}), parser.parse("0.1*0.2").evaluate({})) self.assertExactEqual(parser.parse(".5^3").evaluate({}), float(0.125)) self.assertExactEqual(parser.parse("16^.5").evaluate({}), 4.0) self.assertExactEqual(parser.parse(".5**3").evaluate({}), float(0.125)) self.assertExactEqual(parser.parse("16**.5").evaluate({}), 4.0) self.assertExactEqual(parser.parse("8300*.8").evaluate({}), 6640.0) self.assertExactEqual(parser.parse("1E3*2.0").evaluate({}), 2000.0) self.assertExactEqual(parser.parse("-1e3*2.0").evaluate({}), -2000.0) self.assertExactEqual(parser.parse("-1E3*2.E2").evaluate({}), -200000.0) with self.assertRaises(ValueError): parser.parse("..5").evaluate({})
class Curse(): def __init__(self): self.stdscr = curses.initscr() self.WIDTH = curses.COLS self.HEIGHT = curses.LINES # dont write on screen and dont wait for enter curses.noecho() curses.cbreak() curses.curs_set(False) # no blinking curses.start_color() # colors # epic keys self.stdscr.keypad(True) self.stdscr = curses.newwin(self.HEIGHT-1,self.WIDTH,0,0) self.bottom = curses.newwin(1,self.WIDTH,self.HEIGHT-1,0) self.bar(default_items) curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLACK) if curses.has_colors(): curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK) curses.init_pair(3, curses.COLOR_YELLOW, curses.COLOR_BLACK) curses.init_pair(4, curses.COLOR_GREEN, curses.COLOR_BLACK) curses.init_pair(5, curses.COLOR_CYAN, curses.COLOR_BLACK) self.grapher = Grapher(self.stdscr,self.WIDTH,self.HEIGHT) self.painter = Painter(self.stdscr,self.WIDTH,self.HEIGHT) self.parser = Parser() self.command_hist = [] self.command_indx = -1 def clear(self): self.stdscr.clear() self.stdscr.refresh() def quit(self): # kill it curses.nocbreak() self.stdscr.keypad(False) curses.echo() curses.endwin() def test(self): self.clear() self.stdscr.addstr(0,0,'\nthis screen is {} wide and {} tall'.format(self.WIDTH,self.HEIGHT)) if curses.has_colors(): self.stdscr.addstr('\nthis screen should support color') for i in range(1,6): self.stdscr.addstr('\n' + str(i) , curses.color_pair(i)) else: self.stdscr.addstr('\nthis screen does not support color') self.stdscr.refresh() def bar(self,items): def make_el(msg): l = len(msg) if l < 7: msg += ' '*(7-l) self.bottom.addstr(msg[0].upper(),curses.A_STANDOUT) self.bottom.addstr(msg[1:6].lower() + ' ') self.bottom.clear() self.bottom.move(0,1) # to-do enforce max amount of menu elements disp ... if more :^) for msg in items[1:]: make_el(msg) self.bottom.move(0,self.WIDTH-len(items[0])-1) self.bottom.addstr(items[0].upper(),curses.A_BOLD) self.bottom.refresh() def prompt(self,text,cond=lambda x: x): while True: self.bottom.clear() self.bottom.move(0,1) self.bottom.addstr(text) curses.curs_set(True) curses.echo() s = self.bottom.getstr(0,len(text)+2) if cond(s): curses.noecho() curses.curs_set(False) return s def func_prompt(self,text="f(x) = "): self.bottom.clear() self.bottom.move(0,1) self.bottom.addstr(text) curses.curs_set(True) curses.echo() while True: fx = self.bottom.getstr(0,len(text)+2).decode(encoding="utf-8") if fx == 'q': return None self.command_hist.append(fx) self.command_indx += 1 try: expr = self.parser.parse(fx) if expr.variables() == ['x']: curses.noecho() curses.curs_set(False) return expr except: for _ in range(2): self.bottom.clear() self.bottom.move(0,1) self.bottom.addstr('TRY AGAIN ',curses.A_STANDOUT) self.bottom.refresh() time.sleep(.1) self.bottom.clear() self.bottom.move(0,1) self.bottom.addstr('TRY AGAIN ') time.sleep(.1) self.bottom.refresh() def func_hist(self,up_down): # 0 is up, 1 is down print(no) def graph(self): self.stdscr.clear() self.bar(graph_menu) self.grapher.border() while True: c = self.stdscr.getch() if c == ord('g'): self.grapher.border() #elif c == ord('t'): # #self.grapher.plot([0,1,2,3,4,5,6,7,8,9,10,11],[0,1,2,3,4,5,6,7,8,9,10,11],col=2) # xs = [x for x in range(0,self.WIDTH)] # ys = [x**2//(self.WIDTH**2//self.HEIGHT+1) for x in xs] # self.grapher.plot(xs,ys,col=3) elif c == ord('f'): fx = self.func_prompt() self.bar(graph_menu) if fx is not None: # graph the function xs = [x for x in range(0,self.WIDTH)] ys = [int(fx.evaluate({'x': x})) for x in xs] self.grapher.plot(xs,ys,col=4) elif c == ord('c'): self.clear() self.grapher.border() elif c == ord('q'): #self.clear() self.bottom.clear() self.bar(default_items) break elif c == curses.KEY_UP: # go up if self.command_indx < len(self.command_hist) and self.command_indx >= 0: self.bottom.addstr(self.command_hist[self.command_indx]) self.command_indx -= 1 elif c == curses.KEY_DOWN: # go down self.command_indx += 1 if self.command_indx < len(self.command_hist): self.bottom.addstr(self.command_hist[self.command_indx]) def draw(self): #self.stdscr.clear() self.bottom.clear() self.bar(draw_menu) while True: c = self.stdscr.getch() if c == ord('l'): p1 = int(self.prompt('x1?',self.painter.isint)) p2 = int(self.prompt('y1?',self.painter.isint)) p3 = int(self.prompt('x2?',self.painter.isint)) p4 = int(self.prompt('y2?',self.painter.isint)) ch = self.prompt('paint?',lambda x: True) if ch: self.painter.line(p2,p1,p4,p3,ch[0]) else: self.painter.line(p2,p1,p4,p3) self.bar(draw_menu) elif c == ord('v'): p1 = int(self.prompt('x?',self.painter.isint)) p2 = int(self.prompt('y?',self.painter.isint)) l = int(self.prompt('length?',self.painter.isint)) self.painter.v_line(p2,p1,l) self.bar(draw_menu) elif c == ord('h'): p1 = int(self.prompt('x?',self.painter.isint)) p2 = int(self.prompt('y?',self.painter.isint)) l = int(self.prompt('length?',self.painter.isint)) self.painter.h_line(p2,p1,l) self.bar(draw_menu) elif c == ord('b'): p1 = int(self.prompt('x1?',self.painter.isint)) p2 = int(self.prompt('y1?',self.painter.isint)) w = int(self.prompt('w?',self.painter.isint)) h = int(self.prompt('h?',self.painter.isint)) self.painter.box(p2,p1,h,w) self.bar(draw_menu) elif c == ord('c'): self.clear() elif c == ord('q'): self.bottom.clear() self.bar(default_items) break
def test_parser(self): parser = Parser() self.assertEqual(parser.parse('2 * 3').evaluate({}), 6) self.assertEqual(parser.parse('2 ^ x').evaluate({'x': 3}), 8) self.assertEqual(parser.parse('2 * x + 1').evaluate({'x': 3}), 7) self.assertEqual(parser.parse('2 + 3 * x').evaluate({'x': 4}), 14) self.assertEqual(parser.parse('(2 + 3) * x').evaluate({'x': 4}), 20) self.assertEqual(parser.parse('2-3^x').evaluate({'x': 4}), -79) self.assertEqual(parser.parse('-2-3^x').evaluate({'x': 4}), -83) self.assertEqual(parser.parse('-3^x').evaluate({'x': 4}), -81) self.assertEqual(parser.parse('(-3)^x').evaluate({'x': 4}), 81) self.assertEqual(parser.parse('2*x + y').evaluate({'x': 4, 'y': 1}), 9) # test substitute expr = parser.parse('2 * x + 1') expr2 = expr.substitute('x', '4 * x') # ((2*(4*x))+1) self.assertEqual(expr2.evaluate({'x': 3}), 25) # test simplify expr = parser.parse('x * (y * atan(1))').simplify({'y': 4}) self.assertIn('x*3.141592', expr.toString()) self.assertEqual(expr.evaluate({'x': 2}), 6.283185307179586) # test variables expr = parser.parse('x * (y * atan(1))') self.assertEqual(expr.variables(), ['x', 'y']) self.assertEqual(expr.simplify({'y': 4}).variables(), ['x'])
class ParserTestCase(unittest.TestCase): def setUp(self): self.parser = Parser() def test_parser(self): parser = Parser() #parser and variables self.assertEqual(parser.parse('lulu(x,y)').variables(), ['lulu','x','y']) #evaluate self.assertEqual(parser.parse('2 * 3').evaluate({}), 6) self.assertEqual(parser.parse('2 ^ x').evaluate({'x': 3}), 8) self.assertEqual(parser.parse('2 * x + 1').evaluate({'x': 3}), 7) self.assertEqual(parser.parse('2 + 3 * x').evaluate({'x': 4}), 14) self.assertEqual(parser.parse('(2 + 3) * x').evaluate({'x': 4}), 20) self.assertEqual(parser.parse('2-3^x').evaluate({'x': 4}), -79) self.assertEqual(parser.parse('-2-3^x').evaluate({'x': 4}), -83) self.assertEqual(parser.parse('-3^x').evaluate({'x': 4}), -81) self.assertEqual(parser.parse('(-3)^x').evaluate({'x': 4}), 81) self.assertEqual(parser.parse('2*x + y').evaluate({'x': 4, 'y': 1}), 9) self.assertEqual(parser.parse("x||y").evaluate({'x': 'hello ', 'y': 'world'}), 'hello world') self.assertEqual(parser.parse("'x'||'y'").evaluate({}), 'xy') self.assertEqual(parser.parse("'x'=='x'").evaluate({}), True) self.assertEqual(parser.parse("(a+b)==c").evaluate({'a': 1, 'b': 2, 'c': 3}), True) self.assertEqual(parser.parse("(a+b)!=c").evaluate({'a': 1, 'b': 2, 'c': 3}), False) self.assertEqual(parser.parse("(a^2-b^2)==((a+b)*(a-b))").evaluate({'a': 4859, 'b': 13150}), True) self.assertEqual(parser.parse("(a^2-b^2+1)==((a+b)*(a-b))").evaluate({'a': 4859, 'b': 13150}), False) #functions self.assertEqual(parser.parse('pyt(2 , 0)').evaluate({}),2) self.assertEqual(parser.parse("concat('Hello',' ','world')").evaluate({}),'Hello world') #external function self.assertEqual(parser.parse('testFunction(x , y)').evaluate({"x":2,"y":3,"testFunction":testFunction}),13) # test substitute expr = parser.parse('2 * x + 1') expr2 = expr.substitute('x', '4 * x') # ((2*(4*x))+1) self.assertEqual(expr2.evaluate({'x': 3}), 25) # test simplify expr = parser.parse('x * (y * atan(1))').simplify({'y': 4}) self.assertIn('x*3.141592', expr.toString()) self.assertEqual(expr.evaluate({'x': 2}), 6.283185307179586) # test toString with string constant expr = parser.parse("'a'=='b'") self.assertIn("'a'=='b'",expr.toString()) expr = parser.parse("concat('a\n','\n','\rb')=='a\n\n\rb'") self.assertEqual(expr.evaluate({}),True) #test toString with an external function expr=parser.parse("myExtFn(a,b,c,1.51,'ok')") self.assertEqual(expr.substitute("a",'first').toString(),"myExtFn(first,b,c,1.51,'ok')") # test variables expr = parser.parse('x * (y * atan(1))') self.assertEqual(expr.variables(), ['x', 'y']) self.assertEqual(expr.simplify({'y': 4}).variables(), ['x']) def test_consts(self): # self.assertEqual(self.parser.parse("PI ").variables(), [""]) self.assertEqual(self.parser.parse("PI").variables(), []) self.assertEqual(self.parser.parse("PI ").variables(), []) self.assertEqual(self.parser.parse("E ").variables(), []) self.assertEqual(self.parser.parse(" E").variables(), []) self.assertEqual(self.parser.parse("E").variables(), []) self.assertEqual(self.parser.parse("E+1").variables(), []) self.assertEqual(self.parser.parse("E / 1").variables(), []) self.assertEqual(self.parser.parse("sin(PI)+E").variables(), []) def test_parsing_e_and_pi(self): self.assertEqual(self.parser.parse('Pie').variables(), ["Pie"]) self.assertEqual(self.parser.parse('PIe').variables(), ["PIe"]) self.assertEqual(self.parser.parse('Eval').variables(), ["Eval"]) self.assertEqual(self.parser.parse('Eval1').variables(), ["Eval1"]) self.assertEqual(self.parser.parse('EPI').variables(), ["EPI"]) self.assertEqual(self.parser.parse('PIE').variables(), ["PIE"]) self.assertEqual(self.parser.parse('Engage').variables(), ["Engage"]) self.assertEqual(self.parser.parse('Engage * PIE').variables(), ["Engage", "PIE"]) self.assertEqual(self.parser.parse('Engage_').variables(), ["Engage_"]) self.assertEqual(self.parser.parse('Engage1').variables(), ["Engage1"]) self.assertEqual(self.parser.parse('E1').variables(), ["E1"]) self.assertEqual(self.parser.parse('PI2').variables(), ["PI2"]) self.assertEqual(self.parser.parse('(E1 + PI)').variables(), ["E1"]) self.assertEqual(self.parser.parse('E1_').variables(), ["E1_"]) self.assertEqual(self.parser.parse('E_').variables(), ["E_"]) def test_evaluating_consts(self): self.assertEqual(self.parser.evaluate("Engage1", variables={"Engage1": 2}), 2) self.assertEqual(self.parser.evaluate("Engage1 + 1", variables={"Engage1": 1}), 2)
def test_parser(self): parser = Parser() #parser and variables self.assertEqual(parser.parse('lulu(x,y)').variables(), ['lulu','x','y']) #evaluate self.assertEqual(parser.parse('2 * 3').evaluate({}), 6) self.assertEqual(parser.parse('2 ^ x').evaluate({'x': 3}), 8) self.assertEqual(parser.parse('2 * x + 1').evaluate({'x': 3}), 7) self.assertEqual(parser.parse('2 + 3 * x').evaluate({'x': 4}), 14) self.assertEqual(parser.parse('(2 + 3) * x').evaluate({'x': 4}), 20) self.assertEqual(parser.parse('2-3^x').evaluate({'x': 4}), -79) self.assertEqual(parser.parse('-2-3^x').evaluate({'x': 4}), -83) self.assertEqual(parser.parse('-3^x').evaluate({'x': 4}), -81) self.assertEqual(parser.parse('(-3)^x').evaluate({'x': 4}), 81) self.assertEqual(parser.parse('2*x + y').evaluate({'x': 4, 'y': 1}), 9) self.assertEqual(parser.parse("x||y").evaluate({'x': 'hello ', 'y': 'world'}), 'hello world') self.assertEqual(parser.parse("'x'||'y'").evaluate({}), 'xy') self.assertEqual(parser.parse("'x'=='x'").evaluate({}), True) self.assertEqual(parser.parse("(a+b)==c").evaluate({'a': 1, 'b': 2, 'c': 3}), True) self.assertEqual(parser.parse("(a+b)!=c").evaluate({'a': 1, 'b': 2, 'c': 3}), False) self.assertEqual(parser.parse("(a^2-b^2)==((a+b)*(a-b))").evaluate({'a': 4859, 'b': 13150}), True) self.assertEqual(parser.parse("(a^2-b^2+1)==((a+b)*(a-b))").evaluate({'a': 4859, 'b': 13150}), False) #functions self.assertEqual(parser.parse('pyt(2 , 0)').evaluate({}),2) self.assertEqual(parser.parse("concat('Hello',' ','world')").evaluate({}),'Hello world') #external function self.assertEqual(parser.parse('testFunction(x , y)').evaluate({"x":2,"y":3,"testFunction":testFunction}),13) # test substitute expr = parser.parse('2 * x + 1') expr2 = expr.substitute('x', '4 * x') # ((2*(4*x))+1) self.assertEqual(expr2.evaluate({'x': 3}), 25) # test simplify expr = parser.parse('x * (y * atan(1))').simplify({'y': 4}) self.assertIn('x*3.141592', expr.toString()) self.assertEqual(expr.evaluate({'x': 2}), 6.283185307179586) # test toString with string constant expr = parser.parse("'a'=='b'") self.assertIn("'a'=='b'",expr.toString()) expr = parser.parse("concat('a\n','\n','\rb')=='a\n\n\rb'") self.assertEqual(expr.evaluate({}),True) #test toString with an external function expr=parser.parse("myExtFn(a,b,c,1.51,'ok')") self.assertEqual(expr.substitute("a",'first').toString(),"myExtFn(first,b,c,1.51,'ok')") # test variables expr = parser.parse('x * (y * atan(1))') self.assertEqual(expr.variables(), ['x', 'y']) self.assertEqual(expr.simplify({'y': 4}).variables(), ['x'])
class TestOptimizationAlgorithm(unittest.TestCase): def setUp(self): self.parser = Parser() make_expr = lambda string, start, stop, num_of_val1, num_of_val2: \ [self.parser.parse(string), [start, start], [stop, stop], [num_of_val1, num_of_val2]] self.expressions = [make_expr('x^2 + y^3', -4., 4., 801, 701), make_expr('y^2*sin(x) + 2*y^4', -4., 4., 1001, 901)] self.tests_values = [[[-2., -2.], [1., 2.5], [-1.5, 0]], [[1., 1.], [-1.5, 2.5]]] self.answers_values = [[[-4.0], [16.625], [2.25]], [[2.841], [71.89]]] self.tests_gradient = [[[-2., -2.], [0., -1.5]], [[1.3, -0.5], [-0.5, 1]]] self.answers_gradient = [[[-4., 12.], [0., 6.75]], [[0.0669, -1.9635], [0.8776, 7.0411]]] self.tests_hessian = [[[-2., 1.5]], [[-2, 1.5]]] self.answers_hessian = [[[2., 0, 0, 9.]], [[2.046, -1.248, -1.248, 52.181]]] def testValues(self): for i in range(self.expressions.__len__()): self.opt_alg = OptimizationAlgorithm(*self.expressions[i]) for (test, answer) in zip(self.tests_values[i], self.answers_values[i]): self.assertAlmostEqual(answer, self.opt_alg.value_at(*test), delta=0.1) def testGradient(self): for i in range(self.expressions.__len__()): self.grad_alg = GradientAlgorithm(*self.expressions[i]) for (test, answer) in zip(self.tests_gradient[i], self.answers_gradient[i]): gx, gy = self.grad_alg.get_gradient_at(*test) self.assertAlmostEqual(answer[0], gx, delta=0.1) self.assertAlmostEqual(answer[1], gy, delta=0.1) def testGradientArray(self): for i in range(self.expressions.__len__()): self.grad_alg = GradientAlgorithm(*self.expressions[i]) for (test, answer) in zip(self.tests_gradient[i], self.answers_gradient[i]): grad = self.grad_alg.get_gradient_as_array_at(*test) self.assertAlmostEqual(answer[0], grad[0][0], delta=0.1) self.assertAlmostEqual(answer[1], grad[1][0], delta=0.2) def testHessian(self): for i in range(self.expressions.__len__()): self.grad_alg = GradientAlgorithm(*self.expressions[i]) for (test, answer) in zip(self.tests_hessian[i], self.answers_hessian[i]): gxx, gxy, gyx, gyy = self.grad_alg.get_hessian_at(*test) self.assertAlmostEquals(answer[0], gxx, delta=0.1) self.assertAlmostEquals(answer[1], gxy, delta=0.1) self.assertAlmostEquals(answer[2], gyx, delta=0.1) self.assertAlmostEquals(answer[3], gyy, delta=0.1) def testHessianArray(self): for i in range(self.expressions.__len__()): self.grad_alg = GradientAlgorithm(*self.expressions[i]) for (test, answer) in zip(self.tests_hessian[i], self.answers_hessian[i]): hessian = self.grad_alg.get_hessian_as_array_at(*test) self.assertAlmostEquals(answer[0], hessian[0][0], delta=0.1) self.assertAlmostEquals(answer[1], hessian[0][1], delta=0.1) self.assertAlmostEquals(answer[2], hessian[1][0], delta=0.1) self.assertAlmostEquals(answer[3], hessian[1][1], delta=0.1)
def calculate_hessian(self): self.gxy, self.gxx = np.gradient(self.gx, self.dy, self.dx) self.gyy, self.gyx = np.gradient(self.gy, self.dy, self.dx) def get_gradient_at_id(self, id_x, id_y): return self.gx[id_y][id_x], self.gy[id_y][id_x] def get_hessian_at_id(self, id_x, id_y): return self.gxx[id_y][id_x], self.gxy[id_y][id_x],\ self.gyx[id_y][id_x], self.gyy[id_y][id_x] if __name__ == "__main__": from py_expression_eval import Parser parser = Parser() expr = parser.parse('x^2 + y^3*x') ga = GradientAlgorithm(expr, [-4., -4.], [4., 4.], [801, 801]) print "---------------------------" print "Gradient: " print ga.get_gradient_at(-2., -1.) print ga.get_gradient_as_array_at(-2., -1.) print "---------------------------" print "Hessian: " print ga.get_hessian_at(-2., -1.) print ga.get_hessian_as_array_at(-2., -1.) print "---------------------------" print "Gradient: " print ga.get_gradient_at(1.2, 0.6) print ga.get_gradient_as_array_at(1.2, 0.6) print "---------------------------" print "Hessian: "