[МУЗЫКА] [МУЗЫКА] В этом занятии я несколько раз вбивал данные прямо в код программы, чтобы не вводить их каждый раз заново. Вообще говоря, просто лень было, конечно, можно было скопировать их в буфер, вставлять, но вообще часто информация хранится в виде текстовых файлов. Например, какие-нибудь данные для наших задачек вы можете вбить один раз в текстовый файл и потом пользоваться им. Сейчас мы научимся это делать. Итак, мы хотим открыть текстовый файл. Для начала его нужно создать. Давайте какую-нибудь простую задачу возьмем, например, взять два числа из файла input.txt по одному в строке и вывести их сумму. Сначала создадим файл. Его можно создавать в любом текстовом редакторе простом, это должен быть блокнот, например, Windows, или еще что-нибудь, но можно прямо из среды. Как это можно сделать? Выбираем наш проект, нажимаем правую кнопку New и просто File. Пишем его имя, input.txt, и кладем туда два числа, и сохраняем его. Все, он будет лежать там же, где и лежит исходный код нашей программы, где лежит наш скрипт, и по умолчанию, собственно, и используется эта папка. Открываем файл. Что для этого понадобится? Понадобится переменная, содержащая дескриптор file. Открывается файл с помощью функции open. Первый параметр — это имя файла. Вот подсказочка у нас появляется, файл — это input.txt. Следующий параметр — режим, в котором будем открывать файл. Нам нужно читать из файла, поэтому используется режим r, read. Он используется по умолчанию, в принципе, можно было не писать. И, наконец, еще один часто нужный параметр, как видите, их здесь много, но по жизни нужный параметр — это encoding, кодировка. Что такое кодировка? Я немного рассказывал об этом, то есть кодировки бывают очень разные, мы пользуемся кодировкой utf8. Это кодировка, которая сейчас применяется чаще всего. Она позволяет записывать себе не только там один какой-то алфавит, латинский, например, но и многие другие алфавиты, в том числе кириллицу, в том числе какие-то специальные символы, умляуты в европейских языках, иероглифы, даже египетские иероглифы там есть. В общем, достаточно универсальный, хотя и не без недостатков, способ кодирования, но будем пользоваться им, поскольку сейчас это стандарт. Вообще говоря, если там содержатся только числа или только английские буквы, то encoding писать необязательно. По умолчанию кодировка другая, поэтому если вы работаете с русским языком или вообще там с каким-то языком, отличным от английского, то лучше указывать utf8, вероятнее всего, все будет хорошо. Итак, нам нужно теперь считать числа из файла. Если с консоли мы читали с помощью функции input, то аналогом этой функции для файлов будет метод readline, считать строку в смысле — строка до перевода строки, нечто похожее на абзац, line в смысле line, строка в смысле line, без параметров. И вторую переменную тоже считываем методом readline без параметров. Ну и печатать пока что мы будем на экран. Поехали! Смотрим, [БЕЗ_ЗВУКА] что у нас происходит. Ну, не совсем то, чего мы хотели. У нас печатается 2 и 3 с какими-то табуляциями в начале. Почему так произошло? Потому что readline так же, как и input, считывает по одному элементу по строке. Здесь у нас появились какие-то ненужные пробелы, я их удалил, тем не менее, не должно измениться ничего от этого. Что нужно сделать? Так же, как мы считывали числа, мы писали int от input. Давайте писать int от readline теперь, и все должно быть хорошо. Те пробелы не должны были повлиять на работу программы, то есть функция int по-прежнему смогла бы распознать, но просто чтобы было красиво, я их убрал. Итак, теперь получилась пятерка, то есть нам, наконец, удалось сложить два числа. То есть readline — это аналог функции input, предназначенный для чтения из файла. Что еще можно делать? Во-первых, можно сделать чтение вообще всех строк, которые содержатся в файле, и положить их в список. Для этого существует метод readlines, то есть мы можем создать какой-то список и положить туда все содержимое файла, разбитое на отдельные line, на строки, заканчивающиеся переводом строки. Давайте напечатаем просто его, чтобы проверить, что все окей. Ага! Вот, смотрите, что интересно здесь, когда мы видим все содержимое в чистом виде. У нас при чтении с помощью readlines попадает символ перевода строки, то есть этот символ не обрезается, в input'е он обрезался. Как от него избавляться, если у вас стоит задача, например, обрабатывать какие-то по одной строке содержащиеся в файле? Достаточно отрезать последний символ, но это будет работать не всегда. Почему? Потому что после последней строки у нас нет перевода строки, и мы отрежем что-то нужное. Это немножко объясняет вам, зачем pep8, в частности, за что он ругается на нас, что мы не сделали перевод после последней строки. Теперь, когда мы во входных данных сделали такое, у нас все стало единообразно, и теперь будет обрабатываться правильно. В тестирующей системе у вас всегда есть перевод после последней строки, ну и в ваших скриптах тоже нужно стараться это делать, потому что вдруг кто-то будет обрабатывать ваши тексты и будет надеяться, что там это тоже выполнено. Тем не менее, если вы хотите избавиться от этой проблемы, универсальное решение написать, вы можете использовать метод strip для строк. Давайте напечатаем, например, вот так это сделаем, поэлементно, [ЗВУК] возьмем и каждую отдельно строку, поскольку это метод не списка, а строки, для нее сделаем strip. Strip обрезает все пробельные символы в начале и в конце. К пробельным символам относятся непосредственно пробелы, табуляции и наши переводы строк. Давайте объединим это в список, чтобы нам красиво все было нарисовано и все было понятно. Действительно ли отрезалось, все это сейчас проверим. Да, теперь никаких переводов строк нет, и даже если мы входные данные сделаем не единообразно, все равно все будет хорошо. То есть это наше такое универсальное решение, позволяющее отрезать все лишнее по краям строки. Что еще можно сделать? Метод readlines считывает все строки в память, и если файл был очень большой, то память у вас будет забиваться, иногда даже может кончиться. То есть если файл больше, чем размер вашей оперативной памяти, то это вызовет некоторые проблемы считывания с помощью readlines. Если вам нужно обрабатывать строки по одной, просто идти, например, и печатать число на единицу больше, можно сделать вот такую штуку: for line in fin, fin — это название fin, file input нашего файла. То есть это iterable, и будет возвращать он строки по одной, как они встречаются: считал — вернул, считал — вернул. И поэтому в памяти весь файл храниться не будет, будет поочередно доставаться по одной строке из него. Ну и вот у нас напечатались числа на единицу больше, то есть этот способ позволяет не хранить весь список строк в памяти. Еще один метод чтения — это просто read, read из файла делает строку, одну такую длинную колбасу из символов, где у вас все-все-все содержимое файла записывается в одну строку, включая переводы строк. Смотрите, сейчас я сделаю такую штуку, чтобы нам все backslash'и она красиво напечатала, и вот оно всё абсолютно, содержимое нашего файла. Иногда возникает задача еще и печатать файл, то есть сейчас мы читали из файла, печатали на экран. Можно печатать также в файл. Открывается файл с помощью функции open, только параметр у него w, write, писать туда, и кодировку на всякий случай тоже поставим, это хорошая привычка, чтобы не нарваться неожиданно на проблемы. Итак, давайте что-нибудь сделаем, напечатаем, например, в этот файл сумму двух чисел, всех чисел. Значит, что мы хотим сделать? Мы хотим просуммировать список, или необязательно превращать его в список, всех строк, содержащихся во входном файле. Чтобы функция print печатала не на экран, а в файл, используется именованный параметр file, file и имя дескриптора. Если файла не было, то он создастся автоматически. Если какой-то файл был, то старое все пропадет и запишется новое. Давайте откроем, создадим файлик этот, положим туда, убедимся, что оно затрется, какую бы муть мы ни написали там, она исчезнет. На самом деле, в операционной системе запись файла происходит не сразу, оно постепенно накапливается в буфере и сбрасывается время от времени, это сделано для скорости. Чтобы оно точно сбросилось, нужно воспользоваться методом close — закрыть файл. Итак, вот мы запустили нашу программу, на экран ничего не выводится, но зато в файле оказывается результат вычисления. Таким образом, вы можете читать из файла и писать в файл. В тестирующей системе мы поддерживаем чтение из файлов input.txt, output.txt, или с консоли, как вам удобнее. Так что теперь для решения задач вы можете пользоваться этим. И наконец, вы научились считывать неопределенное количество данных, которые могут быть записаны в файле по одному в строке, например. [МУЗЫКА] [МУЗЫКА]