作业:

使用正则表达式实现计算器功能。

实现:

1、实现带括号的计算

2、实现指数、加减乘除求余等功能

先看运行结果:

  1. 请输入您的计算式: 1 - 2 * ( (60-30 +(-40.0/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )
  2. 1 选取的()为: ★(-40.0/5)★
  3. 选取 乘除 运算第 1 运算式为:★40.0/5
  4. 乘除 运算第 1 运算式的结果为: ★-8.0
  5. 1 选取的()计算结果为: ★-8.0
  6. 新的表达式为: 1-2*((60-30-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))
  7. 2 选取的()为: ★(9-2*5/3+7/3*99/4*2998+10*568/14)★
  8. 选取 乘除 运算第 1 运算式为:★2*5
  9. 乘除 运算第 1 运算式的结果为: 9-10.0/3+7/3*99/4*2998+10*568/14
  10. 选取 乘除 运算第 2 运算式为:★10.0/3
  11. 乘除 运算第 2 运算式的结果为: 9-3.3333+7/3*99/4*2998+10*568/14
  12. 选取 乘除 运算第 3 运算式为:★7/3
  13. 乘除 运算第 3 运算式的结果为: 9-3.3333+2.3333*99/4*2998+10*568/14
  14. 选取 乘除 运算第 4 运算式为:★2.3333*99
  15. 乘除 运算第 4 运算式的结果为: 9-3.3333+230.9967/4*2998+10*568/14
  16. 选取 乘除 运算第 5 运算式为:★230.9967/4
  17. 乘除 运算第 5 运算式的结果为: 9-3.3333+57.7491*2998+10*568/14
  18. 选取 乘除 运算第 6 运算式为:★57.7491*2998
  19. 乘除 运算第 6 运算式的结果为: 9-3.3333+173131.8018+10*568/14
  20. 选取 乘除 运算第 7 运算式为:★10*568
  21. 乘除 运算第 7 运算式的结果为: 9-3.3333+173131.8018+5680.0/14
  22. 选取 乘除 运算第 8 运算式为:★5680.0/14
  23. 乘除 运算第 8 运算式的结果为: 9-3.3333+173131.8018+405.7142
  24. 选取 加减 运算第 1 运算式为:★9-3.3333
  25. 加减 运算第 1 运算式的结果为: 5.6667+173131.8018+405.7142
  26. 选取 加减 运算第 2 运算式为:★5.6667+173131.8018
  27. 加减 运算第 2 运算式的结果为: 173137.4685+405.7142
  28. 选取 加减 运算第 3 运算式为:★173137.4685+405.7142
  29. 加减 运算第 3 运算式的结果为: 173543.1826
  30. 2 选取的()计算结果为: 173543.1826
  31. 新的表达式为: 1-2*((60-30-8.0*173543.1826)-(-4*3)/(16-3*2))
  32. 3 选取的()为: ★(60-30-8.0*173543.1826)★
  33. 选取 乘除 运算第 1 运算式为:★8.0*173543.1826
  34. 乘除 运算第 1 运算式的结果为: 60-30-1388345.4608
  35. 选取 加减 运算第 1 运算式为:★60-30
  36. 加减 运算第 1 运算式的结果为: 30.0-1388345.4608
  37. 选取 加减 运算第 2 运算式为:★30.0-1388345.4608
  38. 加减 运算第 2 运算式的结果为: ★-1388315.4608
  39. 3 选取的()计算结果为: ★-1388315.4608
  40. 新的表达式为: 1-2*(-1388315.4608-(-4*3)/(16-3*2))
  41. 4 选取的()为: ★(-4*3)★
  42. 选取 乘除 运算第 1 运算式为:★4*3
  43. 乘除 运算第 1 运算式的结果为: ★-12.0
  44. 4 选取的()计算结果为: ★-12.0
  45. 新的表达式为: 1-2*(-1388315.4608+12.0/(16-3*2))
  46. 5 选取的()为: ★(16-3*2)★
  47. 选取 乘除 运算第 1 运算式为:★3*2
  48. 乘除 运算第 1 运算式的结果为: 16-6.0
  49. 选取 加减 运算第 1 运算式为:★16-6.0
  50. 加减 运算第 1 运算式的结果为: 10.0
  51. 5 选取的()计算结果为: 10.0
  52. 新的表达式为: 1-2*(-1388315.4608+12.0/10.0)
  53. 6 选取的()为: ★(-1388315.4608+12.0/10.0)★
  54. 选取 乘除 运算第 1 运算式为:★12.0/10.0
  55. 乘除 运算第 1 运算式的结果为: ★-1388315.4608+1.2
  56. 选取 加减 运算第 1 运算式为:★-1388315.4608+1.2
  57. 加减 运算第 1 运算式的结果为: ★-1388314.2608
  58. 6 选取的()计算结果为: ★-1388314.2608
  59. 新的表达式为: 1-2*-1388314.2608
  60. ()选择结束,执行如上最后计算式
  61. 选取 乘除 运算第 1 运算式为:★2*-1388314.2608
  62. 乘除 运算第 1 运算式的结果为: 1+2776628.5216
  63. 选取 加减 运算第 1 运算式为:★1+2776628.5216
  64. 加减 运算第 1 运算式的结果为: 2776629.5216
  65. 最后的计算结果为: 2776629.5216

运行结果

大致思路:

1、匹配模块:

循环匹配最内部括号,匹配后计算结果并替换原字符串

2、计算模块:

循环匹配乘除运算、匹配后计算结果并替换

循环匹配加减运算、匹配后计算结果并替换

3、里面有很多细节要注意如:

检测非法输入、保留四位小数、-号的处理原则等。

源码如下:

  1. import re
  2. welcome = '''
  3. -------------------------------------
  4. welcome to the counter of lmh
  5. -------------------------------------
  6. '''
  7. def format_s(x): #格式化输出
  8. x = re.sub(r'\s+','',x)
  9. x = re.sub(r'\++|\-\-',r'+',x)
  10. x = re.sub(r'\-\+|\+\-',r'-',x)
  11. x = re.sub(r'\.+',r'.',x)
  12. while True:
  13. x1 = re.search(r'\d+\.\d{5}',x)
  14. if x1 == None:
  15. break
  16. else:
  17. x2 = re.search(r'\d+\.\d{4}',x1.group())
  18. x = re.sub(r'\d+\.\d{5,}',x2.group(),x,1)
  19. return x
  20.  
  21. def islegal(x): #判断输入是否合法
  22. global flag
  23. flag = 0
  24. ret0 = re.search('\.\d+\..*',x)
  25. ret = re.sub(r'\d|\+|\-|\*|\/|\(|\)|\s+|\.+','',x)
  26. if ret0 ==None and ret == '':
  27. pass
  28. else:
  29. print('您的输入不合法请重新输入')
  30. flag = 1
  31.  
  32. def cal_num(x): #二元计算式算法,x为需要处理的二元字符串
  33. ss = re.search('\D',x)
  34. if ss == None:
  35. return x
  36. else:
  37. s1 = float(re.search('^\-*\d+\.?\d*',x).group()) #选取元素x
  38. s2 = float(re.search('\-*\d+\.?\d*$',x).group()) #选取元素y
  39. sb = re.search(r'\*',x) #匹配二元计算式是否包含元素*
  40. sb2 = re.search(r'/',x) #匹配二元计算式是否包含元素/
  41. sb3 = re.search(r'\+',x) #匹配二元计算式是否包含是否元素+,前面已经格式化。有+号代表选取的二元计算式只能是+法运算
  42. sb4 = re.search('\-*\d+\.?\d*\-\-*\d+\.?\d*',x) #选取元素- 注意:第一个元素可能有负号,因此需要选取左右都为数字的
  43. if sb != None:
  44. s4 = float(s1) * float(s2)
  45. elif sb2 != None:
  46. s4 = float(s1) / float(s2)
  47. elif sb3 != None:
  48. s4 = float(s1) + float(s2)
  49. elif sb4 != None:
  50. s4 = float(s1) + float(s2)
  51. else:
  52. s4 = float(s1)
  53. s5 = str(s4)
  54. return s5
  55.  
  56. def cal_select(p):#先乘除后加减方法
  57. d = '乘除'
  58. first = re.compile(r'\d+\.*\d*\*\-*\d+\.*\d*|\d+\.*\d*/\-*\d+\.*\d*')#匹配*号或者/前面的数字和后面的数字。注意:前面不匹配-号,后面需要匹配-号
  59. second = re.compile(r'\-*\d+\.*\d*\+\-*\d+\.*\d*|\-*\d+\.*\d*\-\-*\d+\.*\d*')#匹配+号前面的数字和后面的数字。注意:前面匹配-号,后面也需要匹配-号
  60. def cir(x):
  61. i = 1
  62. while True:
  63. nonlocal p
  64. s0 = x.search(p) #选取第一个2元计算式
  65. if s0 == None:
  66. break
  67. s0 = s0.group()
  68. print(' 选取 %s 运算第 %s 运算式为:★%s★'%(d,i,s0))
  69. p = re.sub(x, cal_num(s0), p,count=1)
  70. p = format_s(p)
  71. print(' %s 运算第 %s 运算式的结果为: ★%s★'%(d,i,p))
  72. i += 1
  73. cir(first)
  74. d = '加减'
  75. cir(second)
  76. p = format_s(p)
  77. return p
  78.  
  79. while True:#判断输入合法性
  80. print(welcome)
  81. s = input(r'请输入您的计算式: ')
  82. islegal(s)
  83. if flag == 1:
  84. continue
  85. else:
  86. break
  87. s = format_s(s)
  88.  
  89. i=1
  90. while True:#依次匹配最内部()
  91. find_parentheses = re.compile(r'\([^()]*\)') #匹配最内部(..)方法
  92. clear_parentheses = re.compile('\(|\)') #只匹配()方法
  93. ret = find_parentheses.search(s) #匹配字符串s最内部括号
  94. if ret == None:
  95. break
  96. s0 = clear_parentheses.sub('',ret.group()) #取消字符串s最内部括号,保留内部计算式s0
  97. print('第 %s 选取的()为: ★%s★'%(i,ret.group()))
  98. s5 = cal_select(s0) #计算s0结果
  99. print('第 %s 选取的()计算结果为: ★%s★'%(i,s5))
  100. s = re.sub(find_parentheses,s5,s,count=1) #替换在s字符串中替换so
  101. s = format_s(s) #刷新格式
  102. print('新的表达式为: %s'%s)
  103. i += 1
  104.  
  105. print('()选择结束,执行如上最后计算式')
  106. s = cal_select(s)
  107. print('最后的计算结果为: ★%s★'%s)

counter

初版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* ...

随机推荐

  1. awk取每行最大值

    需求 有一个数字文本,每行都是数字,以空格分开:现在需要将每行中最大值取出来 文本如下: [root@localhost ~]#cat urfile 1 1 2 1 2 1 1 3 1 使用awk解决 ...

  2. 【转】GPS基线的精化处理

    影响基线解算结果的因素主要有: (1)基线解算时所设定的起点坐标不准确. 起点坐标不准确,会导致基线出现尺度和方向上的偏差,造成的影响目前还没有较容易的方法来加以判别,因此,在实际工作中,只有尽量提高 ...

  3. 刚买个炼狱蝰蛇1800dpi的下完驱动提示没有发现鼠标

    2017-02-19补充:可以下载下面的程序 ,也可以访问 http://cn.razerzone.com/synapse/  下载雷云 也可解决问题 ------------------------ ...

  4. 关于define和const

    1.通过define定义的常量,在C语言里面一般叫宏定义.define的本质是简单的文本替换. 2.const定义一个变量,但是这个变量的值只能在定义的时候赋予,之后就不能被更改了. 如果变量声明中带 ...

  5. 浅谈最大流的Dinic算法

    PART 1 什么是网络流 网络流(network-flows)是一种类比水流的解决问题方法,与线性规划密切相关.网络流的理论和应用在不断发展,出现了具有增益的流.多终端流.多商品流以及网络流的分解与 ...

  6. nodejs cluster模块初探

    大家都知道nodejs是一个单进程单线程的服务器引擎,不管有多么的强大硬件,只能利用到单个CPU进行计算.所以,为了使用多核cpu来提高性能 就有了cluster,让node可以利用多核CPU实现并行 ...

  7. CF266D. BerDonalds [图的绝对中心]

    D. BerDonalds time limit per test 5 seconds memory limit per test 256 megabytes input standard input ...

  8. SpringMVC之使用requestMapping映射请求、映射参数、映射头

    1. 映射请求 作用:使用requestMapping可以指定处理器可以处理那些请求 地方:类和方法前面都可以 @requestMapping 类定义处: 提供初步的请求映射信息,相对于web应用的根 ...

  9. Windows Server 2016-部署第一台域控制器

    上节我们提到有关WinSer 2016 Active Directory域服务概述.WinSer2016 AD域中新增的功能及先决条件等,本节就为大家带来WinSer2016下搭建部署第一台域控的操作 ...

  10. 二维码开源库ZBar-实现中文解码

    中文乱码 上篇<ZBar-windows下编译和使用>已经成功解析了条形码,但目标是二维码,经测试二维码中文会出现乱码.下图二维码的内容是"http123测试456", ...