fork download
  1. class Table:
  2. def __init__(self, meta, tups):
  3. self._validate_data(meta, tups) # валидация введенных данных
  4. self.meta = list(meta)
  5. self.tables = list(tups)
  6.  
  7. def _validate_data(self, meta, tups):
  8. '''Валидация данных'''
  9. if len(meta) != len(tups[0]):
  10. raise ValueError('Meta header and tuples lengths dont match!')
  11. if not all(len(tups[0]) == len(x) for x in tups):
  12. raise ValueError('All tuples must be the same length!')
  13.  
  14. def _find_lengths(self):
  15. '''Поиск максимальной длины каждой колонки. Вспомогательная функция'''
  16. result = [0 for _ in range(len(self.tables[0]))]
  17. merged = [self.meta] + self.tables
  18. for i in range(len(merged[0])):
  19. for row in merged:
  20. if len(str(row[i])) > result[i]:
  21. result[i] = len(str(row[i]))
  22. return result
  23.  
  24. def _draw_border(self):
  25. ''' "Рисует" рамку таблицы '''
  26. rows = ['' for _ in range((len(self.tables)+1)*2+1)]
  27. lengths = self._find_lengths()
  28. for i in range(len(rows)):
  29. if i % 2 == 0: # если строка четная, значит там очертания рамки
  30. rows[i] = '+'
  31. for num in lengths:
  32. rows[i] += '-'*num + '--+'
  33. else: # если нечетная, значит там будут данные
  34. rows[i] = '|'
  35. for num in lengths:
  36. rows[i] += ' '*num + ' |'
  37. return rows # возвращаем список строк таблицы
  38.  
  39. def draw_table(self):
  40. '''Рисует таблицу целиком'''
  41. from itertools import count
  42. merged = [self.meta] + self.tables
  43. table = self._draw_border() # подготавливаем рамку заранее
  44. lengths = self._find_lengths() # нужно, чтобы знать максимальную длину каждой колонки
  45. for i, idx in zip(range(1, len(table), 2), count()): # итерация по индексам списка table и индексам списка merged
  46. result = '|'
  47. for j, elem in enumerate(merged[idx]):
  48. extra_l = (lengths[j] - len(str(elem))) // 2
  49. extra_r = extra_l+1 if (lengths[j] - len(str(elem))) % 2 != 0 else extra_l
  50. result += ' ' + ' '*extra_l + str(elem) + ' '*extra_r + ' |'
  51. table[i] = result
  52. print('\n'.join(table))
  53.  
  54.  
  55. if __name__ == '__main__':
  56. meta = ['id', 'name', 'description', 'count']
  57. tups = [
  58. (1, 'tomato', 'shit', '2000'),
  59. (24, 'pineapple', 'good', '13000'),
  60. (7, 'watermelon', 'eatable', '600')
  61. ]
  62. t = Table(meta, tups)
  63. t.draw_table()
Success #stdin #stdout 0.02s 9160KB
stdin
Standard input is empty
stdout
+----+------------+-------------+-------+
| id |    name    | description | count |
+----+------------+-------------+-------+
| 1  |   tomato   |    shit     | 2000  |
+----+------------+-------------+-------+
| 24 | pineapple  |    good     | 13000 |
+----+------------+-------------+-------+
| 7  | watermelon |   eatable   |  600  |
+----+------------+-------------+-------+