2021-2022-2 《Python程序设计》实验二报告

 # 2021-2022-2 《Python程序设计》实验二报告

课程:《Python程序设计》
班级: 2143
实验教师:王志强
实验日期:2022年4月5日
必修/选修: 公选课

## 1.实验内容

  • 设计并完成一个完整的应用程序,完成加减乘除模等运算,功能多多益善。

  • 考核基本语法、判定语句、循环语句、逻辑运算等知识点


## 2. 实验过程及结果

  • 思考计算器功能框架

  • 通过已学知识尽可能好的实现预设功能
  • 通过在网上和书上的学习,目前功能已全部实现

 

 

 

全部功能如图所示:

1、上课时老师讲的基础二目四则运算

2、老师讲的基础复数运算

3、任意两天日期之差计算

4、阶乘运算

5、n阶行列式计算

6、华氏<——>摄氏温度换算

7、解二次方程(可带复根)

8、支持四则运算及其括号顺序的N目计算器

详细过程如下:

一、代码整体通过main函数调用子函数形成菜单模块

 

 

二、(1)(2)模块上课时跟着老师一起写的,所以此处略

三、两天日期之差,该问题有多种解法,但是如果硬解的话因为闰年的存在代码会比较复杂,所以此处直接调用现成的datetime库中的strptime函数计算

 

 

四、阶乘计算,通过简单的循环即可实现

 

 

五、行列式计算,本来打算直接通过最基本的行列式解法通过逆序数硬解,但在网上看了一下发现numpy中有现成的线性代数相关函数,通过嵌套循环生成列表后调用numpy中的array函数转换为行列式再使用

linalg.det函数即可简单计算

 

 

六、温度换算,没什么好说的,简单的计算罢了

 

 

七、二次方程计算,通过判别式先判断delta的正负性,当delta为负是调用cmath库中的sqrt方法进行复数计算即可

 

 

八、带括号的N目计算器,本次实验中最难的一个部分,不过经过拆解分析后可以通过以下几个步骤解决
1、将算式字符串转换成列表构成栈,通过出栈时循环判断来达到重组数字、剔除空格的效果,同时将符号暂存。
2、对于括号对顺序的影响直接通过栈的特性来实现,通过pop方法来对转换成列表的算式从左到右进行出栈,当遇到(是直接递归调用函数即可将括号里的内容当成新的算式层层拆解,当遇到)时即可将括号内的算式的运算结果直接看作一个数计算。

 

 

以下是程序原码(已托管至码云https://e.gitee.com/besti-cs/repos/besti-cs/my_codes/blob/master/experiment2.py

  1 from datetime import *
  2 import numpy as np
  3 import time,os,math,cmath
  4 
  5 #定义清屏函数并初始化界面
  6 def clear():
  7     os.system('cls')
  8 clear()
  9 
 10 choice = 0
 11 def main():
 12     global choice
 13     while True:
 14         choice = input(
 15 '''
 16 欢迎使用Besti计算器!  请按数字:
 17 0.退出      1.基础计算    2.复数计算     3.日期计算  
 18 4.阶乘计算  5.行列式计算  6.温度换算     7.二次方程计算
 19 8.N目计算器(可带括号)
 20 ''')
 21         clear()
 22         print("\n")
 23         if choice == "0":
 24             print("感谢使用")
 25             break
 26         elif choice == "1" or choice == "2":
 27             base()
 28         elif choice == "3":
 29             date()
 30         elif choice == "4":
 31             fact()
 32         elif choice == "5":
 33             determinant()        
 34         elif choice == "6":
 35             temperature()       
 36         elif choice == "7":
 37             quadratic_equation() 
 38         elif choice == "8":
 39             calculate()             
 40         else:
 41             print("error")
 42         time.sleep(0.5)
 43 
 44 
 45 
 46 def base():
 47     global choice
 48     if choice == "1":
 49         a = int(input("a?"))
 50         b = int(input("b?"))
 51     elif choice == "2":
 52         a = complex(input("complex a?"))
 53         b = complex(input("complex b?"))
 54     op = input("operate?")
 55     if op == "+":
 56         result = a + b
 57 
 58     elif op == "-":
 59         result = a - b
 60 
 61     elif op == "*":
 62         result = a * b
 63 
 64     elif op == "/":
 65         try:
 66             result = a / b
 67         except:
 68             print("cannot devided by zero!")
 69     
 70     else:
 71         print("error please input again")
 72 
 73     print("{} {} {} = {}".format(a,op,b,result))
 74 
 75 def fact():
 76     n=int(input("n?"))
 77     sum=1
 78     for i in range(1,n+1):
 79         sum *=i
 80     print("{} 的阶乘为 {}".format(n,sum))
 81 
 82 def date():
 83     date1 = input("请输入日期(xxxx-xx-x)")
 84     date2 = input("请输入日期(xxxx-xx-x)")
 85     d1 = datetime.strptime(date1, '%Y-%m-%d')
 86     d2 = datetime.strptime(date2, '%Y-%m-%d')
 87     delta = abs(d2 - d1)
 88     print("相差 {} 天".format(delta.days))
 89 
 90 def quadratic_equation():
 91     print("ax ** 2 + bx + c = 0")
 92     while True:
 93         a = int(input("a?"))
 94         if a!=0:
 95             break
 96         else:
 97             print("二次项系数不能为零!")
 98     b = int(input("b?"))
 99     c = int(input("c?"))
100     delta = b**2-4*a*c
101     if delta>0:
102         result1 = (-b + math.sqrt(delta))/(2*a)
103         result2 = (-b - math.sqrt(delta))/(2*a)
104     else:
105         result1 = (-b + cmath.sqrt(delta))/(2*a)
106         result2 = (-b - cmath.sqrt(delta))/(2*a)
107     if result1 ==result2:
108         print("{}x ** 2 + {}x + {} = 0 的解为:     X1 = X2 = {}".format(a,b,c,result1))
109     else:
110         print("{}x ** 2 + {}x + {} = 0 的解为:     X1 = {}  X2 = {}".format(a,b,c,result1,result2))
111 
112 def temperature():
113     choice = int(input("1.摄氏度 -> 华氏度\n2.华氏度 -> 摄氏度\n"))
114     if choice == 1:
115             C = int(input("摄氏度?"))
116             print("对应华氏度为:  {}°F".format(C*1.8+32))
117     elif choice == 2:
118             F = int(input("华氏度?"))
119             print("对应摄氏度为:  {}°C".format((F-32)/1.8))
120 
121 def determinant():
122     A = []
123     n = int(input("几阶行列式?"))
124     for x in range(n):
125         row = []
126         for y in range(n):
127             row.append(int(input("A {} {}      ".format(x+1,y+1))))
128         A.append(row)
129     a = np.array(A) 
130     print ("行列式的值为: {:.3f}".format(np.linalg.det(a)))
131 
132 def calculate():
133     s = input("请输入算式")
134     s = list(s)
135     def subcalcu(s):
136         num = 0
137         stack = []
138         sign = '+'
139         while len(s)>0:
140             c = s.pop(0)
141             if c.isdigit():
142                 num = 10 * num + int(c)
143             if c == '(':
144                 num = subcalcu(s)
145             if (not c.isdigit() and c != " ") or len(s) == 0:
146                 if sign == "+":
147                     stack.append(num)
148                 elif sign == "-":
149                     stack.append(-num)
150                 elif sign == "*":
151                     stack[-1] = stack[-1]*num
152                 elif sign == "/":
153                     stack[-1] = stack[-1]/float(num)
154                 num = 0
155                 sign = c
156             if c == ')':
157                 break
158         return sum(stack)
159     print("结果为 {}".format(subcalcu(s)))
160 
161 
162 main()

 


## 3. 实验过程中遇到的问题和解决过程
- 问题1:两天日期之差判断闰年时代码冗长
- 问题1解决方案:查找资料通过使用datetime库解决

- 问题2:行列式计算时难以计算逆序数
- 问题2解决方案:通过使用numpy库解决

- 问题3: 二次方程复根无法简单通过complex()进行强制类型转换解决
- 问题3解决方案:通过使用cmath库解决复数运算

- 问题4: N目计算器中括号对顺序的影响难以解决
- 问题4解决方案:通过查找资料后运用栈的特性和递归思想解决

- 问题5: 行列式计算中单元格数据的输入不太美观
- 问题5解决方案:查找资料后发现Python的input()函数无法控制是否换行和字符串位宽,pass

- 问题6: 希望在主程序中加一个超时无输入自动退出的功能
- 问题6解决方案:查找资料后发现Python的input()函数只要没有输入就会一直卡住,pass

- 问题7: 程序反复打印大量内容,不太美观
- 问题7解决方案:查找资料通过使用os库在循环时清屏解决

 

## 其他(感悟、思考等)

算法学习长路漫漫
遇到bug不要慌,大不了直接全部重写

## 参考资料

-  《labuladong的算法小抄》

- 《算法(第4版)》

posted @ 2022-04-05 18:38  Ethan-Chase  阅读(110)  评论(0编辑  收藏  举报
-->