graph TD
folder["<i class="fa-solid fa-folder-open"></i> Скрипты<br>(текущий рабочий каталог)"]
script([<i class="fa-regular fa-file-code"></i> script.py])
file(["<i class="fa-regular fa-file-lines"></i> verse.txt"])
folder-->script
folder-->file
Занятие № 9. Применение файлов для решения задач
Цель: научится использовать файлы для чтения и записи информации.
Теория
Чтение файла
Файлы можно разбить на два вида:
Plaintext (текстовые) файлы – содержат информацию, которая понятна человеку;
Бинарные файлы – файлы, открыв которые в текстовом редакторе, человек не сможет понять содержимого (исполняемые файлы, изображения, документы и др.).
В заданиях будем использовать только текстовые файлы.
Чтобы открыть файл используется функция open(<путь>, <режим доступа>). Эта функция возвращает файловый объект, который будет связан с файлом в файловой системе. Аргумент <путь> - это строка с расположением файла, <режим доступа> - строка с режимом в котором мы открываем файл: чтение "r" или запись "w". В следующем коде переменная file_obj будет содержать ссылку на файл с именем
x
?
, открытый для
x
чтения:
script.py
Вы можете навести курсор на имена файлов и пути, обозначенные подчёркиванием, чтобы увидеть их расположение на рисунках.
В такой форме записи пути, файл verse.txt должен находиться в той же папке, что и Python-скрипт. Папка из которой запускается скрипт считается для него текущим рабочим каталогом.
После использования, файл нужно закрыть методом close():
Если этого не сделать, операционная система будет считать, что файл ещё занят и не даст открыть его другим программам.
Для чтения содержимого текстового файла используются следующие методы файлового объекта:
| Метод | Назначение |
|---|---|
<файл>.read() |
Возвращает всё содержимое файла в одной строке (str). |
<файл>.readline() |
Читает следующую строку файла и возвращает её (str). |
<файл>.readlines() |
Возвращает список (list) строк файла. |
Используем все три метода для чтения содержимого следующего файла:
verse.txt
Прочитаем всё содержимое файла в виде одной строки:
file_obj = open("verse.txt", "r")
text = file_obj.read() # чтение файла целиком
print(text)
file_obj.close()
Прочитаем файл построчно:
file_obj = open("verse.txt", "r")
line = file_obj.readline() # читаем первую строку
print(line)
line = file_obj.readline() # читаем вторую строку
print(line)
file_obj.close()
Обратите внимание, после каждой строки появилась пустая строка. В файле, чтобы обозначить конец строки ставится управляющая последовательность \n - перенос строки. Реально в переменной line хранится строка У лукоморья дуб зелёный;\n. Функция print() не выводит управляющие символы а интерпретирует их значение.
Запишем все строки в список:
file_obj = open("verse.txt", "r")
lines_list = file_obj.readlines() # список строк
print(lines_list[0:2]) # выведем первые два элемента списка
file_obj.close()
Запись в файл
Для записи в текстовый файл используется метод write(). Файл должен быть открыть для записи, по этому в функции open() второй аргумент будет равен "w" (от англ. write).
Предположим, что нам нужно записать в файл sq_numbers.txt квадраты целых чисел от 1 до 12. Откроем файл для записи:
Далее запускаем цикл for, чтобы перебрать числа из заданного отрезка:
Осталось записать число square в файл: output.write(square). Но на этой инструкции появится ошибка - записать в файл можно только данные типа str. Необходимо преобразовать значение в строку:
После запуска скрипта мы увидим в файле такой текст:
149162536496481100121144
Метод write() не добавляет перенос на новую строку. Нужно самостоятельно добавить управляющий символ \n к записываемой строке:
Только после этого в файле будут находится значения, записанные с новой строки.
Режим "a" позволяет открыть файл для дозаписи в конец файла.
Относительный и абсолютный путь к файлу
Рисунок 2 показывает пример структуры каталогов и файлов.
Если мы хотим открыть файл temp.txt в скрипте work.py, мы напрямую напишем имя файла в функции: open("temp.txt", "r").
Как открыть в этом же скрипте файл data.txt, который находятся в другой папке? Можно использовать абсолютный путь в котором указывается полная последовательность папок от корневого каталога. В нашем примере: C:\Проекты\Данные\data.txt. Второй вариант - использовать относительный путь: ..\Проекты\Данные\data.txt. Символы ..\ означают, что мы поднимаемся на один уровень выше, относительно текущего рабочего каталога. Чтобы в скрипте work.py открыть файл val.csv запишем следующий относительный путь: ..\..\val.csv.
graph TD
folderC["<i class="fa-solid fa-folder-open"></i> C:\"]
scriptCSV([<i class="fa-solid fa-file-csv"></i> val.csv])
file1(["<i class="fa-regular fa-file-lines"></i> exp.txt"])
file2(["<i class="fa-regular fa-file-lines"></i> data.txt"])
script3(["<i class="fa-regular fa-file-lines"></i> temp.txt"])
foto(["<i class="fa-regular fa-image"></i> cat.jpg"])
scriptsF["<i class="fa-solid fa-folder-open"></i> Скрипты<br>(<strong>текущий рабочий каталог</strong>)"]
dataF["<i class="fa-solid fa-folder-open"></i> Данные"]
projF["<i class="fa-solid fa-folder-open"></i> Проекты"]
script2([<i class="fa-regular fa-file-code"></i> work.py])
folderC---scriptCSV
projF---scriptsF
folderC---projF
projF---dataF
scriptsF---script2
scriptsF---script3
dataF---file1
dataF---file2
dataF---foto
Вам нужно открыть для чтения файл оценки.csv в скрипте stats.py. Скрипт запускается из папки задача. На рисунке показана файловая структура:
graph TD
folder["<i class="fa-solid fa-folder-open"></i> D:\"]
csv([<i class="fa-solid fa-file-csv"></i> оценки.csv])
script(["<i class="fa-regular fa-file-lines"></i> stats.py"])
folder_task["<i class="fa-solid fa-folder-open"></i> задача"]
folder_proj["<i class="fa-solid fa-folder-open"></i> проект"]
folder---folder_task
folder_task---script
folder---folder_proj
folder_proj---csv
Выберите варианты функции open() подходящие для решения задачи.
Безопасное открытие файла
С помощью инструкции with можно автоматически закрывать файл после использования:
Запишем решение задачи с записью квадратов чисел с помощью инструкции with:
После выполнения инструкций внутри with, файл output будет закрыт автоматически.
Примеры
Пример № 1 (ex01.py)
Создайте программу, которая построчно считывает содержимое файла и выводит его на экран.
Скачайте файл сообщение.txt и сохраните его в папке с примером.
Чтобы сохранить этот файл, щёлкните по ссылке правой кнопкой мыши, и выберите пункт меню Сохранить объект как….
Пример № 2 (ex02.py)
Запишите в файл таблицу значений функции \(y=\frac{5}{x}\), для x от 5 до 10 с шагом 0.2. В этой же программе прочитайте полученный файл, и выведите таблицу на экран.
Обратите внимание, что в f-строке мы явно добавляем специальный символ переноса строки \n, иначе файл формально будет содержать только одну строку текста.
После запуска программы, проверьте, появился ли в папке с программой файл table.txt
Добавьте к программе следующие строки, для того чтобы прочитать содержимое файла и вывести его на экран:
# открываем файл для записи
table_file = open(file_name, 'r', encoding="utf8")
# получаем список всех строк в файле
file_lines = table_file.readlines()
# перебираем строки в цикле
for line in file_lines:
# получаем список значений в строке, разделённых пробелом
values = line.split()
# сохраняем отдельно x и y
x = float(values[0])
y = float(values[1])
# выводим значения на экран
print(f"x={x} y={y}")
table_file.close()Пример № 3 (ex03.py)
Дан файл шифровка.txt состоящий из набора ASCII-кодов, разделённых пробелами. Напишите программу, которая декодирует файл в выводит сообщение на экран.
Скачайте файл шифровка.txt и сохраните его в папке с примером.
Чтобы сохранить этот файл, щёлкните по ссылке правой кнопкой мыши, и выберите пункт меню Сохранить объект как….
# открываем файл для чтения
with open("шифровка.txt", 'r', encoding="utf8") as file:
text = file.read() # считываем содержимое файла полностью
codes = text.split() # получаем список "чисел"
message = [] # создаём пустой список
# перебираем все "числа" из кода
for numStr in codes:
codeNum = int(numStr)
message.append(chr(codeNum))
# получаем из списка букв одну строку
messageStr = "".join(message)
print(f"Текст сообщения: {messageStr}")Задания для самостоятельной работы
Задание № 1 (sam01.py)
Создайте программу, которая сохранит список дел. Пользователь вводит три строки, которые сохраняются в файл заметки.txt. После ввода строк, программа читает содержимое файла и выводит его на экран.
Пример:
Введите задачу: Почитать книгу
Введите задачу: Сделать домашнее задание
Введите задачу: Погулять на свежем воздухе
Список дел:
Почитать книгу
Сделать домашнее задание
Погулять на свежем воздухе
Составьте решение задачи из предложенных инструкций:
f.close()
print('Список дел:')
zametka = input("Введите текст")
for line in f.readlines():
print(line, end="")
f.close()
f.write(zametka+"\n")
for i in range(3):
f = open('заметки.txt', 'w')
f = open('заметки.txt', 'r')
Задание № 2 (sam02.py)
Напишите программу с помощью которой можно приблизительно оценить, сколько минут в среднем понадобится для набора текса. С помощью программы оцените сколько времени необходимо для набора примеров этого занятия.
Средняя скорость набора - 190 символов в минуту. Свою скорость набора можете проверить на этом сайте.
Задание № 3 (sam03.py)
В файле temp.txt хранятся данные о среднегодовой температуре в Минске с 1912 по 2020 годы.
Скачайте файл temp.txt и сохраните его в папке с программой.
Чтобы сохранить этот файл, щёлкните по ссылке правой кнопкой мыши, и выберите пункт меню Сохранить объект как….
Откройте файл и выведите среднегодовую температуру для представленного диапазона в следующем формате:
...
1999: 7.7 град. Цельсия
2000: 7.8 град. Цельсия
2001: 7.0 град. Цельсия
2002: 7.7 град. Цельсия
2003: 6.4 град. Цельсия
2004: 6.6 град. Цельсия
...
Дополнительный плюс, если для повышения наглядности, округлённое целое значение температуры умножить на символ "#" , чтобы получить столбчатую диаграмму изменения температур в следующем формате:
...
1979: ##### 5.7
1980: #### 4.8
1981: ###### 6.4
1982: ###### 6.4
1983: ####### 7.3
1984: ###### 6.0
1985: #### 4.5
1986: ##### 5.7
...
Задание № 4 (sam04.py)
Дан файл good_data.txt с парами чисел x, y, разделённых пробелом.
Скачайте файл good_data.txt и сохраните его в папке с программой.
Чтобы сохранить этот файл, щёлкните по ссылке правой кнопкой мыши, и выберите пункт меню Сохранить объект как….
Найти значение выражения \(z=\sqrt{\frac{x}{y}}\). Результаты вычислений запишите в файл func.txt в следующем формате:
...
3.8 2.2 1.3
3.6 2.4 1.2
3.4 2.6 1.1
3.2 2.8 1.1
...
Задание № 5 (sam05.py)
Даны два файла, которые содержат одинаковое количество строк. Напишите программу, которая построчно сравнит файлы. Если строки одинаковы, выводится символ =. Если строки отличаются, выводится номер символа, начиная с которого строки не совпадают.
Программу можете проверить с помощью следующих двух файлов - first.txt, second.txt.
Пример (для файлов first.txt и second.txt):
1. =
2. отличие с 11 символа
3. отличие с 16 символа
4. =
5. отличие с 13 символа
6. отличие с 13 символа
7. =
8. =
9. =
10. =
11. =
12. отличие с 18 символа
13. отличие с 19 символа
14. =