說明
該計算器主要是為了練習正則表達式以及python基礎所寫:代碼比較low!
運行過程
請輸入你的計算公式, 計算器會將計算結果輸出到屏幕上(此處會打印步驟); 退出(exit/quit)
MyCalc> 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) ) 1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2)) ----------- 步驟 [] ['-40/5'] (-40/5) 運算結果: -8.0 parenthesis_calc_result: 1-2*((60-30+-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2)) ----------- 步驟 ['-', '+', '+'] ['9', '2*5/3', '7/3*99/4*2998', '10*568/14'] (9-2*5/3+7/3*99/4*2998+10*568/14) 運算結果: 173545.88095238098 parenthesis_calc_result: 1-2*((60-30-8.0*173545.88095238098)-(-4*3)/(16-3*2)) ----------- 步驟 ['-', '-'] ['60', '30', '8.0*173545.88095238098'] (60-30-8.0*173545.88095238098) 運算結果: -1388337.0476190478 parenthesis_calc_result: 1-2*(-1388337.0476190478-(-4*3)/(16-3*2)) ----------- 步驟 [] ['-4*3'] (-4*3) 運算結果: -12.0 parenthesis_calc_result: 1-2*(-1388337.0476190478--12.0/(16-3*2)) ----------- 步驟 ['-'] ['16', '3*2'] (16-3*2) 運算結果: 10.0 parenthesis_calc_result: 1-2*(-1388337.0476190478+12.0/10.0) ----------- 步驟 ['+'] ['-1388337.0476190478', '12.0/10.0'] (-1388337.0476190478+12.0/10.0) 運算結果: -1388335.8476190479 parenthesis_calc_result: 1-2*-1388335.8476190479 ----------- 步驟 ['-'] ['1', '2*-1388335.8476190479'] 1-2*-1388335.8476190479 運算結果: 2776672.6952380957 最后的運算結果: 2776672.6952380957
具體代碼實現
#/usr/bin/env python3
# _*_ coding: utf-8 _*_
__author__ = 'rianley cheng'
__blog__ ='https://www.cnblogs.com/rianley'
'''
left is too short , I use python !
數據規范化, 正則拆分,結合運算 打印運算表達式及運算步驟
'''
import re,time
def math_legal(num): #判斷輸入公式是否合法,如包含字符或者特殊字符,做特殊處理
try:
num = float(num)
return True
except (ValueError,TypeError) as diag:
pass
def calc_formula(formula): #替換多余的加減操作
formula = formula.replace("++", "+")
formula = formula.replace("+-", "-")
formula = formula.replace("-+", "-")
formula = formula.replace("--", "+")
return formula
def match_calc_formula(parenthesises_formula): #匹配加減操作符和加減表達式列表
# 取出圓括號表達式中所有的"+-"號,保存為列表形式,如['-', '+', '+']
# 用"+-"號作為分隔符,將圓括號中的乘除表達式取出,保存為列表形式,如['9', '2*5/3', '7/3*99/4*2998', '10*568/14']
parenthesises_formula = re.sub("[()]", "", parenthesises_formula)
plusminus_operator_list = re.findall("[+-]", parenthesises_formula)
plusminus_expression_list = re.split("[+-]", parenthesises_formula)
if plusminus_expression_list[0] == "":
#圓括號表達式列表中,如果第一個元素為空,則表明第一個元素為一個負數,則"-"號開頭,將第一個"-"號合並到列表第一個元素
plusminus_expression_list[1] = plusminus_operator_list[0] + plusminus_expression_list[1]
del plusminus_expression_list[0]
del plusminus_operator_list[0]
for i, e in enumerate(plusminus_expression_list):
#處理成正確的結果:['1 * -2', '3 * -5', '6/-3']
e = e.strip()
if e.endswith("*") or e.endswith("/"):
try:
plusminus_expression_list[i] = plusminus_expression_list[i] + plusminus_operator_list[i] + plusminus_expression_list[i + 1]
del plusminus_expression_list[i + 1]
del plusminus_operator_list[i]
except IndexError as diag:
pass
return plusminus_operator_list,plusminus_expression_list
def matching_multiply_divide_operator(plusminus_equations): #匹配乘除操作符和乘除表達式列表
operator_list = re.findall("[*/]", plusminus_equations)
value_list = re.split("[*/]", plusminus_equations)
return operator_list,value_list
def plus_minus_calc(plusminus_operator_list,plusminus_expression_list): #加減運算
'''對運算公式進行加減運算,返回加減結果'''
plusminus_result = None
for i, e in enumerate(plusminus_expression_list):
match = math_legal(e)
if match == True:
if plusminus_result:
if plusminus_operator_list[i - 1] == "+":
plusminus_result += float(e)
elif plusminus_operator_list[i - 1] == "-":
plusminus_result -= float(e)
else:
plusminus_result = float(e)
else:
print("\33[33;0m輸入的公式中包含非數字字符!\33[0m")
print("\33[33;0m嘗試運算: %s\33[0m" % e)
e = re.sub("\D", "", e)
if e == "": e = 0
if plusminus_result:
if plusminus_operator_list[i - 1] == "+":
plusminus_result += float(e)
elif plusminus_operator_list[i - 1] == "-":
plusminus_result -= float(e)
else:
try:
plusminus_result = float(e)
except ValueError as diag:
print("\33[33;1m無效輸入!\33[0m")
return plusminus_result
def multiply_divide_calc(multiply_divide_operator_list,multiply_divide_value_list): #乘除運算
'''對運算公式進行乘除運算,返回乘除結果'''
multiply_divide_result = None
for i, num in enumerate(multiply_divide_value_list):
match = math_legal(num)
if match == True:
if multiply_divide_result:
if multiply_divide_operator_list[i - 1] == "*":
multiply_divide_result *= float(num)
elif multiply_divide_operator_list[i - 1] == "/":
try:
multiply_divide_result /= float(num)
except ZeroDivisionError as diag:
multiply_divide_result = 0
print("\33[33;0m輸入的公式中存在除數為0,重新輸入!\33[0m")
else:
multiply_divide_result = float(num)
else:
print("\33[33;0m輸入的公式中存在無法識別的內容!\33[0m")
print("\33[33;0m嘗試為您運算: %s\33[0m" % num)
num = re.sub("\D", "", num)
if num == "": num = 1
if multiply_divide_result:
if multiply_divide_operator_list[i - 1] == "*":
multiply_divide_result *= float(num)
elif multiply_divide_operator_list[i - 1] == "/":
multiply_divide_result /= float(num)
else:
try:
multiply_divide_result = float(num)
except ValueError as diag:
print("\33[33;1m無效輸入!\33[0m")
return multiply_divide_result
def calculating_priority_formulas(priority_formula): #計算圓括號表達式
""""""
plusminus_operator_list, plusminus_expression_list = match_calc_formula(priority_formula)
print("-----------")
print("\33[31;1m步驟\33[0m")
print(plusminus_operator_list, plusminus_expression_list)
for index, equations in enumerate(plusminus_expression_list):
if "*" in equations or "/" in equations:
""""""
multiply_divide_operator_list, multiply_divide_value_list = matching_multiply_divide_operator(equations)
multiply_divide_result = multiply_divide_calc(multiply_divide_operator_list, multiply_divide_value_list) #取出乘除表達式進行乘除運算
plusminus_expression_list[index] = multiply_divide_result
plus_minus_result = plus_minus_calc(plusminus_operator_list, plusminus_expression_list) #將乘除的結果進行加減運算
print("%s 運算結果: %s" % (priority_formula, plus_minus_result))
return plus_minus_result
def start_operation(formula):
""" 運算主程序入口,對輸入的數學公式進行處理,匹配最底層圓括號表達式,並交給乘除函數計算返回結果,替換圓括號表達式"""
formula = formula.replace(" ", "") #去掉表達式多余的空格
formula = calc_formula(formula) #去掉表達式里重復的"+-"號
print(formula)
parenthesises_flag = True
while parenthesises_flag:
formula = calc_formula(formula)
parenthesis_formula = re.search(r"\(([^()]+)\)", formula)
if parenthesis_formula:
parenthesis_formula = parenthesis_formula.group()
parenthesis_calc_result = calculating_priority_formulas(parenthesis_formula)
formula = formula.replace(parenthesis_formula, str(parenthesis_calc_result))
print("parenthesis_calc_result: %s" % formula)
else:
calc_result = calculating_priority_formulas(formula)
parenthesises_flag = False
print("最后的運算結果: \33[31;1m%s\33[0m" % calc_result)
def myCalcMain():
prompt = '''
請輸入你的計算公式, 計算器會將計算結果輸出到屏幕上(此處會打印步驟); 退出(exit/quit)
示例公式: 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )
'''
print(prompt)
while True:
formula = input("MyCalc> ").strip()
if formula == "exit" or formula == "quit":
print('歡迎下次使用,歡迎關注作者博客!(https://cnblogs.com/rianley)更多資訊敬請期待')
time.sleep(3)
exit("Bye.Bye...")
elif formula == "":
continue
else:
start_operation(formula)
if __name__ == '__main__':
myCalcMain()
結言
努力成為想要成為的人,就算最后失敗了!也沒關系,因為遺憾比失敗可怕的多!
