python実装コンピューティング


pythonで計算機を書きました.「+」、「-」、「*」、「/」およびカッコの混合式の計算を実現できます.最初は式を解析する時に2つの再帰を使って、最後に運行時のエラーを報告して、再帰の深さが足りないことを提示して、sysを使って下の再帰の深さを設定して、やはりだめで、いったん設定が大きすぎるとメモリのエラーが現れて、本人の機械がlowすぎるかもしれません.その後、そのうちの1つを再帰的にサイクルに変更し、最終的には正常に動作することができます.
# coding:utf-8
# Author:  
# date:2016-03-20

#    +、-、*、/            :'-1-(2+(10-2*3)/(20-30/5))+(100-(4-300/6)-5*9/4+5)'
#                    ---     

import re
import sys
import argparse

#      
sys.setrecursionlimit(5000)
#          ,           ,       low-----           
class MyMaths():
    def __init__(self):
       pass

    #       ,   
    def operatorParse(self,express):
        # operators = {'+':self.addition,'-':self.subtraction,'*':self.multiplication,'/':self.division}
        express = express.group()
        **#         ,        ,         **
        if '+' in express:
            return self.addition(express)

        if '-' in express:
            return self.subtraction(express)

        if '*' in express:
            return self.multiplication(express)

        if '/' in express:
            return self.division(express)

    #    
    def addition(self,express):
        first_data,second_data = express.split('+')
        return str(float(first_data)+float(second_data))

    #    
    def subtraction(self,express):
        #              
        if express.startswith('-'):
            first_data,second_data = express[1:].split('-',1)#     ,   ‘-’split  
            first_data = '-' + first_data
        else:
            first_data,second_data = express.split('-',1)
        return str(float(first_data)-float(second_data))

    #    
    def multiplication(self,express):
        first_data,second_data = express.split('*')
        return str(float(first_data)*float(second_data))

    #    
    def division(self,express):
        first_data,second_data = express.split('/')
        return str(float(first_data)/float(second_data))

    **#     ,        ,        **
    def operator_priority(self,express):
        pattern_1 = re.compile('(\-?\d+\.?\d*(\*|\/)+\-?\d+\.?\d*)')
        pattern_2 = re.compile('(\-?\d+\.?\d*(\+|\-)+\-?\d+\.?\d*)')
        if re.search(pattern_1,express):
            express = re.sub(pattern_1,self.operatorParse,express)
            return self.operator_priority(express)
        elif re.search(pattern_2,express):
            express = re.sub(pattern_2,self.operatorParse,express)
            return self.operator_priority(express)
        else:
            return express
#       ,   ,      
def operatorParse(express):
    # operators = {'+':self.addition,'-':self.subtraction,'*':self.multiplication,'/':self.division}

    #    
    def addition(express):
        first_data,second_data = express.split('+')
        return str(float(first_data)+float(second_data))

    #    
    def subtraction(express):
        #              
        if express.startswith('-'):
            #     ,   ‘-’split  
            first_data,second_data = express[1:].split('-',1)
            first_data = '-' + first_data
        else:
            first_data,second_data = express.split('-',1)
        return str(float(first_data)-float(second_data))

    #    
    def multiplication(express):
        first_data,second_data = express.split('*')
        return str(float(first_data)*float(second_data))

    #    
    def division(express):
        first_data,second_data = express.split('/')
        return str(float(first_data)/float(second_data))

    express = express.group()
    **#         ,        ,         **
    if '+' in express:
        return addition(express)

    if '-' in express:
        return subtraction(express)

    if '*' in express:
        return multiplication(express)

    if '/' in express:
        return division(express)

#express      ‘+’,‘-’,‘*’,‘/’   ,operator_priority           
def operator_priority(express):
    #           express     ‘*’  ‘/’    
    pattern = re.compile('(\d+\.?\d*(\*|\/)+\-?\d+\.?\d*)')
    while re.search(pattern,express):#re.search('(\*|\/)',express):
        #  express            ,    re.sub                  operatorParse
        # operatorParse             
        #express              ,       
        # print re.search(pattern,express).group()
        express = re.sub(pattern,operatorParse,express)

    #         express     ‘+’  ‘-’    
    pattern = re.compile('(\-?\d+\.?\d*(\+|\-)+\d+\.?\d*)')
    while re.search(pattern,express):#re.search('(\+|\-)',express):
        #  express            ,    re.sub                  operatorParse
        # operatorParse             
        #express              ,       
        express = re.sub(pattern,operatorParse,express)
    return express


#                           ,       operator_priority  
def parseBracket(srcStr):
    # my_maths = MyMaths()
    if '(' in srcStr or ')' in srcStr:
        #        ‘)’   
        first_Rbracket_pos = srcStr.find(')')
        match_lbrocket_pos = None
        for i in xrange(first_Rbracket_pos):
            #     ‘)’       ,       ‘(’
            if srcStr[first_Rbracket_pos - i] == '(':
                match_lbrocket_pos = first_Rbracket_pos - i
                break
            else:
                continue
        #     ‘(’ ‘)’  ,         
        sub_Expression = srcStr[match_lbrocket_pos:first_Rbracket_pos+1]
        # print sub_Expression
        #  my_maths.operator_priority,                     
        retStr = operator_priority(sub_Expression.lstrip('(').rstrip(')'))
        # print retStr
        #                   ,       
        newExpre = srcStr.replace(sub_Expression,retStr)
        # print newExpre
        #    
        return parseBracket(newExpre)
    else:
        #        ‘()’,           operator_priority    ,      
        retStr = operator_priority(srcStr)
        return retStr

if __name__ == '__main__':
    s = "-200-(1-(2+(10-2*3/2)/(20-30/5))+(100-(4-300/6)-5*9/4+5))"
    print s + " = " + parseBracket(s)

プログラムテストが実行され、結果は以下の通りである:-200-(1-(10-2*3/2)/(20-30/5)+(100-(4-300/6)-5*9/4+5)=-33.25