docs: def transposed_matrix(matrix, filler=None, row_type=list, matrix_type=list, value_type=None):
      """Like numpy.transposed, evens up row (list) lengths that aren't uniform, filling with None.
  
      Also, makes all elements a uniform type (default=type(matrix[0][0])),
      except for filler elements.
  
      TODO: add feature to delete None's at the end of rows so that transpose(transpose(LOL)) = LOL
  
      >>> transposed_matrix([[1, 2], [3, 4, 5], [6]])
      [[1, 3, 6], [2, 4, None], [None, 5, None]]
      >>> transposed_matrix(transposed_matrix([[1, 2], [3, 4, 5], [6]]))
      [[1, 2, None], [3, 4, 5], [6, None, None]]
      >>> transposed_matrix([[], [1, 2, 3], [4]])  # empty first row forces default value type (float)
      [[None, 1.0, 4.0], [None, 2.0, None], [None, 3.0, None]]
      >>> transposed_matrix(transposed_matrix([[], [1, 2, 3], [4]]))
      [[None, None, None], [1.0, 2.0, 3.0], [4.0, None, None]]
      >>> x = transposed_matrix([range(4),[4,5]])
      >>> x
      [[0, 4], [1, 5], [2, None], [3, None]]
      >>> transposed_matrix(x)
      [[0, 1, 2, 3], [4, 5, None, None]]
      >>> transposed_matrix([[1,2],[1],[1,2,3]])
      [[1, 1, 1], [2, None, 2], [None, None, 3]]
      """
      matrix_type = matrix_type or type(matrix)
  
      try:
          row_type = row_type or type(matrix[0])
      except (IndexError, ValueError, AttributeError, TypeError):
          pass
      if not row_type or row_type is None:
          row_type = list
  
      try:
          if matrix[0][0] is None:
              value_type = value_type or float
          else:
              value_type = value_type or type(matrix[0][0]) or float
      except (IndexError, ValueError, AttributeError, TypeError):
          pass
      if not value_type or value_type is None:
          value_type = float
  
      # original matrix is NxM, new matrix will be MxN
      N = len(matrix)
      Ms = [len(row) for row in matrix]
      M = 0 if not Ms else max(Ms)
  
      ans = []
      # for each row in the new matrix (column in old matrix)
      for j in range(M):
          # add a row full of copies the `fill` value up to the maximum width required
          ans += [row_type([filler] * N)]
          for i in range(N):
              try:
                  ans[j][i] = value_type(matrix[i][j])
              except IndexError:
                  ans[j][i] = filler
              except TypeError:
                  ans[j][i] = filler
  
      return matrix_type(ans) if isinstance(ans[0], row_type) else matrix_type([row_type(row) for row in ans])