作业内容:计算器
 #!/usr/bin/env python
# -*- coding:utf-8 -*-
import re,time
#加减字符处理函数
def handle_symbol(cal_str):
# if cal_str.__contains__("+-") or cal_str.__contains__("--") or cal_str.__contains__("-+") or cal_str.__contains__("++"):
if "+-" in cal_str or "++" in cal_str or "-+" in cal_str or "--" in cal_str:
cal_str = cal_str.replace("+-","-")
cal_str = cal_str.replace("--","+")
cal_str = cal_str.replace("++","+")
cal_str = cal_str.replace("-+","-")
return handle_symbol(cal_str) #递归替换符号
else:
return cal_str
#递归加减函数
def plus_minus(cal_str):
if cal_str[0] == "+":
cal_str = cal_str[1:]
m = re.search("[\-]?\d+[\.]?\d*[\+\-]\d+[\.]?\d*",cal_str)
if m:
m_str = m.group()
str_list = cal_str.split(m_str)
if len(m_str.split("+")) == 2: #如果长度为2,说明是加法,如果不是,就是减法
num1,num2 = m_str.split("+")
num = float(num1) + float(num2)
elif m_str[0] == '-': #减法中,如果匹配到的字符串第一个字符是-,需要特殊处理
m_str = m_str[1:]
num1,num2 = m_str.split("-")
num = -(float(num1) + float(num2))
else:
num1,num2 = m_str.split("-")
num = float(num1) - float(num2)
cal_str = "%s%s%s"%(str_list[0],num,str_list[1])
return plus_minus(cal_str)
else:
return cal_str
#递归乘除函数
def mul_div(cal_str):
m = re.search("\d+\.*\d*[\*\/][\-]?\d+\.*\d*",cal_str)
if m:
m_str = m.group()
str_list = cal_str.split(m_str)
if len(m_str.split("*")) == 2:
num1,num2 = m_str.split("*")
num = float(num1) * float(num2)
else:
num1,num2 = m_str.split("/")
num = float(num1) / float(num2)
cal_str = "%s%s%s"%(str_list[0],num,str_list[1])
return mul_div(cal_str)
else:
return cal_str
#递归计算函数
def calculate(cal_str):
if "(" in cal_str:
m = re.search("\([^\(\)]+\)",cal_str).group() #取出最里层括号
m2 = m[1:-1] #去括号
m_result = mul_div(m2) #做乘除运算
m_result = plus_minus(m_result) #做加减运算
cal_list = cal_str.split(m)
cal_str = cal_list[0] + str(m_result) + cal_list[1] #把运算结果放回原来字符串中
cal_str = handle_symbol(cal_str)
return calculate(cal_str)
else:
cal_str = mul_div(cal_str)
cal_str = handle_symbol(cal_str)
cal_str = plus_minus(cal_str)
return cal_str def main():
welcome = "欢迎进入简便计算器"
print("%s"%welcome.center(40,"*"))
print("计算器说明:"
"\n1.术式只能包括加减乘除、数字、点和小括号;"
"\n2.请严格按照示例格式输入术式;"
"\n3.示例:(1-2)*(60-30+(-40/5)*(9-2*5/3+12-3))+(5*8/9+(1/2+3))/(1+3)+(5-2/2);"
"\n4.输入q可以退出。")
while True:
cal_str = re.sub(" ",'',input("请输入计算术式:"))
cal_str = handle_symbol(cal_str)
if cal_str == "q":
exit("欢迎下次光临")
# 以下if都是判断格式有没有错误的,还有一些bug暂时没法解决
if re.search("[^0-9\+\-\*\/\(\)\.]",cal_str) or re.match("[\.\*\/]",cal_str) or re.search("\([\+\-\*\/]?\)",cal_str):
print("输入有误,请重新输入")
time.sleep(1)
continue
if "." in cal_str:
if len(re.findall("[0-9]+\.[0-9]+",cal_str)) != cal_str.count("."):
print("输入有误,请重新输入")
time.sleep(1)
continue
if "(" in cal_str or ")" in cal_str:
left = cal_str.count("(")
right = cal_str.count(")")
if left != right:
print("输入有误,请重新输入")
time.sleep(1)
continue
result = calculate(cal_str) #调用计算函数算出结果
print("我的计算结果是:%s"%result)
print("eval正确结果是:%s"%eval(cal_str)) if __name__ == "__main__":
main()

calculate.py

测试环境:windows7下Python3.5.1

程序说明:
1、启动程序会提示欢迎信息并提示计算器用法
2、输入计算术式按回车进行运算,输入q退出程序,如果术式不对会提示错误并返回重新输入
3、术式正确会进行运算并显示计算结果
程序设计思维想法:
1.先检测有没有小括号,如果有小括号就把最里层小括号拿出来进行运算,把运算结果替代原来的小括号位置,然后递归运算直到没有小括号为止
2.如果没有小括号,直接调用乘除函数和加减函数计算得出结果

day4作业的更多相关文章

  1. day4作业模拟实现一个ATM + 购物商城程序

    作业需求: 模拟实现一个ATM + 购物商城程序 1.额度 15000或自定义: 2.实现购物商城,买东西加入 购物车,调用信用卡接口结账: 3.可以提现,手续费5%: 4.每月22号出账单,每月10 ...

  2. day4 作业计算器

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

  3. 老男孩Day4作业:员工信息查询系统

    1.作业需求: (1).工信息表程序,实现增删改查操作: (2).可进行模糊查询,语法至少支持下面3种:          select name,age from staff_table where ...

  4. python基础: day4作业计算器

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

  5. Day4作业:蛋疼CRM系统

    先上流程图,还得27寸4K显示器,画图各种爽: ReadMe: 运行程序前的提示: 1.抱歉,你得装prettytable模块...... 2.还得抱歉,如果shell中运行,最好把字体调得小点,表格 ...

  6. Python3.5 day4作业:对员工信息文件,实现增删改查操作。

    需求: 1.可进行模糊查询,语法至少支持下面3种: 1.select name,age from staff_table where age > 22 2.select  * from staf ...

  7. day4作业之信息表

    实在是太low了,终究是自己写的,记录下 #!/usr/bin/env python # coding=utf8 import os, re #这里我把查询这块分为3个函数了,纠结了很久是放一起还是分 ...

  8. day4作业小代码练习

    登录模块: 我们无论上那个网站,经常遇到这样的情况,让我们登录这个网站,流程图如下: 思路: 1.当我们登录网站的时候,我们首先会输入用户名,这个时候,有些网站会提醒我们用户名是否存在,如果我们输入的 ...

  9. Day4作业及默写

    1,写代码,有如下列表,按照要求实现每一个功能 li = ["alex", "WuSir", "ritian", "barry&q ...

随机推荐

  1. MyBatis使用DEMO及cache的使用心得

    下面是一个简单的MyBatis使用DEMO. 整体结构 整体代码大致如下: POM依赖 需要引用两个jar包,一个是mybatis,另一个是mysql-connector-java,如果是maven工 ...

  2. dp-史上最戳最长最臭代码-hdu-4733-G(x)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4733 题目大意: 定义G(x)=x⊕(x>>1).给两个由0.1.?组成的长度相同的字符 ...

  3. Java图形化界面设计——布局管理器之null布局(空布局)

    一般容器都有默认布局方式,但是有时候需要精确指定各个组建的大小和位置,就需要用到空布局. 操作方法: 1)       首先利用setLayout(null)语句将容器的布局设置为null布局(空布局 ...

  4. Reorder the Books(规律)

    Reorder the Books Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  5. [C# 基础知识系列]专题六:泛型基础篇——为什么引入泛型

    引言: 前面专题主要介绍了C#1中的2个核心特性——委托和事件,然而在C# 2.0中又引入一个很重要的特性,它就是泛型,大家在平常的操作中肯定会经常碰到并使用它,如果你对于它的一些相关特性还不是很了解 ...

  6. 关于typedef之四种用途 和 两个陷进

    typedef用来声明一个别名,typedef后面的语法,是一个声明.本来笔者以为这里不会产生什么误解的,但结果却出乎意料,产生误解的人 不在少数.罪魁祸首又是那些害人的教材.在这些教材中介绍type ...

  7. ##DAY8 界面通信

    ##DAY8 界面通信 注意:延展中写的东西只能在类内使用 #pragma mark ———————属性传值—————————— (第一个页面往第二个页面传值) 一.属性传值:(第一个页面往第二个页面 ...

  8. php实现简单的上一页下一页

    思路整理: 现在好多人用id的增1和减1实现上一篇和下一篇但是难道文章ID不会断了吗所以你要知道上个ID和个ID是多少就OK了那怎么解决这个问题呢,很简单例子:假如这篇文章的ID200 <a h ...

  9. Linux下使用ps命令来查看Oracle相关的进程

    Linux下可以使用ps命令来查看Oracle相关的进程 Oracle Listener 这个命令会列出Oracle Net Listener的进程 [oracle@ www.linuxidc.com ...

  10. utf8_general_ci 、utf8_general_cs和utf8_bin的区别

    用了这么长时间,发现自己竟然不知道utf_bin和utf_general_ci这两者到底有什么区别..ci是 case insensitive, 即 "大小写不敏感", a 和 A ...