作业:

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

实现:

1、实现带括号的计算

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) )
第 1 选取的()为: ★(-40.0/5)★
选取 乘除 运算第 1 运算式为:★40.0/5★
乘除 运算第 1 运算式的结果为: ★-8.0★
第 1 选取的()计算结果为: ★-8.0★
新的表达式为: 1-2*((60-30-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))
第 2 选取的()为: ★(9-2*5/3+7/3*99/4*2998+10*568/14)★
选取 乘除 运算第 1 运算式为:★2*5★
乘除 运算第 1 运算式的结果为: ★9-10.0/3+7/3*99/4*2998+10*568/14★
选取 乘除 运算第 2 运算式为:★10.0/3★
乘除 运算第 2 运算式的结果为: ★9-3.3333+7/3*99/4*2998+10*568/14★
选取 乘除 运算第 3 运算式为:★7/3★
乘除 运算第 3 运算式的结果为: ★9-3.3333+2.3333*99/4*2998+10*568/14★
选取 乘除 运算第 4 运算式为:★2.3333*99★
乘除 运算第 4 运算式的结果为: ★9-3.3333+230.9967/4*2998+10*568/14★
选取 乘除 运算第 5 运算式为:★230.9967/4★
乘除 运算第 5 运算式的结果为: ★9-3.3333+57.7491*2998+10*568/14★
选取 乘除 运算第 6 运算式为:★57.7491*2998★
乘除 运算第 6 运算式的结果为: ★9-3.3333+173131.8018+10*568/14★
选取 乘除 运算第 7 运算式为:★10*568★
乘除 运算第 7 运算式的结果为: ★9-3.3333+173131.8018+5680.0/14★
选取 乘除 运算第 8 运算式为:★5680.0/14★
乘除 运算第 8 运算式的结果为: ★9-3.3333+173131.8018+405.7142★
选取 加减 运算第 1 运算式为:★9-3.3333★
加减 运算第 1 运算式的结果为: ★5.6667+173131.8018+405.7142★
选取 加减 运算第 2 运算式为:★5.6667+173131.8018★
加减 运算第 2 运算式的结果为: ★173137.4685+405.7142★
选取 加减 运算第 3 运算式为:★173137.4685+405.7142★
加减 运算第 3 运算式的结果为: ★173543.1826★
第 2 选取的()计算结果为: ★173543.1826★
新的表达式为: 1-2*((60-30-8.0*173543.1826)-(-4*3)/(16-3*2))
第 3 选取的()为: ★(60-30-8.0*173543.1826)★
选取 乘除 运算第 1 运算式为:★8.0*173543.1826★
乘除 运算第 1 运算式的结果为: ★60-30-1388345.4608★
选取 加减 运算第 1 运算式为:★60-30★
加减 运算第 1 运算式的结果为: ★30.0-1388345.4608★
选取 加减 运算第 2 运算式为:★30.0-1388345.4608★
加减 运算第 2 运算式的结果为: ★-1388315.4608★
第 3 选取的()计算结果为: ★-1388315.4608★
新的表达式为: 1-2*(-1388315.4608-(-4*3)/(16-3*2))
第 4 选取的()为: ★(-4*3)★
选取 乘除 运算第 1 运算式为:★4*3★
乘除 运算第 1 运算式的结果为: ★-12.0★
第 4 选取的()计算结果为: ★-12.0★
新的表达式为: 1-2*(-1388315.4608+12.0/(16-3*2))
第 5 选取的()为: ★(16-3*2)★
选取 乘除 运算第 1 运算式为:★3*2★
乘除 运算第 1 运算式的结果为: ★16-6.0★
选取 加减 运算第 1 运算式为:★16-6.0★
加减 运算第 1 运算式的结果为: ★10.0★
第 5 选取的()计算结果为: ★10.0★
新的表达式为: 1-2*(-1388315.4608+12.0/10.0)
第 6 选取的()为: ★(-1388315.4608+12.0/10.0)★
选取 乘除 运算第 1 运算式为:★12.0/10.0★
乘除 运算第 1 运算式的结果为: ★-1388315.4608+1.2★
选取 加减 运算第 1 运算式为:★-1388315.4608+1.2★
加减 运算第 1 运算式的结果为: ★-1388314.2608★
第 6 选取的()计算结果为: ★-1388314.2608★
新的表达式为: 1-2*-1388314.2608
()选择结束,执行如上最后计算式
选取 乘除 运算第 1 运算式为:★2*-1388314.2608★
乘除 运算第 1 运算式的结果为: ★1+2776628.5216★
选取 加减 运算第 1 运算式为:★1+2776628.5216★
加减 运算第 1 运算式的结果为: ★2776629.5216★
最后的计算结果为: ★2776629.5216★

运行结果

大致思路:

1、匹配模块:

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

2、计算模块:

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

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

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

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

源码如下:

 import re
welcome = '''
-------------------------------------
welcome to the counter of lmh
-------------------------------------
'''
def format_s(x): #格式化输出
x = re.sub(r'\s+','',x)
x = re.sub(r'\++|\-\-',r'+',x)
x = re.sub(r'\-\+|\+\-',r'-',x)
x = re.sub(r'\.+',r'.',x)
while True:
x1 = re.search(r'\d+\.\d{5}',x)
if x1 == None:
break
else:
x2 = re.search(r'\d+\.\d{4}',x1.group())
x = re.sub(r'\d+\.\d{5,}',x2.group(),x,1)
return x def islegal(x): #判断输入是否合法
global flag
flag = 0
ret0 = re.search('\.\d+\..*',x)
ret = re.sub(r'\d|\+|\-|\*|\/|\(|\)|\s+|\.+','',x)
if ret0 ==None and ret == '':
pass
else:
print('您的输入不合法请重新输入')
flag = 1 def cal_num(x): #二元计算式算法,x为需要处理的二元字符串
ss = re.search('\D',x)
if ss == None:
return x
else:
s1 = float(re.search('^\-*\d+\.?\d*',x).group()) #选取元素x
s2 = float(re.search('\-*\d+\.?\d*$',x).group()) #选取元素y
sb = re.search(r'\*',x) #匹配二元计算式是否包含元素*
sb2 = re.search(r'/',x) #匹配二元计算式是否包含元素/
sb3 = re.search(r'\+',x) #匹配二元计算式是否包含是否元素+,前面已经格式化。有+号代表选取的二元计算式只能是+法运算
sb4 = re.search('\-*\d+\.?\d*\-\-*\d+\.?\d*',x) #选取元素- 注意:第一个元素可能有负号,因此需要选取左右都为数字的
if sb != None:
s4 = float(s1) * float(s2)
elif sb2 != None:
s4 = float(s1) / float(s2)
elif sb3 != None:
s4 = float(s1) + float(s2)
elif sb4 != None:
s4 = float(s1) + float(s2)
else:
s4 = float(s1)
s5 = str(s4)
return s5 def cal_select(p):#先乘除后加减方法
d = '乘除'
first = re.compile(r'\d+\.*\d*\*\-*\d+\.*\d*|\d+\.*\d*/\-*\d+\.*\d*')#匹配*号或者/前面的数字和后面的数字。注意:前面不匹配-号,后面需要匹配-号
second = re.compile(r'\-*\d+\.*\d*\+\-*\d+\.*\d*|\-*\d+\.*\d*\-\-*\d+\.*\d*')#匹配+号前面的数字和后面的数字。注意:前面匹配-号,后面也需要匹配-号
def cir(x):
i = 1
while True:
nonlocal p
s0 = x.search(p) #选取第一个2元计算式
if s0 == None:
break
s0 = s0.group()
print(' 选取 %s 运算第 %s 运算式为:★%s★'%(d,i,s0))
p = re.sub(x, cal_num(s0), p,count=1)
p = format_s(p)
print(' %s 运算第 %s 运算式的结果为: ★%s★'%(d,i,p))
i += 1
cir(first)
d = '加减'
cir(second)
p = format_s(p)
return p while True:#判断输入合法性
print(welcome)
s = input(r'请输入您的计算式: ')
islegal(s)
if flag == 1:
continue
else:
break
s = format_s(s) i=1
while True:#依次匹配最内部()
find_parentheses = re.compile(r'\([^()]*\)') #匹配最内部(..)方法
clear_parentheses = re.compile('\(|\)') #只匹配()方法
ret = find_parentheses.search(s) #匹配字符串s最内部括号
if ret == None:
break
s0 = clear_parentheses.sub('',ret.group()) #取消字符串s最内部括号,保留内部计算式s0
print('第 %s 选取的()为: ★%s★'%(i,ret.group()))
s5 = cal_select(s0) #计算s0结果
print('第 %s 选取的()计算结果为: ★%s★'%(i,s5))
s = re.sub(find_parentheses,s5,s,count=1) #替换在s字符串中替换so
s = format_s(s) #刷新格式
print('新的表达式为: %s'%s)
i += 1 print('()选择结束,执行如上最后计算式')
s = cal_select(s)
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. js按位运算符及其妙用

    大多数语言都提供了按位运算符,恰当的使用按位运算符有时候会取得的很好的效果. 在我看来按位运算符应该有7个: 1.& 按位与 &是二元运算符,它以特定的方式的方式组合操作数中对应的位, ...

  2. cobbler自动化安装系统

    笔者Q:972581034 交流群:605799367.有任何疑问可与笔者或加群交流 在很久很久以前,使用kickstart实现自动化安装的时候,我一直认为装系统是多么高大上的活,直到cobbler的 ...

  3. iOS-cocoapods安装与使用以及常见错误

    前言 CocoaPods是一个负责管理iOS项目中第三方开源代码的工具. 二.安装由于网上的教程基本都大同小异,但细节之处还不是很完善,所以借机会在这里补充下:注:要使用CocoaPods,那就要下载 ...

  4. 监控mysql主从同步状态

    在高并发网站架构中,MySQL数据库主从同步是不可或缺的,不过经常会发生由于网络原因或者操作错误,MySQL主从经常会出现不同步的情况,那么如何监控MySQL主从同步,也变成网站正常运行的重要环节. ...

  5. 树莓派用U盘安装系统

    * 需要使用Raspbian / Raspbian Lite或更高版本的2017-04-10版本 *不会SD卡装系统? 1.  先用装好Raspbian系统的SD卡启动 在命令行输入    echo ...

  6. Django框架初识

    一.安装: pip3 install django 注意pip加入环境变量,安装好以后记得把Django加入环境变量     安装完成后,会在python目录下多了两个文件:1个django文件,1个 ...

  7. 《深入理解Java虚拟机》学习笔记(二)

    垃圾回收的前提是判断对象是否存活,对象不再存活时将会被回收,下面是2种判断的方法. 引用计数法: 主流的Java虚拟机并没有使用引用计数法来管理内存,重要的原因就是循环引用的问题难以解决. 可达性分析 ...

  8. HDU [P1704] Rank

    传递闭包裸题 但是本题的Floyd一定要优化,不然会T cpp #include <iostream> #include <cstdio> #include <cstri ...

  9. Linux内存机制以及手动释放swap和内存

    今天我们来谈谈Linux的内存机制. 首先我们理一下概念 一.什么是linux的内存机制? 我们知道,直接从物理内存读写数据要比从硬盘读写数据要快的多,因此,我们希望所有数据的读取和写入都在内存完成, ...

  10. Azure ARM (21) Azure订阅的两种管理模式

    <Windows Azure Platform 系列文章目录> 熟悉Azure平台的读者都知道,Microsoft Azure服务管理,分为三个层次: 1.企业服务合同 (Enterpri ...