Не работает программа по примеру из книги "Укус Питона"

В книге "Укус Питона" была предложена программа для резервного копирования данных. После выполнения шагов, указанных автором, я попытался сделать программу более разговорчивой, но столкнулся с проблемой. После указания комментария (comment) программа перестает что-либо делать. Пробовал убирать некоторые элементы, но всё безуспешно.

UPD: Проблема заключалась в строке "source.extend(file)", которая разбивала вводимую строчку на отдельные символы. При замене на "source.append(file)" всё работает так, как должно.

import os
import sys
import time

source, target_dir = [], ''


def _input_file():
    print('Введите, какой файл вы хотите скопировать - ')
    file = input()
    if len(file) == 0:
        print('No files')
        answer = input('Повторить ввод файлов? Y/N\n')
        if answer == 'Y':
            _input_file()
        elif answer == 'N':
            sys.exit()
        else:
            print('Нет такой команды!')
            _input_file()
    else:
        source.extend(file)
        answer1 = input('Хотите ввести еще один файл? Y/N\n')
        if answer1 == 'Y':
            _input_file()
        elif answer1 == 'N':
            _dir_file()
        else:
            print('Такой команды нет. Примем ваш ответ за N')
            _dir_file()


def _dir_file():
    global target_dir
    print('Введите куда необходимо скопировать файл - ')
    target_dir = input()
    if len(target_dir) == 0:
        print('Введена пустота! Повторите ввод :)')
        _dir_file()


_input_file()
today = target_dir + os.sep + time.strftime('%Y%m%d')
now = time.strftime('%H%M%S')

print('Введите комментарий - ')
comment = input()
if len(comment) == 0:
    target = today + os.sep + now + '.zip'
else:
    target = today + os.sep + now + '_' + comment.replace(' ', '_') + '.zip'

if not os.path.exists(today):
    os.mkdir(today)
    print('Каталог успешно создан', today)

zip_command = f"zip -qr {target} {' '.join(source)}"
if os.system(zip_command) == 0:
    print('Резервная копия успешно создана в', target)
else:
    print('Создание резервной копии НЕ УДАЛОСЬ')

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


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

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

Считаю, что вы не совсем правы. source.extend выполняется много ранее, чем добавление комментария. Однако вы правы, в том, что его необходима заментиь на append, вы верно подметили, что extend добавлял каждую букву как элемент списка. Которая в последствии получалась в файл в команде zip_command = f"zip -qr {target} {' '.join(source)}" в которой и была основная часть проблемы.

#append source=['c:/file.txt']
#extend source=['c',':','/','f'...
print('Введите комментарий - ') #эта строка отработала
comment = input() #эта так же, что будет очевидно если добавить вывод сразу за ней
print('Выполняю')
...

if not os.path.exists(today):
    os.mkdir(today)
    print('Каталог успешно создан', today) #этого сообщения не выводилось тк каталог был создан ранее

zip_command = f"zip -qr {target} {' '.join(source)}"
#append zip -qr c:/bacup c:/file.txt
#extend zip -qr c:bacup c : / f внимание на пробелы, в cmd bash они являются разделителями, то есть здесь мы имеем команду вида zip -qr c:/backup c:/file1.txt c:/file2.txt c:/file3 то есть хотим выполнить архивирование с кучей файлов

if os.system(zip_command) == 0: #здесь идёт выполнение консольной команды, занимающее значительное время, так как указана опция -q (тихий режим) то никаких сообщений не выводится.

Консоль во время выполнения какой либо команды, остаётся доступна для ввода новой команды, это особеннасть командной строки в купе с отсутствием вывода после инпут и вызывает ложное впечатление, что происходит ввод input, хотя на самом деле уже выполняется программа zip. Так же хотелось бы отметить что можно исспользовать input('строка: ') чтобы не писать принт перед каждым вводом; Исспользование ctrl+c или ctrl+d завершит текущую выполняемую консольную программу.

→ Ссылка
Автор решения: OlegUP
zip_command = f"zip -qr {target} {' '.join(source)}"
print(zip_command)

Вывело:

zip -qr /home/oleg/proj/examples/python/backup_prog//20220702/110556_asdasdasd_asd.zip / h o m e / o l e g / p r o j / e x a m p l e s / p y t h o n / b a c k u p _ p r o g / b a c k u p . p 

Вместо source.extend(file) пропишите source.append(file)

Окончательный вариант программы:

import os
import sys
import time

source, target_dir = [], ''


def _input_file():
    print('Введите, какой файл вы хотите скопировать - ')
    file = input()
    if len(file) == 0:
        print('No files')
        answer = input('Повторить ввод файлов? Y/N\n')
        if answer == 'Y':
            _input_file()
        elif answer == 'N':
            sys.exit()
        else:
            print('Нет такой команды!')
            _input_file()
    else:
        source.append(file)
        answer1 = input('Хотите ввести еще один файл? Y/N\n')
        if answer1 == 'Y':
            _input_file()
        elif answer1 == 'N':
            _dir_file()
        else:
            print('Такой команды нет. Примем ваш ответ за N')
            _dir_file()


def _dir_file():
    global target_dir
    print('Введите куда необходимо скопировать файл - ')
    target_dir = input()
    if len(target_dir) == 0:
        print('Введена пустота! Повторите ввод :)')
        _dir_file()


_input_file()
today = target_dir + os.sep + time.strftime('%Y%m%d')
now = time.strftime('%H%M%S')

print('Введите комментарий - ')
comment = input()
if len(comment) == 0:
    target = today + os.sep + now + '.zip'
else:
    target = today + os.sep + now + '_' + comment.replace(' ', '_') + '.zip'

if not os.path.exists(today):
    os.mkdir(today)
    print('Каталог успешно создан', today)

zip_command = f"zip -qr {target} {' '.join(source)}"
if os.system(zip_command) == 0:
    print('Резервная копия успешно создана в', target)
else:
    print('Создание резервной копии НЕ УДАЛОСЬ')
→ Ссылка