diff --git a/expression.py b/expression.py new file mode 100644 index 0000000..949a2a0 --- /dev/null +++ b/expression.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python +# encoding: utf-8 + + +class Expression(object): + """A calculus expression. Today it can andle only expression with numbers later it will be able to manipulate unknown""" + + def __init__(self, exp): + """ Initiate the expression. + + :param exp: the expression. It can be a string or a list of tokens. It can be infix or postfix expression + """ + pass + + # --------------------- + # String parsing + + # @classmethod ???? + def parseExp(self, exp): + """ Parse the expression, ie tranform a string into a list of tokens + + :param exp: The expression + :returns: list of token + + """ + pass + + # --------------------- + # "fix" recognition + + def expressionFix(self, exp): + """ Give the "fix" of an expression + infix -> A + B + prefix -> + A B + postfix -> A B + + + :param exp: the expression + :returns: the "fix" (infix, postfix, prefix) + + """ + pass + + # ---------------------- + # "fix" tranformations + + def toPostfix(self): + """ Transorm the expression into postfix form """ + pass + + def toInfix(self): + """ Tranform the expression into infix form""" + pass + + # --------------------- + # Tools for placing parenthesis in infix notation + + + def needPar(operande, operator, posi = "after"): + """ Says whether or not the operande needs parenthesis + + :param operande: the operande + :param operator: the operator + :param posi: "after"(default) if the operande will be after the operator, "before" othewise + :returns: bollean + """ + pass + + def get_main_op(exp): + """ Gives the main operation of the expression + + :param exp: the expression + :returns: the main operation (+, -, * or /) or 0 if the expression is only one element + + """ + pass + + # --------------------- + # Computing the expression + + def compute(self): + """ Recursive method for computing as a student the expression + :returns: list of steps needed to reach the result + + """ + pass + + def doMath(op, op1, op2): + """Compute "op1 op op2" + + :param op: operator + :param op1: first operande + :param op2: second operande + :returns: string representing the result + + """ + return str(eval(op1 + op + op2)) + +# ----------------------------- +# Reglages pour 'vim' +# vim:set autoindent expandtab tabstop=4 shiftwidth=4: +# cursor: 16 del diff --git a/expression.py.back b/expression.py.back new file mode 100644 index 0000000..75c3e4e --- /dev/null +++ b/expression.py.back @@ -0,0 +1,115 @@ +#!/usr/bin/env python +# encoding: utf-8 + +from generic import Stack +from calculus import isNumber, doMath + + +class Expression(object): + """An arithmetic expression""" + + priority = {"*" : 3, "/": 3, "+": 2, "-":2, "(": 1} + + def __init__(self, exp, fix = "infix"): + """Initiate the expression. + + :param exp: the string representing the expression (infx form by default) + :param fix: form of the expression infix (default) - postfix - prefix + + """ + if fix == "infix": + self._exp_infix = exp + self._token_infix = exp.split(" ") + elif fix == "postfix": + self._token_postfix = exp + else: + print("Pas encore fait!") + + def infixToPostfix(self): + """Convert the infix expression into postfix expression. + """ + #@todo importer les exemples + opStack = Stack() + postfixList = [] + + for token in self._token_infix: + if token == "(": + opStack.push(token) + elif token == ")": + topToken = opStack.pop() + while topToken != "(": + postfixList.append(topToken) + topToken = opStack.pop() + elif token in "+-*/": + while (not opStack.isEmpty()) and (self.priority[opStack.peek()] >= self.priority[token]): + postfixList.append(opStack.pop()) + opStack.push(token) + else: + postfixList.append(token) + + while not opStack.isEmpty(): + postfixList.append(opStack.pop()) + + self._token_postfix = postfixList + self._exp_postfix = " ".join(postfixList) + + def computePostfix(self): + """Compute a postfix expression like a good student + + :returns: list of steps to reach the result (postfix form) + + """ + tokenList = self._token_postfix.copy() + tmpTokenList = [] + # on va chercher les motifs du genre A B + pour les calculer + while len(tokenList) > 2: + #print(tokenList[2]) + if isNumber(tokenList[0]) and isNumber(tokenList[1]) and tokenList[2] in "+-*/": + # S'il y a une opération à faire + op1 = tokenList[0] + op2 = tokenList[1] + token = tokenList[2] + res = doMath(token, op1, op2) + + tmpTokenList.append(res) + + # Comme on vient de faire le calcul, on peut détruire aussi les deux prochains termes + del tokenList[0:3] + else: + tmpTokenList.append(tokenList[0]) + + del tokenList[0] + tmpTokenList += tokenList + + if len(tmpTokenList) > 1: + next_steps = Expression(tmpTokenList, fix = "postfix").computePostfix() + else: + next_steps = tmpTokenList + print(self._exp_postfix) + return [self._exp_postfix] + next_steps + + +def test(exp): + """Make various test on an expression + + """ + print("-------------") + print("Expression ",exp) + expression = Expression(exp) + expression.infixToPostfix() + print(expression.computePostfix()) + +if __name__ == '__main__': + exp = "1 + 3 * 5" + test(exp) + + exp = "2 * 3 * 3 * 5" + test(exp) + + exp = "2 * 3 + 3 * 5" + test(exp) + +# ----------------------------- +# Reglages pour 'vim' +# vim:set autoindent expandtab tabstop=4 shiftwidth=4: +# cursor: 16 del