Перейти к содержанию
Educora
Продвинутый20 мин14 / 42

Файлы и мини-проект: калькулятор оценок

Научись записывать данные в файлы и читать их, а затем объедини всё изученное в проекте «калькулятор оценок».

Проверь себя
В этом уроке ты узнаешь
  • Записывать в файл и читать из него через with open(...)
  • Различать режимы 'r', 'w' и 'a'
  • Объединять переменные, циклы, функции, словари и обработку ошибок в одной программе

Как только программа завершается, все переменные стираются из памяти: рекорд в игре, оценки в журнале, список покупок — всё исчезает. Чтобы сохранить данные, их нужно записать в файл. В этом уроке ты научишься работать с файлами, а затем объединишь всё, что узнал за курс, в одном настоящем проекте — калькуляторе оценок.

Запись и чтение файлов

Функция open() открывает файл: первый аргумент — имя файла, второй — режим. Оператор with автоматически закрывает файл, когда блок заканчивается, — даже если произошла ошибка. А encoding='utf-8' гарантирует, что буквы вроде ё, щ или ş сохранятся правильно.

РежимЗначениеЕсли файл уже есть
'r'чтение (по умолчанию)содержимое читается; если файла нет — FileNotFoundError
'w'записьстарое содержимое стирается
'a'дозапись в конецновый текст добавляется в конец
Python
with open('notes.txt', 'w', encoding='utf-8') as f:
    f.write('Python is fun\n')
    f.write('Files keep data\n')

with open('notes.txt', encoding='utf-8') as f:
    for line in f:
        print(line.strip())
▸ Ожидаемый результат
Python is fun
Files keep data

write() не добавляет перевод строки, поэтому \n мы пишем сами. При чтении файла по строкам в цикле for этот \n остаётся в конце каждой строки — strip() его убирает. Чтобы сразу получить все строки списком, используют readlines():

Python
with open('log.txt', 'w', encoding='utf-8') as f:
    f.write('Day 1: started Python\n')

with open('log.txt', 'a', encoding='utf-8') as f:
    f.write('Day 2: learned loops\n')

with open('log.txt', encoding='utf-8') as f:
    lines = f.readlines()
print(len(lines), 'lines')
print(lines[-1].strip())
▸ Ожидаемый результат
2 lines
Day 2: learned loops

Если попытаться прочитать несуществующий файл, возникнет FileNotFoundError. Как в уроке об обработке ошибок, его можно перехватить через try / except:

Python
try:
    with open('missing.txt', encoding='utf-8') as f:
        print(f.read())
except FileNotFoundError:
    print('File not found, starting with an empty list.')
▸ Ожидаемый результат
File not found, starting with an empty list.

Мини-проект: калькулятор оценок

Учитель хранит оценки учеников в простом текстовом файле: в каждой строке имя и оценки через запятую. Такой формат называется CSV (comma-separated values — значения, разделённые запятыми). Наша программа прочитает файл, пропустит ошибочные строки, посчитает средний балл каждого ученика и запишет отчёт в новый файл.

  1. 1
    Подготовь данные

    Запиши оценки в файл grades.csv. В одну строку специально добавим ошибку (x), чтобы посмотреть, как программа на неё отреагирует.

  2. 2
    Прочитай и разбери файл

    Раздели каждую строку через split(','): первая часть — имя, остальные — оценки. Преобразуй их через int() и сохрани в словарь.

  3. 3
    Перехвати ошибки

    int('x') вызовет ValueError — перехвати его через try / except, выведи предупреждение и пропусти эту строку.

  4. 4
    Посчитай и запиши отчёт

    С помощью функций найди средний балл и уровень, запиши результаты в report.txt и прочитай файл, чтобы проверить.

Python
lines = ['Aysel,5,4,5,5', 'Murad,4,3,4', 'Leyla,5,5,4,5', 'Elvin,3,x,4', 'Nigar,2,3,3']
with open('grades.csv', 'w', encoding='utf-8') as f:
    f.write('\n'.join(lines))

journal = {}
with open('grades.csv', encoding='utf-8') as f:
    for line in f:
        parts = line.strip().split(',')
        name = parts[0]
        try:
            journal[name] = [int(m) for m in parts[1:]]
        except ValueError:
            print(f'Skipped {name}: bad data')
print(journal)
▸ Ожидаемый результат
Skipped Elvin: bad data
{'Aysel': [5, 4, 5, 5], 'Murad': [4, 3, 4], 'Leyla': [5, 5, 4, 5], 'Nigar': [2, 3, 3]}
Шаги 1–3: файл создаётся и читается, ошибочная строка пропускается. Срез parts[1:] берёт все части после имени.

Теперь разделим расчёт на две функции: average возвращает средний балл, а level — уровень словом (пороги мы выбрали сами). Генератор словаря считает все средние одной строкой, а результат записывается в файл report.txt:

Python
journal = {'Aysel': [5, 4, 5, 5], 'Murad': [4, 3, 4], 'Leyla': [5, 5, 4, 5], 'Nigar': [2, 3, 3]}

def average(scores):
    return sum(scores) / len(scores)

def level(avg):
    if avg >= 4.5:
        return 'excellent'
    elif avg >= 3.5:
        return 'good'
    elif avg >= 2.5:
        return 'satisfactory'
    return 'needs help'

averages = {name: average(s) for name, s in journal.items()}
with open('report.txt', 'w', encoding='utf-8') as f:
    for name, avg in averages.items():
        f.write(f'{name}: {avg:.2f} ({level(avg)})\n')

with open('report.txt', encoding='utf-8') as f:
    print(f.read().strip())
print(f'Best average: {max(averages.values()):.2f}')
▸ Ожидаемый результат
Aysel: 4.75 (excellent)
Murad: 3.67 (good)
Leyla: 4.75 (excellent)
Nigar: 2.67 (satisfactory)
Best average: 4.75
Задание

Запиши каждый фрукт из списка fruits в файл fruits.txt на отдельной строке (режим 'w'). Затем прочитай файл и выведи его строки с номерами от 1, в виде 1. apple.

Задание · Python
fruits = ['apple', 'pomegranate', 'fig']
# 1) write each fruit on its own line to fruits.txt
# 2) read fruits.txt and print: 1. apple, 2. pomegranate, ...
▸ Ожидаемый результат
1. apple
2. pomegranate
3. fig
Задание

Мини-проект: каждая строка файла sales.csv имеет вид товар,количество,цена. Прочитай файл и сложи в словаре выручку по каждому товару (количество × цена). Строку с ошибочными данными пропусти с помощью try/except и выведи Skipped: и эту строку. В конце выведи товары в алфавитном порядке в виде cup: 2.00 AZN, а последней — строку Total: в том же формате.

Задание · Python
lines = ['pen,3,0.5', 'notebook,2,1.25', 'bag,1,x', 'pen,4,0.5']
with open('sales.csv', 'w', encoding='utf-8') as f:
    f.write('\n'.join(lines))

totals = {}
# 1) read sales.csv line by line: product,quantity,price
# 2) skip bad lines (print Skipped: and the line)
# 3) add quantity * price to totals[product]
# 4) print the products in alphabetical order, then the Total
▸ Ожидаемый результат
Skipped: bag,1,x
notebook: 2.50 AZN
pen: 3.50 AZN
Total: 6.00 AZN

Главное

  • with open(имя, режим, encoding='utf-8') as f: открывает файл и автоматически закрывает его в конце блока.
  • 'r' — чтение, 'w' — запись со стиранием, 'a' — дозапись в конец.
  • write() не добавляет \n; из прочитанных строк \n убирает strip().
  • Чтение несуществующего файла вызывает FileNotFoundError — перехватывай его через try / except.
  • Строки CSV можно разбить на части с помощью split(',').

Проверь себя

Вопросов: 10. Каждый правильный ответ приносит XP.

1 / 10
Какой режим добавляет текст в файл, не стирая старое содержимое?