Доброго времени суток, читатели, зрители моего канала programmer's notes.
Приложение к видео
Библиотека sys в Python. Ввод с консоли
Сегодня статья, я бы сказал, будет состоять из нюансов. Нюансы, кстати, важные. Я как старый организатор олимпиад по программированию встречал студентов и школьников, которые прекрасно программировали, но нюансов не знали. Говорить будем о потоковом вводе. Обычно в стандартных олимпиадах по программированию как раз и предполагается, что для ввода и вывода используются стандартные потоки. Их обычно называют stdin и stdout и, которые, читаются и выводятся с помощью перенаправление работающей программы ('<' и '>'). При этом можно использовать стандартные средства ввода-вывода на консоль. Но, как я уже сказал, есть нюансы.
Нюансы с input()
Если к примеру на входе программы (prog.py) есть строка с данными, то строка
s = input()
считает входную строку так
prog.py < t.txt
это действия теперь автоматически выполняет проверяющая система (на олимпиаде, я имею в виду), и вы просто должны об это знать. Если в условии задачи известно сколько строк, или их количество можно вычислить, то проблем в общем-то и нет. Напомним только один важный момент: функция input() удаляет коды (символы) перевода строки в конце строк.
И вот на тебе, в условии задачи сказано, что строк произвольное количество и у олимпиадник часто впадает в ступор.
А в чем же дело? А дело в том, что не понятно, как с помощью input() считать все строки, точнее как знать, где остановиться. Ситуация в действительности проста. Если вы запустите бесконечный цикл чтения строк с помощью input(), то увидите, что при попытке чтения после достижения последней приводит к исключению. Правильно, а как обрабатывать исключения мы знаем. Решение элементарно
Например
primer51.py < txt
получаем
['qwerty', 'asdasdad', 'DASDAD', 'asdasd', 'xzczx']
Ещё обращу внимание, что функция input() удаляет символы перевода строки в конце строк. И был ли такой символ в конце последней строки мы так и не узнаем. В большинстве случаев это никому не надо, но помнить ещё об одном нюансе ввода с помощью input() будем.
Ввод с помощью библиотеки sys и опять нюансы
Библиотека sys предоставляет прекрасный класс stdin, позволяющий осуществлять ввод с консоли не боясь исключений.
И так первый способ прочесть текст с консоли
Запуск
./primer52.py < txt
Результат выполнения
['qwerty\n', 'asdasdad\n', 'DASDAD\n', 'asdasd\n', 'xzczx']
Отлично. И вот что важно. Теперь строки считались вместе с кодом (символом) перевода строки. А вот в последней строке этого кода нет. А и его и не было, таким образом мы считали точную копию текста и это важно.
И так sys.stdin представляет собой итерируемый объект, извлекающий строки из текста, который перенаправили на вход исполняемой программы.
Второй способ прочесть текст с консоли
Запуск
./primer53.py < txt
Результат выполнения
['qwerty\n', 'asdasdad\n', 'DASDAD\n', 'asdasd\n', 'xzczx']
Результат идентичен предыдущему. Для чтения строки использовали метод sys.stdin.readline(). Особенность данного подхода заключается в том, что попытка чтения, когда файл закончился, дает пустую строку. Чтение входного потока с неизвестным количеством строк вот так я не встречал. Специально сейчас поискал в Интернете. Впрочем не важно, берём на вооружение.
Третий способ прочесть текст с консоли.
Запуск
./primer54.py < txt
Результат
['qwerty\n', 'asdasdad\n', 'DASDAD\n', 'asdasd\n', 'xzczx']
И опять результат идентичный предыдущим.
readlines() метод замечательный, так как возвращает уже готовый список из строк. Но не забывайте о размере файла. Возможно обработка текстовых файлов, представленных выше, будет надёжнее.
Четвёртый способ прочесть текст с консоли.
Запуск
./primer54.py < txt
Результат
['qwerty', 'asdasdad', 'DASDAD', 'asdasd', 'xzczx']
Здесь мы потеряли символы перевода строк. Впрочем, ради забавы попробуйте получить "правильный" список.
Метод read() читает весь поток (файл).
Ну пока мы оставим библиотеку sys. Но будем к ней возвращаться уже время от времени в разных контекстах.
Хорошего программирования. Оставляйте свои комментарии, не забывайте про лайки и подписывайтесь на мой канал programmer's notes.