Python 3矩阵计算器

wlsrxk51  于 2023-02-18  发布在  Python
关注(0)|答案(2)|浏览(189)

我有一个问题,这个代码,它的工作错误的选项7至少是主要问题,它应该做矩阵修改和保存新值像2A(A s 2)应该保存在A,也许因为它不更新到新值它给出了错误的输出,请帮助.

class Matrix:
    def __init__(self, name, m, n, values):
        self.name = name
        self.m = m
        self.n = n
        self.values = values

    def __str__(self):
        rows = [self.values[i:i+self.n] for i in range(0, len(self.values), self.n)]
        return f'{self.name} = \n' + '\n'.join([' '.join(map(str, row)) for row in rows])

class MatrixMultiplier:
    def __init__(self):
        self.matrices = []

    def create_matrix(self, name):
        m = int(input(f'Introduceți numărul de rânduri pentru matricea {name}: '))
        n = int(input(f'Introduceți numărul de coloane pentru matricea {name}: '))
        values = []
        for i in range(m):
            for j in range(n):
                value = int(input(f'Introduceți valoarea pentru poziție ({i}, {j}) în matricea {name}: '))
                values.append(value)
        matrix = Matrix(name, m, n, values)
        self.matrices.append(matrix)

    def add_matrices(self, name1, name2):
        matrix1 = next(matrix for matrix in self.matrices if matrix.name == name1)
        matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
        if matrix1.m != matrix2.m or matrix1.n != matrix2.n:
            raise ValueError('Cele două matrice trebuie să aibă aceleași dimensiuni')
        result = [matrix1.values[i] + matrix2.values[i] for i in range(len(matrix1.values))]
        return Matrix(f'{name1}+{name2}', matrix1.m, matrix1.n, result)

    def multiply_matrices(self, name1, name2):
        matrix1 = next(matrix for matrix in self.matrices if matrix.name == name1)
        matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
        if matrix1.n != matrix2.m:
            raise ValueError('Numărul de coloane din prima matrice trebuie să se potrivească cu numărul de rânduri din a doua matrice')
        result = []
        for i in range(matrix1.m):
            for j in range(matrix2.n):
                val = 0
                for k in range(matrix1.n):
                    val += matrix1.values[i * matrix1.n + k] * matrix2.values[k * matrix2.n + j]
                result.append(val)
        return Matrix(f'{name1}{name2}', matrix1.m, matrix2.n, result)
    
    def scalar_multiply(self, name, scalar):
        matrix = next(matrix for matrix in self.matrices if matrix.name == name)
        result = [scalar * val for val in matrix.values]
        matrix.values = result
        matrix.name = f'{scalar}{name}'
        return Matrix(f'{scalar}{name}', matrix.m, matrix.n, result)

    def flip_matrix(self, name):
        matrix = next(matrix for matrix in self.matrices if matrix.name == name)
        result = []
        for j in range(matrix.n):
            for i in range(matrix.m):
                result.append(matrix.values[i * matrix.n + j])
        matrix.values = result
        matrix.m, matrix.n = matrix.n, matrix.m
        matrix.name = f'{name}^T'
        return matrix

    def subtract_matrices(self, name1, name2):
        matrix1 = next(matrix for matrix in self.matrices if matrix.name == name1)
        matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
        if matrix1.m != matrix2.m or matrix1.n != matrix2.n:
            raise ValueError('Cele două matrice trebuie să aibă aceleași dimensiuni')
        result = [matrix1.values[i] - matrix2.values[i] for i in range(len(matrix1.values))]
        return Matrix(f'{name1}-{name2}', matrix1.m, matrix1.n, result)

    def custom_input(self, ops):
        ops = ops.split()
        name = ops[0]
        matrix = next(matrix for matrix in self.matrices if matrix.name == name)
        for i in range(1, len(ops), 2):
            op = ops[i]
            if op == 's':
                scalar = int(ops[i + 1])
                matrix = self.scalar_multiply(matrix.name, scalar)
                self.matrices[self.matrices.index(next(matrix for matrix in self.matrices if matrix.name == matrix.name))] = matrix
            elif op == '+':
                name2 = ops[i + 1]
                matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
                matrix = self.add_matrices(matrix.name, matrix2.name)
                self.matrices.append(matrix)
            elif op == '-':
                name2 = ops[i + 1]
                matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
                matrix = self.subtract_matrices(matrix.name, matrix2.name)
                self.matrices.append(matrix)
            elif op == 't':
                matrix = self.flip_matrix(matrix.name)
                self.matrices[self.matrices.index(next(matrix for matrix in self.matrices if matrix.name == matrix.name))] = matrix
        return matrix

def print_menu():
...
    print('7. Intrare personalizată')
    print('8. Ieșire')
def main():
    matrix_multiplier = MatrixMultiplier()
    while True:
        print_menu()
        choice = input('Introdu alegerea ta: ')
...
        elif choice == '7':
            update_con = input('Vrei sa salvezi noile valori?: ')
            if update_con in ['yes', 'y']:
                update_con = 1
            operations = input('Introduceți succesiunea operațiilor cu matrice: ')
            try:
                result = matrix_multiplier.custom_input(operations)
                print(result)
            except (ValueError, IndexError) as e:
                print(e)
        else:
            print('Alegere nevalidă')

if __name__ == '__main__':
    main()

基本上,当我对它进行奇异矩阵运算时,它工作正常,但当我使用选项7(自定义输入)时,我得到了错误的答案。下面是我的错误输出:

1. Creați matrice
2. Înmulțiți matrice
3. Înmulțire scalară
4. Adăugați matrice
5. Scăderea matricilor
6. Flip Matrix
7. Intrare personalizată
8. Ieșire
Introdu alegerea ta: 1
Introduceți numele matricei: A
Introduceți numărul de rânduri pentru matricea A: 3
Introduceți numărul de coloane pentru matricea A: 3
Introduceți valoarea pentru poziție (0, 0) în matricea A: 1
Introduceți valoarea pentru poziție (0, 1) în matricea A: -1
Introduceți valoarea pentru poziție (0, 2) în matricea A: 0
Introduceți valoarea pentru poziție (1, 0) în matricea A: 0
Introduceți valoarea pentru poziție (1, 1) în matricea A: -2
Introduceți valoarea pentru poziție (1, 2) în matricea A: 1
Introduceți valoarea pentru poziție (2, 0) în matricea A: -2
Introduceți valoarea pentru poziție (2, 1) în matricea A: 3
Introduceți valoarea pentru poziție (2, 2) în matricea A: 1
1. Creați matrice
2. Înmulțiți matrice
3. Înmulțire scalară
4. Adăugați matrice
5. Scăderea matricilor
6. Flip Matrix
7. Intrare personalizată
8. Ieșire
Introdu alegerea ta: 1
Introduceți numele matricei: B
Introduceți numărul de rânduri pentru matricea B: 3
Introduceți numărul de coloane pentru matricea B: 3
Introduceți valoarea pentru poziție (0, 0) în matricea B: 1
Introduceți valoarea pentru poziție (0, 1) în matricea B: 1
Introduceți valoarea pentru poziție (0, 2) în matricea B: -1
Introduceți valoarea pentru poziție (1, 0) în matricea B: 0
Introduceți valoarea pentru poziție (1, 1) în matricea B: 2
Introduceți valoarea pentru poziție (1, 2) în matricea B: 3
Introduceți valoarea pentru poziție (2, 0) în matricea B: 1
Introduceți valoarea pentru poziție (2, 1) în matricea B: 4
Introduceți valoarea pentru poziție (2, 2) în matricea B: 1
1. Creați matrice
2. Înmulțiți matrice
3. Înmulțire scalară
4. Adăugați matrice
5. Scăderea matricilor
6. Flip Matrix
7. Intrare personalizată
8. Ieșire
Introdu alegerea ta: 7
Vrei sa salvezi noile valori?: y
Introduceți succesiunea operațiilor cu matrice: A s 2 - B t
2A-B^T = 
1 0 -5
-3 -6 2
1 -1 1

下面是它应该是什么正确

1. Creați matrice
2. Înmulțiți matrice
3. Înmulțire scalară
4. Adăugați matrice
5. Scăderea matricilor
6. Flip Matrix
7. Intrare personalizată
8. Ieșire
Introdu alegerea ta: 1
Introduceți numele matricei: A
Introduceți numărul de rânduri pentru matricea A: 3
Introduceți numărul de coloane pentru matricea A: 3
Introduceți valoarea pentru poziție (0, 0) în matricea A: 1
Introduceți valoarea pentru poziție (0, 1) în matricea A: -1
Introduceți valoarea pentru poziție (0, 2) în matricea A: 0
Introduceți valoarea pentru poziție (1, 0) în matricea A: 0
Introduceți valoarea pentru poziție (1, 1) în matricea A: -2
Introduceți valoarea pentru poziție (1, 2) în matricea A: 1
Introduceți valoarea pentru poziție (2, 0) în matricea A: -2
Introduceți valoarea pentru poziție (2, 1) în matricea A: 3
Introduceți valoarea pentru poziție (2, 2) în matricea A: 1
1. Creați matrice
2. Înmulțiți matrice
3. Înmulțire scalară
4. Adăugați matrice
5. Scăderea matricilor
6. Flip Matrix
7. Intrare personalizată
8. Ieșire
Introdu alegerea ta: 1
Introduceți numele matricei: B
Introduceți numărul de rânduri pentru matricea B: 3
Introduceți numărul de coloane pentru matricea B: 3
Introduceți valoarea pentru poziție (0, 0) în matricea B: 1
Introduceți valoarea pentru poziție (0, 1) în matricea B: 1
Introduceți valoarea pentru poziție (0, 2) în matricea B: -1
Introduceți valoarea pentru poziție (1, 0) în matricea B: 0
Introduceți valoarea pentru poziție (1, 1) în matricea B: 2
Introduceți valoarea pentru poziție (1, 2) în matricea B: 3
Introduceți valoarea pentru poziție (2, 0) în matricea B: 1
Introduceți valoarea pentru poziție (2, 1) în matricea B: 4
Introduceți valoarea pentru poziție (2, 2) în matricea B: 1
1. Creați matrice
2. Înmulțiți matrice
3. Înmulțire scalară
4. Adăugați matrice
5. Scăderea matricilor
6. Flip Matrix
7. Intrare personalizată
8. Ieșire
Introdu alegerea ta: 7
Vrei sa salvezi noile valori?: y
Introduceți succesiunea operațiilor cu matrice: A s 2 - B t
2A-B^T = 
1 -2 -1
-1 -6 -2
-3 3 1

有人能帮帮我吗?

o3imoua4

o3imoua41#

下面是测试代码并查找错误的方法:
首先,你必须弄清楚你的问题是在用户输入的解析上还是在计算的数学上。要做到这一点,你需要编写一种方法,通过代码而不是用户输入来初始化你的矩阵乘法器,然后用你在网上找到的任何矩阵乘法网站的结果来检查你的乘法结果。如果你得到了一个错误的结果,那么就去研究数学逻辑。如果您得到正确结果,请处理用户输入。
我是说

def __init__(self, matrices=None):
    self.matrices = [] if matrices == None else matrices

因此,您可以从代码中生成它,而不是手动输入所有数字,然后使用doctestunittest编写测试,以检查操作的数学逻辑是否正确。
以下是包含此更改和自动测试的代码:

import doctest

class Matrix:
    def __init__(self, name, m, n, values):
        self.name = name
        self.m = m
        self.n = n
        self.values = values

    def __str__(self):
        rows = [self.values[i:i+self.n] for i in range(0, len(self.values), self.n)]
        return f'{self.name} = \n' + '\n'.join([' '.join(map(str, row)) for row in rows])
    
    def __repr__(self):
        return f'Matrix({self.name}, {self.m}, {self.n}, {self.values})'
class MatrixMultiplier:
    def __init__(self, matrices=None):
        self.matrices = [] if matrices is None else matrices

    def create_matrix(self, name):
        m = int(input(f'Introduceți numărul de rânduri pentru matricea {name}: '))
        n = int(input(f'Introduceți numărul de coloane pentru matricea {name}: '))
        values = []
        for i in range(m):
            for j in range(n):
                value = int(input(f'Introduceți valoarea pentru poziție ({i}, {j}) în matricea {name}: '))
                values.append(value)
        matrix = Matrix(name, m, n, values)
        self.matrices.append(matrix)

    def add_matrices(self, name1, name2):
        matrix1 = next(matrix for matrix in self.matrices if matrix.name == name1)
        matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
        if matrix1.m != matrix2.m or matrix1.n != matrix2.n:
            raise ValueError('Cele două matrice trebuie să aibă aceleași dimensiuni')
        result = [matrix1.values[i] + matrix2.values[i] for i in range(len(matrix1.values))]
        return Matrix(f'{name1}+{name2}', matrix1.m, matrix1.n, result)

    def multiply_matrices(self, name1, name2):
        """
        >>> m1 = Matrix('A', 2, 2, [1, 2, 3, 4])
        >>> m2 = Matrix('B', 2, 2, [0, 1, 2, 3])
        >>> MatrixMultiplier(matrices=[m1, m2]).multiply_matrices(m1.name, m2.name)
        Matrix(AB, 2, 2, [4, 7, 8, 15])
        """
        matrix1 = next(matrix for matrix in self.matrices if matrix.name == name1)
        matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
        if matrix1.n != matrix2.m:
            raise ValueError('Numărul de coloane din prima matrice trebuie să se potrivească cu numărul de rânduri din a doua matrice')
        result = []
        for i in range(matrix1.m):
            for j in range(matrix2.n):
                val = 0
                for k in range(matrix1.n):
                    val += matrix1.values[i * matrix1.n + k] * matrix2.values[k * matrix2.n + j]
                result.append(val)
        return Matrix(f'{name1}{name2}', matrix1.m, matrix2.n, result)
    
    def scalar_multiply(self, name, scalar):
        matrix = next(matrix for matrix in self.matrices if matrix.name == name)
        result = [scalar * val for val in matrix.values]
        matrix.values = result
        matrix.name = f'{scalar}{name}'
        return Matrix(f'{scalar}{name}', matrix.m, matrix.n, result)

    def flip_matrix(self, name):
        matrix = next(matrix for matrix in self.matrices if matrix.name == name)
        result = []
        for j in range(matrix.n):
            for i in range(matrix.m):
                result.append(matrix.values[i * matrix.n + j])
        matrix.values = result
        matrix.m, matrix.n = matrix.n, matrix.m
        matrix.name = f'{name}^T'
        return matrix

    def subtract_matrices(self, name1, name2):
        matrix1 = next(matrix for matrix in self.matrices if matrix.name == name1)
        matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
        if matrix1.m != matrix2.m or matrix1.n != matrix2.n:
            raise ValueError('Cele două matrice trebuie să aibă aceleași dimensiuni')
        result = [matrix1.values[i] - matrix2.values[i] for i in range(len(matrix1.values))]
        return Matrix(f'{name1}-{name2}', matrix1.m, matrix1.n, result)

    def custom_input(self, ops):
        ops = ops.split()
        name = ops[0]
        matrix = next(matrix for matrix in self.matrices if matrix.name == name)
        for i in range(1, len(ops), 2):
            op = ops[i]
            if op == 's':
                scalar = int(ops[i + 1])
                matrix = self.scalar_multiply(matrix.name, scalar)
                self.matrices[self.matrices.index(next(matrix for matrix in self.matrices if matrix.name == matrix.name))] = matrix
            elif op == '+':
                name2 = ops[i + 1]
                matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
                matrix = self.add_matrices(matrix.name, matrix2.name)
                self.matrices.append(matrix)
            elif op == '-':
                name2 = ops[i + 1]
                matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
                matrix = self.subtract_matrices(matrix.name, matrix2.name)
                self.matrices.append(matrix)
            elif op == 't':
                matrix = self.flip_matrix(matrix.name)
                self.matrices[self.matrices.index(next(matrix for matrix in self.matrices if matrix.name == matrix.name))] = matrix
        return matrix

if __name__ == "__main__":
    doctest.testmod()

这个测试通过了,我从一个矩阵乘法网站上得到了正确的结果(请看图片中网站的结果)(假设第一个矩阵是[[1,2]],[3,4]])。现在你可以专注于输入处理方法并修复那里的bug。

因此错误最有可能出现在输入处理中。
这是完全修复的代码,技巧是处理之前的转置,因为它有更高的优先级,并小心名称的变化。

import doctest

class Matrix:
    def __init__(self, name, m, n, values):
        self.name = name
        self.m = m
        self.n = n
        self.values = values

    def __str__(self):
        rows = [self.values[i:i+self.n] for i in range(0, len(self.values), self.n)]
        return f'{self.name} = \n' + '\n'.join([' '.join(map(str, row)) for row in rows])
    
    def __repr__(self):
        return f'Matrix({self.name}, {self.m}, {self.n}, {self.values})'

class MatrixMultiplier:
    def __init__(self, matrices=None):
        self.matrices = [] if matrices is None else matrices

    def create_matrix(self, name):
        m = int(input(f'Introduceți numărul de rânduri pentru matricea {name}: '))
        n = int(input(f'Introduceți numărul de coloane pentru matricea {name}: '))
        values = []
        for i in range(m):
            for j in range(n):
                value = int(input(f'Introduceți valoarea pentru poziție ({i}, {j}) în matricea {name}: '))
                values.append(value)
        matrix = Matrix(name, m, n, values)
        self.matrices.append(matrix)

    def add_matrices(self, name1, name2):
        """
        >>> m1 = Matrix('A', 2, 2, [1, 2, 3, 4])
        >>> m2 = Matrix('B', 2, 2, [0, 1, 2, 3])
        >>> MatrixMultiplier([m1, m2]).add_matrices('A', 'B')
        Matrix(A+B, 2, 2, [1, 3, 5, 7])
        """
        matrix1 = next(matrix for matrix in self.matrices if matrix.name == name1)
        matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
        if matrix1.m != matrix2.m or matrix1.n != matrix2.n:
            raise ValueError('Cele două matrice trebuie să aibă aceleași dimensiuni')
        result = [matrix1.values[i] + matrix2.values[i] for i in range(len(matrix1.values))]
        return Matrix(f'{name1}+{name2}', matrix1.m, matrix1.n, result)

    def multiply_matrices(self, name1, name2):
        """
        >>> m1 = Matrix('A', 2, 2, [1, 2, 3, 4])
        >>> m2 = Matrix('B', 2, 2, [0, 1, 2, 3])
        >>> MatrixMultiplier(matrices=[m1, m2]).multiply_matrices(m1.name, m2.name)
        Matrix(AB, 2, 2, [4, 7, 8, 15])
        """
        matrix1 = next(matrix for matrix in self.matrices if matrix.name == name1)
        matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
        if matrix1.n != matrix2.m:
            raise ValueError('Numărul de coloane din prima matrice trebuie să se potrivească cu numărul de rânduri din a doua matrice')
        result = []
        for i in range(matrix1.m):
            for j in range(matrix2.n):
                val = 0
                for k in range(matrix1.n):
                    val += matrix1.values[i * matrix1.n + k] * matrix2.values[k * matrix2.n + j]
                result.append(val)
        return Matrix(f'{name1}{name2}', matrix1.m, matrix2.n, result)
    
    def scalar_multiply(self, name, scalar):
        """
        >>> m1 = Matrix('A', 2, 2, [1, 2, 3, 4])
        >>> MatrixMultiplier([m1]).scalar_multiply(m1.name, 2)
        Matrix(2A, 2, 2, [2, 4, 6, 8])
        """
        matrix = next(matrix for matrix in self.matrices if matrix.name == name)
        result = [scalar * val for val in matrix.values]
        matrix.values = result
        matrix.name = f'{scalar}{name}'
        return Matrix(f'{scalar}{name}', matrix.m, matrix.n, result)

    def flip_matrix(self, name):
        """
        >>> m1 = Matrix('A', 2, 2, [1, 2, 3, 4])
        >>> MatrixMultiplier([m1]).flip_matrix(m1.name)
        Matrix(A^T, 2, 2, [1, 3, 2, 4])
        """
        matrix = next(matrix for matrix in self.matrices if matrix.name == name)
        result = []
        for j in range(matrix.n):
            for i in range(matrix.m):
                result.append(matrix.values[i * matrix.n + j])
        matrix.values = result
        matrix.m, matrix.n = matrix.n, matrix.m
        matrix.name = f'{name}^T'
        return matrix

    def subtract_matrices(self, name1, name2):
        """
        >>> m1 = Matrix('A', 2, 2, [1, 2, 3, 4])
        >>> m2 = Matrix('B', 2, 2, [0, 1, 2, 3])
        >>> MatrixMultiplier([m1, m2]).subtract_matrices('A', 'B')
        Matrix(A-B, 2, 2, [1, 1, 1, 1])
        """
        matrix1 = next(matrix for matrix in self.matrices if matrix.name == name1)
        matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
        if matrix1.m != matrix2.m or matrix1.n != matrix2.n:
            raise ValueError('Cele două matrice trebuie să aibă aceleași dimensiuni')
        result = [matrix1.values[i] - matrix2.values[i] for i in range(len(matrix1.values))]
        return Matrix(f'{name1}-{name2}', matrix1.m, matrix1.n, result)
    
    def proprocess_transpose(self, ops):
        """
        >>> m1 = Matrix('A', 2, 2, [1, 2, 3, 4])
        >>> mult = MatrixMultiplier([m1])
        >>> mult.proprocess_transpose('A t')
        'A^T'
        >>> mult.matrices[0]
        Matrix(A^T, 2, 2, [1, 3, 2, 4])
        """
        ops = ops.split()
        remove_idxs = []
        for i in range(len(ops)):
            #print(locals())
            if ops[i] == 't':
                name = ops[i - 1]
                matrix = self.flip_matrix(name)
                #print(locals())
                name = name + '^T'
                #print("matrices", self.matrices)
                self.matrices[self.matrices.index(next(m for m in self.matrices if m.name == name))] = matrix
                remove_idxs.append(i)
                ops[i-1] = f'{name}'
        #print("remove_idxs: ", remove_idxs)
        ops = [ops[i] for i in range(len(ops)) if i not in remove_idxs]
        return ' '.join(ops)
        
    def custom_input(self, ops):
        """
        >>> from copy import deepcopy
        >>> m1 = Matrix('A', 3, 3, [1, -1, 0, 0, -2, 1, -2, 3, 1])
        >>> m2 = Matrix('B', 3, 3, [1,  1,-1, 0,  2, 3,  1, 4, 1])
        >>> mult = MatrixMultiplier([deepcopy(m1), deepcopy(m2)])
        >>> deepcopy(mult).custom_input('A s 2 - B t')
        Matrix(2A-B^T, 3, 3, [1, -2, -1, -1, -6, -2, -3, 3, 1])
        >>> mult.custom_input('A t - B t')
        Matrix(A^T-B^T, 3, 3, [0, 0, -3, -2, -4, -1, 1, -2, 0])
        """
        ("Input")
        #print(locals())
        ops = self.proprocess_transpose(ops)
        #print(locals())
        ops = ops.split()
        #print(locals())
        name = ops[0]
        #print(locals(), self.matrices)
        matrix = next(m for m in self.matrices if m.name == name)
        #print(locals())
        for i in range(1, len(ops), 2):
            #print(locals())
            op = ops[i]
            if op == 's':
                scalar = int(ops[i + 1])
                matrix = self.scalar_multiply(matrix.name, scalar)
                self.matrices[self.matrices.index(next(m for m in self.matrices if m.name == matrix.name))] = matrix
            elif op == '+':
                name2 = ops[i + 1]
                matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
                matrix = self.add_matrices(matrix.name, matrix2.name)
                self.matrices.append(matrix)
            elif op == '-':
                name2 = ops[i + 1]
                matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
                matrix = self.subtract_matrices(matrix.name, matrix2.name)
                self.matrices.append(matrix)
        return matrix

if __name__ == "__main__":
    doctest.testmod()
4xrmg8kj

4xrmg8kj2#

因此,经过大量的研究和失败或无用的代码,我设法解决了这个问题,是的,它是在输入用户给出的,即它没有根据优先级分组,因为我们都知道什么是在括号中的数学有优先级解决。

def parse_parentheses(self,input_str):
        stack = []
        term = ""
        if "(" in input_str:
            for char in input_str:
                if char in ['+', '-', '*']:
                    if term:
                        stack.append(term)
                        term = ""
                    stack.append(char)
                elif char == "(":
                    if term:
                        stack.append(term)
                        term = ""
                    stack.append(char)
                elif char == ")":
                    if term:
                        stack.append(term)
                        term = ""
                    temp = []
                    while stack and stack[-1] != "(":
                        temp.append(stack.pop())
                    if stack[-1] == "(":
                        stack.pop()
                    if temp:
                        stack += temp[::-1]
                else:
                    term += char

            if term:
                stack.append(term)
            for op in ['*', '-', '+']:
                while op in stack:
                    op_index = stack.index(op)
                    stack.pop(op_index)
                    stack.append(op)
                    if op not in stack[op_index + 1:]:
                        break

            return stack
        else:
            return [input_str]

    def custom_input(self, equation):
        equation = self.parse_parentheses(equation)
        equation_list = []
        temp_str = ""
        if len(equation)>1:
            #IT IS FIXED SO WORKS FOR 2 () sets
            _n1 = equation[0][0]
            _n2 = equation[1][0]
            ###################################
            for ec in equation:
                if ec not in ['+', '-', '*'] and len(ec) > 1:
                    equation_list.append(ec)
                elif ec in ['+', '-', '*']:
                    equation_list.append(f'{_n1}{ec}{_n2}')
        else:
            equation_list.append(equation[0])
        for equation in equation_list:
            if '*' in equation:
                matrices = equation.split('*')
                matrix1 = next(matrix for matrix in self.matrices if matrix.name == matrices[0])
                matrix2 = next(matrix for matrix in self.matrices if matrix.name == matrices[1])
                result_matrix = self.multiply_matrices(matrix1.name, matrix2.name)
                matrix_name = matrix1.name
            elif '-' in equation:
                matrices = equation.split('-')
                matrix1 = next(matrix for matrix in self.matrices if matrix.name == matrices[0])
                matrix2 = next(matrix for matrix in self.matrices if matrix.name == matrices[1])
                result_matrix = self.subtract_matrices(matrix1.name, matrix2.name)
                matrix_name = matrix1.name
            elif 'o' in equation: # SELF MULTIPLY
                matrices = equation.split('o')
                matrix = next(matrix for matrix in self.matrices if matrix.name == matrices[0])
                result_matrix = self.multiply_matrices(matrix.name, matrix.name)
                matrix_name = matrix.name
            elif 's' in equation:
                matrices = equation.split('s')
                matrix = next(matrix for matrix in self.matrices if matrix.name == matrices[0])
                scalar = float(matrices[1])
                result_matrix = self.scalar_multiply(matrix.name, scalar)
                matrix_name = matrix.name
            elif 't' in equation:
                matrix_name = equation.split('t')[0]
                matrix = next(matrix for matrix in self.matrices if matrix.name == matrix_name)
                result_matrix = self.flip_matrix(matrix.name)
                matrix_name = matrix.name
            else:
                raise ValueError(f"Invalid equation '{equation}'")
            if result_matrix is not None:
                self.matrices[self.matrices.index(next(matrix for matrix in self.matrices if matrix.name == matrix_name))] = result_matrix

        return result_matrix

这将是解决方案,当然有一些小的或大的错误,但每个人都会根据自己的需要修复它们,因为在我的情况下,它的工作,因为它的意图。我想感谢@Caridorc的帮助,时间和想法的解决方案,再次感谢你。

**EDIT:**我忘了告诉你,这2个函数被添加到MatrixMultiplier类,你必须在类的每个函数中进行某些更改,有一些函数可以重命名矩阵:scalar_multiply,flip_matrix,您可以注意到以下代码行:

matrix.values ​​= result
        matrix.name = f'{scalar}{name}'

matrix.values ​​= result
        matrix.name = f'{name}^T'

替换为:

matrix.values ​​= result
        matrix.name = f'{name}'

此处为完整代码:https://pastebin.com/vsAkY8gX

相关问题