code: def assemble_rows(data, max_allowed_lengths=None, dividechars=1,
                    ignore_columns=None):
      
      rows = []
      max_lengths = {}
      ignore_columns = ignore_columns or []
  
      # shitty performance, here we go
      # it would be way better to do a single double loop and provide mutable variable
      # FIXME: merge this code with calculate() from above
      for row in data:
          col_index = 0
          for widget in row:
              if col_index in ignore_columns:
                  continue
              l = len(widget.text)
              if max_allowed_lengths:
                  if col_index in max_allowed_lengths and max_allowed_lengths[col_index] < l:
                      # l is bigger then what is allowed
                      l = max_allowed_lengths[col_index]
  
              max_lengths.setdefault(col_index, l)
              max_lengths[col_index] = max(l, max_lengths[col_index])
              col_index += 1
  
      for row in data:
          row_widgets = []
          for idx, item in enumerate(row):
              if idx in ignore_columns:
                  row_widgets.append(item)
              else:
                  row_widgets.append((max_lengths[idx], item))
          rows.append(
              RowWidget(row_widgets, dividechars=dividechars)
          )
  
      return rows
docs: :param data: list of lists:
      [["row 1 column 1", "row 1 column 2"],
       ["row 2 column 1", "row 2 column 2"]]
      each item consists of instance of urwid.Text
  
      :param max_allowed_lengths: dict:
          {col_index: maximum_allowed_length}
      :param ignore_columns: list of ints, indexes which should not be calculated