计算器功能

  • 实现优先级解析,加减乘除四则运算
  • 自定义小数位精度

实现思想:

  • 先找到最里层括号,根据乘除,加减优先级,调用写好的乘除、加减运算函数算出括号内总值,再将原括号式用所得值替换,此过程循环进行,直到去除所有括号,得到一个只剩加减乘除的运算式。
  • 再次调用乘除加减函数算出结果。

实现方法:

  1. 正则匹配出最里层括号
  2. 括号内先算乘除后算加减,算出结果替换原括号字符串,循环执行

    乘除:正则匹配出 ([-]num1) ([*/]) ([-]num2) 分组,findall查找得到 [('2', '*', '3'), ('5', '/', '3')]列表,计算元组内值替换原字符串,循环执行,直到去除所有乘除法

    加减:正则匹配出 ([-]num1)([+-])(num2)分组,由于符号‘-’和负号相同,带符号匹配用findall方法一次匹配出所有会出现符号混乱问题;用search每次都是从头匹配只可能出现

    [-]num1 +- num2 情况,再根据分组可以直接拿到[-]num1,num2和运算符号,把结果计算出来替换原字符串,循环执行。
  3. 将最后得到的只有加减乘除的运算式再进行 乘除 加减 运算,得出最后计算结果。

代码

#!/usr/bin/env python
# -*-coding:utf-8 -*-
import re
#乘除运算
def mult(args):
pat = re.compile(r'[\-\+]?(\-?\d+\.?\d*)([\*\/])(\-?\d+\.?\d*)') #取出 [-]a*[-]b 或 [-]a/[-]b
while pat.search(args): #有符合条件的程序就一直执行,直到匹配不到返回None
m = pat.findall(args) #[('2', '*', '3'), ('5', '/', '3'), ('40', '*', '4'), ('3', '/', '5'), ('6', '*', '3')]
for tup in m: #循环列表里的元组进行计算,再用结果替换原式中对应的值 如用结果 6 替换 2*3
num1,symbol,num2 = tup
if symbol == '*':
result = float(num1) * float(num2)
elif symbol == '/':
result = float(num1) / float(num2)
args = args.replace(num1+symbol+num2, str(result), 1)
return args #加减运算
def com(args):
args = args.replace('--', '+') #将计算过程中出现的不规则运算符替换
args = args.replace('-+', '-')
args = args.replace('+-', '-')
args = args.replace('++', '+')
pat = re.compile(r'(\-?\d+\.?\d*)([\-\+])(\d+\.?\d*)') #查找 [-]a +\- b ,并对 数字 和 运算符号分组
while pat.search(args):
m = pat.search(args)
num = m.group()
num1 = float(m.group(1)) # 第一个数字
symbol = m.group(2) # 运算符号
num3 = float(m.group(3)) #第二个数字 if symbol == '-': #计算结果并替换原串中对应的值 如,用 结果 6 替换 2+3
result = num1 - num3
elif symbol == '+':
result = num1 + num3
args = args.replace(num, str(result), 1)
return args #取括号并进行括号内加减运算
def bracket(value):
pat = re.compile(r'\([^()]*\)') #取括号
while pat.search(value): #有符合条件的就一直循环,直到返回None时结束
m = pat.search(value)
# print(m.group())
res = m.group()
res_mult = mult(res) #括号内乘除法运算
res_mult = res_mult.strip('(').strip(')') #去 两边 ()号
result = com(res_mult) #加减运算
value = value.replace(res,result,1) #替换
# print(value)
return value #source = "1 - 2 * ( (60-30 +(-9-2-5-2*3-5/3-40*4/2-3/5+6*3) * (-9-2-5-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )"
print(
'''
使用方法:
1)退出程序:
按q|Q退出
2)设置精度(默认取整):
sales = NUM (设置小数精度,使用方法:在操作\计算提示符后输入 sales = NUM(NUM必须是正整数))
''')
NUM = None
while True: #计算,可设置精度
source = input('操作\计算:')
source = re.sub(r' ', '', source) if source == 'q' or source == 'Q': #是否退出判断
print('程序退出!!!')
break if not re.findall(r'\d*\.?\d*[\+\-\*\/]\d*\.?\d*', source): #如果不是计算式
if 'sales=' in source and source[6].isdigit(): #如果输入符合设置精度的要求
NUM = int(re.split(r'sales=', source)[1]) #将精度位数值赋给 NUM,返回输入计算式
continue
else: #输入不符合条件不做处理,返回重新输入
continue finn = com(mult(bracket(source))) #bracket()为去除括号后的结果,再对其进行先乘除后加减运算
print('结果:', round(float(finn), NUM))

片段解析:

加减运算部分:

def com(args):
'''
去括号之后会出现原括号外符号和括号内符号紧临的情况,要先符号合并;加减运算在乘除运算完之后进行
'''
args = args.replace('--', '+') #将计算过程中出现的不规则运算符替换
args = args.replace('-+', '-')
args = args.replace('+-', '-')
args = args.replace('++', '+') '''
匹配 ([-]num1) (+\-) (num2) 并对数字和符号分组;
所有运算都是带符号运算
'''
pat = re.compile(r'(\-?\d+\.?\d*)([\-\+])(\d+\.?\d*)') #查找 [-]a +\- b ,并对 数字 和 运算符号分组 '''
pat.search(string) 正则匹配有结果返回一个对象,为真;匹配不到返回 None,为假。
用匹配结果作循环条件
'''
while pat.search(args):
m = pat.search(args) #匹配出第一个符合条件的字符串
num = m.group()
num1 = float(m.group(1)) # 取出分组中的第一个数字
symbol = m.group(2) # 取出运算符号
num3 = float(m.group(3)) # 取出第二个数字 if symbol == '-': #判断symbol是 '-'还是'+' 计算结果
result = num1 - num3
elif symbol == '+':
result = num1 + num3
args = args.replace(num, str(result), 1) #用计算结果替换原串中对应的字符串 如,用结果 5.0 替换 2+3
return args

自定义小数位精度

使用 round(round(number, ndigits=None) 用户可自定义 ndigits.

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

  1. 从零开始学习PYTHON3讲义(二)把Python当做计算器

    <从零开始PYTHON3>第二讲 上一讲我们说过了如何启动Python IDLE集成开发学习环境,macOS/Linux都可以在命令行执行idle3.Windows则从开始菜单中去寻找ID ...

  2. python之计算器(第四天)

    作业: 使用正则表达式和递归实现计算器功能. 实现: 1.实现带括号的计算 2.实现指数.加减乘除求余等功能 一.实例说明: 本实例自己写了个版本,但依旧存在一点bug,例:-2-2等计算问题,故最后 ...

  3. 利用PYTHON设计计算器功能

    通过利用PYTHON 设计处理计算器的功能如: 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 ))- (-4*3 ...

  4. Python科学计算器(计算器)

    说明 该计算器主要是为了练习正则表达式以及python基础所写:代码比较low! 运行过程 请输入你的计算公式, 计算器会将计算结果输出到屏幕上(此处会打印步骤); 退出(exit/quit) MyC ...

  5. Python数学运算入门把Python当作计算器

    让我们尝试一些简单的 Python 命令.启动解释器,等待界面中的提示符,>>> (这应该花不了多少时间). 3.1.1. 数字 解释器就像一个简单的计算器一样:你可以在里面输入一个 ...

  6. python之计算器

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

  7. [IT学习]转载python 项目 计算器

    这个是从网上搜到的Python小项目之计算器(原文地址:http://www.2cto.com/kf/201402/279637.html).但该段代码估计是Python 2 写的. 如果你使用的程序 ...

  8. python编写计算器

    程序代码 # coding: utf-8# 将tkinter改为Tkinter兼容Python 2.xfrom tkinter import *class App: def __init__(self ...

  9. python写计算器

    #!/usr/bin/env python # -*- coding:utf-8 -*- import re def chu(arg1): #定义加减 arg = arg1[0] #beacuse p ...

随机推荐

  1. php 7.0 安装以及老版本php删除

    一, 安装php7 php7对php5是99%的兼容, 而且性能更好, 网上很多的优秀的库都对版本有一定的要求, 所以推荐安装php7 低于ubuntu 16.04的系统默认的源不带php7, 所以需 ...

  2. rails中的session

    学rails toturial的时候,第八章一直觉得有点没吃透,后来看了两篇rails关于session和cookies源码分析的文章,cookie原理与实现(rails篇) 和session原理与实 ...

  3. sql 判断 函数 存储过程是否存在的方法

    下面为您介绍sql下用了判断各种资源是否存在的代码,需要的朋友可以参考下,希望对您学习sql的函数及数据库能够有所帮助.库是否存在if exists(select * from master..sys ...

  4. [转]看懂UML类图

    这里不会将UML的各种元素都提到,我只想讲讲类图中各个类之间的关系: 能看懂类图中各个类之间的线条.箭头代表什么意思后,也就足够应对 日常的工作和交流: 同时,我们应该能将类图所表达的含义和最终的代码 ...

  5. ORACLE 9i 数据库体系结构图

    ORACLE 9i 的数据库体系结构图,非常的全面.系统.高屋建瓴的整体介绍了ORACLE 9i 的数据库体系结构.如果能全面了解.清晰梳理.深入掌握这些知识点,相信对你了解学习.深入研究ORACLE ...

  6. LINUX下的PHP

    由于linux系统的稳定性,大部分的PHP服务器都被部署在linux上,而且像redis等扩展在linux能得到更好的支持,所以对于PHP程序员来说,使用linux的功底也相当重要,接下来总结一下我从 ...

  7. x01.Weiqi.8: 一点改进

    原来的代码全部删除,进行了深层次重构,得其意而忘其言.得意之处有二: 1.关于显示 以 StoneSize 属性为依托,在 set 中加了一句:Width = Height = m_StoneSize ...

  8. 使用本地JConsole监控远程JVM(最权威的总结)

    问题背景   Tomcat经常崩溃crash,想看看JVM内存使用情况,就想到了用Jconsole监控,以前只是监控本地的JVM,这次要监控远程的,遇到了不少问题.   经过几个小时的努力,参考了众多 ...

  9. Centos下yum安装PHP

    添加 yum 源 Centos 6.x 的源 # rpm -Uvh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6 ...

  10. Neutron 理解 (2): 使用 Open vSwitch + VLAN 组网 [Netruon Open vSwitch + VLAN Virutal Network]

    学习 Neutron 系列文章: (1)Neutron 所实现的虚拟化网络 (2)Neutron OpenvSwitch + VLAN 虚拟网络 (3)Neutron OpenvSwitch + GR ...