1. # 开发一个简单的python计算器
    # 实现加减乘除及括号优先级解析
    # 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )
    # 等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式(不能调用eval等类似功能偷懒实现),运算后得出结果,结果必须与真实的计算器所得出的结果一致
  2.  
  3. 一.对公式进行简单处理(去掉空格及公式化简)
  1. import re
  2.  
  3. def format_string(string):
  4. string = string.replace(' ','')
  5. string = string.replace('++','+')
  6. string = string.replace('+-','-')
  7. string = string.replace('-+','-')
  8. string = string.replace('--','+')
  9. string = string.replace('*+','*')
  10. string = string.replace('/+','/')
  11. return string

二.对于不符合要求的公式进行异常处理,给出错误提示信息

  1. def check_expression(string):
  2. check_result = True
  3. if not string.count("(") == string.count(")"):
  4. print('括号不对称')
  5. check_result = False
  6. if re.findall('[a-z]',string.lower()):
  7. print('表达式有错,包含非法字符')
  8. check_result = False
  9. return check_result

三.进行乘除运算,并将计算的结果替换掉原公式中的乘除法运算

  1. def mul_div(string):
      #正则表达式匹配(x乘以y或x除以y)
  2. regular = '\d+\.?\d*([*/]|\*\*)[\-]?\d+\.?\d*'
      #一直到公式中没有除法或乘法运算时,退出循环
  3. while re.findall(regular,string):
  4. expression = re.search(regular,string).group()
      #计算乘法,并将计算的结果替换原来的式子
  5. if expression.count("*") == 1:
  6. x,y = expression.split('*')
  7. mul_result = str(float(x) * float(y))
  8. string = string.replace(expression,mul_result)
  9. string = format_string(string)
      #计算除法,并将计算的结果替换原来的式子
  10. if expression.count("/") :
  11. x,y = expression.split('/')
  12. div_result = str(float(x) / float(y))
  13. string = string.replace(expression,div_result)
  14. string = format_string(string)
  15. return string

四.进行加减法运算

  1. def add_sub(string):
  2. sub_regu = '[\-]?\d+\.?\d*\-[\-]?\d+\.?\d*'
  3. add_regu = '[\-]?\d+\.?\d*\+[\-]?\d+\.?\d*'
  4. #计算加法
  5. while re.findall(add_regu,string):
  6. add_list = re.findall(add_regu,string)
  7. for add_str in add_list:
  8. x,y = add_str.split("+")
  9. add_result = "+" + str(float(x) + float(y))
  10. string = string.replace(add_str, add_result)
  11. #计算减法
  12. while re.findall(sub_regu,string):
  13. sub_list = re.findall(sub_regu,string)
  14. for sub_str in sub_list:
  15. numbers = sub_str.split('-')
  16. if len(numbers) == 3:
  17. result = 0
  18. #计算-1-2这种情况
  19. for v in numbers:
  20. if v:
  21. result -= float(v)
  22. else:
  23. x,y = numbers
  24. result = float(x)-float(y)
  25. string = string.replace(sub_str,"+" + str(result))
  26. string = format_string(string)
  27. return string

五.轮子造好了,主逻辑程序

  1. if __name__ =="__main__":

  2. if check_expression(source):
  3. strs = format_string(source)
  4. while source.count('(') > 0:
    #匹配最里层括号的内容
  5. strs = re.search('\([^()]*\)',source).group()
  6. replace_str = mul_div(strs)
  7. replace_str = add_sub(replace_str)
           #每次计算的结果去掉括号
  8. source = format_string(source.replace(strs,replace_str[1:-1]))
  9. # print(source)
    #else下边的逻辑是计算不带括号的式子
  10. else:
  11. replace_str = mul_div(source)
  12. replace_str = add_sub(replace_str)
  13. source = source.replace(source,replace_str)
  14. print(source)

六.总结-难点

1.匹配最里层的式子:'\([^()]*\)'

2.匹配乘除法及加减法的正则表达式

3.主逻辑的设计

七.总程序

  1. import re
  2.  
  3. def format_string(string):
  4. string = string.replace(' ','')
  5. string = string.replace('++','+')
  6. string = string.replace('+-','-')
  7. string = string.replace('-+','-')
  8. string = string.replace('--','+')
  9. string = string.replace('*+','*')
  10. string = string.replace('/+','/')
  11. return string
  12.  
  13. def mul_div(string):
  14. "计算乘除运算,所得的结果替换原先的表达式返回"
  15. regular = '\d+\.?\d*([*/]|\*\*)[\-]?\d+\.?\d*'
  16. while re.findall(regular,string):
  17. expression = re.search(regular,string).group()
  18. if expression.count("*") == 1:
  19. x,y = expression.split('*')
  20. mul_result = str(float(x) * float(y))
  21. string = string.replace(expression,mul_result)
  22. string = format_string(string)
  23. if expression.count("/") :
  24. x,y = expression.split('/')
  25. div_result = str(float(x) / float(y))
  26. string = string.replace(expression,div_result)
  27. string = format_string(string)
  28. return string
  29.  
  30. def add_sub(string):
  31. sub_regu = '[\-]?\d+\.?\d*\-[\-]?\d+\.?\d*'
  32. add_regu = '[\-]?\d+\.?\d*\+[\-]?\d+\.?\d*'
  33. #计算加法
  34. while re.findall(add_regu,string):
  35. add_list = re.findall(add_regu,string)
  36. for add_str in add_list:
  37. x,y = add_str.split("+")
  38. add_result = "+" + str(float(x) + float(y))
  39. string = string.replace(add_str, add_result)
  40. #计算减法
  41. while re.findall(sub_regu,string):
  42. sub_list = re.findall(sub_regu,string)
  43. for sub_str in sub_list:
  44. numbers = sub_str.split('-')
  45. if len(numbers) == 3:
  46. result = 0
  47. #计算-1-2这种情况
  48. for v in numbers:
  49. if v:
  50. result -= float(v)
  51. else:
  52. x,y = numbers
  53. result = float(x)-float(y)
  54. string = string.replace(sub_str,"+" + str(result))
  55. string = format_string(string)
  56. return string
  57.  
  58. def check_expression(string):
  59. check_result = True
  60. if not string.count("(") == string.count(")"):
  61. print('表达式有错,括号不对')
  62. check_result = False
  63. if re.findall('[a-z]',string.lower()):
  64. print('表达式有错,包含非法字符')
  65. check_result = False
  66. return check_result
  67.  
  68. if __name__ =="__main__":
  69. source = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
  70. if check_expression(source):
  71. strs = format_string(source)
  72. while source.count('(') > 0:
  73. strs = re.search('\([^()]*\)',source).group()
  74. replace_str = mul_div(strs)
  75. replace_str = add_sub(replace_str)
  76. source = format_string(source.replace(strs,replace_str[1:-1]))
  77. else:
  78. replace_str = mul_div(source)
  79. replace_str = add_sub(replace_str)
  80. source = source.replace(source,replace_str)
  81. print(source)

python-计算器实现的更多相关文章

  1. python 计算器的(正则匹配+递归)

    经过2天的长时间的战斗,python计算器终于完成了. import re val="1-2*((60-30*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3 ...

  2. Python计算器实操

    要求: 开发一个简单的python计算器 实现加减乘除及拓号优先级解析 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * ...

  3. 7_python之路之python计算器

    7_python之路之python计算器 1.程序说明:Readme.cmd 1.程序文件及说明: calculator.py 2.python版本:python-3.5.3 3.程序使用:pytho ...

  4. 作业1开发一个简单的python计算器

    开发一个简单的python计算器 实现加减乘除及拓号优先级解析 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568 ...

  5. 老男孩python作业5-开发一个简单的python计算器

    开发一个简单的python计算器 实现加减乘除及拓号优先级解析 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568 ...

  6. project1_calculator(使用tkinter实现python计算器,含有具体过程与注释)

    最终的运行效果图(程序见序号7): #!/usr/bin/env python# -*- coding:utf-8 -*-# ------------------------------------- ...

  7. Github Python计算器开源项目 二次开发--增加函数图形

    先上原项目链接:https://github.com/xhf79/Calculator_pyqt python+Qt 开发的计算器 原项目界面和功能如图所示: 科学计算的内容基本都有,但按照项目的提示 ...

  8. python计算器

    思路:优先级处理思路一:正则表达式+递归(计算时间慢)思路二:堆栈的方式队列:先进先出电梯-->队列上电梯(入队123):第三个人3,第二个人2,第一个人1>>> li = [ ...

  9. 开发一个简单的python计算器

    要求: 实现加减乘除及拓号优先级解析 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4* ...

  10. 初版python计算器

    作业: 使用正则表达式实现计算器功能. 实现: 1.实现带括号的计算 2.实现指数.加减乘除求余等功能 先看运行结果: 请输入您的计算式: 1 - 2 * ( (60-30 +(-40.0/5) * ...

随机推荐

  1. Android调试技巧

    转自:http://gityuan.com/2017/07/11/android_debug/ 一. 获取Trace 调用栈信息(Trace)是分析异常经常使用的,这里简单划分两类情况: 当前线程Tr ...

  2. bs-loading

    根据bootstrap的modal来显示loading动效. 核心内容: 1.图片转base64方法: // 图片压缩-start function run(input_file,get_data){ ...

  3. 关于egret.Tween传递参数的问题

    参考: setTimeOut传参数(转) setTimeout传参数 CSDN 一.延迟后执行,并输出参数 for(let i=0;i<10;i++){ egret.Tween.get(this ...

  4. CentOS系统下docker的安装与卸载

    Docker简介 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制, ...

  5. Java虚拟机二 虚拟机的基本结构

    Java虚拟机的基本结构如图所示 类加载子系统负责从文件系统或网络中加载Class信息,加载的类信息存放于一块称为方法区的内存空间.除了类的信息外,方法区中可能还会存放运行是的常量池信息, 包括字符串 ...

  6. Penn Treebank

    NLP中常用的PTB语料库,全名Penn Treebank.Penn Treebank是一个项目的名称,项目目的是对语料进行标注,标注内容包括词性标注以及句法分析. 语料来源为:1989年华尔街日报语 ...

  7. iOS8新特性(2)——UIPopoverController和UIPresentationController

    一.以往使用 UIPopoverController 都是只在iPad上使用 /** * UIPopoverController 只能用于iPad,上,iPhone上使用会崩溃 */ -(void)o ...

  8. python类中的self参数和cls参数

    1. self表示一个类的实例对象本身.如果用了staticmethod就无视这个self了,就将这个方法当成一个普通的函数使用了. 2. cls表是这个类本身. # 代码为证 class A(obj ...

  9. POJ-2184 Cow Exhibition(01背包变形)

    Cow Exhibition Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10949 Accepted: 4344 Descr ...

  10. Ubuntu 16.04: How to install OpenCV

    参考:https://www.pyimagesearch.com/2016/10/24/ubuntu-16-04-how-to-install-opencv/ 步骤# 1:安装opencv的依赖项 本 ...