class Table:
    def __init__(self, meta, tups):
        self._validate_data(meta, tups)  # валидация введенных данных
        self.meta = list(meta)
        self.tables = list(tups)
 
    def _validate_data(self, meta, tups):
        '''Валидация данных'''
        if len(meta) != len(tups[0]):
            raise ValueError('Meta header and tuples lengths dont match!')
        if not all(len(tups[0]) == len(x) for x in tups):
            raise ValueError('All tuples must be the same length!')
 
    def _find_lengths(self):
        '''Поиск максимальной длины каждой колонки. Вспомогательная функция'''
        result = [0 for _ in range(len(self.tables[0]))]
        merged = [self.meta] + self.tables
        for i in range(len(merged[0])):
            for row in merged:
                if len(str(row[i])) > result[i]:
                    result[i] = len(str(row[i]))
        return result
 
    def _draw_border(self):
        ''' "Рисует" рамку таблицы '''
        rows = ['' for _ in range((len(self.tables)+1)*2+1)]
        lengths = self._find_lengths()
        for i in range(len(rows)):
            if i % 2 == 0:  # если строка четная, значит там очертания рамки
                rows[i] = '+'
                for num in lengths:
                    rows[i] += '-'*num + '--+'
            else:  # если нечетная, значит там будут данные
                rows[i] = '|'
                for num in lengths:
                    rows[i] += ' '*num + '  |'
        return rows  # возвращаем список строк таблицы
 
    def draw_table(self):
        '''Рисует таблицу целиком'''
        from itertools import count
        merged = [self.meta] + self.tables
        table = self._draw_border()  # подготавливаем рамку заранее
        lengths = self._find_lengths()  # нужно, чтобы знать максимальную длину каждой колонки
        for i, idx in zip(range(1, len(table), 2), count()):  # итерация по индексам списка table и индексам списка merged
            result = '|'
            for j, elem in enumerate(merged[idx]):
                extra_l = (lengths[j] - len(str(elem))) // 2
                extra_r = extra_l+1 if (lengths[j] - len(str(elem))) % 2 != 0 else extra_l
                result += ' ' + ' '*extra_l + str(elem) + ' '*extra_r + ' |'
            table[i] = result
        print('\n'.join(table))
 
 
if __name__ == '__main__':
    meta = ['id', 'name', 'description', 'count']
    tups = [
        (1, 'tomato', 'shit', '2000'),
        (24, 'pineapple', 'good', '13000'),
        (7, 'watermelon', 'eatable', '600')
    ]
    t = Table(meta, tups)
    t.draw_table()
				Y2xhc3MgVGFibGU6CiAgICBkZWYgX19pbml0X18oc2VsZiwgbWV0YSwgdHVwcyk6CiAgICAgICAgc2VsZi5fdmFsaWRhdGVfZGF0YShtZXRhLCB0dXBzKSAgIyDQstCw0LvQuNC00LDRhtC40Y8g0LLQstC10LTQtdC90L3Ri9GFINC00LDQvdC90YvRhQogICAgICAgIHNlbGYubWV0YSA9IGxpc3QobWV0YSkKICAgICAgICBzZWxmLnRhYmxlcyA9IGxpc3QodHVwcykKCiAgICBkZWYgX3ZhbGlkYXRlX2RhdGEoc2VsZiwgbWV0YSwgdHVwcyk6CiAgICAgICAgJycn0JLQsNC70LjQtNCw0YbQuNGPINC00LDQvdC90YvRhScnJwogICAgICAgIGlmIGxlbihtZXRhKSAhPSBsZW4odHVwc1swXSk6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ01ldGEgaGVhZGVyIGFuZCB0dXBsZXMgbGVuZ3RocyBkb250IG1hdGNoIScpCiAgICAgICAgaWYgbm90IGFsbChsZW4odHVwc1swXSkgPT0gbGVuKHgpIGZvciB4IGluIHR1cHMpOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdBbGwgdHVwbGVzIG11c3QgYmUgdGhlIHNhbWUgbGVuZ3RoIScpCgogICAgZGVmIF9maW5kX2xlbmd0aHMoc2VsZik6CiAgICAgICAgJycn0J/QvtC40YHQuiDQvNCw0LrRgdC40LzQsNC70YzQvdC+0Lkg0LTQu9C40L3RiyDQutCw0LbQtNC+0Lkg0LrQvtC70L7QvdC60LguINCS0YHQv9C+0LzQvtCz0LDRgtC10LvRjNC90LDRjyDRhNGD0L3QutGG0LjRjycnJwogICAgICAgIHJlc3VsdCA9IFswIGZvciBfIGluIHJhbmdlKGxlbihzZWxmLnRhYmxlc1swXSkpXQogICAgICAgIG1lcmdlZCA9IFtzZWxmLm1ldGFdICsgc2VsZi50YWJsZXMKICAgICAgICBmb3IgaSBpbiByYW5nZShsZW4obWVyZ2VkWzBdKSk6CiAgICAgICAgICAgIGZvciByb3cgaW4gbWVyZ2VkOgogICAgICAgICAgICAgICAgaWYgbGVuKHN0cihyb3dbaV0pKSA+IHJlc3VsdFtpXToKICAgICAgICAgICAgICAgICAgICByZXN1bHRbaV0gPSBsZW4oc3RyKHJvd1tpXSkpCiAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgIGRlZiBfZHJhd19ib3JkZXIoc2VsZik6CiAgICAgICAgJycnICLQoNC40YHRg9C10YIiINGA0LDQvNC60YMg0YLQsNCx0LvQuNGG0YsgJycnCiAgICAgICAgcm93cyA9IFsnJyBmb3IgXyBpbiByYW5nZSgobGVuKHNlbGYudGFibGVzKSsxKSoyKzEpXQogICAgICAgIGxlbmd0aHMgPSBzZWxmLl9maW5kX2xlbmd0aHMoKQogICAgICAgIGZvciBpIGluIHJhbmdlKGxlbihyb3dzKSk6CiAgICAgICAgICAgIGlmIGkgJSAyID09IDA6ICAjINC10YHQu9C4INGB0YLRgNC+0LrQsCDRh9C10YLQvdCw0Y8sINC30L3QsNGH0LjRgiDRgtCw0Lwg0L7Rh9C10YDRgtCw0L3QuNGPINGA0LDQvNC60LgKICAgICAgICAgICAgICAgIHJvd3NbaV0gPSAnKycKICAgICAgICAgICAgICAgIGZvciBudW0gaW4gbGVuZ3RoczoKICAgICAgICAgICAgICAgICAgICByb3dzW2ldICs9ICctJypudW0gKyAnLS0rJwogICAgICAgICAgICBlbHNlOiAgIyDQtdGB0LvQuCDQvdC10YfQtdGC0L3QsNGPLCDQt9C90LDRh9C40YIg0YLQsNC8INCx0YPQtNGD0YIg0LTQsNC90L3Ri9C1CiAgICAgICAgICAgICAgICByb3dzW2ldID0gJ3wnCiAgICAgICAgICAgICAgICBmb3IgbnVtIGluIGxlbmd0aHM6CiAgICAgICAgICAgICAgICAgICAgcm93c1tpXSArPSAnICcqbnVtICsgJyAgfCcKICAgICAgICByZXR1cm4gcm93cyAgIyDQstC+0LfQstGA0LDRidCw0LXQvCDRgdC/0LjRgdC+0Log0YHRgtGA0L7QuiDRgtCw0LHQu9C40YbRiwoKICAgIGRlZiBkcmF3X3RhYmxlKHNlbGYpOgogICAgICAgICcnJ9Cg0LjRgdGD0LXRgiDRgtCw0LHQu9C40YbRgyDRhtC10LvQuNC60L7QvCcnJwogICAgICAgIGZyb20gaXRlcnRvb2xzIGltcG9ydCBjb3VudAogICAgICAgIG1lcmdlZCA9IFtzZWxmLm1ldGFdICsgc2VsZi50YWJsZXMKICAgICAgICB0YWJsZSA9IHNlbGYuX2RyYXdfYm9yZGVyKCkgICMg0L/QvtC00LPQvtGC0LDQstC70LjQstCw0LXQvCDRgNCw0LzQutGDINC30LDRgNCw0L3QtdC1CiAgICAgICAgbGVuZ3RocyA9IHNlbGYuX2ZpbmRfbGVuZ3RocygpICAjINC90YPQttC90L4sINGH0YLQvtCx0Ysg0LfQvdCw0YLRjCDQvNCw0LrRgdC40LzQsNC70YzQvdGD0Y4g0LTQu9C40L3RgyDQutCw0LbQtNC+0Lkg0LrQvtC70L7QvdC60LgKICAgICAgICBmb3IgaSwgaWR4IGluIHppcChyYW5nZSgxLCBsZW4odGFibGUpLCAyKSwgY291bnQoKSk6ICAjINC40YLQtdGA0LDRhtC40Y8g0L/QviDQuNC90LTQtdC60YHQsNC8INGB0L/QuNGB0LrQsCB0YWJsZSDQuCDQuNC90LTQtdC60YHQsNC8INGB0L/QuNGB0LrQsCBtZXJnZWQKICAgICAgICAgICAgcmVzdWx0ID0gJ3wnCiAgICAgICAgICAgIGZvciBqLCBlbGVtIGluIGVudW1lcmF0ZShtZXJnZWRbaWR4XSk6CiAgICAgICAgICAgICAgICBleHRyYV9sID0gKGxlbmd0aHNbal0gLSBsZW4oc3RyKGVsZW0pKSkgLy8gMgogICAgICAgICAgICAgICAgZXh0cmFfciA9IGV4dHJhX2wrMSBpZiAobGVuZ3Roc1tqXSAtIGxlbihzdHIoZWxlbSkpKSAlIDIgIT0gMCBlbHNlIGV4dHJhX2wKICAgICAgICAgICAgICAgIHJlc3VsdCArPSAnICcgKyAnICcqZXh0cmFfbCArIHN0cihlbGVtKSArICcgJypleHRyYV9yICsgJyB8JwogICAgICAgICAgICB0YWJsZVtpXSA9IHJlc3VsdAogICAgICAgIHByaW50KCdcbicuam9pbih0YWJsZSkpCgoKaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzoKICAgIG1ldGEgPSBbJ2lkJywgJ25hbWUnLCAnZGVzY3JpcHRpb24nLCAnY291bnQnXQogICAgdHVwcyA9IFsKICAgICAgICAoMSwgJ3RvbWF0bycsICdzaGl0JywgJzIwMDAnKSwKICAgICAgICAoMjQsICdwaW5lYXBwbGUnLCAnZ29vZCcsICcxMzAwMCcpLAogICAgICAgICg3LCAnd2F0ZXJtZWxvbicsICdlYXRhYmxlJywgJzYwMCcpCiAgICBdCiAgICB0ID0gVGFibGUobWV0YSwgdHVwcykKICAgIHQuZHJhd190YWJsZSgp