2025, Dec 26 18:03
Баг в todo на Python: пропущен перевод строки, show склеивает записи
Почему в CLI‑todo на Python add/show склеивают записи и как это исправить: пропущен перевод строки. Решение простое — добавляйте \n при записи в файл.
Когда пишешь простое CLI‑приложение для списка дел на Python, легко забыть, что файлы устроены построчно. Стоит пропустить один перевод строки — и вывод команды «show» внезапно склеивает несколько записей. Именно это и происходит, когда добавляешь пункт вроде «add bro», а затем вызываешь «show»: последние два задания оказываются в одной строке, вместо того чтобы отображаться отдельными элементами.
Как воспроизвести проблему
Основной цикл читает и записывает задачи в обычный текстовый файл. Логика показа убирает символы перевода строки перед печатью, а вот ветка add добавляет новый пункт без завершающего переноса. В итоге две соседние записи могут «склеиться» в файле и, как следствие, в выводе.
while True:
cmd_text = input("type add, show, edit, remove or exit ")
cmd_text = cmd_text.strip()
if 'add' in cmd_text:
entry_text = cmd_text[4:]
with open('todos.txt', 'r') as fh:
items_list = fh.readlines()
items_list.append(entry_text)
with open('todos.txt', 'w') as fh:
fh.writelines(items_list)
elif 'show' in cmd_text:
with open('todos.txt', 'r') as fh:
items_list = fh.readlines()
for pos, line_item in enumerate(items_list):
line_item = line_item.strip("\n")
pos = pos + 1
line_out = f"{pos}-{line_item}"
print(line_out)
elif 'edit' in cmd_text:
idx_num = int(cmd_text[5:])
print(idx_num)
idx_num = idx_num - 1
with open('todos.txt', 'r') as fh:
items_list = fh.readlines()
updated_entry = input("Type the new todo:")
items_list[idx_num] = updated_entry + "\n"
with open('todos.txt', 'w') as fh:
fh.writelines(items_list)
elif 'remove' in cmd_text:
idx_num = int(cmd_text[6:])
with open('todos.txt', 'r') as fh:
items_list = fh.readlines()
pos = idx_num - 1
removed_entry = items_list[pos].strip("\n")
items_list.pop(pos)
with open('todos.txt', 'w') as fh:
fh.writelines(items_list)
feedback = f"todo {removed_entry} was removed from the list"
print(feedback)
elif 'exit' in cmd_text:
break
else:
print("Command is not valid ")
print("bye!")
Что именно ломается и почему
Ветка вывода удаляет завершающие переводы строк с помощью strip("\n"), чтобы элементы аккуратно смотрелись в консоли. Это нормально. Проблема в ветке add: она добавляет новую строку задачи без конца строки и затем перезаписывает весь список через writelines. Если у предыдущего последнего элемента уже не осталось перевода строки или у только что добавленного его нет, следующая запись поместит их в одну физическую строку. Так записи «hii» и «bro» превращаются в одну строку «hiibro», а последующие добавления продолжают сливаться.
Как исправить
Гарантируйте, что каждый новый пункт сохраняется с переводом строки. Больше ничего менять не нужно. Если при добавлении дописывать «\n», каждая задача окажется отдельной строкой в todos.txt. Ветка show по‑прежнему может убирать перевод строки для аккуратного вывода, а структура файла останется корректной.
if 'add' in cmd_text:
entry_text = cmd_text[4:]
with open('todos.txt', 'r') as fh:
items_list = fh.readlines()
items_list.append(entry_text + '\n')
with open('todos.txt', 'w') as fh:
fh.writelines(items_list)
Почему это важно
Если вы работаете с файлом как с набором строк, согласованность концов строк — это основа. readlines полагается на «\n», чтобы находить границы. writelines записывает ровно то, что вы ему передаёте. Если при сохранении записи опустить перевод строки, у следующей записи не будет разделителя, и простое хранение в виде списка даёт сбой. Исправление крошечное, но оно предотвращает скрытую порчу списка дел и делает поведение вашего CLI предсказуемым.
Практические заметки напоследок
Всегда завершайте каждую сохранённую запись переводом строки, чтобы сохранить семантику «одна запись — одна строка». Если позже захотите упростить логику вывода, можно сразу начинать нумерацию с единицы или ужесточить разбор команд так, чтобы ветка add срабатывала только на точное «add», а не на adding или hello add. Для более продвинутого поведения CLI существуют специализированные модули, которые управляют командными циклами и удобствами вроде запоминания предыдущих команд и подсветки; к ним можно перейти, когда базовое хранение будет надёжным.
Итог прост: при записи новых задач добавляйте «\n». Тогда «show» выведет каждый элемент на своей строке — ровно как задумано.