Как выравниванить время по правой стороне?

Нужно чтобы из этого

name1212 | (0:55)
name12122 | (0:43)
name45152 | (0:38)
name121212 | (0:25)
name11212 | (0:18)
name1123 | (0:06)
name123 | (0:02)
name1232 | (0:01)

Было это

name1212    | (0:55)
name12122   | (0:43)
name45152   | (0:38)
name121212  | (0:25)
name11212   | (0:18)
name1123    | (0:06)
name123     | (0:02)
name1232    | (0:01)

Но проблема в том что я для получение игроков и время делаю это как отдельную функцию и не понимаю как реализовать как это другие делали.

Код получение игроков и времени:

    def get_players_with_time(server_ip):
        ip = str(server_ip.split(',')[0])
        port = int(server_ip.split(',')[1])
        address = (f"{ip}", port)

        get_players = a2s.players(address)
        players = "\n".join(player.name + ' | (' + str(datetime.timedelta(seconds=player.duration))[0:4] + ')' for player in get_players)
        return players

Ответы (2 шт):

Автор решения: Amgarak

Можно примерно так сделать:

get_players = ["Амгарак", "Стас", "Тёмный лорд"]
max_len = 15
players = "\n".join(player+' '*(max_len - len(player))+' | (ВРЕМЯ ИГРЫ)' for player in get_players)

print(players)

Вывод:

Амгарак         | (ВРЕМЯ ИГРЫ)
Стас            | (ВРЕМЯ ИГРЫ)
Тёмный лорд     | (ВРЕМЯ ИГРЫ)

[Program finished]

Как ещё один вариант, определить максимальную длину строки в зависимости от самого длинного имени:

max_len= max(len(player) for player in get_players)
    
players = "\n".join(player.ljust(max_len + 1)+' | (ВРЕМЯ ИГРЫ)' for player in get_players)

print(players)

Вывод:

Амгарак      | (ВРЕМЯ ИГРЫ)
Стас         | (ВРЕМЯ ИГРЫ)
Тёмный лорд  | (ВРЕМЯ ИГРЫ)

[Program finished]

С телеграмом оказалось всё не так просто, так что предлагаю такой вариант:

players = "\n".join(player.ljust(max_len + 1) + '| (ВРЕМЯ ИГРЫ)' for player in get_players)
players = f"```\n{players}\n```"

bot.send_message(message.chat.id, players, parse_mode='Markdown')

Вывод:

введите сюда описание изображения

Основная идея - (```) позволяет телеграму воспринимать текст как код + parse_mode='Markdown'

Таким образом все символы занимают одинаковое пространство, что сохранит форматирование.


pip install PrettyTable

Если добавить библиотеку PrettyTable можно добиться вообще красивого вывода:

table = PrettyTable()
get_players = ["Амгарак", "Стас", "Тёмный лорд"]
table.field_names = ['Player', 'Time']

table.align["Player"] = "l"
table.align["Time"] = "c"

for player in get_players:
    table.add_row([player, '(ВРЕМЯ ИГРЫ)'])

players = table.get_string()
players = f"```\n{players}\n```"
print(players)

Вывод:

введите сюда описание изображения

Выравнивание таблицы может быть установлено равным r, l, c (справа, слева или по центру)

→ Ссылка
Автор решения: mrgervant

Есть вариант форматирования внутри f-строк (или по старинке через format) с помощью операторов выравнивания:

get_players = ["foo", "foobar", "foobarbaz"]
max_len = 15
players = "\n".join(f"{player:<{max_len}} | (ВРЕМЯ ИГРЫ)" for player in get_players)

print(players)

Вывод:

foo             | (ВРЕМЯ ИГРЫ)
foobar          | (ВРЕМЯ ИГРЫ)
foobarbaz       | (ВРЕМЯ ИГРЫ)

< | > | = | ^ - операторы выравнивания (влево, вправо, по ширине - только для чисел, по центру

А перед операторами можно поставить символ, которым нужно заполнить пространство вместо пробелов: {player:*<{max_len}} - заполнит *

После операторов указывается число, определяющее сколько отдается на вывод строки. Если превысить - будет сдвиг. Поэтому предварительно нужно определить max_len по самому длинному имени.

Либо же можно настроить обрезку имени, если оно превышает установленную длину - через добавление .ЧИСЛО:

get_players = ["foo", "foobar", "foobarbaz"]
max_len = 7
players = "\n".join(f"{player:<{max_len}.{max_len}} | (ВРЕМЯ ИГРЫ)" for player in get_players)

print(players)

Вывод:

foo     | (ВРЕМЯ ИГРЫ)  <-- добавили пробелов
foobar  | (ВРЕМЯ ИГРЫ)  <-- добавили пробелов
foobarb | (ВРЕМЯ ИГРЫ)  <-- обрезали строку до 7 символов

С этим можно "поиграть" и гибко настроить вывод:

get_players = ["foo", "foobar", "foobarbaz"]
max_len_str = 7
max_len_name = 5
players = "\n".join(f"{player:<{max_len_str}.{max_len_name}} | (ВРЕМЯ ИГРЫ)" for player in get_players)

print(players)
foo     | (ВРЕМЯ ИГРЫ)
fooba   | (ВРЕМЯ ИГРЫ)
fooba   | (ВРЕМЯ ИГРЫ)
→ Ссылка