相信大家在读大学的时候都会上过一门叫做线性代数的课程,在这门课中,需要掌握各种矩阵的知识,并且还要有异常强大的心理才能在各种矩阵运算中脱身,否则,大学除了有一棵高高的树,还有一棵很现代的树,上面都挂着很多人
可能有人不信,下面就放上一道简单的计算行列式的例题,来感受一下这繁杂的过程吧
当然,只用一道是看不出什么的,但是当你需要在众多的习题中,快速得到答案时,这就很烦人了,对吧。正所谓,程序就是让人从繁杂重复的工作中脱离出来的宗旨,所以,乘着Numpy的东风,弄一个矩阵计算器的需求,不算过分吧
总体思路
- 使用PyQt5设计矩阵计算器的UI界面
- 处理输入矩阵的数据(元素和形态)
- 提供常见的基础计算功能
- 打包成EXE文件,便于分享
设计UI界面
对于界面的设计,使用PyQt5和Qt Designer进行拖拽式设计;设计完之后使用Qt插件将UI文件转化为Python代码
处理输入数据
虽然想本着一切的输入都是不怀好意的思想取处理,但是技术和思维不成熟,所以只是尽量往完善的方向处理。
通过UI设计那张图,可以看出,需要处理两个问题:
1. 中文逗号
2. 输入前后的逗号
所以写了个方法进行处理
def to_array(text, row):
'''
将输入的数字转为矩阵
:param text: 矩阵元素字符串
:param row: 矩阵形态字符串
:return: 元素列表,形态列表
'''
# 将中文逗号替换为英文逗号
text = text.replace(',', ',')
row = row.replace(',', ',')
# 切除矩阵元素前后的逗号
if text[-1] == ',':
text = text[:-1]
if text[0] == ',':
text = text[1:]
# 切除矩阵形态前后的逗号
if row[-1] == ',':
row = row[:-1]
if row[0] == ',':
row = row[1:]
new = []
rowlis = []
numlist = text.split(',')
# 将字符串转换为列表
for i in range(len(numlist)):
new.append(int(numlist[i]))
rowlist = row.split(',')
for i in range(len(rowlist)):
rowlis.append(int(rowlist[i]))
return new, rowlis
绑定按钮事件
在设计UI界面的时候已经对各个按钮进行了id编号,所以根据id,在将UI转化为py文件后面添上一个类绑定相应的事件,至于事件的处理方法,后面再考虑
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.btn_dot.clicked.connect(self.dot_func)#矩阵乘积按钮绑定事件
self.btn_solve.clicked.connect(self.solve_func)#解矩阵方程按钮绑定事件
self.btn_t.clicked.connect(self.t_func)#矩阵转置按钮绑定事件
self.btn_inv.clicked.connect(self.inv_func)#矩阵的逆按钮绑定事件
self.btn_det.clicked.connect(self.det_func)#矩阵的行列式按钮绑定事件
self.btn_clear.clicked.connect(self.clear_func)#归零按钮绑定事件
事件处理函数
对于矩阵的处理,Numpy提供了很多的方法,但是这儿只是为了满足大学生这一群体的需求,所以只使用了5种方法
函数 | 说明 |
---|---|
T | 矩阵转置 |
det | 行列式 |
inv | 矩阵的逆 |
dot | 矩阵乘法 |
solve | 解矩阵方程 |
ps:解矩阵方程需要注意,矩阵一是需要输入带有变量那边的矩阵,矩阵二是需要输入结果的矩阵
对于矩阵的生成使用
np.array(linelist1).reshape(rowlist1)
其中linelist1是矩阵的元素列表,rowlist1是矩阵的形态列表
例如:
In [1]: import numpy as np
In [2]: np.array([1,2,3,4]).reshape([2,2])
Out[2]:
array([[1, 2],
[3, 4]])
显然,可以根据需要的矩阵,将上述函数分为两类:一类是只需要一个矩阵,另一类是需要两个矩阵。所以这里各选一个作为代表
第一类:
#矩阵转置
def t_func(self):
line1 = self.lineEdit_1.text()#矩阵一元素
line2 = self.lineEdit_2.text()#矩阵二元素
row1 = self.lineEdit_row1.text()#矩阵一形态
row2 = self.lineEdit_row2.text()#矩阵二形态
try:
linelist1, rowlist1 = to_array(line1, row1)
# 修正错误
self.lineEdit_1.setText(str(linelist1)[1:-1])
self.lineEdit_row1.setText(str(rowlist1)[1:-1])
#生成矩阵
A = np.array(linelist1).reshape(rowlist1)
txt = '矩阵一的转置:\n' + str(A.T)
self.textEdit_result1.setText(txt)
except:
A_text = '请检查矩阵一'
self.textEdit_result1.setText(A_text)
try:
linelist2, rowlist2 = to_array(line2, row2)
# 修正错误
self.lineEdit_2.setText(str(linelist2)[1:-1])
self.lineEdit_row2.setText(str(rowlist2)[1:-1])
B = np.array(linelist2).reshape(rowlist2)
txt = '矩阵二的转置:\n' + str(B.T)
self.textEdit_result2.setText(txt)
except:
self.textEdit_result2.setText("请检查矩阵二")
第二类:
def solve_func(self):
line1 = self.lineEdit_1.text()#矩阵一元素
line2 = self.lineEdit_2.text()#矩阵二元素
row1 = self.lineEdit_row1.text()#矩阵一形态
row2 = self.lineEdit_row2.text()#矩阵二形态
try:
linelist1, rowlist1 = to_array(line1, row1)
linelist2, rowlist2 = to_array(line2, row2)
# 修正错误的输入
self.lineEdit_1.setText(str(linelist1)[1:-1])
self.lineEdit_row1.setText(str(rowlist1)[1:-1])
self.lineEdit_2.setText(str(linelist2)[1:-1])
self.lineEdit_row2.setText(str(rowlist2)[1:-1])
#生成矩阵
A = np.array(linelist1).reshape(rowlist1)
B = np.array(linelist2).reshape(rowlist2)
txt = '矩阵的解:\n' + str(solve(A, B))
self.textEdit_result1.setText(txt)
except:
A_text = '矩阵错误或无解'
self.textEdit_result1.setText(A_text)
self.textEdit_result2.setText(A_text)
添加主函数
在py文件的最后添加主函数,就可以运行了
if __name__ == '__main__':
app = QApplication(sys.argv)
MainWindow = MainWindow()
MainWindow.show()
sys.exit(app.exec_())
打包成EXE
利用Pyinstaller将py文件打包成EXE文件。关于Pyinstaller的使用网上有一大堆教程,但是坑也有不少。这里我就不详细介绍了,因为我的打包了运行不了,可能是版本问题。如果哪位打包成功了,可以pull request哈
最后
Numpy作为科学计算的基础,听上去高大上,让我们学起来有点悬空的感觉,所以还是需要一点落地感,才能引起兴趣,继续深入学习,而不是止于表面。
希望这个文章能够带给大家一点学习的思路:边学边用,利用学习过的知识,去解决生活中的小问题,从中收获成就感,不断向前
项目地址:https://github.com/stormdony/python_demo/tree/master/numpy_calc
关注微信公众号:Python绿洲,获取更多内容