Start objecting expression
This commit is contained in:
		
							
								
								
									
										277
									
								
								expression.py
									
									
									
									
									
								
							
							
						
						
									
										277
									
								
								expression.py
									
									
									
									
									
								
							| @@ -8,182 +8,185 @@ class Expression(object): | |||||||
|     priority = {"*" : 3, "/": 3, "+": 2, "-":2, "(": 1} |     priority = {"*" : 3, "/": 3, "+": 2, "-":2, "(": 1} | ||||||
|  |  | ||||||
|     def __init__(self, exp): |     def __init__(self, exp): | ||||||
|         """ Initiate the expression. |         """ Initiate the expression | ||||||
|  |  | ||||||
|         :param exp: the expression. It can be a string or a list of tokens. It can be infix or postfix expression |         :param exp: the expression. It can be a string or a list of tokens. It can be infix or postfix expression | ||||||
|         """ |         """ | ||||||
|         self._tokens = {} |         self._exp = exp | ||||||
|         self._strings = {} |  | ||||||
|         if type(exp) == list: |     def simplify(self): | ||||||
|             fix = self.get_fix(exp) |         """ Generator which return steps for computing the expression """ | ||||||
|             self._tokens[fix] = exp |         if self._exp == 0: | ||||||
|         elif type(exp) == str: |             yield "Zero!" | ||||||
|             tokens = self.parseExp(exp) |  | ||||||
|             fix = self.get_fix(tokens) |  | ||||||
|             self._tokens[fix] = tokens |  | ||||||
|             self._strings[fix] = exp |  | ||||||
|         else: |         else: | ||||||
|             raise ValueError("The expression needs to be a string or a list of token") |             self.children = Expression(self._exp - 1) | ||||||
|  |             yield "num: " + str(self._exp) | ||||||
|  |             yield self.children.simplify().next() | ||||||
|  |  | ||||||
|     # --------------------- |     ## --------------------- | ||||||
|     # String parsing |     ## String parsing | ||||||
|  |  | ||||||
|     # @classmethod ???? |     ## @classmethod ???? | ||||||
|     def parseExp(self, exp): |     #def parseExp(self, exp): | ||||||
|         """ Parse the expression, ie tranform a string into a list of tokens |     #    """ Parse the expression, ie tranform a string into a list of tokens | ||||||
|  |  | ||||||
|         :param exp: The expression (a string) |     #    :param exp: The expression (a string) | ||||||
|         :returns: list of token |     #    :returns: list of token | ||||||
|  |  | ||||||
|         """ |     #    """ | ||||||
|         return exp.split(" ") |     #    return exp.split(" ") | ||||||
|  |  | ||||||
|     # --------------------- |     ## --------------------- | ||||||
|     # "fix" recognition |     ## "fix" recognition | ||||||
|  |  | ||||||
|     def get_fix(self, tokens): |     #def get_fix(self, tokens): | ||||||
|         """ Give the "fix" of an expression |     #    """ Give the "fix" of an expression | ||||||
|         infix -> A + B |     #    infix -> A + B | ||||||
|         prefix -> + A B |     #    prefix -> + A B | ||||||
|         postfix -> A B + |     #    postfix -> A B + | ||||||
|  |  | ||||||
|         :param exp: the expression (list of token) |     #    :param exp: the expression (list of token) | ||||||
|         :returns: the "fix" (infix, postfix, prefix) |     #    :returns: the "fix" (infix, postfix, prefix) | ||||||
|  |  | ||||||
|         """ |     #    """ | ||||||
|         if tokens[0] in  "+-*/": |     #    if tokens[0] in  "+-*/": | ||||||
|             return "prefix" |     #        return "prefix" | ||||||
|         elif token[0] not in "+-*/" ans token[1] not in "+-*/": |     #    elif token[0] not in "+-*/" ans token[1] not in "+-*/": | ||||||
|             return "postfix" |     #        return "postfix" | ||||||
|         else: |     #    else: | ||||||
|             return "infix" |     #        return "infix" | ||||||
|  |  | ||||||
|     # ---------------------- |     ## ---------------------- | ||||||
|     # Expressions - tokens getters |     ## Expressions - tokens getters | ||||||
|  |  | ||||||
|     def tokens(self, fix = "infix"): |     #def tokens(self, fix = "infix"): | ||||||
|         """Get the list of tokens with the wanted fix |     #    """Get the list of tokens with the wanted fix | ||||||
|  |  | ||||||
|         :param fix: the fix wanted (infix default) |     #    :param fix: the fix wanted (infix default) | ||||||
|         :returns: list of tokens |     #    :returns: list of tokens | ||||||
|  |  | ||||||
|         """ |     #    """ | ||||||
|         # Si ce fix n'a pas encore été enregistré |     #    # Si ce fix n'a pas encore été enregistré | ||||||
|         if fix not in self._tokens: |     #    if fix not in self._tokens: | ||||||
|             # Il peut venir de la version string |     #        # Il peut venir de la version string | ||||||
|             if fix in self._string: |     #        if fix in self._string: | ||||||
|                 self._tokens[fix] = self.parseExp(self._string[fix]) |     #            self._tokens[fix] = self.parseExp(self._string[fix]) | ||||||
|             # Sinon il faut le calculer à partir d'une autre forme |     #        # Sinon il faut le calculer à partir d'une autre forme | ||||||
|             else: |     #        else: | ||||||
|                 fix_transfo = "to" + fix.capitalize() |     #            fix_transfo = "to" + fix.capitalize() | ||||||
|                 getattr(self,fix_transfo)() |     #            getattr(self,fix_transfo)() | ||||||
|  |  | ||||||
|         return self._tokens[fix] |     #    return self._tokens[fix] | ||||||
|  |  | ||||||
| ##### On en est là,il faudra faire attention à bien vérifier ce que les "to..." enregistre (string ou tokens)   | ###### On en est là,il faudra faire attention à bien vérifier ce que les "to..." enregistre (string ou tokens)   | ||||||
|  |  | ||||||
|     def string(self, fix = "infix"): |     #def string(self, fix = "infix"): | ||||||
|         """Get the string with the wanted fix |     #    """Get the string with the wanted fix | ||||||
|  |  | ||||||
|         :param fix: the fix wanted (infix default) |     #    :param fix: the fix wanted (infix default) | ||||||
|         :returns: the string representing the expression |     #    :returns: the string representing the expression | ||||||
|  |  | ||||||
|         """ |     #    """ | ||||||
|         # Si ce fix n'a pas encore été enregistré |     #    # Si ce fix n'a pas encore été enregistré | ||||||
|         if fix not in self._string: |     #    if fix not in self._string: | ||||||
|             # Il peut venir de la version string |     #        # Il peut venir de la version string | ||||||
|             if fix in self._tokens: |     #        if fix in self._tokens: | ||||||
|                 self._string[fix] = self.parseExp(self._string[fix]) |     #            self._string[fix] = self.parseExp(self._string[fix]) | ||||||
|             # Sinon il faut le calculer à partir d'une autre forme |     #        # Sinon il faut le calculer à partir d'une autre forme | ||||||
|             else: |     #        else: | ||||||
|                 fix_transfo = "to" + fix.capitalize() |     #            fix_transfo = "to" + fix.capitalize() | ||||||
|                 getattr(self,fix_transfo)() |     #            getattr(self,fix_transfo)() | ||||||
|  |  | ||||||
|         return self._string[fix] |     #    return self._string[fix] | ||||||
|      |     # | ||||||
|     # ---------------------- |     ## ---------------------- | ||||||
|     # "fix" tranformations |     ## "fix" tranformations | ||||||
|  |  | ||||||
|     def toPostfix(self): |     #def toPostfix(self): | ||||||
|         """ Transorm the expression into postfix form using the infix form""" |     #    """ Transorm the expression into postfix form using the infix form""" | ||||||
|         pass |     #    pass | ||||||
|  |  | ||||||
|     def toInfix(self): |     #def toInfix(self): | ||||||
|         """ Tranform the expression into infix form using postfix form""" |     #    """ Tranform the expression into infix form using postfix form""" | ||||||
|         pass |     #    pass | ||||||
|  |  | ||||||
|     # --------------------- |     ## --------------------- | ||||||
|     # Tools for placing parenthesis in infix notation |     ## Tools for placing parenthesis in infix notation | ||||||
|  |  | ||||||
|     def needPar(operande, operator, posi = "after"): |     #def needPar(operande, operator, posi = "after"): | ||||||
|         """ Says whether or not the operande needs parenthesis |     #    """ Says whether or not the operande needs parenthesis | ||||||
|  |  | ||||||
|         :param operande: the operande |     #    :param operande: the operande | ||||||
|         :param operator: the operator |     #    :param operator: the operator | ||||||
|         :param posi: "after"(default) if the operande will be after the operator, "before" othewise |     #    :param posi: "after"(default) if the operande will be after the operator, "before" othewise | ||||||
|         :returns: bollean |     #    :returns: bollean | ||||||
|         """ |     #    """ | ||||||
|         if isNumber(operande) and "-" in operande: |     #    if isNumber(operande) and "-" in operande: | ||||||
|             return 1 |     #        return 1 | ||||||
|         elif not isNumber(operande): |     #    elif not isNumber(operande): | ||||||
|             # Si c'est une grande expression ou un chiffre négatif |     #        # Si c'est une grande expression ou un chiffre négatif | ||||||
|             stand_alone = get_main_op(operande) |     #        stand_alone = get_main_op(operande) | ||||||
|             # Si la priorité de l'operande est plus faible que celle de l'opérateur |     #        # Si la priorité de l'operande est plus faible que celle de l'opérateur | ||||||
|             minor_priority = self.priority[get_main_op(operande)] < self.priority[operator] |     #        minor_priority = self.priority[get_main_op(operande)] < self.priority[operator] | ||||||
|             # Si l'opérateur est -/ pour after ou juste / pour before |     #        # Si l'opérateur est -/ pour after ou juste / pour before | ||||||
|             special = (operator in "-/" and posi == "after") or (operator in "/" and posi == "before") |     #        special = (operator in "-/" and posi == "after") or (operator in "/" and posi == "before") | ||||||
|  |  | ||||||
|             return stand_alone and (minor_priority or special) |     #        return stand_alone and (minor_priority or special) | ||||||
|         else: |     #    else: | ||||||
|             return 0 |     #        return 0 | ||||||
|      |     # | ||||||
| # J'aime pas bien cette endroit faudrait que ce soit une méthode qui s'applique uniquement à l'expression en question (self) pas à n'importe quel string, ça serait plus propre. | # J'#aime pas bien cette endroit faudrait que ce soit une méthode qui s'applique uniquement à l'expression en question (self) pas à n'importe quel string, ça serait plus propre. | ||||||
|     def get_main_op(exp): |     #def get_main_op(exp): | ||||||
|         """ Gives the main operation of the expression |     #    """ Gives the main operation of the expression | ||||||
|  |  | ||||||
|         :param exp: the expression |     #    :param exp: the expression | ||||||
|         :returns: the main operation (+, -, * or /) or 0 if the expression is only one element |     #    :returns: the main operation (+, -, * or /) or 0 if the expression is only one element | ||||||
|  |  | ||||||
|         """ |     #    """ | ||||||
|         parStack = Stack() |     #    parStack = Stack() | ||||||
|         tokenList = exp.split(" ") |     #    tokenList = exp.split(" ") | ||||||
|  |  | ||||||
|         if len(tokenList) == 1: |     #    if len(tokenList) == 1: | ||||||
|         # Si l'expression n'est qu'un élément |     #    # Si l'expression n'est qu'un élément | ||||||
|             return 0 |     #        return 0 | ||||||
|  |  | ||||||
|         main_op = [] |     #    main_op = [] | ||||||
|  |  | ||||||
|         for token in tokenList: |     #    for token in tokenList: | ||||||
|             if token == "(": |     #        if token == "(": | ||||||
|                 parStack.push(token) |     #            parStack.push(token) | ||||||
|             elif token == ")": |     #        elif token == ")": | ||||||
|                 parStack.pop() |     #            parStack.pop() | ||||||
|             elif token in "+-*/" and parStack.isEmpty(): |     #        elif token in "+-*/" and parStack.isEmpty(): | ||||||
|                 main_op.append(token) |     #            main_op.append(token) | ||||||
|  |  | ||||||
|         return min(main_op, key = lambda s: priority[s]) |     #    return min(main_op, key = lambda s: priority[s]) | ||||||
|  |  | ||||||
|     # --------------------- |     ## --------------------- | ||||||
|     # Computing the expression |     ## Computing the expression | ||||||
|  |  | ||||||
|     def compute(self): |     #def compute(self): | ||||||
|         """ Recursive method for computing as a student the expression |     #    """ Recursive method for computing as a student the expression | ||||||
|         :returns: list of steps needed to reach the result |     #    :returns: list of steps needed to reach the result | ||||||
|  |  | ||||||
|         """ |     #    """ | ||||||
|         pass |     #    pass | ||||||
|      |     # | ||||||
|     def doMath(op, op1, op2): |     #def doMath(op, op1, op2): | ||||||
|         """Compute "op1 op op2" |     #    """Compute "op1 op op2" | ||||||
|  |  | ||||||
|         :param op: operator |     #    :param op: operator | ||||||
|         :param op1: first operande |     #    :param op1: first operande | ||||||
|         :param op2: second operande |     #    :param op2: second operande | ||||||
|         :returns: string representing the result |     #    :returns: string representing the result | ||||||
|  |  | ||||||
|         """ |     #    """ | ||||||
|         return str(eval(op1 + op + op2)) |     #    return str(eval(op1 + op + op2)) | ||||||
|  |  | ||||||
|  | if __name__ == '__main__': | ||||||
|  |     a = Expression(10) | ||||||
|  |     for i in a.simplify(): | ||||||
|  |         print(i) | ||||||
|  |  | ||||||
| # ----------------------------- | # ----------------------------- | ||||||
| # Reglages pour 'vim' | # Reglages pour 'vim' | ||||||
|   | |||||||
							
								
								
									
										191
									
								
								expression.py_back
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								expression.py_back
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,191 @@ | |||||||
|  | #!/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""" | ||||||
|  |  | ||||||
|  |     priority = {"*" : 3, "/": 3, "+": 2, "-":2, "(": 1} | ||||||
|  |  | ||||||
|  |     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 | ||||||
|  |         """ | ||||||
|  |         self._tokens = {} | ||||||
|  |         self._strings = {} | ||||||
|  |         if type(exp) == list: | ||||||
|  |             fix = self.get_fix(exp) | ||||||
|  |             self._tokens[fix] = exp | ||||||
|  |         elif type(exp) == str: | ||||||
|  |             tokens = self.parseExp(exp) | ||||||
|  |             fix = self.get_fix(tokens) | ||||||
|  |             self._tokens[fix] = tokens | ||||||
|  |             self._strings[fix] = exp | ||||||
|  |         else: | ||||||
|  |             raise ValueError("The expression needs to be a string or a list of token") | ||||||
|  |  | ||||||
|  |     # --------------------- | ||||||
|  |     # String parsing | ||||||
|  |  | ||||||
|  |     # @classmethod ???? | ||||||
|  |     def parseExp(self, exp): | ||||||
|  |         """ Parse the expression, ie tranform a string into a list of tokens | ||||||
|  |  | ||||||
|  |         :param exp: The expression (a string) | ||||||
|  |         :returns: list of token | ||||||
|  |  | ||||||
|  |         """ | ||||||
|  |         return exp.split(" ") | ||||||
|  |  | ||||||
|  |     # --------------------- | ||||||
|  |     # "fix" recognition | ||||||
|  |  | ||||||
|  |     def get_fix(self, tokens): | ||||||
|  |         """ Give the "fix" of an expression | ||||||
|  |         infix -> A + B | ||||||
|  |         prefix -> + A B | ||||||
|  |         postfix -> A B + | ||||||
|  |  | ||||||
|  |         :param exp: the expression (list of token) | ||||||
|  |         :returns: the "fix" (infix, postfix, prefix) | ||||||
|  |  | ||||||
|  |         """ | ||||||
|  |         if tokens[0] in  "+-*/": | ||||||
|  |             return "prefix" | ||||||
|  |         elif token[0] not in "+-*/" ans token[1] not in "+-*/": | ||||||
|  |             return "postfix" | ||||||
|  |         else: | ||||||
|  |             return "infix" | ||||||
|  |  | ||||||
|  |     # ---------------------- | ||||||
|  |     # Expressions - tokens getters | ||||||
|  |  | ||||||
|  |     def tokens(self, fix = "infix"): | ||||||
|  |         """Get the list of tokens with the wanted fix | ||||||
|  |  | ||||||
|  |         :param fix: the fix wanted (infix default) | ||||||
|  |         :returns: list of tokens | ||||||
|  |  | ||||||
|  |         """ | ||||||
|  |         # Si ce fix n'a pas encore été enregistré | ||||||
|  |         if fix not in self._tokens: | ||||||
|  |             # Il peut venir de la version string | ||||||
|  |             if fix in self._string: | ||||||
|  |                 self._tokens[fix] = self.parseExp(self._string[fix]) | ||||||
|  |             # Sinon il faut le calculer à partir d'une autre forme | ||||||
|  |             else: | ||||||
|  |                 fix_transfo = "to" + fix.capitalize() | ||||||
|  |                 getattr(self,fix_transfo)() | ||||||
|  |  | ||||||
|  |         return self._tokens[fix] | ||||||
|  |  | ||||||
|  | ##### On en est là,il faudra faire attention à bien vérifier ce que les "to..." enregistre (string ou tokens)   | ||||||
|  |  | ||||||
|  |     def string(self, fix = "infix"): | ||||||
|  |         """Get the string with the wanted fix | ||||||
|  |  | ||||||
|  |         :param fix: the fix wanted (infix default) | ||||||
|  |         :returns: the string representing the expression | ||||||
|  |  | ||||||
|  |         """ | ||||||
|  |         # Si ce fix n'a pas encore été enregistré | ||||||
|  |         if fix not in self._string: | ||||||
|  |             # Il peut venir de la version string | ||||||
|  |             if fix in self._tokens: | ||||||
|  |                 self._string[fix] = self.parseExp(self._string[fix]) | ||||||
|  |             # Sinon il faut le calculer à partir d'une autre forme | ||||||
|  |             else: | ||||||
|  |                 fix_transfo = "to" + fix.capitalize() | ||||||
|  |                 getattr(self,fix_transfo)() | ||||||
|  |  | ||||||
|  |         return self._string[fix] | ||||||
|  |      | ||||||
|  |     # ---------------------- | ||||||
|  |     # "fix" tranformations | ||||||
|  |  | ||||||
|  |     def toPostfix(self): | ||||||
|  |         """ Transorm the expression into postfix form using the infix form""" | ||||||
|  |         pass | ||||||
|  |  | ||||||
|  |     def toInfix(self): | ||||||
|  |         """ Tranform the expression into infix form using postfix 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 | ||||||
|  |         """ | ||||||
|  |         if isNumber(operande) and "-" in operande: | ||||||
|  |             return 1 | ||||||
|  |         elif not isNumber(operande): | ||||||
|  |             # Si c'est une grande expression ou un chiffre négatif | ||||||
|  |             stand_alone = get_main_op(operande) | ||||||
|  |             # Si la priorité de l'operande est plus faible que celle de l'opérateur | ||||||
|  |             minor_priority = self.priority[get_main_op(operande)] < self.priority[operator] | ||||||
|  |             # Si l'opérateur est -/ pour after ou juste / pour before | ||||||
|  |             special = (operator in "-/" and posi == "after") or (operator in "/" and posi == "before") | ||||||
|  |  | ||||||
|  |             return stand_alone and (minor_priority or special) | ||||||
|  |         else: | ||||||
|  |             return 0 | ||||||
|  |      | ||||||
|  | # J'aime pas bien cette endroit faudrait que ce soit une méthode qui s'applique uniquement à l'expression en question (self) pas à n'importe quel string, ça serait plus propre. | ||||||
|  |     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 | ||||||
|  |  | ||||||
|  |         """ | ||||||
|  |         parStack = Stack() | ||||||
|  |         tokenList = exp.split(" ") | ||||||
|  |  | ||||||
|  |         if len(tokenList) == 1: | ||||||
|  |         # Si l'expression n'est qu'un élément | ||||||
|  |             return 0 | ||||||
|  |  | ||||||
|  |         main_op = [] | ||||||
|  |  | ||||||
|  |         for token in tokenList: | ||||||
|  |             if token == "(": | ||||||
|  |                 parStack.push(token) | ||||||
|  |             elif token == ")": | ||||||
|  |                 parStack.pop() | ||||||
|  |             elif token in "+-*/" and parStack.isEmpty(): | ||||||
|  |                 main_op.append(token) | ||||||
|  |  | ||||||
|  |         return min(main_op, key = lambda s: priority[s]) | ||||||
|  |  | ||||||
|  |     # --------------------- | ||||||
|  |     # 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  | ||||||
		Reference in New Issue
	
	Block a user