20191331刘宇轩 《Python程序设计》实验二报告
课程:《Python程序设计》
班级: 1913
姓名: 刘宇轩
学号:20191331
实验教师:王志强
实验日期:2021年5月7日
必修/选修: 公选课
1. 实验内容
- 设计并完成一个完整的应用程序,完成加减乘除模等运算,功能多多益善。
- 考核基本语法、判定语句、循环语句、逻辑运算等知识点
2. 实验要求
- 创建工程项目,使用Python语言实现具体的操作运算,并完成程序调试和运行,代码托管到码云。
3.实验过程及结果
- 对于一个计算器,其拥有的功能很重要。首先要实现加减乘除、求模和幂函数这几个简单功能。
代码如下
def add(a, b): return a + b def minus(a, b): return a - b def mul(a, b): return a * b def div(a, b): if b == 0: print("Error") else: return a / b def mod(a, b): return a % b def power(a, b): return a ** b print("1:加法 2:减法 3:乘法 4:除法 5:求模 6:幂运算 ") s = int(input("请输入运算方法:")) n1 = float(input("请输入第一个数:")) n2 = float(input("请输入第二个数:")) print("结果为:") if s == 1: print(add(n1, n2)) if s == 2: print(minus(n1, n2)) if s == 3: print(mul(n1, n2)) if s == 4: print(div(n1, n2)) if s == 5: print(mod(n1, n2)) if s == 6: print(power(n1, n2))
一个拥有基本功能的计算器完成了。
- 在实现计算器的基本功能后,我想让计算器可以一次处理多个数,查找后发现可以使用
eval()
函数来进行运算。
代码如下
# 表达式运算 def test(date): result = eval(date) return result print("支持加减乘除和求模(%)与幂函数(**) 示例:(8+7)%3**4") m = input("请输入表达式:") print("结果为:", test(m))
- 继续添加开方,三角函数,对数运算,最大公约数,向下取整这些功能,幸好python中math库中有这些功能,只需引入Python中的
math
函数库,便能实现我想要的功能,非常easy。
代码如下
import math s = int(input("请输入运算方法:")) if s == 1: print("对数运算") n3 = float(input("请输入运算数:")) n4 = float(input("请输入底数:")) print("结果为:", math.log(n3, n4)) elif s == 10: print("最大公约数") n5 = float(input("请输入第一个运算数:")) n6 = float(input("请输入第二个运算数:")) print("结果为:", math.gcd(n5, n6)) elif 2 <= s <= 9: n7 = float(input("请输入运算数(三角函数仅输入弧度制pi前的系数):")) if s == 2: print("开方运算 结果为:", math.sqrt(n7)) if s == 3: print("向下取整 结果为:", math.trunc(n7)) if s == 4: print("向上取整 结果为:", math.ceil(n7)) if s == 5: print("弧度转换角度 结果为:", math.degrees(n7)) if s == 6: print("角度转换弧度 结果为:", math.radians(n7)) if s == 7: print("正弦函数 结果为:", math.sin(math.pi*n7)) if s == 8: print("余弦函数 结果为:", math.cos(math.pi*n7)) if s == 9: print("正切函数 结果为:", math.tan(math.pi*n7))
- 所需功能均已实现,接下来就是整合到一起了,使用
while
循环实现计算器的多次使用,再用if语句进行功能选择。
当需要退出时使用break
elif i == 0: break
代码如下
while True:
print("计算器")
i = int(input("基本运算输1,表达式运算输2,高级功能输3,输0退出
请输入:"))
if i == 1:
print("1:加法 2:减法 3:乘法 4:除法 5:求模 6:幂运算
")
s = int(input("请输入运算方法:"))
n1 = float(input("请输入第一个数:"))
n2 = float(input("请输入第二个数:"))
print("结果为:")
if s == 1:
print(add(n1, n2))
if s == 2:
print(minus(n1, n2))
if s == 3:
print(mul(n1, n2))
if s == 4:
print(div(n1, n2))
if s == 5:
print(mod(n1, n2))
if s == 6:
print(power(n1, n2))
elif i == 2:
print("支持加减乘除和求模(%)与幂函数(**)
示例:3+4-(3-2)**2")
m = input("请输入表达式:")
print("结果为:", test(m))
elif i == 3:
print("1:对数函数 2:开方 3:向下取整 4:向上取整 5:弧度转换角度 6:角度转换弧度 7:正弦函数 8:余弦函数 9:正切函数 10:最大公约数")
s = int(input("请输入运算方法:"))
if s == 1:
print("对数运算")
n3 = float(input("请输入运算数:"))
n4 = float(input("请输入底数:"))
print("结果为:", math.log(n3, n4))
elif s == 10:
print("最大公约数")
n5 = float(input("请输入第一个运算数:"))
n6 = float(input("请输入第二个运算数:"))
print("结果为:", math.gcd(n5, n6))
elif 2 <= s <= 9:
n7 = float(input("请输入运算数(三角函数仅输入弧度制pi前的系数):"))
if s == 2:
print("开方运算
结果为:", math.sqrt(n7))
if s == 3:
print("向下取整
结果为:", math.trunc(n7))
if s == 4:
print("向上取整
结果为:", math.ceil(n7))
if s == 5:
print("弧度转换角度
结果为:", math.degrees(n7))
if s == 6:
print("角度转换弧度
结果为:", math.radians(n7))
if s == 7:
print("正弦函数
结果为:", math.sin(math.pi*n7))
if s == 8:
print("余弦函数
结果为:", math.cos(math.pi*n7))
if s == 9:
print("正切函数
结果为:", math.tan(math.pi*n7))
elif i == 0:
break
- 在cmd界面运行计算器既不美观也不方便,每一次运算命令都要手动输入选择,十分的不方便,所以参照上学期计算机实习时制作GUI界面时的经验,为计算器进行GUI界面设计,将所有操作替换为鼠标按钮设计,这样既美观又方便。实践过程中python的GUI设计比较简单,引入tkinter库后只需合理分配窗口化大小,和按钮位置,就能制作简单的GUI计算器界面。
GUI代码如下
'''
作者:刘宇轩
文件名称:计算器GUI
时间:2021.5.7
'''
import tkinter as tk
from tkinter import ttk
import math
def get(entry, argu):
indata = entry.get()
if (indata[-1:] == '+') and (argu in ['+', '*', '/', '%', '**']):
return
if (indata[-1:] == '-') and (argu in ['+', '*', '/', '%', '**']):
return
if (indata[-1:] == '*') and (argu in ['+', '/', '%', '**']):
return
if (indata[-1:] == '/') and (argu in ['+', '*', '%', '**']):
return
if (indata[-1:] == '&') and (argu in ['+', '*', '/', '%', '**']):
return
if (indata[-2:] == '+-') and (argu in ['+', '-', '*', '/', '%', '**']):
return
if (indata[-2:] == '--') and (argu in ['+', '-', '*', '/', '%', '**']):
return
if (indata[-2:] == '**') and (argu in ['+', '*', '/', '%', '**']):
return
entry.insert("end", argu)
def back(entry):
l = len(entry.get())
entry.delete(l - 1)
def clear(entry):
entry.delete(0, "end")
def calculate(entry):
date = entry.get()
if not date:
return
else:
for i in date:
if i not in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '+', '=', '*', '/', '%', '.']:
t = 0
else:
t = 1
if t == 0:
error(2)
else:
clear(entry)
result = str(eval(date))
if len(result) > 20:
entry.insert("end", "Value overflow")
else:
entry.insert("end", result)
def error(t):
win0 = tk.Tk()
win0.title("")
if t == 1:
l1 = ttk.Label(win0, text="无法运算")
l1.grid(column=0, row=0, columnspan=2)
elif t == 2:
l1 = ttk.Label(win0, text="Illegal character")
l1.grid(column=0, row=0, columnspan=2)
b1 = ttk.Button(win0, text='关闭', command=lambda: win0.destroy())
b1.grid(column=0, row=1)
win0.mainloop()
def f1_get(entry):
date = entry.get()
if not date:
return
else:
for i in date:
if i not in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.']:
t = 0
else:
t = 1
if t == 0:
error(1)
else:
entry.delete(0, "end")
date = float(date)
result = math.sqrt(date)
entry.insert("end", result)
def f2down_get(entry):
date = entry.get()
if not date:
return
else:
for i in date:
if i not in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.']:
t = 0
else:
t = 1
if t == 0:
error(1)
return
else:
entry.delete(0, "end")
date = float(date)
result = math.trunc(date)
entry.insert("end", result)
def f2up_get(entry):
date = entry.get()
if not date:
return
else:
for i in date:
if i not in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.']:
t = 0
else:
t = 1
if t == 0:
error(1)
return
else:
entry.delete(0, "end")
date = float(date)
result = math.ceil(date)
entry.insert("end", result)
def f3_get(entry2, entry3, entry4):
date1 = entry2.get()
date2 = entry3.get()
if (not date1) or (not date2):
return
else:
for i in (date1 or date2):
if i not in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.']:
t = 0
else:
t = 1
if t == 0:
error(1)
else:
entry4.delete(0, "end")
date1 = float(date1)
date2 = float(date2)
result = math.log(date1, date2)
entry4.insert("end", result)
def f3_clear(entry2, entry3, entry4):
entry2.delete(0, "end")
entry3.delete(0, "end")
entry4.delete(0, "end")
def f3():
win2 = tk.Tk()
win2.title("对数运算")
l1 = ttk.Label(win2, text="对数运算")
l1.grid(column=0, row=0, columnspan=3)
l1 = ttk.Label(win2, text="请输入真数")
l1.grid(column=0, row=1)
l1 = ttk.Label(win2, text="请输入底数")
l1.grid(column=0, row=2)
l1 = ttk.Label(win2, text="结果为")
l1.grid(column=0, row=3)
entry2 = ttk.Entry(win2, width=20, justify="right", font=1)
entry2.grid(row=1, column=1, columnspan=2, padx=20, pady=5)
entry3 = ttk.Entry(win2, width=20, justify="right", font=1)
entry3.grid(row=2, column=1, columnspan=2, padx=20, pady=5)
entry4 = ttk.Entry(win2, width=20, justify="right", font=1)
entry4.grid(row=3, column=1, columnspan=2, padx=20, pady=5)
b1 = ttk.Button(win2, text='log运算', command=lambda: f3_get(entry2, entry3, entry4))
b1.grid(column=2, row=4)
b2 = ttk.Button(win2, text='clear', command=lambda: f3_clear(entry2, entry3, entry4))
b2.grid(column=1, row=4)
win2.mainloop()
def f4_get(entry5, entry6, entry7):
date1 = entry5.get()
date2 = entry6.get()
if (not date1) or (not date2):
return
else:
for i in (date1 or date2):
if i not in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']:
t = 0
else:
t = 1
if t == 0:
error(1)
else:
entry7.delete(0, "end")
date1 = int(date1)
date2 = int(date2)
result = math.gcd(date1, date2)
entry7.insert("end", result)
def f4_clear(entry5, entry6, entry7):
entry5.delete(0, "end")
entry6.delete(0, "end")
entry7.delete(0, "end")
def f4():
win2 = tk.Tk()
win2.title("最大公约数运算")
l1 = ttk.Label(win2, text="最大公约数运算")
l1.grid(column=0, row=0, columnspan=3)
l1 = ttk.Label(win2, text="请输入第一个数")
l1.grid(column=0, row=1)
l1 = ttk.Label(win2, text="请输入第二个数")
l1.grid(column=0, row=2)
l1 = ttk.Label(win2, text="结果为")
l1.grid(column=0, row=3)
entry5 = ttk.Entry(win2, width=20, justify="right", font=1)
entry5.grid(row=1, column=1, columnspan=2, padx=20, pady=5)
entry6 = ttk.Entry(win2, width=20, justify="right", font=1)
entry6.grid(row=2, column=1, columnspan=2, padx=20, pady=5)
entry7 = ttk.Entry(win2, width=20, justify="right", font=1)
entry7.grid(row=3, column=1, columnspan=2, padx=20, pady=5)
b1 = ttk.Button(win2, text='运算', command=lambda: f4_get(entry5, entry6, entry7))
b1.grid(column=2, row=4)
b2 = ttk.Button(win2, text='clear', command=lambda: f4_clear(entry5, entry6, entry7))
b2.grid(column=1, row=4)
win2.mainloop()
def f5_get(entry8, s):
date = entry8.get()
if not date:
return
else:
for i in date:
if i not in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.']:
t = 0
else:
t = 1
if t == 0:
error(1)
else:
entry8.delete(0, "end")
date = float(date)
if s == 2:
result = math.degrees(date)
if s == 3:
result = math.radians(date)
if s == 4:
result = math.sin(math.pi * date)
if s == 5:
result = math.cos(math.pi * date)
if s == 6:
result = math.tan(math.pi * date)
entry8.insert("end", result)
def f5():
win2 = tk.Tk()
win2.title("三角函数运算")
l1 = ttk.Label(win2, text="三角函数运算")
l1.grid(column=0, row=0, columnspan=3)
entry8 = ttk.Entry(win2, width=20, justify="right", font=1)
entry8.grid(row=1, column=0, columnspan=3, padx=20, pady=5)
b1 = ttk.Button(win2, text='弧度转换角度', command=lambda: f5_get(entry8, 2))
b1.grid(column=1, row=2)
b2 = ttk.Button(win2, text='角度转换弧度', command=lambda: f5_get(entry8, 3))
b2.grid(column=2, row=2)
b3 = ttk.Button(win2, text='sin(π*n)', command=lambda: f5_get(entry8, 4))
b3.grid(column=0, row=3)
b4 = ttk.Button(win2, text='cos(π*n)', command=lambda: f5_get(entry8, 3))
b4.grid(column=1, row=3)
b5 = ttk.Button(win2, text='tan(π*n)', command=lambda: f5_get(entry8, 3))
b5.grid(column=2, row=3)
b6 = ttk.Button(win2, text='clear', command=lambda: entry8.delete(0, "end"))
b6.grid(column=0, row=2)
win2.mainloop()
win = tk.Tk()
win.title("计算器")
menubar = tk.Menu(win)
menubar.add_command(label='向下取整',command=lambda:f2down_get(entry))
menubar.add_command(label='开方',command=lambda: f1_get(entry))
menubar.add_command(label='对数函数',command=lambda: f3())
menubar.add_command(label='最大公约数',command=lambda: f4())
menubar.add_command(label='三角函数',command=lambda: f5())
win.config(menu=menubar)
entry = ttk.Entry(win, justify="right", font=1)
entry.grid(row=0, column=0, columnspan=6, padx=20, pady=5)
b0 = ttk.Button(win, text='0', command=lambda: get(entry, '0'))
b0.grid(column=1, row=4)
b1 = ttk.Button(win, text='1', command=lambda: get(entry, '1'))
b1.grid(column=0, row=3)
b2 = ttk.Button(win, text='2', command=lambda: get(entry, '2'))
b2.grid(column=1, row=3)
b3 = ttk.Button(win, text='3', command=lambda: get(entry, '3'))
b3.grid(column=2, row=3)
b4 = ttk.Button(win, text='4', command=lambda: get(entry, '4'))
b4.grid(column=0, row=2)
b5 = ttk.Button(win, text='5', command=lambda: get(entry, '5'))
b5.grid(column=1, row=2)
b6 = ttk.Button(win, text='6', command=lambda: get(entry, '6'))
b6.grid(column=2, row=2)
b7 = ttk.Button(win, text='7', command=lambda: get(entry, '7'))
b7.grid(column=0, row=1)
b8 = ttk.Button(win, text='8', command=lambda: get(entry, '8'))
b8.grid(column=1, row=1)
b9 = ttk.Button(win, text='9', command=lambda: get(entry, '9'))
b9.grid(column=2, row=1)
bb0 = ttk.Button(win, text='.', command=lambda: get(entry, '.'))
bb0.grid(column=2, row=4)
bb1 = ttk.Button(win, text='+', command=lambda: get(entry, '+'))
bb1.grid(column=3, row=1)
bb2 = ttk.Button(win, text='-', command=lambda: get(entry, '-'))
bb2.grid(column=3, row=2)
bb3 = ttk.Button(win, text='*', command=lambda: get(entry, '*'))
bb3.grid(column=3, row=3)
bb4 = ttk.Button(win, text='/', command=lambda: get(entry, '/'))
bb4.grid(column=3, row=4)
bb5 = ttk.Button(win, text='回退', command=lambda: back(entry))
bb5.grid(column=0, row=4)
bb6 = ttk.Button(win, text='x^n', command=lambda: get(entry, '**'))
bb6.grid(column=5, row=1)
bb7 = ttk.Button(win, text='mod', command=lambda: get(entry, '%'))
bb7.grid(column=5, row=2)
bb8 = ttk.Button(win, text='clear', command=lambda: clear(entry))
bb8.grid(column=5, row=3)
bb9 = ttk.Button(win, text='=', command=lambda: calculate(entry))
bb9.grid(column=5, row=4, )
win.mainloop()
- 引入
tkinter
进行窗口化设计。在窗口化时简单的功能可以合并到表达式的计算中去。- 最终效果如图:
- 计算实例
- 结果为
4.实验中遇到的问题
- 计算三角函数时为弧度制,使用不方便
解决方法:在计算时引入
math.pi
进行处理
- 在使用
eval()
函数时能运行命令行,有安全风险
解决方法:在调用函数前先检查是否有非法字符
- 在tkinter中设置按钮时无法正常调用函数
解决方法:在要调用的函数前再用
lambda:
调用
5.感悟
- 在编写代码之前要对自己希望实现的功能和效果有大致的设想,包括可以用什么库实现什么功能,大概的循环体结构,界面样式;
- 如果要设计GUI界面的话,可以先找一张草稿纸,画出自己想要的菜单按钮,大致考虑好这些按钮的位置,和整体界面的大小,这样在代码实现的时候就会比较方便容易。
- python库真的非常丰富非常强大,有句话说的就是不必重复造车轮,意思就是我们要学会baidu我们包含想要实现功能的库,总能在浩如烟海的库中找到需要的那一个。
参考资料
https://www.cnblogs.com/xiaoyh/p/9791670.html
https://blog.csdn.net/weixin_42795087/article/details/89931944
https://www.cnblogs.com/mxh1099/p/5386529.html