Skip to content

Latest commit

 

History

History
3142 lines (2128 loc) · 97.8 KB

File metadata and controls

3142 lines (2128 loc) · 97.8 KB

Урок 33: Работа с файлами в Python

Содержание урока:


Модуль 1. Что такое файл и файловая система

Прежде чем Python научится читать и записывать файлы, важно разобраться где вообще живут файлы, как программа «видит» компьютер и каким образом код взаимодействует с файловой системой.

Этот модуль закладывает фундамент. Без него дальнейшая работа с txt, csv, json будет выглядеть как набор магических действий без понимания, что именно происходит.


1. Понятие файла и каталога

(на примере Windows)

Что такое файл

Файл — это именованная область на диске, в которой хранятся данные.

С точки зрения Python:

  • файл — это источник или приёмник данных;
  • данные в файле — это последовательность символов (в текстовых файлах) или байтов.

Примеры файлов в Windows:

report.txt
students.csv
config.json
photo.jpg

Каждый файл:

  • имеет имя (report)
  • имеет расширение (.txt, .csv, .json)
  • находится в конкретной папке

Что такое каталог (папка)

Каталог (директория, папка) — это контейнер для файлов и других каталогов.

Пример структуры каталогов в Windows:

C:\
 └── Users
     └── Igor
         └── Documents
             └── PythonProjects
                 └── lesson_33
                     ├── main.py
                     ├── data.txt
                     └── students.csv

Здесь:

  • lesson_33 — папка проекта
  • main.py — Python-скрипт
  • data.txt, students.csv — файлы с данными

Важно: Python не работает с абстрактными файлами. Он всегда работает с файлами, которые находятся в конкретном месте файловой системы.


2. Пути к файлам: абсолютные и относительные

Чтобы Python мог открыть файл, ему нужно точно указать путь к этому файлу.

Абсолютный путь

Абсолютный путь — это полный путь от корня диска до файла.

Пример (Windows):

C:\Users\Igor\Documents\PythonProjects\lesson_33\data.txt

Особенности:

  • начинается с буквы диска (C:\)
  • однозначно указывает местоположение файла
  • работает независимо от того, где находится программа

Плюс: надёжно Минус: неудобно и негибко (особенно при переносе проекта)


Относительный путь

Относительный путь указывается относительно текущей рабочей директории программы.

Пример:

data.txt

или

data\data.txt

Это означает:

«Возьми файл, который лежит рядом с текущим скриптом (или в указанной подпапке)»


Сравнение наглядно

Предположим, структура проекта такая:

lesson_33/
├── main.py
└── data.txt

В main.py:

# относительный путь
open("data.txt")

# абсолютный путь
open("C:\\Users\\Igor\\Documents\\PythonProjects\\lesson_33\\data.txt")

Оба варианта работают, но:

  • в учебных и реальных проектах почти всегда используют относительные пути;
  • абсолютные пути делают код непереносимым.

3. Рабочая директория и структура проекта

Что такое рабочая директория

Рабочая директория — это папка, которую Python считает «текущей» в момент запуска программы.

Именно от неё отсчитываются относительные пути.

Пример:

  • если рабочая директория — lesson_33
  • и вы пишете open("data.txt")
  • Python ищет файл именно в lesson_33

Почему это важно

Очень частая ошибка новичков:

«Файл существует, но Python его не находит»

Причина почти всегда одна:

  • файл лежит не в рабочей директории
  • или путь указан неверно

Рекомендуемая структура учебного проекта

lesson_33/
├── main.py
├── data/
│   ├── text.txt
│   └── students.csv
└── output/

Такой подход:

  • делает проект аккуратным;
  • упрощает работу с файлами;
  • масштабируется на реальные задачи.

4. Модуль os: работа с файловой системой из Python

Ранее вы уже работали с модулями Python, например:

import math

Модуль math предоставляет функции для работы с математикой.

Модуль os — это то же самое, но:

  • для работы с операционной системой,
  • файлами,
  • каталогами,
  • путями.

Мы будем использовать его аккуратно и по делу, без углубления в системное программирование.


4.1 Получение текущей рабочей директории (getcwd())

Первое, что полезно узнать — где Python считает себя запущенным.

import os

current_dir = os.getcwd()
print(current_dir)

Пример вывода (Windows):

C:\Users\Igor\Documents\PythonProjects\lesson_33

Это и есть рабочая директория.


4.2 Проверка существования файла или папки (path.exists())

Перед работой с файлом часто нужно убедиться, что он существует.

import os

file_path = "data.txt"

if os.path.exists(file_path):
    print("Файл найден")
else:
    print("Файл не существует")

Что здесь происходит:

  • os.path.exists() проверяет:
    • файл это или папка — не важно;
    • главное, существует ли объект по указанному пути.

Это напрямую связано с предыдущими темами:

  • условия if
  • логический тип bool

4.3 Создание папок (mkdir())

Иногда программе нужно создать папку для результатов работы.

import os

os.mkdir("output")

Если папка уже существует, возникнет ошибка. Поэтому часто делают так:

import os

folder_name = "output"

if not os.path.exists(folder_name):
    os.mkdir(folder_name)

Мы пока не углубляемся в нюансы — важно понять идею:

  • Python может управлять файловой системой;
  • это делается через модуль os.

Логическая связь модуля

  1. Файлы и папки — это реальные объекты на компьютере.
  2. Python работает с ними через пути.
  3. Относительные пути зависят от рабочей директории.
  4. Модуль os позволяет:
    • узнать, где запущена программа;
    • проверить наличие файлов;
    • управлять каталогами.

Это знание — фундамент для следующего шага: открытия, чтения и записи файлов.


Модуль 2. Открытие и закрытие файлов

В прошлом модуле мы разобрались, где находятся файлы и как Python их находит. Теперь переходим к ключевому вопросу:

Как именно программа начинает работать с файлом и что означает «открыть файл»?

Этот модуль — один из самых важных во всей теме. Именно здесь формируется базовое понимание того, что такое файл для Python и как с ним взаимодействует программа.


1. Что означает «открыть файл»

Когда мы говорим «открыть файл» в Python, мы имеем в виду не то же самое, что двойной клик в Windows.

С точки зрения Python:

Открыть файл — значит установить соединение между программой и файлом в файловой системе.

После этого:

  • программа может читать данные из файла;
  • или записывать данные в файл;
  • или делать и то, и другое (в зависимости от режима).

Схема взаимодействия

[ Файл на диске ]
        ↑
        │ (open)
        ↓
[ Файловый объект в Python ]
        ↑
        │ (read / write)
        ↓
[ Данные в программе ]

Python не работает с файлом напрямую. Он работает с файловым объектом, который представляет файл в памяти.


2. Функция open()

Для открытия файлов используется встроенная функция open().

Базовый синтаксис:

file = open("data.txt", "r")

Где:

  • "data.txt" — путь к файлу;
  • "r" — режим работы с файлом;
  • file — файловый объект.

На этом этапе важно понять: open() не читает файл, а лишь открывает доступ к нему.


Минимальный пример

file = open("data.txt", "r")
print(file)

Вывод будет примерно таким:

<_io.TextIOWrapper name='data.txt' mode='r' encoding='cp1251'>

Это и есть файловый объект — специальный объект Python, через который происходит работа с файлом.


3. Режимы работы с файлами

Режим определяет:

  • что мы хотим делать с файлом;
  • что произойдёт, если файла не существует.

Рассмотрим три основных режима, которые используются чаще всего r, w, a.


3.1 Режим r — чтение (read)

file = open("data.txt", "r")

Что означает:

  • файл открывается только для чтения;
  • файл должен существовать;
  • если файла нет — будет ошибка.

Используется, когда:

  • нужно прочитать данные;
  • нельзя изменять содержимое файла.

3.2 Режим w — запись (write)

file = open("data.txt", "w")

Особенности режима w:

  • файл открывается для записи;
  • если файл существует — он будет полностью очищен;
  • если файла не существует — он будет создан.

Это крайне важный момент:

Режим w удаляет всё старое содержимое файла.


3.3 Режим a — добавление (append)

file = open("data.txt", "a")

Что делает режим a:

  • данные записываются в конец файла;
  • существующее содержимое сохраняется;
  • если файла нет — он будет создан.

Режим a часто используется для:

  • логов;
  • накопления данных;
  • истории операций.

Краткое сравнение режимов

Режим Назначение Файл должен существовать Старые данные
r чтение да сохраняются
w запись нет удаляются
a добавление нет сохраняются

4. Текстовый режим работы с файлами

По умолчанию Python открывает файл в текстовом режиме.

Это означает:

  • файл воспринимается как последовательность строк;
  • данные читаются и записываются как строки (str);
  • применяется кодировка.

Для базового курса мы работаем только с текстовым режимом, так как:

  • он напрямую связан со строками;
  • он используется для txt, csv, json.

5. Кодировка файлов (encoding)

Почему вообще существует кодировка

Файл на диске хранит байты, а не символы.

Кодировка — это правило, которое говорит:

«Как преобразовать байты в символы и обратно»

Самая распространённая кодировка сегодня — UTF-8.


Явное указание кодировки

Рекомендуемый стиль:

file = open("data.txt", "r", encoding="utf-8")

Почему это важно:

  • код будет одинаково работать на разных компьютерах;
  • исчезнут проблемы с кириллицей;
  • код станет предсказуемым.

Типичная ошибка новичков

file = open("data.txt", "r")

Такой код:

  • может работать;
  • но зависит от настроек операционной системы;
  • часто приводит к ошибкам с русскими символами.

Вывод: Всегда указывайте encoding="utf-8" явно.


6. Почему файл нужно закрывать

После работы с файлом его обязательно нужно закрыть.

file.close()

Что происходит, если файл не закрыть

  1. Файл остаётся занятым программой.
  2. Другие программы могут не получить к нему доступ.
  3. Данные могут не записаться полностью.
  4. Возникают утечки ресурсов.

С точки зрения системы:

  • открытый файл — это занятый ресурс;
  • таких ресурсов ограниченное количество.

Полный пример (без контекстного менеджера with)

file = open("data.txt", "r", encoding="utf-8")
content = file.read()
print(content)
file.close()

Этот код корректен, но:

  • требует дисциплины;
  • легко забыть close().

Именно поэтому в следующем модуле мы будем использовать with.


7. Формирование базовой модели работы с файлами

  1. Файл на диске ≠ файл в программе.
  2. open() создаёт файловый объект.
  3. Режим определяет поведение файла.
  4. Кодировка управляет преобразованием байтов в символы.
  5. Любой открытый файл нужно закрывать.

Модуль 3. Контекстный менеджер with

В предыдущем модуле мы научились открывать файлы с помощью open() и закрывать их методом close(). Формально этого достаточно, чтобы работать с файлами. Однако на практике такой подход не считается корректным стилем и почти не используется в реальных проектах.

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


1. Проблемы ручного закрытия файлов

Рассмотрим уже знакомый пример:

file = open("data.txt", "r", encoding="utf-8")
content = file.read()
print(content)
file.close()

На первый взгляд код выглядит аккуратно. Но у него есть системные проблемы, которые неочевидны новичку.


1.1 Забытый close()

Самая распространённая ошибка:

file = open("data.txt", "r", encoding="utf-8")
content = file.read()
print(content)

Файл остаётся открытым до завершения программы.

Последствия:

  • файл остаётся занятым;
  • данные могут не сохраниться полностью;
  • в больших программах это приводит к утечкам ресурсов.

1.2 Ошибка в процессе работы с файлом

Более тонкая и опасная ситуация:

file = open("data.txt", "r", encoding="utf-8")
number = int(file.read())  # если в файле не число
file.close()

Если в файле окажется текст:

  • возникнет ошибка ValueError;
  • строка file.close() никогда не выполнится;
  • файл останется открытым.

Системная проблема

Ручное закрытие файла:

  • требует постоянной дисциплины;
  • легко ломается при ошибках;
  • плохо масштабируется в сложных программах.

Именно поэтому Python предлагает специальный механизм управления ресурсами.


2. Что такое контекстный менеджер

Контекстный менеджер — это конструкция, которая:

  • автоматически подготавливает ресурс к работе;
  • гарантированно освобождает ресурс после завершения работы.

В случае файлов:

  • открывает файл;
  • всегда закрывает файл, даже если произошла ошибка.

3. Конструкция with ... as ...

Базовый синтаксис:

with open("data.txt", "r", encoding="utf-8") as file:
    content = file.read()
    print(content)

Что здесь происходит логически:

  1. Python открывает файл.
  2. Создаёт файловый объект file.
  3. Выполняет весь код внутри блока with.
  4. Автоматически закрывает файл, независимо от результата.

Визуальная схема

with open(...) as file:
    ├─ файл открыт
    ├─ выполняется код
    ├─ возможна ошибка
    └─ файл ЗАКРЫВАЕТСЯ ВСЕГДА

Это ключевая идея модуля.


4. Почему with — стандарт де-факто

В профессиональном Python-коде:

  • файлы почти никогда не закрывают вручную;
  • with используется по умолчанию;
  • код без with воспринимается как потенциально опасный.

Причины:

4.1 Гарантия закрытия ресурса

Даже если внутри блока:

  • произошла ошибка;
  • был выполнен return;
  • программа завершилась преждевременно,

файл всё равно будет закрыт.


4.2 Читаемость кода

with open("data.txt", "r", encoding="utf-8") as file:
    print(file.read())

С первого взгляда понятно:

  • где файл открывается;
  • где заканчивается работа с файлом.

4.3 Безопасность и масштабируемость

В реальных проектах одновременно могут открываться:

  • файлы;
  • сетевые соединения;
  • базы данных.

Контекстные менеджеры позволяют:

  • управлять ресурсами централизованно;
  • избегать трудноуловимых ошибок.

5. Сравнение: open() с with и без with

Без контекстного менеджера

file = open("data.txt", "r", encoding="utf-8")
data = file.read()
print(data)
file.close()

Проблемы:

  • close() можно забыть;
  • close() может не выполниться;
  • код уязвим к ошибкам.

С контекстным менеджером

with open("data.txt", "r", encoding="utf-8") as file:
    data = file.read()
    print(data)

Преимущества:

  • файл закрывается автоматически;
  • код компактнее;
  • риск ошибок минимален.

Принципиальное различие

Критерий Без with С with
Закрытие файла вручную автоматически
Защита от ошибок нет да
Читаемость ниже выше
Профессиональный стиль нет да

6. with и уже знакомые конструкции Python

Важно понимать:

  • with — это не магия;
  • это языковая конструкция, как if или for.

Она отлично сочетается с:

  • условиями;
  • циклами;
  • функциями.

Пример:

with open("numbers.txt", "r", encoding="utf-8") as file:
    for line in file:
        print(line.strip())

Здесь:

  • файл открывается один раз;
  • строки читаются по очереди;
  • файл закрывается автоматически после цикла.

7. Формирование правильной привычки

С этого момента правило должно быть жёстким:

Если вы работаете с файлом — используйте with.

Исключения существуют, но:

  • они редки;
  • они относятся к продвинутым сценариям;
  • на базовом уровне их не рассматривают.

Модуль 4. Работа с текстовыми файлами (.txt)

На этом этапе мы переходим от теории к активной практике. Все основные инструменты уже изучены:

  • мы понимаем, что такое файл и путь;
  • умеем открывать файлы;
  • используем контекстный менеджер with.

Теперь пришло время реально работать с текстовыми данными.


Подготовка: тестовый файл data.txt

В начале создадим текстовый файл, с которым будем работать на протяжении всего модуля.

Содержимое файла data.txt

Python — это высокоуровневый язык программирования.
Он используется для веб-разработки, анализа данных и автоматизации.
Python прост для изучения и чтения.
Файлы позволяют программе сохранять и загружать данные.
Работа с файлами — важный навык программиста.

Файл должен находиться:

  • либо в той же папке, что и Python-скрипт,
  • либо по корректному относительному пути.

1. Чтение файла целиком

Самый простой способ работы с текстовым файлом — прочитать его полностью.

Метод read()

with open("data.txt", "r", encoding="utf-8") as file:
    content = file.read()

print(content)

Что происходит:

  • файл открывается;
  • всё содержимое читается в одну строку;
  • файл автоматически закрывается.

Важный момент

Метод read():

  • возвращает одну строку (str);
  • сохраняет все символы перевода строки (\n);
  • загружает весь файл в память.

Это удобно:

  • для небольших файлов;
  • для конфигураций;
  • для текстов ограниченного размера.

2. Чтение файла построчно

Очень часто файл логически состоит из строк:

  • каждая строка — отдельная запись;
  • отдельная команда;
  • отдельное сообщение.

Итерация по файлу

Файловый объект является итерируемым.

with open("data.txt", "r", encoding="utf-8") as file:
    for line in file:
        print(line)

Каждая итерация цикла:

  • читает одну строку;
  • строка заканчивается символом \n.

Удаление символа перевода строки

Обычно символ \n мешает обработке:

with open("data.txt", "r", encoding="utf-8") as file:
    for line in file:
        line = line.strip()
        print(line)

Здесь мы используем:

  • методы строк;
  • уже знакомую конструкцию for.

Когда построчное чтение предпочтительнее

  • файл может быть большим;
  • строки обрабатываются по одной;
  • не требуется хранить весь файл в памяти.

3. Запись строк в файл

Теперь научимся создавать и записывать данные.

Метод write()

with open("output.txt", "w", encoding="utf-8") as file:
    file.write("Это первая строка файла\n")
    file.write("Это вторая строка файла\n")

Что важно помнить:

  • режим w очищает файл;
  • метод write() не добавляет \n автоматически;
  • всё, что вы хотите видеть в файле, нужно писать явно.

Запись списка строк

lines = [
    "Первая строка\n",
    "Вторая строка\n",
    "Третья строка\n"
]

with open("output.txt", "w", encoding="utf-8") as file:
    file.writelines(lines)

Метод writelines():

  • принимает список строк;
  • не добавляет переносы строк автоматически.

4. Добавление данных в файл (режим a)

Если нужно дописать данные, а не перезаписать файл, используется режим a.

with open("output.txt", "a", encoding="utf-8") as file:
    file.write("Новая строка добавлена в конец файла\n")

Поведение:

  • старые данные сохраняются;
  • новые данные добавляются в конец.

Типичные сценарии:

  • логирование;
  • накопление результатов;
  • история действий.

5. Обработка текстовых данных с помощью строк и циклов

Файл — это источник строк. А строки — это объект, с которым вы уже хорошо знакомы.

Пример: подсчёт количества строк

count = 0

with open("data.txt", "r", encoding="utf-8") as file:
    for _ in file:
        count += 1

print("Количество строк:", count)

Пример: поиск строк по условию

with open("data.txt", "r", encoding="utf-8") as file:
    for line in file:
        if "Python" in line:
            print(line.strip())

Здесь используется:

  • оператор in;
  • условие if;
  • методы строк.

Пример: преобразование данных

result = []

with open("data.txt", "r", encoding="utf-8") as file:
    for line in file:
        result.append(line.strip().upper())

print(result)

Фактически:

  • файл → строки → список → обработанные данные.

6. Работа с большими файлами (ситуативно)

До этого момента мы работали с небольшими файлами. Но в реальных задачах файлы могут быть:

  • десятки мегабайт;
  • сотни мегабайт;
  • гигабайты.

Проблема

content = file.read()

Для большого файла:

  • занимает много памяти;
  • может привести к падению программы.

6.1 Чтение файла частями (чанками)

Чанк — это порция данных фиксированного размера.

with open("data.txt", "r", encoding="utf-8") as file:
    while True:
        chunk = file.read(50)
        if not chunk:
            break
        print(chunk)

Здесь:

  • читаем по 50 символов;
  • обрабатываем данные постепенно;
  • не загружаем файл целиком.

Что можно делать с чанками

  • анализировать текст;
  • считать символы;
  • искать подстроки;
  • передавать данные дальше по цепочке.

7. Логическая картина модуля

Текстовый файл
   ↓
Последовательность строк
   ↓
Циклы + строки
   ↓
Обработка данных

Файлы — это продолжение уже изученных тем, а не отдельный мир.


Итог модуля

  • Читать файл целиком и построчно.
  • Записывать и добавлять данные в файл.
  • Обрабатывать строки из файла с помощью циклов.
  • Понимать, почему большие файлы читают частями.
  • Использовать with как стандартный инструмент.

Практическая работа Модуль 4

Условие

Есть текстовый файл data.txt, содержащий произвольный текст (одна строка — одно текстовое выражение).

Python is one of the most popular programming languages today.
Many developers start learning PYTHON as their first language.
This line talks about programming in general.
   python can be used for web development, data analysis and automation.
Java and C++ are also widely used languages.
I write scripts in Python almost every day.
This sentence does not mention the keyword.
   PYTHON is often used in machine learning projects.
Databases, networks and operating systems are important topics.
Sometimes people compare python with other languages.

Необходимо написать программу, которая:

  1. Читает файл построчно, используя контекстный менеджер with.

  2. Нормализует текст:

    • удаляет лишние пробелы в начале и конце строки;
    • приводит строки к нижнему регистру.
  3. Ищет строки, содержащие слово python.

  4. Анализирует найденные строки:

    • определяет количество строк, в которых найдено слово python;
    • подсчитывает общее количество слов во всех найденных строках;
    • проверяет, найдено ли хотя бы одно совпадение.
  5. Выводит результаты анализа в консоль в читаемом виде.

Требования к архитектуре программы

Программа обязательно должна быть разбита на отдельные функции:

  1. чтение файла;
  2. нормализация строк;
  3. поиск строк по ключевому слову;
  4. анализ результатов;
  5. запускаться через функцию main().

Реализация

Шаг 1. Чтение файла

def read_file(filename):
    with open(filename, 'r', encoding='utf-8') as file:
        return file.readlines()

Шаг 2. Нормализация текста

def normalize_lines(lines):
    return list(map(lambda line: line.strip().lower(), lines))

Шаг 3. Поиск строк с ключевым словом

def find_python_lines(lines):
    return list(filter(lambda line: 'python' in line, lines))

Шаг 4. Анализ найденных строк

def analyze_lines(lines):
    count_lines = len(lines)
    total_words = sum(len(line.split()) for line in lines)
    has_results = any(lines)

    return count_lines, total_words, has_results

Шаг 5. Главная функция main()

def main():
    filename = 'data.txt'

    lines = read_file(filename)
    normalized_lines = normalize_lines(lines)
    python_lines = find_python_lines(normalized_lines)

    count, words, found = analyze_lines(python_lines)

    print('Результаты анализа:')
    print(f'Найдено строк с "python": {count}')
    print(f'Общее количество слов в найденных строках: {words}')
    print(f'Есть ли совпадения: {found}')

Самостоятельная практическая работа Модуль 4

Анализ текста о протоколе HTTPS

1. Исходный текст для работы студентов

Текст предназначен для сохранения в файл, например https_info.txt.

Протокол HTTPS

Протокол HTTPS (HyperText Transfer Protocol Secure) используется для безопасной передачи данных между браузером пользователя и веб-сервером. В отличие от обычного HTTP, HTTPS применяет шифрование, что защищает данные от перехвата и подмены.

Основой безопасности HTTPS является использование SSL/TLS-сертификатов. Эти сертификаты подтверждают подлинность сайта и позволяют установить зашифрованное соединение. Подробное описание принципов работы TLS можно найти в официальной документации по адресу https://security.example.org/tls-overview.

HTTPS широко используется в интернет-магазинах, банковских сервисах и на любых сайтах, где передаются персональные данные. Например, рекомендации по внедрению HTTPS для веб-проектов опубликованы на сайте https://web-guides.example.com/https-setup.

Также важно учитывать, что поисковые системы отдают предпочтение сайтам, использующим HTTPS. Аналитический отчет о влиянии HTTPS на SEO доступен по ссылке https://research.example.net/seo-and-https.

Таким образом, переход на HTTPS является обязательным шагом для современных веб-ресурсов, заботящихся о безопасности и доверии пользователей.

Примерный результат итогового файла, например links_result.txt:

https://security.example.org/tls-overview — Подробное описание принципов работы TLS

https://web-guides.example.com/https-setup — Например, рекомендации по внедрению HTTPS для веб-проектов

https://research.example.net/seo-and-https — Аналитический отчет о влиянии HTTPS на SEO

2. Условие практической задачи

Задание

Необходимо создать программу для анализа текстового файла.

Программа должна:

  1. Считать текстовую информацию из файла.
  2. Проанализировать содержимое файла и найти все интернет-ссылки, присутствующие в тексте.
  3. Для каждой найденной ссылки определить, о чём она упоминается в тексте (описание находится в той же строке).
  4. Сформировать новый текстовый файл с результатом анализа.

Требования к результату:

  • В новом файле каждая строка должна содержать:

    • найденную ссылку;
    • краткое текстовое пояснение, связанное с этой ссылкой.
  • Исходный файл изменять нельзя.

  • Программа должна корректно обрабатывать многострочный текст.

  • Вся логика работы программы должна быть реализована с помощью функций объединенных в main().


Модуль 5. Работа с CSV-файлами

Введение: зачем программисту CSV

На предыдущих этапах мы работали с обычными текстовыми файлами (.txt). Это универсальный, но слабоструктурированный формат: программа не знает заранее, где заканчивается одно поле данных и начинается другое.

В реальных задачах очень часто требуется работать с табличными данными:

  • списки пользователей;
  • результаты тестов;
  • отчёты;
  • выгрузки из баз данных;
  • данные из Excel или Google Sheets.

Для таких задач используется формат CSV.


1. Что такое CSV и где он используется

CSV (Comma-Separated Values) — это текстовый формат хранения табличных данных, где:

  • каждая строка файла — это одна запись;
  • значения внутри строки разделены специальным символом (чаще всего запятой).

Пример из жизни:

name age city
Ivan 25 Moscow
Anna 30 Kazan

В формате CSV это будет выглядеть так:

name,age,city
Ivan,25,Moscow
Anna,30,Kazan

Где используется CSV

CSV — один из самых распространённых форматов обмена данными, потому что он:

  • прост;
  • человекочитаем;
  • поддерживается почти всеми системами.

Типичные сценарии использования:

  • экспорт данных из Excel;
  • импорт данных в базы данных;
  • обмен данными между сервисами;
  • хранение отчётов и логов;
  • загрузка тестовых данных в проекты.

Важно понимать: CSV — это не Excel, а обычный текстовый файл со строгими правилами.


2. Структура CSV-файла

Рассмотрим базовую структуру CSV-файла:

id,name,score
1,Alex,85
2,Maria,92
3,John,78

Ключевые особенности

  1. Первая строка часто содержит заголовки столбцов

    • она описывает, какие данные находятся в каждом столбце;
  2. Каждая строка — одна запись

  3. Разделитель

    • чаще всего ,
    • иногда ; (особенно в локализованных версиях Excel)

Схема представления

┌────┬────────┬───────┐
│ id │  name  │ score │  ← заголовки
├────┼────────┼───────┤
│ 1  │ Alex   │ 85    │
│ 2  │ Maria  │ 92    │
│ 3  │ John   │ 78    │
└────┴────────┴───────┘

Для Python это идеальный формат: строки → списки → словари.


3. Модуль csv в Python

Как и в случае с math или os, Python предоставляет стандартный модуль для работы с CSV — csv.

import csv

Модуль csv решает сразу несколько проблем:

  • корректно обрабатывает разделители;
  • учитывает кавычки;
  • избавляет от ручного split().

Это стандарт де-факто для работы с CSV в Python.


4. Чтение CSV в списки

Начнём с самого простого варианта — чтения CSV как списка строк.

Пример CSV-файла students.csv

name,age,grade
Ivan,20,85
Anna,21,90
Petr,19,78

Чтение файла

import csv

with open("students.csv", encoding="utf-8") as file:
    reader = csv.reader(file)
    for row in reader:
        print(row)

Что происходит

  • csv.reader(file) создаёт объект-итератор;
  • каждая строка файла преобразуется в список строк.

Результат:

['name', 'age', 'grade']
['Ivan', '20', '85']
['Anna', '21', '90']
['Petr', '19', '78']

Когда это удобно

  • если структура простая;
  • если заголовки не важны;
  • если данные обрабатываются позиционно (по индексам).

5. Чтение CSV в словари

На практике чаще используется чтение в словари, так как это делает код:

  • более читаемым;
  • менее зависимым от порядка столбцов.

Использование csv.DictReader

import csv

with open("students.csv", encoding="utf-8") as file:
    reader = csv.DictReader(file)
    for row in reader:
        print(row)

Результат

{'name': 'Ivan', 'age': '20', 'grade': '85'}
{'name': 'Anna', 'age': '21', 'grade': '90'}
{'name': 'Petr', 'age': '19', 'grade': '78'}

Преимущества

  • доступ к данным по ключу:

    row["name"]
    row["grade"]
  • код становится самодокументируемым;

  • проще поддерживать и расширять.


6. Запись данных в CSV

Теперь перейдём к обратной операции — записи данных в CSV-файл.

Запись списка строк (csv.writer)

import csv

data = [
    ["name", "age", "grade"],
    ["Ivan", 20, 85],
    ["Anna", 21, 90],
    ["Petr", 19, 78]
]

with open("output.csv", "w", newline="", encoding="utf-8") as file:
    writer = csv.writer(file)
    writer.writerows(data)

Почему важен newline=""

При работе с CSV в Windows без newline="" возможны пустые строки между записями. Это рекомендация официальной документации Python.


7. Запись словарей в CSV

Наиболее универсальный вариант — запись словарей.

Пример

import csv

students = [
    {"name": "Ivan", "age": 20, "grade": 85},
    {"name": "Anna", "age": 21, "grade": 90},
    {"name": "Petr", "age": 19, "grade": 78}
]

with open("students_out.csv", "w", newline="", encoding="utf-8") as file:
    fieldnames = ["name", "age", "grade"]
    writer = csv.DictWriter(file, fieldnames=fieldnames)

    writer.writeheader()
    writer.writerows(students)

Что важно

  • fieldnames определяет порядок столбцов;
  • writeheader() записывает заголовки;
  • каждая запись — словарь.

8. CSV-файлы с нестандартными разделителями

На практике CSV-файлы далеко не всегда используют запятую в качестве разделителя. Это важный момент, который часто вызывает ошибки у начинающих разработчиков.

Почему используются другие разделители

В ряде локализаций (особенно в Windows и Excel):

  • запятая используется как десятичный разделитель (3,14);
  • поэтому в CSV-файлах применяют:
    • ; (точка с запятой),
    • |,
    • \t (табуляция).

Пример CSV-файла с разделителем ;:

name;age;grade
Ivan;20;85
Anna;21;90
Petr;19;78

Формально это всё ещё CSV, но с другим delimiter.


Параметр delimiter

Модуль csv в Python позволяет явно указать символ-разделитель с помощью параметра delimiter.

Чтение CSV с ; в качестве разделителя

import csv

with open("students_semicolon.csv", encoding="utf-8") as file:
    reader = csv.reader(file, delimiter=";")
    for row in reader:
        print(row)

Результат:

['name', 'age', 'grade']
['Ivan', '20', '85']
['Anna', '21', '90']
['Petr', '19', '78']

Без указания delimiter=";" Python прочитал бы каждую строку как одно большое поле.


DictReader с нестандартным разделителем

Аналогично работает и csv.DictReader.

import csv

with open("students_semicolon.csv", encoding="utf-8") as file:
    reader = csv.DictReader(file, delimiter=";")
    for row in reader:
        print(row)

Результат:

{'name': 'Ivan', 'age': '20', 'grade': '85'}
{'name': 'Anna', 'age': '21', 'grade': '90'}
{'name': 'Petr', 'age': '19', 'grade': '78'}

Код остаётся читаемым и устойчивым, независимо от формата файла.


Запись CSV с нестандартным разделителем

При записи CSV также можно указать нужный разделитель.

import csv

students = [
    {"name": "Ivan", "age": 20, "grade": 85},
    {"name": "Anna", "age": 21, "grade": 90},
    {"name": "Petr", "age": 19, "grade": 78}
]

with open("students_semicolon_out.csv", "w", newline="", encoding="utf-8") as file:
    writer = csv.DictWriter(
        file,
        fieldnames=["name", "age", "grade"],
        delimiter=";"
    )
    writer.writeheader()
    writer.writerows(students)

В результате файл будет корректно открыт, например, в Excel с локалью, где ожидается ;.


9. Проблема корректного открытия CSV в UTF-8

Excel не умеет автоматически корректно открывать CSV в UTF-8 (особенно версии до Microsoft 365). Даже если файл сохранён в utf-8 или cp1251, Excel при двойном клике:

  • игнорирует реальную кодировку;
  • открывает файл «как считает нужным»;
  • в результате русские символы превращаются в Товар и т.п.

Способ 1. Использовать UTF-8 с BOM (рекомендуется)

Excel корректно распознаёт UTF-8, если в файле есть BOM (Byte Order Mark).

Что нужно сделать в коде

При записи файла использовать кодировку:

encoding="utf-8-sig"

Исправленный фрагмент записи CSV

with open(filename, "w", encoding="utf-8-sig", newline="") as file:
    writer = csv.writer(file, delimiter=";")

utf-8-sig автоматически добавляет BOM в начало файла — Excel это понимает.


Способ 2. Импорт CSV через Excel (вручную)

Если файл уже создан, правильный путь в Excel:

  1. Открыть Excel

  2. Данные → Получить данные → Из текста/CSV

  3. Выбрать файл

  4. Указать:

    • кодировку: 65001 (UTF-8)
    • разделитель: ;
  5. Загрузить данные


Ключевая идея модуля

CSV — это мост между текстовыми файлами и структурированными данными. Умение работать с CSV — базовый навык для аналитики, backend-разработки и автоматизации. Хороший разработчик всегда адаптируется к формату данных, а не ожидает, что данные будут идеальными.


Практическая работа Модуль 5

Условие

Вам дан CSV-файл data.csv, содержащий информацию о студентах, их учебной группе и оценках по нескольким предметам.

Необходимо написать программу, которая проанализирует эти данные и выведет сводную информацию об успеваемости.

full_name;group;math;python;databases
Иванов Иван;RPO-1;5;4;5
Петров Петр;RPO-1;3;4;3
Сидорова Анна;RPO-1;5;5;4
Кузнецов Максим;RPO-1;4;4;4
Орлова Мария;RPO-1;5;5;5

Смирнов Алексей;RPO-2;4;3;4
Васильева Ольга;RPO-2;5;4;5
Морозов Денис;RPO-2;3;3;4
Федорова Ирина;RPO-2;4;4;4
Зайцев Кирилл;RPO-2;5;5;4

Романов Сергей;RPO-3;3;4;3
Николаева Елена;RPO-3;4;5;4
Попов Артем;RPO-3;5;5;5
Климова Анастасия;RPO-3;4;4;5
Тихонов Павел;RPO-3;3;3;3

Андреев Михаил;RPO-4;5;4;4
Белова Наталья;RPO-4;4;4;4
Киселев Роман;RPO-4;3;4;4
Соколова Юлия;RPO-4;5;5;5
Григорьев Илья;RPO-4;4;3;4

Программа должна:

  1. Прочитать данные из CSV-файла data.csv:

    • использовать контекстный менеджер with;
    • учитывать, что разделитель — ;.
  2. Преобразовать оценки студентов из строк в числа.

  3. Для каждого студента:

    • вычислить средний балл по всем предметам.
  4. Разделить студентов на категории:

    • отличники — средний балл ≥ 4.5;
    • хорошисты — от 3.5 до 4.49;
    • троечники — ниже 3.5.
  5. Определить:

    • группу с самым высоким средним баллом.
  6. Проверить:

    • есть ли студенты без троек (оценки ≥ 4 по всем предметам).

Требования к архитектуре программы

  • Вся логика должна быть разделена на функции:
    • чтение данных;
    • вычисление среднего балла;
    • анализ категорий;
    • анализ групп.
    • Основной сценарий выполнения программы должен быть реализован в функции main().

Реализация

Шаг 1. Чтение CSV-файла

import csv
from functools import reduce
def read_students(filename):
    with open(filename, encoding="utf-8") as file:
        reader = csv.DictReader(file, delimiter=";")
        return list(reader)

Шаг 2. Вычисление среднего балла студента

def calculate_average(grades):
    total = reduce(lambda x, y: x + y, grades)
    return total / len(grades)

Шаг 3. Обработка данных студентов

def process_students(students):
    result = []

    for student in students:
        grades = list(
            map(
                int,
                [student["math"], student["python"], student["databases"]]
            )
        )

        average = calculate_average(grades)

        result.append({
            "name": student["full_name"],
            "group": student["group"],
            "grades": grades,
            "average": average
        })

    return result

Шаг 4. Категоризация студентов

def categorize_students(students):
    excellent = list(filter(lambda s: s["average"] >= 4.5, students))
    good = list(filter(lambda s: 3.5 <= s["average"] < 4.5, students))
    average = list(filter(lambda s: s["average"] < 3.5, students))

    return excellent, good, average

Шаг 5. Анализ групп

def best_group(students):
    groups = {}

    for student in students:
        groups.setdefault(student["group"], []).append(student["average"])

    group_averages = {
        group: sum(scores) / len(scores)
        for group, scores in groups.items()
    }

    return max(group_averages, key=group_averages.get)
    # return max(group_averages, key=lambda g: group_averages[g])

Упрощенный вариант функции

def best_group(students):
    groups = {}

    # 1. Группируем студентов по группам
    for student in students:
        group = student["group"]
        average = student["average"]

        if group not in groups:
            groups[group] = []

        groups[group].append(average)

    # 2. Считаем средний балл по каждой группе
    group_averages = {}

    for group in groups:
        scores = groups[group]
        total = 0

        for score in scores:
            total += score

        group_averages[group] = total / len(scores)

    # 3. Ищем группу с максимальным средним баллом
    best_group_name = None
    best_average = 0

    for group in group_averages:
        average = group_averages[group]

        if average > best_average:
            best_average = average
            best_group_name = group

    return best_group_name

Шаг 6. Проверка студентов без троек

def students_without_threes(students):
    return all(all(grade >= 4 for grade in s["grades"]) for s in students)

Шаг 7. Основная функция main()

def main():
    students_raw = read_students("data.csv")
    students = process_students(students_raw)

    excellent, good, average = categorize_students(students)

    print(f"Отличники: {len(excellent)}")
    print(f"Хорошисты: {len(good)}")
    print(f"Троечники: {len(average)}")

    print("Лучшая группа:", best_group(students))

    if students_without_threes(students):
        print("Есть студенты без троек")
    else:
        print("Все студенты имеют хотя бы одну тройку")

Самостоятельная практическая работа Модуль 5

Анализ CSV-файла с товарами магазина

1. Исходные данные для CSV-файла

Текст ниже предназначен для прямого копирования и сохранения в файл, например products.csv. Разделитель — ;.

id;name;price;sale_count;stock_count
1;Хлеб пшеничный;45;30;10
2;Молоко 1л;80;25;0
3;Сыр твёрдый;550;5;4
4;Яйца куриные;110;18;0
5;Сахар;70;40;15
6;Хлеб пшеничный;45;20;5
7;Молоко 1л;80;15;0
8;Кофе растворимый;420;7;3
9;Чай черный;210;12;6
10;Сыр твёрдый;550;3;0
11;Макароны;95;22;11
12;Рис;130;16;0
13;Шоколад;120;28;9
14;Кофе растворимый;420;4;0
15;Чай черный;210;9;2

Примерный результат итогового файла, например result.csv:

Общая выручка
31190.0

Товар;Выручка
Хлеб пшеничный;2250.0
Молоко 1л;3200.0
Сыр твёрдый;4400.0
Яйца куриные;1980.0
Сахар;2800.0
Кофе растворимый;4620.0
Чай черный;4410.0
Макароны;2090.0
Рис;2080.0
Шоколад;3360.0

Товары для дозакупки
Сыр твёрдый
Молоко 1л
Яйца куриные
Кофе растворимый
Рис

2. Условие практической задачи

Задание

Необходимо создать программу для анализа данных о продажах товаров небольшого магазина.

Программа должна:

  1. Считать информацию из CSV-файла с товарами.
  2. Проанализировать данные о продажах и остатках.
  3. На основе анализа сформировать новый CSV-файл с итоговой информацией.

В рамках анализа необходимо определить:

  • общую сумму выручки по всем продажам;
  • сумму выручки отдельно по каждому товару;
  • список товаров, которые необходимо закупить повторно (остаток равен нулю).

Требования к реализации:

  • исходный CSV-файл изменять нельзя;
  • итоговый файл должен наглядно отражать результаты анализа;
  • программа должна быть логически разделена на функции, каждая из которых отвечает за отдельный этап обработки данных;
  • объединение всей логики работы программы и её запуск должны выполняться в функции main().

*Формат итогового CSV-файла, структура данных и порядок вывода информации определяются разработчиком программы. Можно сформировать до 3 CSV-файлов.


Модуль 6. Работа с JSON-файлами

Введение

На предыдущих этапах курса мы работали с данными, которые существовали только во время выполнения программы: переменные, списки, словари. Однако в реальных проектах данные почти всегда должны сохраняться, передаваться между программами или загружаться из внешних источников. Один из самых распространённых форматов для этого — JSON.

В этом модуле мы подробно разберём формат JSON, научимся читать и записывать JSON-файлы в Python и поймём, почему именно этот формат стал стандартом для API, конфигурационных файлов и обмена данными между сервисами.


1. Что такое JSON и зачем он нужен

JSON (JavaScript Object Notation) — это текстовый формат представления структурированных данных. Несмотря на название, JSON не привязан к JavaScript и используется практически во всех языках программирования.

Основные свойства JSON:

  • человекочитаемый формат;
  • легко парсится программами;
  • независим от платформы и языка;
  • отлично подходит для передачи данных по сети.

JSON используется:

  • в API (REST, HTTP-сервисы);
  • для хранения конфигураций программ;
  • для сериализации данных;
  • в базах данных (например, PostgreSQL JSONB);
  • в фронтенде и бэкенде.

Пример JSON-документа:

{
  "name": "Ivan",
  "age": 21,
  "is_student": true
}

Это обычный текст, но со строгими правилами структуры.


2. Структура и правила JSON

JSON строится на двух базовых структурах:

  1. Объект — набор пар ключ: значение
  2. Массив — упорядоченный список значений

Основные правила JSON

  • ключи всегда строки и всегда в двойных кавычках;
  • строки — только в двойных кавычках;
  • числа записываются без кавычек;
  • логические значения: true и false (не True / False);
  • отсутствие значения — null;
  • комментарии запрещены;
  • последняя запятая запрещена.

Пример корректного JSON:

{
  "students": [
    {
      "name": "Anna",
      "average": 4.5
    },
    {
      "name": "Petr",
      "average": 3.8
    }
  ]
}

3. Соответствие JSON ↔ типы данных Python

Когда Python читает JSON-файл, он автоматически преобразует JSON-структуры в соответствующие типы данных Python.

JSON Python
object dict
array list
string str
number (int) int
number (float) float
true / false True / False
null None

Схема преобразования

JSON файл
   ↓
json.load()
   ↓
Python dict / list

Это означает, что после загрузки JSON мы работаем с обычными структурами Python.


4. Модуль json

Для работы с JSON в Python используется встроенный модуль json.

Подключение:

import json

Модуль предоставляет четыре ключевые функции:

  • json.load() — чтение JSON из файла
  • json.loads() — чтение JSON из строки
  • json.dump() — запись JSON в файл
  • json.dumps() — преобразование в JSON-строку

В рамках курса мы будем фокусироваться на работе с файлами.


5. Загрузка данных из JSON-файла

Рассмотрим файл students.json:

[
  {
    "name": "Ivan",
    "group": "A",
    "average": 4.2
  },
  {
    "name": "Maria",
    "group": "B",
    "average": 4.8
  }
]

Чтение файла в Python

import json

with open("students.json", "r", encoding="utf-8") as file:
    students = json.load(file)

print(students)
print(type(students))

После выполнения:

  • students — это список (list);
  • каждый элемент списка — словарь (dict).

Теперь мы можем обрабатывать данные привычными способами:

for student in students:
    print(student["name"], student["average"])

6. Сохранение данных в JSON-файл

Допустим, у нас есть данные в Python:

students = [
    {"name": "Ivan", "average": 4.2},
    {"name": "Maria", "average": 4.8}
]

Запись в файл

import json

with open("students.json", "w", encoding="utf-8") as file:
    json.dump(students, file)

После этого будет создан JSON-файл с сохранёнными данными.

Важно понимать: json.dump() переводит Python-структуры в текстовый формат JSON.


7. Форматированный вывод (indent)

По умолчанию JSON записывается в одну строку, что неудобно для чтения.

Пример без форматирования:

[
  { "name": "Ivan", "average": 4.2 },
  { "name": "Maria", "average": 4.8 }
]

Использование indent

with open("students.json", "w", encoding="utf-8") as file:
    json.dump(students, file, indent=4, ensure_ascii=False)

Результат:

[
  {
    "name": "Ivan",
    "average": 4.2
  },
  {
    "name": "Maria",
    "average": 4.8
  }
]

Параметры:

  • indent — количество пробелов для вложенности;
  • ensure_ascii=False — корректное сохранение кириллицы.

Практические задания

  1. Создайте JSON-файл с данными о книгах (название, автор, год).
  2. Загрузите файл и выведите список всех авторов.
  3. Добавьте новую книгу и сохраните файл обратно.
  4. Сохраните данные в отформатированном виде.

8. Работа с JSON-строками: loads() и dumps()

На практике JSON очень часто существует не в файле, а в виде строки — например:

  • данные, полученные по сети (API);
  • ответы от серверов;
  • строки, пришедшие из других программ;
  • временные данные без сохранения на диск.

Для таких случаев в модуле json существуют отдельные функции.


json.loads() — преобразование JSON-строки в Python-объект

Функция json.loads() принимает строку, содержащую JSON, и возвращает соответствующую структуру данных Python.

Важно: loads() работает со строкой, а не с файлом.

Пример JSON-строки

json_string = """
{
  "name": "Ivan",
  "age": 21,
  "is_student": true
}
"""

Преобразование строки в Python-словарь

import json

data = json.loads(json_string)

print(data)
print(type(data))

Результат:

  • data — это dict;
  • далее с ним можно работать как с обычным словарём Python.
print(data["name"])
print(data["age"])

json.dumps() — преобразование Python-объекта в JSON-строку

Функция json.dumps() выполняет обратную операцию: преобразует структуру данных Python в строку JSON.

Важно: dumps() не создаёт файл, а возвращает строку.

Пример

import json

student = {
    "name": "Maria",
    "average": 4.8,
    "is_active": True
}

json_string = json.dumps(student)

print(json_string)
print(type(json_string))

Результат:

  • json_string — это строка (str);
  • её можно передавать, сохранять, отправлять по сети.

Форматирование JSON-строки

Так же как и при работе с файлами, dumps() поддерживает форматирование.

json_string = json.dumps(student, indent=4, ensure_ascii=False)

print(json_string)

Результат:

{
    "name": "Maria",
    "average": 4.8,
    "is_active": true
}

Ключевое различие: файл vs строка

Задача Функция С чем работает
Чтение JSON из файла json.load() файл
Запись JSON в файл json.dump() файл
Чтение JSON из строки json.loads() строка
Преобразование в JSON-строку json.dumps() строка

Схемы работы

Работа с файлом:

JSON файл
   ↓
json.load()
   ↓
Python объект

Работа со строкой:

JSON строка
   ↓
json.loads()
   ↓
Python объект

Когда используются loads() и dumps()

  • при работе с API;
  • при передаче данных между программами;
  • при логировании и сериализации данных;
  • когда нет необходимости сохранять данные в файл.

В рамках этого курса основной упор делается на работу с файлами, но понимание loads() и dumps() необходимо для дальнейшего изучения сетевых приложений и веб-разработки.


Итоги модуля

В этом модуле вы:

  • разобрались, что такое JSON и зачем он используется;
  • изучили соответствие JSON и Python-типов;
  • научились загружать и сохранять данные;
  • поняли, почему JSON — основной формат для API и конфигураций.

Далее мы будем использовать эти знания при работе с API, файлами настроек и реальными проектами.

Практическая работа Модуль 6

Условие

Реализовать консольную программу для анализа и обновления каталога книг, хранящегося в JSON-файле data.json.

Программа должна уметь:

  • загружать данные из JSON-файла;
  • анализировать содержимое;
  • добавлять новую информацию;
  • сохранять изменения обратно в файл.
[
  {
    "title": "Clean Code",
    "author": "Robert C. Martin",
    "year": 2008,
    "available": true
  },
  {
    "title": "Fluent Python",
    "author": "Luciano Ramalho",
    "year": 2015,
    "available": false
  },
  {
    "title": "Effective Python",
    "author": "Brett Slatkin",
    "year": 2019,
    "available": true
  },
  {
    "title": "Python Tricks",
    "author": "Dan Bader",
    "year": 2017,
    "available": true
  },
  {
    "title": "The Pragmatic Programmer",
    "author": "Andrew Hunt",
    "year": 1999,
    "available": false
  },
  {
    "title": "Code Complete",
    "author": "Steve McConnell",
    "year": 2004,
    "available": true
  },
  {
    "title": "Design Patterns",
    "author": "Erich Gamma",
    "year": 1994,
    "available": false
  },
  {
    "title": "Refactoring",
    "author": "Martin Fowler",
    "year": 2018,
    "available": true
  },
  {
    "title": "Introduction to Algorithms",
    "author": "Thomas H. Cormen",
    "year": 2009,
    "available": false
  },
  {
    "title": "Automate the Boring Stuff with Python",
    "author": "Al Sweigart",
    "year": 2020,
    "available": true
  }
]

Требования к архитектуре программы

В программе обязательно должно быть реализовано:

  1. Чтение данных из JSON-файла data.json с использованием конструкции with.

  2. Анализ данных:

    • подсчёт общего количества книг;
    • подсчёт количества доступных книг;
    • проверка наличия книг, изданных более 10 лет назад.
  3. Добавление новой книги в каталог (данные добавляются программно).

  4. Сохранение обновлённого каталога обратно в data.json.

  5. Разделение логики программы на отдельные функции:

    • загрузка данных;
    • анализ каталога;
    • добавление книги;
    • сохранение данных.
  6. Запуск всей программы через функцию main().

Реализация

Шаг 1. Загрузка каталога книг из JSON

import json


def load_books(filename):
    with open(filename, "r", encoding="utf-8") as file:
        return json.load(file)

Шаг 2. Анализ каталога книг

from datetime import datetime


def analyze_books(books):
    total_books = len(books)

    available_books = list(filter(lambda book: book["available"], books))
    available_count = len(available_books)

    current_year = datetime.now().year
    old_books_exist = any(
        current_year - book["year"] > 10
        for book in books
    )

    return {
        "total": total_books,
        "available": available_count,
        "has_old_books": old_books_exist
    }

Шаг 3. Добавление новой книги

def add_book(books, title, author, year, available=True):
    new_book = {
        "title": title,
        "author": author,
        "year": year,
        "available": available
    }
    books.append(new_book)

Шаг 4. Сохранение обновлённого каталога

def save_books(filename, books):
    with open(filename, "w", encoding="utf-8") as file:
        json.dump(books, file, ensure_ascii=False, indent=4)

Шаг 5. Главная функция main()

def main():
    filename = "data.json"

    books = load_books(filename)

    stats = analyze_books(books)

    print("Статистика библиотеки:")
    print(f"Всего книг: {stats['total']}")
    print(f"Доступно книг: {stats['available']}")
    print(f"Есть книги старше 10 лет: {stats['has_old_books']}")

    add_book(
        books,
        title="Learning Python",
        author="Mark Lutz",
        year=2021,
        available=True
    )

    save_books(filename, books)

Модуль 7. Обзор других форматов файлов

Зачем вообще говорить о других форматах

До этого момента мы подробно работали с форматами:

  • txt — простой текст;
  • csv — табличные данные;
  • json — структурированные данные для программ и API.

Эти форматы покрывают 80% задач начинающего разработчика. Однако в реальной разработке вы очень быстро столкнётесь с ситуациями, когда данные:

  • приходят из Excel-файлов;
  • передаются в формате XML;
  • хранятся в бинарном виде (изображения, аудио, видео, архивы).

Цель этого модуля — не научить работать с ними, а:

  • сформировать правильное ментальное представление;
  • показать, когда и почему применяются эти форматы;
  • обозначить инструменты, с которыми вы будете работать позже.

Общая карта форматов данных

Перед разбором отдельных форматов полезно увидеть общую картину:

Данные
│
├── Текстовые (читаемые человеком)
│   ├── txt
│   ├── csv
│   ├── json
│   └── xml
│
└── Бинарные (читаемые программами)
    ├── xlsx
    ├── изображения (png, jpg)
    ├── аудио / видео
    └── архивы

1. Формат xlsx (Excel)

Что это такое

xlsx — это формат электронных таблиц Microsoft Excel.

На первый взгляд он выглядит как один файл, но на самом деле это:

  • набор XML-файлов,
  • упакованных в ZIP-архив.

Поэтому xlsx не является простым текстовым форматом.


Где используется

  • отчёты;
  • бухгалтерия;
  • аналитика;
  • выгрузки данных для бизнеса;
  • обмен данными между людьми, а не программами.

Очень часто сценарий выглядит так:

«Нам прислали Excel-файл, нужно обработать данные и загрузить в систему».


Как с ним работают в Python

С xlsx почти никогда не работают вручную. Используются специализированные библиотеки:

  • openpyxl — работа с Excel-файлами;
  • pandas — анализ и обработка данных;
  • xlsxwriter — генерация отчётов.

Пример (без углубления):

import pandas as pd

df = pd.read_excel("data.xlsx")

Почему мы не изучаем xlsx сейчас

  • формат сложнее, чем кажется;
  • требует сторонних библиотек;
  • важнее сначала понять логику работы с данными, а не конкретный инструмент.

2. Формат xml

Что такое XML

xml — это иерархический текстовый формат, основанный на тегах.

Пример XML:

<book>
    <title>Clean Code</title>
    <author>Robert C. Martin</author>
    <year>2008</year>
</book>

По структуре он похож на HTML, но предназначен для хранения и передачи данных.


Где используется

  • старые и корпоративные API;
  • банковские системы;
  • государственные сервисы;
  • конфигурационные файлы;
  • документооборот.

XML — это формат, который вы обязаны уметь читать, даже если не любите его.


XML vs JSON (ключевое сравнение)

Критерий XML JSON
Читаемость Низкая Высокая
Объём Большой Компактный
Гибкость Очень высокая Ограниченная
Использование Legacy / Enterprise Современные API

Работа с XML в Python

В стандартной библиотеке есть модуль:

  • xml.etree.ElementTree

Пример (обзорно):

import xml.etree.ElementTree as ET

tree = ET.parse("data.xml")
root = tree.getroot()

Почему XML не изучается глубоко в базовом курсе

  • формат громоздкий;
  • редко используется в новых проектах;
  • важно понимать принцип, а не синтаксис.

3. Бинарные файлы

Что такое бинарные файлы

Бинарный файл — это файл, который:

  • не предназначен для чтения человеком;
  • содержит данные в виде байтов.

Примеры:

  • изображения (.png, .jpg);
  • аудио (.mp3);
  • видео (.mp4);
  • архивы (.zip);
  • базы данных;
  • исполняемые файлы.

Чем бинарные файлы отличаются от текстовых

Текстовый файл → символы → строки → текст
Бинарный файл  → байты → структура → данные

Как Python работает с бинарными файлами

Для бинарных файлов используется режим:

"rb"  # read binary
"wb"  # write binary

Пример (идея, без практики):

with open("image.png", "rb") as file:
    data = file.read()

Где это используется

  • загрузка файлов на сервер;
  • работа с изображениями;
  • сетевые протоколы;
  • криптография;
  • обработка больших файлов.

Почему бинарные файлы важны

Даже если вы не будете их обрабатывать напрямую, вы будете:

  • принимать бинарные данные из API;
  • сохранять файлы;
  • передавать данные между сервисами.

4. Когда и какими инструментами работают с форматами

Сводная таблица

Формат Когда используется Основные инструменты
txt простой текст open()
csv табличные данные csv, pandas
json API, конфигурации json, requests
xlsx отчёты, аналитика openpyxl, pandas
xml legacy-системы xml.etree
бинарные медиа, файлы бинарные режимы

Самостоятельная практическая работа

Задача 1. Анализ данных об успеваемости студентов

Описание задачи

Имеется файл с табличными данными, содержащий информацию о студентах, их учебной группе и оценках по нескольким предметам. Необходимо разработать программу, которая выполняет анализ этих данных и выводит обобщённую информацию.

full_name;group;math;python;databases
Иванов Иван;RPO-1;5;4;5
Петров Петр;RPO-1;3;4;3
Сидорова Анна;RPO-1;5;5;5
Кузнецов Максим;RPO-1;4;4;4
Орлова Мария;RPO-1;3;3;4
Смирнов Алексей;RPO-2;4;5;4
Васильева Елена;RPO-2;5;5;4
Морозов Дмитрий;RPO-2;3;4;3
Федорова Ирина;RPO-2;4;4;5
Никитин Олег;RPO-2;5;4;5
Соловьев Артем;RPO-3;3;3;3
Павлова Ксения;RPO-3;4;3;4
Зайцев Кирилл;RPO-3;5;4;4
Тарасова Ольга;RPO-3;4;5;5
Беляев Роман;RPO-3;3;4;3

Входные данные

Файл формата CSV, в котором:

  • каждая строка соответствует одному студенту;
  • значения разделены символом ;;
  • первая строка содержит названия столбцов.

Структура данных включает:

  • фамилию и имя студента;
  • название учебной группы;
  • оценки по нескольким предметам.

Требования к программе

Программа должна:

  1. Загрузить данные из файла.

  2. Корректно обработать числовые значения оценок.

  3. Для каждого студента вычислить среднее значение его оценок.

  4. На основе всех данных определить:

    • общее количество студентов;
    • средний балл каждого студента;
    • средний балл по каждой учебной группе.
  5. Вывести результаты анализа в читаемом виде.


Задача 2. Система пользователей и разграничение доступа

Описание задачи

Для управления доступом к функционалу программы необходимо реализовать систему пользователей. Информация о пользователях хранится в отдельном файле и используется при запуске программы.


Входные данные

Файл формата JSON, содержащий список пользователей. Для каждого пользователя хранится:

  • логин;
  • пароль;
  • роль.

Роль определяет набор доступных возможностей.


Требования к программе

Программа должна:

  1. Загрузить информацию о пользователях из файла.

  2. Запросить у пользователя логин и пароль.

  3. Проверить корректность введённых данных.

  4. Определить роль пользователя.

  5. Разграничить доступ:

    • обычный пользователь может выполнять анализ данных;
    • пользователь с расширенными правами может дополнительно добавлять новых пользователей в систему.
  6. Обеспечить сохранение обновлённых данных о пользователях.


Задача 3. Логирование работы программы

Описание задачи

Для отслеживания работы программы необходимо вести журнал действий. Все важные события должны фиксироваться в отдельном текстовом файле.


Требования к программе

Программа должна записывать в файл сообщения о следующих событиях:

  1. Успешный вход пользователя в систему.
  2. Ошибки при вводе логина или пароля.
  3. Запуск анализа данных.
  4. Добавление нового пользователя.
  5. Завершение работы программы.

Формат записей

Каждая запись должна содержать тип сообщения и краткое описание действия, например:

[MESSAGE] Пользователь успешно вошёл в систему
[WARNING] Введён неверный пароль

Задача 4. Интеграция и финальная программа

Условие задачи

Необходимо реализовать консольную программу для анализа данных из CSV-файла, которая работает в бесконечном цикле и использует разграничение прав доступа.

Программа должна использовать три файла:

  • users.json — хранит данные пользователей программы
  • data.csv — содержит данные для анализа
  • logs.txt — содержит журнал действий пользователей

Пользователи программы

Информация о пользователях хранится в JSON-файле. Каждый пользователь имеет:

  • логин
  • пароль
  • роль (user или admin)

Авторизация

  1. При запуске программы пользователь должен ввести логин и пароль.
  2. Если логин не найден — программа сообщает об ошибке и делает запись в лог.
  3. Если пароль неверный — программа сообщает об ошибке и делает запись в лог.
  4. При успешном входе определяется роль пользователя.

Меню программы

После успешной авторизации программа запускается в бесконечном цикле и отображает меню.

Меню для пользователя (user)

Пользователь с ролью user должен иметь доступ к следующим возможностям:

  1. Проанализировать данные из CSV-файла (анализ зависит от тематики файла, но должен использовать чтение CSV)
  2. Просмотреть краткую статистику по данным
  3. Завершить работу программы

Меню для администратора (admin)

Администратор имеет все возможности пользователя, а также дополнительный пункт:

  1. Создать нового пользователя (с указанием логина, пароля и роли)

Логирование

Каждое значимое действие программы должно записываться в файл logs.txt.

Примеры сообщений:

[MESSAGE] Пользователь admin вошёл в систему
[WARNING] Неверный пароль
[MESSAGE] Выполнен анализ CSV данных
[MESSAGE] Создан новый пользователь

Логи должны добавляться в файл, а не перезаписывать его.


Завершение работы

Выход из программы должен происходить только через пункт меню. При завершении работы также должна создаваться запись в логах.


Предыдущий урок | Следующий урок