Python Development - Implementing Calculator Algorithms Using Regular Expressions

Python Development - Implementing Calculator Algorithms Using Regular Expressions

  (1) Do not use the calculation method that comes with the system such as eval()

  (2) Realize four mixed operations, parenthesis priority analysis

Ideas:

  1. String preprocessing, remove all spaces

  2. Determine whether there is a parenthesis operation. If it exists, go to step 3. If it does not exist, go directly to step 4.

  3. Use regular expressions to obtain the four arithmetic expressions in the bottom brackets

  4. Preprocess the four arithmetic expressions: when there is a negative number at the beginning of the expression, add a 0 before the expression

  5. Use the re.split() and re.findall() methods to split the four operations into multiplication and division expressions and numbers by adding and subtracting symbols, and retain the corresponding position subscripts.

  6. Use the re.split() and re.findall() methods to split the multiplication and division formula into multiplication and division symbols and numbers through the multiplication and division symbols, and then perform the calculation and return the value.

  7. Restore the expression through the subscript position reserved by re.split() and re.findall().

  8. After all multiplication and division operations are completed, return to add and subtract operations.

  9. After the addition and subtraction operations are completed, return the expression for substitution.

  10. Through the recursive function, after all parenthesis operations are completed. Finally, complete the four arithmetic operations to complete all operations.

  Note: In the process, there are three main points in the processing of negative numbers: when the negative number appears at the beginning of the expression, there is a subtraction before the negative number, and there is a negative number in the multiplication and division formula and not at the beginning of the expression.

  (1) When a negative number appears at the beginning of an expression: add a 0 in front

  (2) There is a subtraction in front of a negative number: a sign check and replacement is required after each operation is completed

  (3) There is a negative number in the multiplication and division formula and it is not at the beginning of the expression: move the negative sign to the beginning of the expression

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:Dang

import re

def update_formula(calc_list,calc_operator_list): #Recombine
     the split expression list and symbol list 
    for index, item in enumerate(calc_list):
         if index == 0:
            formula = item
        elif index != 0:
            formula += calc_operator_list[index-1] + item
    return formula

def negative_start_issue(formula):
     #Handle the case where the negative number starts with the expression in parentheses 
    calc_list = re.split( " [+-] " ,formula)     #Separate each multiplication and division operation by +- sign calc_operator_list 
    = re.findall( " [+-] " ,formula)

    for index,item in enumerate(calc_list):
         if index == 0 and item == '' :     #Handle the problem that the negative sign is at the beginning 
            calc_list[index] = ' 0 ' 
        else :
            calc_list[index] = item.strip()

    formula = update_formula(calc_list,calc_operator_list)
    return formula

def deal_unusual_issue(formula): #Double
     addition and subtraction symbol processing 
    formula = formula.replace( "  " , "" ) #Remove spaces 
    formula = formula.replace( " ++ " , " + " )
    formula = formula.replace("+-", "-")
    formula = formula.replace("-+", "-")
    formula = formula.replace("--", "+")
    return formula

def deal_negative_issue(formula): #Handle
     the calculation problem of negative numbers in multiplication and division operations (two cases before and after the position)

    # 1. Negative numbers after 
    m = re.search( " [0-9]+[.]*[0-9]*[*|/][-][0-9]+[.]*[0- 9]* " ,formula)
  #   minus_pre = re.search("[0-9]+[.]*[0-9]*[*|/][-][0-9]+[.]*[ 0-9]*",formula).group() #Pay 
    attention to the necessary and non-essential items for matching, such as: "[0-9]+[.][0-9]+[*|/][-] [0-9]+[.][0-9]+" Mistakes non-essential items as necessary items. 
    if m:
        minus_pre = m.group ()
        minus_pro = "-"+minus_pre.replace("-","")
        formula = formula.replace(minus_pre,minus_pro)
    if "*-" in formula or "/-" in formula:
        return deal_negative_issue(formula)

    # 2. Negative numbers come first 
    formula = deal_unusual_issue(formula)

    return formula


def multiply_divide(formula):
    # print("[%s]"%formula,formula)

    #Multiplication and division calculation 
    calc_list = re.split( " [*/] " , formula)
    operator_list = re.findall( " [*/] " , formula)   #Separate the multiplication and division signs as a list # print("sub_calc_list:" , sub_calc_list) # print("sub_operator_list:", sub_operator_list) 
    res = 0
     for index2, i in enumerate(calc_list):
         if index2 == 0:
    
    

            res = float(i)
         else :
             if operator_list[index2 - 1] == ' * ' :   # Determine whether it is addition or subtraction by index in sub_operator_list, 
                res *= float(i)
             elif operator_list[index2 - 1] == ' / ' :
                res /= float(i)
    return res

def add_abstract(formula): #Addition and
     subtraction calculation

    # 1. Processing of negative numbers at the beginning 
    formula = negative_start_issue(formula)

    # 2. Double plus minus sign processing 
    formula = deal_unusual_issue(formula)

    # 3. Addition and subtraction logical operations 
    calc_list = re.split( " [+-] " , formula)
    operator_list = re.findall("[+-]", formula)

    res = 0
    for index, i in enumerate(calc_list):
        if index == 0:
            res = float(i)
        else:
            if operator_list[index-1] == '+':
                res += float(i)
            elif operator_list[index-1] == '-':
                res -= float(i)
    return res

"""
Four main functions of mixed operation
"""
def elementary_arithmetic(formula):

    #Negative processing 
    formula = negative_start_issue(formula)
    formula = deal_negative_issue(formula)

    #Multiplication and division operation 
    calc_list = re.split( " [+-] " ,formula)     #Separate each multiplication and division operation by +- symbol calc_operator_list 
    = re.findall( " [+-] " ,formula)
     for index1, item in enumerate (calc_list):
        calc_list[index1] = str(multiply_divide(item))   #Coercion of data type! ! ! 
    formula = update_formula(calc_list,calc_operator_list)

    #Addition and subtraction operation 
    formula = add_abstract(formula)

    return formula

"""
parenthesis operation
"""

def calculator(formula):
     #Data preprocessing 
    formula = formula.replace( "  " , "" )

    m = re.search( " \([^()]*\) " ,formula) #Determine
     whether parenthesis operation is required 
    if m:
         #Parenthesis operation # Extract the minimum parenthesis operation formula, calculate the result, and return. 
        subformula = m.group().strip( " () " )   # strip the parentheses found print ( " subformula: " ,subformula,type(subformula))
        
        
        subres = elementary_arithmetic(subformula) #Call   the main function of four mixed operations 
        print ( " subres: " ,subres)
        formula = formula.replace(m.group(), str(subres))
        print("updated formula:",formula)
        if "(" in formula:
            return calculator(formula)
        else:
            print("formula result:",formula)

        #May appear after removing all parentheses: 1-2*-312.8 
        formula = elementary_arithmetic(formula)

        return formula
    else:
        return elementary_arithmetic(formula)

#The following is the test code: 
formula = " 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*9/4*28 +10 * 56/14 )) - (-4*3)/ (16-3*2) ) " 
print ( " %s = " %formula,calculator(formula))

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324831474&siteId=291194637