Python 3 matrix calculator

Question:

I have an issue with this code, It works wrong on option 7 at least is the main problem, It should do the matrix modify and save new value like 2A(A s 2) should be saved on A and maybe because it doesn’t update to new value it gives wrong output, please help.
CODE:

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()

So basically it works fine when I do singular matrix math on it but When I do option 7 (custom input), I get wrong answer.
Here is my WRONG output:

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

Here is how it should be it RIGHT:

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

can somebody help me?

Asked By: Nick403

||

Answers:

Here is a way to test your code and find the bug:

First of all you must understand if your problem is in the parsing of user input or in the mathematics of the computations. To do so, write a way to initialize your MatrixMultiplier from code rather than user input, then check the results of your multiplication with the result of any matrix multiplication website that you find online. If you get a wrong result, work on math logic, if you get a right result work on handling user input.

I mean like

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

so you can generate this from code rather than inputting all numbers manually, then write tests with doctest or unittest to check that the mathematical logic of the operations is right.

Here is your code with this change and an automated test:

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()

This test passes, where I got the correct result from a matrix multiplication website online (see result from the website in the image). (Assuming that the first matrix is [[1,2]],[3,4]]). Now you can focus on the input handling method and fix the bug there.

enter image description here

So the error is most likely in the input handling.


Here is the fully fixed code, the trick was handling the transpose before because it has higher precedence and being careful about the name changes.

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()
Answered By: Caridorc

So after a lot of research and failed or useless code I managed to solve the problem, yes it was in the input given by the user, namely that it was not divided into groups according to priority, as we all know what is in parentheses in mathematics has priority in solving.
Here is the solution:

    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

That would be the solution, of course there are some small or big bugs, but everyone will fix them according to what they need, because in my case it works as it was intended. I want to thanks @Caridorc for the help, the time given and idea’s for the solution, thank you once again.

EDIT:
I forgot to tell you, these 2 functions are added to the MatrixMultiplier class and you have to make certain changes in each function of the class, there are certain functions that rename the matrices: scalar_multiply, flip_matrix,
Where you notice the following lines of code:

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

OR

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

Replace with:

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

FULL CODE HERE: https://pastebin.com/vsAkY8gX

Answered By: Nick403
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.