Implementing an instance of a calculator

Source: Internet
Author: User
Jobs: Calculator Development

(1) Realize subtraction and extension number priority analysis;

(2) User input 1-2 * ((60-30 + ( -40/5) * ( -9-2*5/-3 + 7/3*99/4*2998 +10 * 568/14))-( -4*3)/(16-3*2)) and other similar formulas, you must parse the inside () , +,-, *,/symbols and formulas, and the results must be calculated in accordance with the results of the actual calculator.

The code is as follows:

 1 Import re 2 3 formula = ' 1-2 * ((60-30 + ( -9-2*5/-3 + 7/3*99/4*2998 +10 * 568/14) * ( -40/5))-( -4*3)/(16-3*2)) ' 4 #formula = "(1++1)" 5 def Modify (formula_deep): 6 "' Program modifier function, remove spaces and brackets ' 7 ' '" "in the removal operation of" +--+---+ +-+ "8 fo     Rmula_deep = Re.sub ("[()]", "" ", Formula_deep) #替换空格和空号 9 formula_deep = re.sub (" \+-","-", Formula_deep) #替换 +-10 Formula_deep = Re.sub ("--", ' + ', formula_deep) #替换--for +11 formula_deep = re.sub ("-\+", '-', formula_deep) Form Ula_deep = Re.sub ("\++", "+", Formula_deep) return formula_deep14 def multiply_divide (formula_deep): 16 "calculation multiplication ' ' 17 ' because multiplication is first calculated, our idea is to first calculate the multiplication, and then replace the results of the calculation, you can get only the situation of the addition and subtraction "" "Calc_sign = Re.findall (" [+-] ", Formula_deep) #提取  All the strings in the plus minus sign calc_list = Re.split ("[+ +]", formula_deep) #以加减号进行分割, get multiplication 20 "' because we get the calc_list:[', ' 9 ', ' 2*5/', ' 3 ', ' 7/3*99/4*2998 ', ' 10*568/14 ', inside because of the trouble caused by--9 was divided, 2*5/and so on "if calc_list[0] = =": 22 "" Processing list Beginning "" Empty case, stating this It's a negative number, we split it up. To re-merge ' 23         CALC_LIST[1] = calc_sign[0] + calc_list[1]24 del calc_sign[0]25 del calc_list[0]26 for Num,li NE in Enumerate (calc_list): 27 "Handling the 2*5/case, it means that this is a negative number, because only a negative number will occur 2*5/-3 is split, need to merge ' if Line.endswi Th ("/") or Line.endswith ("*"): 29 "" If the end includes the multiplication number, it means that negative numbers have been split "'" [calc_list[num+1] = Calc_list[num] + C Alc_sign[num] + calc_list[num+1]31 del calc_sign[num]32 del calc_list[num]33 ' ' under the formal operation of multiplication, above  It's all a format conversion. "Index,string in Enumerate (calc_list): 35" First extracts the number, facilitates the subsequent substitution of the calculated value " or "*" in string:37 mul_div_sign = Re.findall ("[/*]", string) Mul_div_list = Re.split ("[/*]", str ing) Calc_value = None40 for e_index,e in Enumerate (mul_div_list): If Calc_val                     ue:42 if mul_div_sign[e_index-1] = = "/": Calc_value/= float (e) 44 Elif mul_div_sIGN[E_INDEX-1] = = "*": Calc_value *= float (e) else:47 Calc     _value = float (e) calc_list[index] = calc_value49 else:50 pass51 ' ' computed value ' 52 Value = None53 for k,v in Enumerate (calc_list): 54 "' Calculates the condition of the addition and subtraction ' if value:56 N[K-1] = = "-": $ Value-= float (v) elif calc_sign[k-1] = = ' + ': $ + + FL Oat (v) else:61 value = float (v) return value63 + def main (Formula): 66 "' program main entrance, generate parentheses true:68 formula_deep = Re.search ("\ (. [ ^ ()]+\) ", formula) if formula_deep:70 formula_deep = Formula_deep.group () formula_list  = Modify (Formula_deep) 72 "get trimmed to calculate the string, now begin to calculate -9-2*5/-3+7/3*99/4*2998+10*568/14" ' Calc_value = Multiply_divide (formula_list) formula = Formula.replace (formula_deEp,str (calc_value)) else:76 "Processing without parentheses" "formula = Modify (Formula) Lc_last_value = multiply_divide (Formula) print ("formula:", Calc_last_value)-exit () Bayi, if __na me__== "__main__": Main (Formula)

Program Run Process:

General idea: We know that to calculate the format of the above string, you can use the Eval () function, but here we have to write a calculator ourselves; we know that the precedence of a mathematical operation is the highest priority of the parentheses, the first thing in parentheses, so our idea is to match the parentheses of the memory and then perform the operation, When we match the contents of the memory brackets, we calculate and replace the values of the original position in the string with the computed values, and replace them with no parentheses in the string, which we calculate in the normal order of operations.

1, the regular match, first find the memory brackets; The code is as follows:

Formula = ' 1-2 * ((60-30 + ( -9-2*5/-3 + 7/3*99/4*2998 +10 * 568/14) * ( -40/5))-( -4*3)/(16-3*2)) '
Formula_deep = Re.search ("\ (. [ ^ ()]+\) ", formula)
Print (Formula_deep.group ())

The results of the operation are as follows:

( -9-2*5/-3 + 7/3*99/4*2998 +10 * 568/14)

Above we observe the extracted memory of the string, it can be seen that there are many places need to decorate, the string has a lot of empty, this will affect our calculations, and in the process of calculation we do not need parentheses, so also to remove the parentheses.

2, the removal of space and brackets;

Formula_deep = Re.sub ("[()]","", Formula_deep)

Run as follows:

-9-2*5/-3+7/3*99/4*2998+10*568/14
3, get the above string, we in the level of operation, we can appear +-,-+,++,--and so on, this time also to be processed, because now is the first layer, do not see the problem, when the operation, if the memory is negative, then the front parenthesis is + or-the words will become +-,-- And so on, this time is also not possible, but also to deal with;

Formula_deep = Re.sub ("\+-",'-', formula_deep)
Formula_deep = Re.sub ("-+",'-', formula_deep)
Formula_deep = Re.sub ("\++","+", Formula_deep)
Formula_deep = Re.sub ("--",' + ', formula_deep)
Run as follows:

-9-2*5/-3+7/3*99/4*2998+10*568/14

4, when the above processing is completed, the official start calculation, we know that the calculation first to calculate multiplication, because the multiplication priority is the highest, because the first to find multiplication, calculate after the completion of the calculation plus and minus;

Calc_sign = Re.findall ("[+-]", formula_deep)
Calc_list = Re.split ("[+-]", formula_deep)
Print (calc_list)
Print (calc_sign)

Run as follows:

[' ', ' 9 ', ' 2*5/', ' 3 ', ' 7/3*99/4*2998 ', ' 10*568/14 ']
['-', '-', '-', '+', '+']

We got a list of calculations, and the arithmetic symbols,[' ', ' 9 ', ' 2*5/', ' 3 ', ' 7/3*99/4*2998 ', ' 10*568/14 '] are also problematic, first of all, the first element of the list is "" Empty case, Note that there is no such situation, the situation is to merge, and 2*5/, which is followed by negative numbers, but also to deal with before the plan calculation, why this situation? This is because in the process of operation, we are "+" or "-" to split the string, which will cause if it is a negative, it will be split, at the beginning, the front will be divided into a null, which will cause our operation error, because it is to be modified.

5, the above operation to amend:

If calc_list[0] = ="":
calc_list[1] = calc_sign[0] + calc_list[1]
   Del calc_list[0]
   Del calc_sign[0]
Print"Calc_list:", calc_list)
Print"Calc_sign:", calc_sign)
For Index,eInchEnumerate (calc_list):
   If E.endswith ("/")or E.endswith ( " * "):
note followed by a negative number, to be modified Span style= "color: #008080; Font-weight:bold "> Calc_list[index+1] = Calc_list[index] + Calc_sign[index] + calc_list[ Index+1]
del Calc_list[index]  
del Calc_sign[index]

  Print ( "calc_list:", calc_list)
Print ( "calc_sign:", calc_sign)

Run as follows:

Calc_list: ['-9 ', ' 2*5/', ' 3 ', ' 7/3*99/4*2998 ', ' 10*568/14 ']
Calc_sign: ['-', '-', ' + ', ' + ']
Calc_list: ['-9 ', ' 2*5/-3 ', ' 7/3*99/4*2998 ', ' 10*568/14 ']
Calc_sign: ['-', ' + ', ' + ']

As can be seen from the above, we have a two-point correction, the first to remove the opening of the "" empty element problem, the second time the multiplication followed by a negative number of cases;

6, at this time, we are going to calculate, we first traverse calc_list: ['-9 ', ' 2*5/-3 ', ' 7/3*99/4*2998 ', ' 10*568/14 '] element, because we want to do multiplication first, so find contains "/" or "*" string, evaluated, and then replaced, you can get a string without multiplication, containing only the addition and subtraction of the situation:

For Num,value in Enumerate (calc_list): The If "/" in Value or "*" in Value: "" "description contains multiplication, first evaluated" "" "Mul_div_sign = Re.findall (" [/*] ", Value)        mul_div_list = Re.split ("[*/]", value)        print (mul_div_sign)        print (mul_div_list)

The results of the operation are as follows:

['*', '/']
[' 2 ', ' 5 ', '-3 ']
['/', '*', '/', '*']
[' 7 ', ' 3 ', ' 99 ', ' 4 ', ' 2998 ']
['*', '/']
[' 10 ', ' 568 ', ' 14 ']

We get the operator and the number inside, now just judge the multiplication, then we can use the previous one multiplied by the back one to calculate. As follows:

7, multiplication calculation:

1 for Num,value in Enumerate (calc_list): 2     If "/" in Value or "*" in Value:3         "" "description contains multiplication, first evaluated" "" "" 4         Mul_div_si GN = Re.findall ("[/*]", value) 5         mul_div_list = Re.split ("[* * *]", value) 6         "' Next, we calculate the multiplication case, first we want to traverse the multiplication, Because you want to do element recursion ' 7         res = None 8 for         E_index,e_value in Enumerate (mul_div_list): 9             if res:10                 if mul_div_sign[ E_INDEX-1] = = "/": one                     res/= float (e_value)                 elif mul_div_sign[e_index-1] = = "*":                     res *= float (e_value)             else:15                 res = float (e_value)      #如果不存在, a new one is generated, but we define a situation that does not exist, so it must be a number for the Mister, and then in the calculation         of the CALC_ List[num] = res17     else:18         pass19 print (calc_list) print (calc_sign)

The results of the operation are as follows:

['-9 ',-3.3333333333333335, 173134.50000000003, 405.7142857142857]
['-', '+', '+']

The above code, we carried out the multiplication operation, so that the operation is not in existence multiplication, only need to add and subtract operations.

As you can see, after we have the operation, only the addition and subtraction is left, so that we can use the elements and symbols of the list for the addition and subtraction operations.

8, plus and minus operations:

1 "' Add minus operation ' ' 2 result = None 3 for K_index,k_value in Enumerate (calc_list): 4     if Result:5         if calc_sign[k_index- 1] = = "+": 6             result + = float (k_value) 7         elif calc_sign[k_index-1] = = '-': 8             result-= float (k_value) 9     Els E:10         result = float (k_value) print ("Result:", result)

Run as follows:

result:173534.54761904766

9, above, we get the result of the operation, and then only need to replace the contents of the memory brackets, so that a layer of substitution, and eventually only left the operation without parentheses, at this time, we in this line of this function, we can get the final result.

Knowledge Points:

(1):

result = None
for k_index, K_value in enumerate(calc_list):
If result:
if calc_sign[k_index-1] = = "+":
result + = float(k_value)
elif calc_sign[k_index-1] = = '-':
result-= float(k_value)
Else:
result = float(k_value)

The above code embodies a thought, because we want to achieve is the previous number plus the next number, but there is no direct method, this time, we can define a null value, and then to judge the value, in fact, the purpose of the judgment is to give this variable assignment, the assignment is the first element of the list, This allows us to implement an overlay or a stack of elements in the list for Each loop. This idea is very good. When it does not exist, when you want it to exist, define an empty value to judge it, and then make the assignment. After assignment, the equivalent of result equals the first value of the element, and the next loop of the element starts with the second value, and the length index of the list is not exceeded.

2, the use of regular expressions, re (regular abbreviation):

^ denotes non, "\" means escape, which means that the meaning of the character itself, + represents one or more

"\(. [^ ()]+\) "stands for matching parentheses, in which the middle of the parentheses contains any number of elements that are not (), that is, the parentheses that match the inner layer.

3, the string replace () method, the string to find and replace, Str.replace (old,new), the regular string findall () find all the values of the regular expression in the element, placed in a list; Re.split () string segmentation, Splits according to a regular string.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.