180119 计算器的优化版
print("\033[31;1m欢迎使用计算器\033[0m".center(59,"-")) import sys,time #导入模块 sys模块,time模块 f = open("intro.txt",'r') #打开文件 同一个目录里的名为“intro”的文件,打开为读取 for line in f: #循环读取刚刚打开的f的行line; for...in... 循环 ;for..in语句是个循环语句,它迭代一个对象的序列,现在,你需要知道的是一个序列只是一个有序的项目的集合。 for i in line: #循环读取文字;读取上一行读取的行line里的每个文字,生成列表i sys.stdout.write(i) #标准输出 这就是导入sys模块的原因,用到其中的stdout.write,后面跟上(i)——标准输出上一行的文字列表i sys.stdout.flush() #刷新 这是间隔一段时间刷新的意思,sys.stdout .flush ... time.sleep(0.05) #输出时间控制 再次看到time模块的.sleep ,参数设定为(0.1)秒 import re,os,sys #导入 re os sys 模块 具体运用到的功能详解。 def compute_exponent(arg): #定义一个函数 指数计算 ps() 里的arg 前几天的博文里有记录作用和含义 """ 操作指数 :param expression:表达式 :return:计算结果 """ val = arg[0] #声明一个变量 val = arg ps.列表是零 pattern = re.compile(r'\d+\.?\d*[\*]{2}[\+\-]?\d+\.?\d*') #有点复杂了,起码用上了re.compile 正则表达式…… mch = pattern.search(val) # 不太懂了!! if not mch: return content = pattern.search(val).group() if len(content.split('**'))>1: n1, n2 = content.split('**') value = float(n1) ** float(n2) else: pass before, after = pattern.split(val, 1) new_str = "%s%s%s" % (before,value,after) arg[0] = new_str compute_exponent(arg) def compute_mul_div(arg): """ 操作乘除 :param expression:表达式 :return:计算结果 """ val = arg[0] pattern = re.compile(r'\d+\.?\d*[\*\/\%\/\/]+[\+\-]?\d+\.*\d*') mch = pattern.search(val) if not mch: return content = pattern.search(val).group() if len(content.split('*'))>1: n1, n2 = content.split('*') value = float(n1) * float(n2) elif len(content.split('//'))>1: n1, n2 = content.split('//') value = float(n1) // float(n2) elif len(content.split('%'))>1: n1, n2 = content.split('%') value = float(n1) % float(n2) elif len(content.split('/'))>1: n1, n2 = content.split('/') value = float(n1) / float(n2) else: pass before, after = pattern.split(val, 1) new_str = "%s%s%s" % (before,value,after) arg[0] = new_str compute_mul_div(arg) def compute_add_sub(arg): """ 操作加减 :param expression:表达式 :return:计算结果 """ while True: if arg[0].__contains__('+-') or arg[0].__contains__("++") or arg[0].__contains__('-+') or arg[0].__contains__("--"): arg[0] = arg[0].replace('+-','-') arg[0] = arg[0].replace('++','+') arg[0] = arg[0].replace('-+','-') arg[0] = arg[0].replace('--','+') else: break if arg[0].startswith('-'): arg[1] += 1 arg[0] = arg[0].replace('-','&') arg[0] = arg[0].replace('+','-') arg[0] = arg[0].replace('&','+') arg[0] = arg[0][1:] val = arg[0] pattern = re.compile(r'\d+\.?\d*[\+\-]{1}\d+\.?\d*') mch = pattern.search(val) if not mch: return content = pattern.search(val).group() if len(content.split('+'))>1: n1, n2 = content.split('+') value = float(n1) + float(n2) else: n1, n2 = content.split('-') value = float(n1) - float(n2) before, after = pattern.split(val, 1) new_str = "%s%s%s" % (before,value,after) arg[0] = new_str compute_add_sub(arg) def compute(expression): """ 操作加减乘除 :param expression:表达式 :return:计算结果 """ inp = [expression,0] # 处理表达式中的指数 compute_exponent(inp) # 处理表达式中的乘除求余等 compute_mul_div(inp) # 处理表达式的加减 compute_add_sub(inp) if divmod(inp[1],2)[1] == 1: result = float(inp[0]) result = result * -1 else: result = float(inp[0]) return result def exec_bracket(expression): """ 递归处理括号,并计算 :param expression: 表达式 :return:最终计算结果 """ pattern = re.compile(r'\(([\+\-\*\/\%\/\/\*\*]*\d+\.*\d*){2,}\)') # 如果表达式中已经没有括号,则直接调用负责计算的函数,将表达式结果返回,如:2*1-82+444 #if not re.search('\(([\+\-\*\/]*\d+\.*\d*){2,}\)', expression): if not pattern.search(expression): final = compute(expression) return final # 获取 第一个 只含有 数字/小数 和 操作符 的括号 # 如: # ['1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'] # 找出:(-40.0/5) content = pattern.search(expression).group() # 分割表达式,即: # 将['1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'] # 分割更三部分:['1-2*((60-30+( (-40.0/5) *(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'] before, nothing, after = pattern.split(expression, 1) print('分解中:',expression) content = content[1:len(content)-1] # 计算,提取的表示 (-40.0/5),并活的结果,即:-40.0/5=-8.0 ret = compute(content) print('%s=%s' %( content, ret)) # 将执行结果拼接,['1-2*((60-30+( -8.0 *(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'] expression = "%s%s%s" %(before, ret, after) print('下一步:',expression) print("~"*10,'按优先级运算ing...',"~"*10) # 循环继续下次括号处理操作,本次携带者的是已被处理后的表达式,即: # ['1-2*((60-30+ -8.0 *(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'] # 如此周而复始的操作,直到表达式中不再含有括号 return exec_bracket(expression) # 使用 __name__ 的目的: # 只有执行 python index.py 时,以下代码才执行 # 如果其他人导入该模块,以下代码不执行 if __name__ == "__main__": flag = True while flag: calculate_input = input('\033[43m请输入要计算的算式 | (退出请按q)\033[0m') calculate_input = re.sub('\s*','',calculate_input) if len(calculate_input) == 0: continue elif calculate_input == 'q': print("欢迎使用,再见!".center(48, "-")) exit() elif re.search('[^0-9\.\-\+\*\/\%\/\/\*\*\(\)]',calculate_input): print('\033[31m 输入错误,请重新输入!!!\033[0m') else: result = exec_bracket(calculate_input) print('\033[31m最终的计算结果是: %s\033[0m' % result)
好吧,这段代码比较长,而且个人感觉还不够完美,只解析了括号内的运算