Продолжаем практиковаться в программировании. После седьмой главы в книге: Майкл Доусон “Программируем на Python”, 2014 (Michael Dawson “Python Programming for the Absolute Beginner”, 3rd Edition), где я изучила работу с файлами, пора переходить к практике. Сделаем домашнее задание вместе!
Краткий конспект по работе с файлами в Python
Открыть и закрыть файл
open() – открыть файл и сообщить путь к директории;
open("файл", "r", encoding="utf-8") – открыть файл на чтение в кодировке Unicode.
Доступ к текстовым файлам бывает:
"r" – чтение;
"w" – запись (замена содержимого) / создание;
"a" – дозапись в конце файла / создание;
"r+" – чтение и запись;
"w+" – запись и чтение (замена содержимого) / создание;
"a+" – дозапись в конце файла и чтение / создание.
.close() – закрыть файл
Читать файл
Посимвольно: метод .read() – чтение всего файла, т.е. пишем "переменная.read()", где в скобках указывается число символов, которые надо прочитать. После каждого прочтения Python оставляет “закладку” в том месте, докуда дочитал.
Построчно: метод .readline() – чтение строки файла, т.е. пишем "переменная.readline()", где в скобках можно указать число символов, которые надо прочитать из текущей строки.
Из текста в список, состоящий из строк: метод .readlines() – создание из строк файла списка, т.е. пишем переменная_2="переменная.readlines()", и теперь переменная_2 является списком всех строк. Запустив цикл печати строки для каждого элемента из списка – можно провести построчное чтение файла.
Записать текст в файл
Запись строки в файл: метод .write(строка)
Запись списка строк в файл: метод .writelines(список строк)
Консервация и сериализация данных
Консервированные файлы хранят в бинарный (двоичных) файлах:
"rb" – чтение;
"wb" – запись / замена / создание;
"ab" – дозапись в конце / создание;
"rb+" – чтение и запись;
"wb+" – запись и чтение / замена / создание;
"ab+" – дозапись в конце / создание.
Консервация:
pickle.dump(объект_с_данными_для_консервации, файл_куда_сохранить)
Можно консервировать списки, словари, кортежи, числа, строки.
Расконсервировать:
pickle.load(файл_откуда_расконсервировать)
Полка для консервированных данных
Открыть файл с консервированными объектами:
shelve.open(файл, режим доступа)
Режимы доступа:
c – чтение / запись / создание (по умолчанию);
n – создание файла для чтения и записи / замена;
r – чтение;
w – запись.
Проверка, что данные записаны в файл полки:
файл.sync()
Закрыть файл полки (и внести все изменения):
файл.close()
Ошибка unicodeescape
Написала код:
file=open("C:UsersDocumentsPythonfile.txt","w",encoding="utf-8")
print(file.read())Что делать если возникает ошибка:
(unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncatedUXXXXXXXX escape
Здесь U в “C:Users…” запускает восьмизначный escape-код Unicode, который в Python имеет формат "U000XXXXX". В нашем коде за escape-символом U следует символ ‘s’, что недопустимо.
Есть два варианта решения:
- Удвоить символы “слэш”: “C:\Users\Documents\Python\file.txt”
- Или перед адресом добавить префикс
r(чтобы получить необработанную строку):r"C:UsersDocumentsPythonfile.txt"
Ошибка io.UnsupportedOperation: not readable
Не получается прочитать файл, так как в коде мы написали “w” – только для записи, а надо написать “r” – для чтения:
file=open(r"C:UsersDocumentsPythonfile.txt","r",encoding="utf-8") print(file.read())
Обработка исключений
try: – фрагмент кода, который может вызвать исключение (ошибка);
except (тип исключения 1, 2....): – код, который исполняется, если выпало исключение (сообщение при ошибке).
В одном try может быть сколько угодно последовательных except.
Если после всех except указать else, то это будет тот код, который исполнится, если ошибок не будет.
Типы исключений:
IOError – ошибка ввода/вывода;
IndexError – не найден элемент с указанным индексом;
KeyError – в словаре не найден ключ;
NameError – не найдено имя;
SyntaxError – синтаксическая ошибка в коде;
TypeError – операция / функция применяется к неподходящему объекту;
ValueError – аргумент функции / операции имеет неподходящее значение;
ZeroDivisionError – в операции деления / нахождения остатка второй аргумент ноль.
Аргумент исключения в Python – текст, который описывает ошибку в интерпретаторе; его можно вывести в переменную через as:
try:
...
except исключение as переменная:
...
Игра “Викторина”
Чтобы выполнить задание по модификации игры “Викторина”, сначала возьмем исходный код и разберем программу по частям, чтобы лучше понять смысл происходящего.
В начале кода укажем глобальные переменные в функции main():
import sys
def main ():
the_file=open('C:/Users/<user_name>/Documents/Python/trivia.txt','r',encoding='utf-8')
title=next_line(the_file)
welcome(title)
score=0
category,question,answers,correct,explanation=next_block(the_file)
while category:
print(category)
print (question)
for i in range(4):
print(' t',i+1,'-',answers[i])
answer=input('Ответ: ')
if answer == correct:
print('/nСупер!')
score+=1
else:
print('/nО, нет!')
print(explanation)
print('Счет:',score)
category, question, answers, correct, explanation = next_block(the_file)
the_file.close()
print('Вопросики закончились')
print('Счет: ', score)
Функция, приветствующая игрока:
def welcome(title):
print('Приветики!')
Функция открытия файла с вопросами и обработки исключений:
file_name='C:/Users/<username>/Documents/Python/trivia.txt'
mode='r'
def open_file (file_name,mode):
try:
the_file=open(file_name,mode, encoding='utf-8')
except IOError as e:
print('Не получается открыть файл', file_name, 'ошибка', e)
input('/n/nНажмите Entr, чтобы выйти.')
sys.exit()
else:
return the_file
Функция, которая принимает файл и достает из него следующую строку текста:
def next_line(the_file):
line=the_file.readline()
line=line.replace('/','n')
return line
Функция, которая достает следующих блок строк, соответствующий одному вопросу – принимает файл и возвращает 4+4 строки (делим текст на вопросы и возможные варианты ответа).
def next_block(the_file):
category=next_line(the_file)
question=next_line(the_file)
answers=[]
for i in range(4):
answers.append(next_line(the_file))
correct=next_line(the_file)
if correct:
correct=correct[0]
explanation=next_line(the_file)
return category, question, answers, correct, explanation
Программа задает вопросы игрокам:
category,question,answers,correct,explanation=next_block(the_file)
while category:
print(category)
print (question)
for i in range(4):
print(' t',i+1,'-',answers[i])
Принимаем ответ игрока:
answer=input('Ответ: ')
Проверяем ответ – правильный или нет:
if answer == correct:
print('/nСупер!')
score+=1
else:
print('/nО, нет!')
print(explanation)
print('Счет:',score)
Переходим дальше к следующему вопросу:
category, question, answers, correct,ArithmeticError explanation = next_block(trivia_files)
Когда вопросы закончились, выводим окончание и счет игрока:
trivia_file.close()
print('Вопросики закончились')
print('Счет: ', score)
Запуск главной функции: main()
Выход из игры: input('Нажмите Entr, чтобы выйти')
Задание 1. Добавить номинал вопроса
Доработайте игру так, чтобы у каждого вопроса появился “номинал” – уникальное количество очков. В конце игры сумма очков пользователя должна стать равной сумме номиналов вопросов, на которые он ответил правильно.
Решение: добавляем строчкой в файл уникальные значения номиналов после правильного ответа. И в коде функции def next_block(the_file): вводим переменную nominal:
def next_block(the_file):
category=next_line(the_file)
question=next_line(the_file)
nominal=0
answers=[]
for i in range(4):
answers.append(next_line(the_file))
correct=next_line(the_file)
if correct:
correct=correct[0]
nominal=int(next_line(the_file).strip())
explanation=next_line(the_file)
return category, question, answers, correct, explanation, nominal
И в функции main() вводим обращения к nominal:
def main ():
the_file=open('C:/Users/shtuk/Documents/Python/trivia.txt','r',encoding='utf-8')
title=next_line(the_file)
welcome(title)
score=0
category,question,answers,correct,explanation,nominal=next_block(the_file)
while category:
print(category)
print (question)
for i in range(4):
print(' t',i+1,'-',answers[i])
answer=input('Ответ: ')
if answer == correct:
print('/nСупер!')
score+=1
else:
print('/nО, нет!')
print(explanation)
print('Счет:',score)
category, question, answers, correct, explanation,nominal = next_block(the_file)
the_file.close()
print('Вопросики закончились')
print('Счет: ', score)
Задание 2: Консервация рекордов
Доработайте игру “Викторина” таким образом, чтобы она хранила в файле список рекордов. В список должны попадать имя и результат игрока-рекордсмена. Используйте для хранения таблицы рекордов консервированные объекты.
Решение: Добавляем функцию high_score (), чтобы сохранить имя игрока и его счет в файле при помощи консервации – pickle, а также, чтобы вывести эту информацию. Вводим файл.dat (в него сохранялись данные). В функции main () игры добавляем эту функцию для отображения счета игрока, если он попадает в список.
def store_high_score ():
try:
with open("файл.dat", "rb") as f:
high_scores = pickle.load(f)
except FileNotFoundError:
high_scores = []
Далее в этой же функции добавляем ввод имени игрока:
name = input("Как тебя зовут")
player_score = int(input("Сколько очков?"))
vvod = (name, player_score)
high_scores.append(vvod)
high_scores.sort(reverse=True)
high_scores = high_scores[:5]Далее в эту же функцию добавляем перезапись файла:
with open("файл.dat", "wb") as f: pickle.dump(high_scores, f)Добавить возможность показать результаты:
f = open("файл.dat", "rb")
show_scores = pickle.load(f)
print(show_scores)
f.close()Задание 3: Сохранить в .txt
Реализуйте ту же самую функциональность, что и в предыдущей задаче, иным способом: на этот раз сохраните список рекордов в обычном текстовом файле.
Решение: вместо f = open(“файл.dat”) использовать f = open(“файл.txt”)