input: Write a function to implement a class in Python that performs various matrix operations like addition, subtraction, multiplication, and transpose. The class should be named Matrix and should include methods to perform each operation. The __str__ method should return a string representation of the matrix.
  
  class Matrix:
      def __init__(self, m, n, lst):
          self.m = m
          self.n = n
          self.mat = []
    
          c = 0
          for i in range(self.m):
              a = []
              for j in range(self.n):
                  a.append(lst[c])
                  c += 1
              self.mat.append(a)
    
      def __str__(self):
          output = ""
          for i in self.mat:
              for j in i:
                  output += str(j) + " "
              output += '\n'
          return output
    
      def add(self, mat2):
          for i in range(self.m):
              for j in range(self.n):
                  self.mat[i][j] += mat2.mat[i][j]
    
      def sub(self, mat2):
          for i in range(self.m):
              for j in range(self.n):
                  self.mat[i][j] -= mat2.mat[i][j]
      
      def mul(self, mat2):
          result = []
          for i in range(self.m):
              a = []
              for j in range(mat2.n):
                  s = 0
                  for k in range(self.n):
                      s += self.mat[i][k] * mat2.mat[k][j]
                  a.append(s)
              result.append(a)
          self.mat = result
          self.m = len(result)
          self.n = len(result[0])
    
      def transpose(self):
          result = [[self.mat[j][i] for j in range(len(self.mat))] for i in range(len(self.mat[0]))]
          self.mat = result
          self.m = len(result)
          self.n = len(result[0])
  
  assert str(Matrix(2, 2, [1, 2, 3, 4])) == "1 2 \n3 4 \n"
  assert str(Matrix(2, 2, [1, 2, 3, 4]).transpose()) == "1 3 \n2 4 \n"
  
  m1 = Matrix(2, 2, [1, 2, 3, 4])
  m2 = Matrix(2, 2, [5, 6, 7, 8])
  m1.add(m2)
  assert str(m1) == "6 8 \n10 12 \n"
  
  m1 = Matrix(2, 2, [1, 2, 3, 4])
  m2 = Matrix(2, 2, [5, 6, 7, 8])
  m1.sub(m2)
  assert str(m1) == "-4 -4 \n-4 -4 \n"
  
  m1 = Matrix(2, 3, [1, 2, 3, 4, 5, 6])
  m2 = Matrix(3, 2, [7, 8, 9, 10, 11, 12])
  m1.mul(m2)
  assert str(m1) == "58 64 \n139 154 \n"
output: 
  def __init__(self, m, n, lst):
      self.m = m
      self.n = n
      self.mat = []
      c = 0
      for i in range(self.m):
          a = []
          for j in range(self.n):
              a.append(lst[c])
              c += 1
          self.mat.append(a)
  
  def __str__(self):
      output = ""
      for i in self.mat:
          for j in i:
              output += str(j) + " "
          output += '\n'
      return output
  
  def add(self, mat2):
      for i in range(self.m):
          for j in range(self.n):
              self.mat[i][j] += mat2.mat[i][j]
  
  def sub(self, mat2):
      for i in range(self.m):
          for j in range(self.n):
              self.mat[i][j] -= mat2.mat[i][j]
  
  def mul(self, mat2):
      result = []
      for i in range(self.m):
          a = []
          for j in range(mat2.n):
              s = 0
              for k in range(self.n):
                  s += self.mat[i][k] * mat2.mat[k][j]
              a.append(s)
          result.append(a)
      self.mat = result
      self.m = len(result)
      self.n = len(result[0])
  
  def transpose(self):
      result = [[self.mat[j][i] for j in range(len(self.mat))] for i in range(len(self.mat[0]))]
      self.mat = result
      self.m = len(result)
      self.n = len(result[0])
  