利用Numpy和PyQt5制作矩阵计算器

版权声明:本文为博主原创文章,未经博主允许不得转载;联系邮箱:[email protected] https://blog.csdn.net/stormdony/article/details/81359064

相信大家在读大学的时候都会上过一门叫做线性代数的课程,在这门课中,需要掌握各种矩阵的知识,并且还要有异常强大的心理才能在各种矩阵运算中脱身,否则,大学除了有一棵高高的树,还有一棵很现代的树,上面都挂着很多人
可能有人不信,下面就放上一道简单的计算行列式的例题,来感受一下这繁杂的过程吧

#### 插图

当然,只用一道是看不出什么的,但是当你需要在众多的习题中,快速得到答案时,这就很烦人了,对吧。正所谓,程序就是让人从繁杂重复的工作中脱离出来的宗旨,所以,乘着Numpy的东风,弄一个矩阵计算器的需求,不算过分吧

总体思路

  1. 使用PyQt5设计矩阵计算器的UI界面
  2. 处理输入矩阵的数据(元素和形态)
  3. 提供常见的基础计算功能
  4. 打包成EXE文件,便于分享

设计UI界面

对于界面的设计,使用PyQt5和Qt Designer进行拖拽式设计;设计完之后使用Qt插件将UI文件转化为Python代码

#### 插图4

处理输入数据

虽然想本着一切的输入都是不怀好意的思想取处理,但是技术和思维不成熟,所以只是尽量往完善的方向处理。
通过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绿洲,获取更多内容

猜你喜欢

转载自blog.csdn.net/stormdony/article/details/81359064
今日推荐