Python с нуля до Junior-разработчика

Курс проведёт от базовых конструкций Python к написанию небольших прикладных проектов и пониманию типичных задач джуна. Вы освоите основы языка, работу с файлами и API, ООП, тестирование, Git и базовые принципы разработки. Итогом станет портфолио из нескольких проектов и уверенность для прохождения собеседований на Junior-позиции.

1. Установка, среда разработки и первые программы

Установка, среда разработки и первые программы

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

Что такое Python и как он запускает ваш код

Python — это язык программирования и одновременно набор инструментов (интерпретатор и стандартная библиотека), которые выполняют ваш код.

Обычно вы пишете программу в файле с расширением *.py, а затем запускаете её командой python имя_файла.py.

!Схема показывает путь от файла с кодом до результата в терминале

Установка Python

Наша цель — поставить актуальный Python 3 и убедиться, что команда python (или python3) работает в терминале.

Windows

  • Скачайте установщик с сайта Python Downloads.
  • Запустите установщик.
  • Перед установкой поставьте галочку Add python.exe to PATH (важно, чтобы python работал из терминала).
  • Завершите установку.
  • Откройте PowerShell и проверьте:
  • Если команда не найдена, обычно проблема в PATH. В таком случае проще всего переустановить Python, не забыв включить добавление в PATH.

    macOS

  • Скачайте установщик с сайта Python Downloads.
  • Установите Python (обычно это пакет *.pkg).
  • Откройте Terminal и проверьте:
  • На macOS часто используется команда python3, потому что python может указывать на системный Python (или отсутствовать).

    Linux

    На большинстве Linux Python уже установлен, но версия может быть не самой новой.

  • Откройте терминал и проверьте:
  • Если Python 3 не установлен — установите через пакетный менеджер вашей системы (в рамках курса не фиксируем одну команду, потому что дистрибутивы отличаются).
  • Проверка установки: интерпретатор, pip и путь к Python

    Проверка интерпретатора

    Проверьте версию:

    или:

    Проверка pip

    pip — это менеджер пакетов Python: с его помощью вы устанавливаете сторонние библиотеки.

    Проверьте:

    Если у вас используется python3, то:

    Почему команда именно такая: запуск через python -m pip гарантирует, что pip относится именно к этому Python, а не к другому, установленному в системе.

    Узнать, какой Python запускается

    Иногда в системе несколько Python. Полезно проверить путь:

    Выбор среды разработки

    Вам нужен редактор кода и терминал. Ниже — два популярных варианта.

    | Среда | Когда подходит | Плюсы | Минусы | |---|---|---|---| | Visual Studio Code | Почти всем, особенно на старте | Быстрый, много расширений, удобно работать с Git и терминалом | Нужно поставить расширение Python и немного настроить | | PyCharm Community Edition | Тем, кто хочет максимально «всё из коробки» | Сильная поддержка Python-проектов, удобная навигация | Требовательнее к ресурсам, иногда «тяжелее» для простых задач |

    Для курса можно выбрать любой вариант. Важно: вы должны уметь запускать код и видеть ошибки.

    Проект и папки: как организовать первые файлы

    Создайте папку, например python-course, а внутри — папку для урока, например lesson-01.

    Рекомендуемая структура:

    Файл main.py — это ваша первая программа.

    Виртуальное окружение

    Виртуальное окружение — это отдельная «песочница» для библиотек конкретного проекта. Оно помогает избежать конфликтов версий и путаницы между проектами.

    Создание виртуального окружения (внутри папки проекта, например lesson-01):

    Активация:

  • Windows (PowerShell):
  • macOS/Linux:
  • После активации в терминале обычно появляется пометка окружения (например, .venv).

    Деактивация:

    Официальная справка: venv — Creation of virtual environments

    Первая программа: Hello, world

    Откройте main.py и напишите:

    Запуск из терминала (в папке lesson-01):

    Если у вас используется python3:

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

  • print(...) — выводит текст в терминал.
  • Строка в кавычках — это текст, который вы выводите.
  • Программа с вводом данных

    Сделаем программу, которая спрашивает имя и здоровается:

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

  • input(...) всегда возвращает строку.
  • Запятая в print("Привет,", name) печатает слова через пробел.
  • Калькулятор на минималках (и типичная ошибка новичка)

    Попробуем сложить два числа:

    Это почти наверняка даст не сумму, а склеивание строк. Например, 2 и 3 превратятся в 23.

    Правильный вариант:

    Здесь:

  • int(...) преобразует строку в целое число.
  • Если пользователь введёт не число, Python покажет ошибку. Позже вы научитесь обрабатывать такие ситуации.
  • Как читать ошибки (traceback)

    Ошибки — нормальная часть разработки. Python обычно показывает:

  • тип ошибки (например, SyntaxError, NameError, ValueError)
  • файл и строку, где ошибка произошла
  • фрагмент проблемного кода
  • Пример частой ошибки:

    Если hello не определено, будет NameError. Исправление — использовать строку:

    Режим REPL: быстрые проверки

    REPL — это интерактивный режим Python, где можно быстро проверить выражения.

    Запуск:

    Выход:

  • Windows: Ctrl+Z, затем Enter
  • macOS/Linux: Ctrl+D
  • REPL полезен, чтобы быстро проверить идею, но основной код курса вы будете писать в файлах.

    Полезные правила на старте

  • Всегда создавайте отдельную папку под проект и храните код в *.py файлах.
  • Используйте виртуальное окружение .venv для каждого проекта.
  • Запускайте pip через python -m pip, чтобы не перепутать версии.
  • Если что-то не работает, сначала проверьте python --version, затем путь к интерпретатору.
  • Что дальше

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

    2. Базовый синтаксис: типы данных, условия, циклы

    Базовый синтаксис: типы данных, условия, циклы

    На прошлом уроке вы установили Python, научились запускать .py файлы и уже использовали print() и input(). Теперь разберём основу, без которой невозможно писать реальные программы: типы данных, условия и циклы*.

    Как Python читает вашу программу

    Python выполняет код сверху вниз, строка за строкой. Управлять этим порядком позволяют:

  • условия if (выполнить код только если истинно)
  • циклы while и for (выполнять код много раз)
  • Ключевая особенность Python — блоки кода задаются отступами. Обычно используется 4 пробела.

    !Иллюстрация показывает, как условия и циклы меняют порядок выполнения кода

    Переменные и присваивание

    Переменная — это имя, которое ссылается на значение.

    Правила, которые важно запомнить:

  • имя переменной может содержать буквы, цифры и _, но не может начинаться с цифры
  • регистр важен: name и Name — разные переменные
  • в Python тип хранится у значения, а не “приклеен” к имени переменной
  • Быстрый взгляд на тип значения

    Документация: Встроенные функции Python (type)

    Базовые типы данных

    Числа: int и float

  • int — целые числа: -2, 0, 15
  • float — числа с точкой: 3.14, -0.5
  • Полезный случай a % b: проверка чётности.

    Строки: str

    Строка — это текст в кавычках.

    Частые операции:

  • конкатенация: "a" + "b"
  • повторение: "ha" * 3
  • длина: len("привет")
  • Документация: Встроенные типы (str)

    Логический тип: bool

    bool имеет два значения: True и False. Он получается из сравнений и логических операций.

    Специальное значение: None

    None означает “нет значения”. Это полезно, когда значение пока неизвестно или отсутствует.

    Ввод данных и преобразование типов

    Вы уже видели, что input() возвращает строку.

    Чтобы получить число:

    Важно:

  • int("12") работает
  • int("12.5") вызовет ошибку ValueError
  • float("12.5") работает
  • Условия: if, elif, else

    Условие выполняет блок кода, только если выражение истинно.

    Если веток больше двух, используйте elif.

    Что считается истинным и ложным

    В Python в условии можно писать не только == True. Многие значения сами по себе трактуются как “истина/ложь”.

    Ложными считаются:

  • 0, 0.0
  • пустая строка ""
  • пустые коллекции (например, [], {})
  • None
  • Пример:

    Цикл while

    while повторяет блок, пока условие истинно.

    Типичная ошибка новичка — забыть изменить переменную, из-за чего цикл станет бесконечным.

    break и continue

  • break — выйти из цикла
  • continue — перейти к следующей итерации
  • Цикл for и range()

    for в Python обычно используют для перебора последовательностей.

    Повторить N раз

    range(5) создаёт последовательность чисел 0, 1, 2, 3, 4.

    Частые формы:

  • range(stop)
  • range(start, stop)
  • range(start, stop, step)
  • Документация: Встроенные функции Python (range)

    Перебор строки

    Строка — это последовательность символов.

    Практический мини-пример: сумма чисел

    Задача: посчитать сумму чисел от 1 до n.

    Вариант с while:

    Вариант с for:

    Частые ошибки и как их чинить

  • SyntaxError из-за двоеточия: после if, elif, else, for, while обязательно ставится :
  • ошибки из-за отступов: в одном блоке используйте одинаковые отступы (обычно 4 пробела)
  • сравнение вместо присваивания: = — присваивание, == — сравнение
  • “склейка строк” вместо сложения чисел: помните, что input() даёт str, и используйте int() или float()
  • Что дальше

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

    3. Функции, модули и работа с исключениями

    Функции, модули и работа с исключениями

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

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

    !Как связаны функции, модули и исключения в одном сценарии

    Функции

    Функция — это именованный блок кода, который можно вызывать многократно. Функции помогают:

  • не повторять одинаковый код
  • делать программу понятнее
  • легче тестировать и исправлять ошибки
  • Документация: Функции в Python (def)

    Объявление и вызов функции

    Простейшая функция:

    Что важно:

  • def объявляет функцию
  • после имени функции идут скобки ()
  • тело функции — это блок с отступом
  • чтобы выполнить функцию, её нужно вызвать по имени
  • Параметры: как передавать данные в функцию

    Функция может принимать параметры (входные данные):

    Если параметров несколько:

    return: как вернуть результат

    Если функция должна вернуть значение, используйте return:

    Если return не указан, функция возвращает None.

    Идея простая:

  • print() показывает текст пользователю
  • return отдаёт значение обратно в код, чтобы его можно было использовать дальше
  • Локальные переменные и область видимости

    Переменные, созданные внутри функции, обычно не видны снаружи:

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

    Значения по умолчанию

    Можно задавать значения по умолчанию для параметров:

    Докстроки: как документировать функцию

    Докстрока — это строка в начале функции, которая описывает, что функция делает:

    Документация: Докстроки (PEP 257)

    Практический пример: вынесем повторяющуюся логику

    Допустим, вы хотите несколько раз безопасно читать число из ввода. Пока мы не умеем обрабатывать ошибки — сделаем версию без защиты:

    В следующем разделе вы научитесь делать этот код устойчивым к неправильному вводу.

    Модули

    Модуль — это обычный файл *.py, который можно подключать в другие файлы с помощью import.

    Документация: Модули

    Зачем нужны модули

    Модули нужны, чтобы:

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

    Python поставляется со стандартной библиотекой. Например, модуль math:

    Документация: Модуль math

    Импорт своих модулей

    Представим структуру:

    utils.py:

    main.py:

    Важно:

  • импортируется имя файла без .py
  • обращаться к функциям нужно через utils.is_even(...)
  • from ... import ... и псевдонимы

    Можно импортировать конкретные имена:

    Можно задавать псевдоним через as:

    Почему нужен if __name__ == "__main__"

    Если файл является точкой входа (вы запускаете его напрямую), часто используют такую конструкцию:

    Смысл:

  • при запуске python main.py условие истинно и main() вызывается
  • если этот файл импортируют как модуль, main() автоматически не запускается
  • Документация: Специальные переменные модуля (__name__)

    Сторонние пакеты и pip

    Ранее вы познакомились с pip и виртуальным окружением. Напоминание:

  • ставьте пакеты в активированное виртуальное окружение
  • используйте python -m pip ..., чтобы не перепутать версии Python
  • Документация: pip — установщик пакетов Python

    Исключения

    Исключение — это механизм Python для сообщения об ошибке во время выполнения программы. Когда возникает ошибка (например, неправильный ввод), Python:

  • создаёт объект исключения
  • прерывает обычный ход выполнения
  • показывает traceback, если исключение не обработано
  • Документация: Ошибки и исключения

    Пример: где возникает ValueError

    Если пользователь введёт не число:

    то int(...) может вызвать ValueError.

    try и except: перехват ошибки

    Чтобы программа не падала, используйте try/except:

    Как это читать:

  • в блоке try мы пишем код, где может случиться ошибка
  • в except ValueError мы описываем, что делать, если случилась именно эта ошибка
  • Несколько except

    Можно обрабатывать разные ошибки по-разному:

    Документация: Встроенные исключения

    else и finally

  • else выполняется, если в try не было ошибки
  • finally выполняется всегда (обычно для освобождения ресурсов)
  • raise: как намеренно создать ошибку

    Иногда вы хотите сами остановить выполнение, если данные неправильные:

    Обратите внимание на as e: так вы получаете текст ошибки.

    Собираем всё вместе: функция безопасного ввода числа

    Вернёмся к идее вынести ввод в функцию, но теперь сделаем её устойчивой к ошибкам:

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

  • цикл while True повторяет попытки
  • return завершает функцию сразу, как только ввод корректный
  • except не даёт программе упасть и объясняет пользователю, что делать
  • Типичные ошибки при работе с исключениями

  • ловить слишком общее исключение без необходимости
  • перехватывать исключение и молча его игнорировать
  • Практическое правило: ловите конкретные ошибки и сообщайте понятное сообщение или исправляйте ситуацию.

    Что дальше

    Теперь вы умеете:

  • превращать повторяющиеся фрагменты в функции
  • выносить код в отдельные модули и подключать их через импорт
  • обрабатывать ошибки ввода и другие проблемы через исключения
  • Дальше этот фундамент пригодится для более сложных тем: коллекций (списки, словари), работы с файлами, тестирования и небольших проектов, где структура кода и обработка ошибок становятся критически важными.

    4. Коллекции и алгоритмическое мышление на практике

    Коллекции и алгоритмическое мышление на практике

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

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

    !Сравнение основных коллекций Python и их типичных применений

    Что такое коллекции и зачем они нужны

    Коллекция — это объект, который хранит несколько значений.

    Самые популярные встроенные коллекции в Python:

  • list (список): упорядоченная изменяемая последовательность.
  • tuple (кортеж): упорядоченная неизменяемая последовательность.
  • dict (словарь): отображение ключ → значение.
  • set (множество): набор уникальных элементов без порядка.
  • Официальная документация по типам:

  • Встроенные типы данных (Python)
  • Список (list)

    Список подходит, когда важен порядок и элементы могут повторяться.

    Создание и доступ по индексу

    Важно:

  • индексация начинается с 0
  • отрицательный индекс идёт с конца (-1 — последний элемент)
  • Добавление, удаление, длина

    Полезные методы (и что они делают):

  • append(x) добавляет элемент в конец
  • pop() удаляет и возвращает последний элемент (или по индексу pop(i))
  • remove(x) удаляет первое вхождение значения
  • sort() сортирует список на месте
  • Документация: Тип list

    Перебор списка

    Если нужен индекс:

    Документация: Встроенная функция enumerate

    Кортеж (tuple)

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

    Частый кейс: вернуть из функции сразу несколько значений.

    Документация: Тип tuple

    Словарь (dict)

    Словарь — это структура ключ → значение. Он незаменим, когда нужно быстро находить данные по ключу.

    Создание и чтение

    Правила, которые важно запомнить:

  • ключи в словаре уникальны
  • если обратиться к отсутствующему ключу через user["city"], будет KeyError
  • Документация: Тип dict

    Безопасное чтение: get

    Если ключ может отсутствовать, удобнее использовать get:

    Добавление и обновление

    Перебор словаря

    Множество (set)

    Множество хранит уникальные элементы. Обычно используют, чтобы:

  • убрать дубликаты
  • быстро проверять принадлежность элемента
  • Важно: порядок элементов в set не фиксирован.

    Документация: Тип set

    Как выбрать коллекцию под задачу

    | Задача | Подходящая коллекция | Почему | |---|---|---| | Хранить элементы по порядку, дополнять, удалять | list | порядок + изменяемость | | Хранить фиксированный набор значений | tuple | неизменяемость, удобно передавать/возвращать | | Быстро получать значение по ключу | dict | доступ по ключу, удобно хранить пары | | Убрать дубликаты, проверять принадлежность | set | уникальность и быстрый in |

    Алгоритмическое мышление: как решать задачи на коллекциях

    Алгоритмическое мышление — это умение превращать задачу в последовательность простых шагов и выбирать подходящие структуры данных.

    Полезный шаблон:

  • Чётко сформулировать входные данные и ожидаемый результат.
  • Выбрать коллекцию(и), которая делает решение простым.
  • Разбить на шаги: чтение → обработка → вывод.
  • Написать решение в виде функций.
  • Добавить обработку ошибок (если есть ввод пользователя).
  • Ниже — несколько типовых задач, которые встречаются постоянно.

    Практика: частотный словарь (подсчёт повторений)

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

    Идея:

  • Завести пустой словарь counts.
  • Для каждого слова увеличивать счётчик.
  • Почему это хороший алгоритм:

  • один проход по данным
  • структура dict идеально подходит для хранения ключ → счётчик
  • Практика: уникальные значения и фильтрация

    Задача: из списка email оставить только уникальные.

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

    Практика: поиск минимума/максимума и «лучшего кандидата»

    Задача: найти самое длинное слово.

    Здесь тренируется важная идея: держать текущий лучший результат и обновлять его по условию.

    Сортировка и параметр key

    Очень частая реальная операция — сортировка по «чему-то».

    Пример: отсортировать список слов по длине.

    Или получить новый отсортированный список, не меняя исходный:

    Документация:

  • Функция sorted
  • Метод list.sort
  • Ошибки и исключения при работе с коллекциями

    Коллекции часто приводят к типовым ошибкам. Хорошая новость: большинство из них предсказуемы.

    KeyError в словаре

    Плохо (может упасть):

    Хорошо (безопасно):

    Если по логике программы отсутствие ключа — это ошибка, можно обработать через try/except:

    IndexError в списке

    Ошибка возникает, если индекс выходит за границы.

    Обычно это чинится проверкой len(items) или правильной логикой цикла.

    Простая «оценка скорости» без сложной математики

    На уровне начинающего достаточно понимать 3 идеи:

  • один цикл по списку — обычно нормально даже для больших данных
  • вложенные циклы по большим спискам быстро становятся медленными
  • проверка x in list обычно требует перебора (медленнее), а x in set — обычно быстрее
  • Практический вывод:

  • для поиска по ключу выбирайте dict
  • для проверки принадлежности выбирайте set
  • для упорядоченных данных выбирайте list
  • Как писать «по-взрослому»: функции + коллекции + модули

    Коллекции почти всегда живут вместе с функциями:

  • функция получает коллекцию
  • возвращает результат (число, строку, новую коллекцию)
  • внутри использует цикл и условия
  • Пример: вынесем подсчёт частот в функцию.

    Дальше это можно вынести в отдельный модуль text_utils.py и импортировать в main.py — ровно как вы делали в уроке про модули.

    Что дальше

    Теперь вы умеете выбирать и применять коллекции под разные задачи, а главное — решать типовые задачи через понятный алгоритм: пройтись по данным, накопить результат (в списке, словаре или множестве) и корректно обработать ошибки.

    Следующий шаг к уровню Junior — закреплять это на мини-проектах и подключать новые темы (работа с файлами, тестирование, основы ООП), где коллекции используются постоянно.

    5. ООП в Python: классы, наследование, композиция

    ООП в Python: классы, наследование, композиция

    На прошлых уроках вы научились писать программы с условиями и циклами, оформлять повторяющуюся логику в функции, разносить код по модулям, использовать исключения и хранить данные в коллекциях. Следующий шаг к уровню Junior — освоить объектно-ориентированное программирование (ООП).

    ООП помогает собирать программу из понятных «кирпичиков»: объектов, которые хранят состояние (данные) и умеют что-то делать (методы). Это особенно полезно, когда проект растёт: появляется больше сущностей, правил и связей.

    Документация: Учебник Python: классы

    Зачем нужно ООП

    ООП обычно используют, когда:

  • в задаче есть сущности с данными и поведением (пользователь, заказ, товар)
  • нужно ограничить доступ к внутренним деталям и защититься от неправильных состояний
  • хочется переиспользовать и расширять код без бесконечных if/elif
  • важна тестируемость и возможность «подменять» части системы
  • Важно: ООП — это инструмент, а не обязательное правило. Многие задачи отлично решаются функциями и словарями. ООП полезно там, где оно упрощает модель предметной области.

    Основные понятия

  • Класс — «чертёж» (шаблон), по которому создаются объекты.
  • Объект (экземпляр) — конкретная созданная сущность.
  • Атрибут — переменная, принадлежащая объекту или классу.
  • Метод — функция, принадлежащая классу (и вызываемая у объекта).
  • !Иллюстрация связи: один класс порождает множество объектов

    Классы и объекты

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

    Что здесь важно:

  • class User: объявляет класс
  • User() создаёт объект (экземпляр)
  • u.greet() вызывает метод у объекта
  • Конструктор __init__ и атрибуты

    Чаще всего объекту нужно начальное состояние. Для этого используют __init__.

    Ключевые идеи:

  • __init__ вызывается при создании объекта
  • self — ссылка на текущий объект
  • self.name и self.age — атрибуты объекта
  • self: почему он нужен

    Метод — это функция, которая работает с конкретным объектом. Чтобы метод мог читать и менять данные объекта, Python передаёт этот объект первым аргументом. По соглашению его называют self.

    Атрибуты объекта и атрибуты класса

    Иногда данные общие для всех объектов. Это атрибуты класса.

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

  • если значение относится к каждому конкретному объекту — делайте атрибут объекта
  • если значение общее для всех — делайте атрибут класса
  • Методы и полезные магические методы

    Обычные методы

    Обычный метод получает self и работает с состоянием объекта.

    __str__ и __repr__

    Эти методы помогают красиво выводить объект.

    Документация: Модель данных Python (специальные методы)

    Инкапсуляция и валидация состояния

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

  • атрибуты, начинающиеся с _, считаются внутренними и не предназначены для прямого использования
  • для контроля чтения и записи часто используют property
  • Пример: защита возраста

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

  • снаружи вы работаете как обычно: u.age
  • внутри можно проверять и защищать состояние
  • Документация: property

    Наследование

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

    Пример: базовый класс и расширение

    Ключевые идеи:

  • class Child(Parent): создаёт наследника
  • super().__init__(...) вызывает конструктор родителя
  • переопределение метода (как final_price) — основа полиморфизма: одинаковый вызов даёт разное поведение в зависимости от типа объекта
  • !Дерево наследования и что общее/что различается

    Когда наследование уместно

    Наследование хорошо работает, когда:

  • связь действительно «является»: PhysicalProduct является Product
  • базовый класс задаёт общий контракт поведения (например, final_price)
  • Осторожно с наследованием:

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

    Композиция — это подход, когда объект содержит другие объекты и делегирует им часть работы. Это связь «имеет»: Order имеет список товаров, Order имеет политику скидок.

    Пример: заказ, товары и политика скидки

    Почему это сильный пример:

  • Order не знает, как именно считать скидку, он делегирует это объекту политики
  • скидку можно легко заменить: Order(NoDiscount())
  • код расширяется добавлением новых политик без переписывания Order
  • Композиция тесно связана с тем, что вы уже знаете:

  • Order.items — это список (коллекции)
  • sum(...) и генераторы — это удобный способ обработать коллекцию
  • объекты можно хранить в списках и словарях как обычные значения
  • Наследование или композиция: как выбрать

    | Ситуация | Чаще подходит | Почему | |---|---|---| | «X является Y» и нужен общий контракт поведения | наследование | общий базовый API, переопределение методов | | «X имеет Y» и нужно легко подменять часть логики | композиция | меньше связности, проще расширять | | Хочется избежать глубоких иерархий | композиция | упрощает поддержку |

    Практическое правило: если сомневаетесь, начните с композиции. Наследование добавляйте тогда, когда связь «является» очевидна и даёт реальную пользу.

    Как это связывается с функциями, модулями и исключениями

  • методы класса — это те же функции, просто сгруппированные вокруг данных
  • классы удобно раскладывать по модулям: models.py, services.py, utils.py
  • исключения по-прежнему основной способ сигнализировать об ошибках: например, ValueError в сеттере age
  • Структура маленького проекта может выглядеть так:

    main.py импортирует классы и собирает сценарий программы, как вы делали раньше с модулями.

    Что дальше

    Теперь у вас есть основа ООП:

  • вы умеете создавать классы и объекты, определять атрибуты и методы
  • понимаете, как работает наследование, super() и переопределение
  • знаете композицию и почему она часто делает код гибче
  • Следующий практический шаг — закреплять ООП на мини-проектах (консольный магазин, трекер задач, простой менеджер заметок) и добавлять темы, которые часто идут рядом с ООП: работа с файлами, тестирование, основы проектирования.

    6. Файлы, JSON, HTTP-запросы и работа с API

    Файлы, JSON, HTTP-запросы и работа с API

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

  • читать и записывать файлы (тексты, настройки, данные)
  • работать с форматом JSON (самый популярный формат обмена данными)
  • делать HTTP-запросы и получать ответы от API
  • аккуратно обрабатывать ошибки: неправильные данные, отсутствие файла, сетевые проблемы
  • !Схема, как данные проходят путь: файл → Python → HTTP API → JSON → файл

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

    Файл на диске можно представить как последовательность байт. В Python чаще всего работают в двух режимах:

  • текстовый режим (строки str, нужна кодировка)
  • бинарный режим (байты bytes, используют для изображений, архивов)
  • В этом уроке сфокусируемся на текстовых файлах.

    Открытие файла и контекстный менеджер with

    Базовая функция для работы с файлами — open(). Почти всегда открывайте файл через with: так файл гарантированно закроется, даже если произошла ошибка.

    Документация: open

    Чтение всего файла целиком:

    Что означают аргументы:

  • "notes.txt" — путь к файлу
  • "r" — режим чтения (read)
  • encoding="utf-8" — кодировка текста (в большинстве проектов используйте UTF-8)
  • Режимы открытия файла

    Чаще всего используются:

  • "r" — чтение (файл должен существовать)
  • "w" — запись (создаст файл заново или перезапишет существующий)
  • "a" — дозапись в конец файла
  • "r+" — чтение и запись
  • Чтение построчно

    Если файл большой, удобнее читать по строкам.

    Почему используется rstrip("\n"):

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

    Запись с перезаписью:

    Дозапись:

    Типичные ошибки при работе с файлами

  • FileNotFoundError — файл не найден
  • PermissionError — нет прав на чтение/запись
  • ошибки кодировки, если открыть файл не в той кодировке
  • Пример безопасного чтения:

    Здесь вы применяете то, что изучали раньше:

  • функция возвращает результат через return
  • ошибка не «роняет» программу, потому что мы обработали исключение
  • Пути к файлам и pathlib

    Чтобы писать переносимый код, удобно работать с путями через pathlib.

    Документация: pathlib

    Полезный момент:

  • оператор / у Path не делит, а «склеивает» части пути корректно для вашей ОС
  • JSON: чтение и запись структурированных данных

    JSON (JavaScript Object Notation) — формат данных, который выглядит похоже на словари и списки Python. В API чаще всего возвращают именно JSON.

    В JSON есть основные типы:

  • объект (object) — похоже на dict
  • массив (array) — похоже на list
  • строка, число, булево (true/false), null
  • В Python JSON обрабатывается модулем json из стандартной библиотеки.

    Документация: json

    Преобразование JSON-строки в объекты Python

    json.loads() берёт строку и превращает её в dict/list.

    Преобразование объектов Python в JSON-строку

    json.dumps() превращает dict/list в строку JSON.

    Что дают параметры:

  • ensure_ascii=False — чтобы кириллица не превращалась в \u041f...
  • indent=2 — красивое форматирование
  • Чтение и запись JSON-файлов

    json.load() читает JSON из файла, а json.dump() записывает JSON в файл.

    Частая проблема: не все объекты сериализуются

    JSON не умеет напрямую хранить, например, set или Path. Поэтому перед записью их обычно преобразуют:

  • setlist
  • Pathstr
  • HTTP и API: как это работает

    HTTP — протокол, по которому клиент (ваша программа) общается с сервером.

    API — интерфейс, который сервер предоставляет для получения/отправки данных. Обычно это URL-адреса (эндпоинты), на которые можно делать HTTP-запросы.

    Частые HTTP-методы

  • GET — получить данные
  • POST — создать данные
  • PUT/PATCH — обновить данные
  • DELETE — удалить данные
  • Статус-коды ответа

  • 200 — успех
  • 201 — создано (часто после POST)
  • 400 — ошибка клиента (неправильные параметры)
  • 401/403 — нет доступа
  • 404 — не найдено
  • 500 — ошибка сервера
  • !Схема запроса и ответа: что отправляем и что получаем

    HTTP-запросы в Python: requests

    В стандартной библиотеке есть urllib.request, но в реальных проектах очень часто используют библиотеку requests, потому что она проще для новичка.

    Документация: Requests

    Установка (в активированном виртуальном окружении):

    Простой GET и разбор JSON

    Возьмём учебный публичный API JSONPlaceholder.

    Что здесь важно:

  • timeout=10 защищает от бесконечного ожидания
  • resp.json() удобнее, чем вручную делать json.loads(resp.text)
  • Параметры запроса (params)

    Query-параметры удобно передавать словарём.

    POST с JSON-телом (json=)

    Параметр json= делает две вещи:

  • сериализует словарь в JSON
  • ставит корректный заголовок Content-Type: application/json
  • Надёжность: ошибки сети и проверка ответа

    Сетевой код почти всегда должен учитывать ошибки:

  • нет интернета
  • сервер не отвечает
  • сервер вернул неуспешный статус
  • пришёл не JSON
  • Обработка сетевых исключений

    У requests есть общий тип исключений RequestException.

    Почему полезен raise_for_status():

  • вам не нужно вручную проверять status_code каждый раз
  • логика ошибки становится явной и попадает в except
  • Практический шаблон: маленький клиент для API

    Ниже пример, который связывает темы курса:

  • модульность: вынесем API-код в отдельный файл
  • функции: сделаем понятные функции
  • исключения: аккуратно обработаем проблемы
  • коллекции: используем list/dict из JSON
  • Структура:

    api_client.py:

    storage.py:

    main.py:

    Обратите внимание на важные «джуновские» привычки:

  • функции маленькие и делают одно понятное действие
  • модули разделяют ответственность: сеть отдельно, хранение отдельно
  • сетевые ошибки не валят программу
  • данные из JSON обрабатываются как обычные коллекции
  • Если хочется сделать это через ООП

    Когда логики и настроек становится много, удобно обернуть работу с API в класс.

    Это продолжение темы ООП:

  • состояние клиента (base_url, timeout) хранится в объекте
  • методы используют это состояние
  • Что дальше

    Теперь вы умеете:

  • читать и записывать файлы через with open(...)
  • сохранять и загружать структурированные данные в JSON
  • делать HTTP-запросы, передавать параметры и JSON-тело
  • обрабатывать типичные ошибки сети и HTTP-ответов
  • Следующий логичный шаг для уровня Junior — закреплять эти навыки на мини-проектах: консольный клиент к API, утилита, которая скачивает данные и строит отчёт, простое приложение с хранением данных в JSON и синхронизацией с сервером.

    7. Инструменты джуна: Git, тестирование, стиль кода и проекты

    Инструменты джуна: Git, тестирование, стиль кода и проекты

    До этого вы учились писать рабочий код: функции, модули, исключения, коллекции, ООП, файлы, JSON и HTTP-запросы. На уровне Junior от вас ждут не только чтобы код работал, но и чтобы вы умели:

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

    Git: контроль версий как стандарт индустрии

    Git — система контроля версий. Она хранит историю изменений, позволяет откатываться, вести разработку параллельно (ветки) и безопасно объединять изменения.

    Официальные ресурсы:

  • Git
  • Git Documentation
  • Базовая модель Git

  • working directory — ваши файлы в папке проекта
  • staging area — “корзина” изменений, которые пойдут в коммит
  • repository — история коммитов
  • !Схема пути изменений: файлы → staging → коммит → удалённый репозиторий

    Инициализация репозитория и первый коммит

  • Создайте репозиторий:
  • Проверьте статус:
  • Добавьте файлы в staging:
  • Создайте коммит:
  • Коммиты: как писать полезную историю

    Коммит — это “атомарная” порция изменений.

    Практические правила:

  • один коммит — одна логическая задача
  • сообщение коммита отвечает на вопрос что сделано
  • не коммитьте мусор: временные файлы, секреты, большие бинарники
  • Пример понятных сообщений:

  • Add safe integer input helper
  • Fix JSON serialization for Path
  • Add tests for discount policy
  • .gitignore: что не должно попадать в репозиторий

    В Python-проектах обычно игнорируют:

  • виртуальное окружение .venv/
  • кеш Python __pycache__/
  • файлы окружения .env
  • Пример .gitignore:

    Ветки: параллельная разработка

    Ветка — отдельная линия истории.

    Базовый сценарий:

  • main — стабильная ветка
  • feature-ветки — для задач (например, feature/add-api-client)
  • Команды:

    Чтобы объединить feature-ветку в main:

    Если возник конфликт, Git попросит вручную выбрать правильный вариант. Конфликты — нормальная часть командной работы.

    Удалённый репозиторий: GitHub и повседневный цикл

    Обычно удалённый репозиторий называется origin.

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

    Отправить изменения:

    Забрать изменения:

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

  • создаёте feature-ветку
  • пушите её в origin
  • открываете Pull Request
  • проходите ревью и тесты
  • мёржите в main
  • Справка по Pull Request на GitHub:

  • About pull requests
  • Тестирование: как быстро проверять корректность кода

    Тесты помогают:

  • ловить баги до пользователей
  • уверенно менять код (рефакторинг)
  • фиксировать ожидаемое поведение
  • Для Python-де-факто стандарт — pytest.

  • pytest documentation
  • Что такое unit-тест

    Unit-тест проверяет маленькую часть логики: функцию или метод.

    Если вы писали функции в прошлых уроках (например, count_words, read_int, final_price), то большинство из них можно покрывать unit-тестами.

    Установка pytest

    В активированном виртуальном окружении:

    Запуск:

    Минимальная структура с тестами

    Обычно тесты кладут в папку tests/.

    Пример:

    Файл src/utils.py:

    Файл tests/test_utils.py:

    Ключевая идея: тест — это обычная функция, которая делает assert.

    Параметризация: меньше копипаста

    Если нужно проверить много входов, используйте параметризацию.

    Проверка исключений

    В прошлых уроках вы поднимали ошибки через raise ValueError(...). Это удобно тестировать.

    Что тестировать в учебных проектах

  • Чистые функции, которые:
  • принимают данные
  • возвращают результат
  • не ходят в сеть
  • не читают файлы напрямую
  • Код с файлами и HTTP лучше проектировать так, чтобы его можно было тестировать отдельно:
  • функции, которые парсят JSON, тестируются без сети
  • функции, которые считают отчёт, тестируются на подготовленных list/dict
  • Стиль кода: читаемость, PEP 8 и автоинструменты

    В реальной разработке ваш код читают чаще, чем пишут. Поэтому стиль — это не “красота”, а снижение стоимости поддержки.

    PEP 8: базовые правила

    PEP 8 — основной гайд по стилю Python.

  • PEP 8
  • Короткий минимум, который надо соблюдать:

  • отступы: 4 пробела
  • имена функций и переменных: snake_case
  • имена классов: PascalCase
  • длина строки: часто ориентируются на 88–120 символов (зависит от команды)
  • понятные имена важнее коротких
  • Type hints: подсказки типов для читаемости

    Аннотации типов помогают:

  • быстрее понимать код
  • ловить часть ошибок статически
  • улучшать автодополнение в IDE
  • Документация:

  • Typing — Support for type hints
  • Пример:

    Если хочется проверять типы автоматически, используйте mypy:

  • mypy
  • Автоформатирование и линтинг

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

  • Black — автоформаттер (делает код единообразным)
  • Black
  • Установка и запуск:

  • Ruff — быстрый линтер (находит ошибки и плохие практики)
  • Ruff
  • Установка и запуск:

    Практический эффект для Junior:

  • меньше замечаний на ревью
  • быстрее учитесь хорошим практикам
  • проще поддерживать качество по мере роста проекта
  • Проектное оформление: как сделать работу “как на настоящей разработке”

    Умение упаковать код в понятный проект — важный критерий уровня Junior.

    Минимальная структура Python-проекта

    Один из удобных вариантов для учебных проектов:

    !Пример структуры небольшого Python-проекта с кодом и тестами

    Почему так удобно:

  • src/ отделяет код от остального
  • tests/ рядом и понятно, где проверки
  • README.md объясняет, как запустить
  • requirements.txt фиксирует зависимости
  • README: что обязательно написать

    README.md должен позволять другому человеку запустить проект.

    Минимальный набор:

  • что делает проект (1–3 предложения)
  • требования: версия Python
  • как установить зависимости
  • как запустить
  • как прогнать тесты
  • Пример содержания (без привязки к конкретной теме):

    requirements.txt: зависимости

    Если вы использовали requests, pytest, ruff, black, их нужно зафиксировать.

    Пример requirements.txt:

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

    Точка входа и аккуратный main

    Хорошая привычка: делать точку входа через main().

    Так ваш код:

  • можно импортировать в тестах
  • не запускается сам по себе при импорте
  • Мини-проекты, которые хорошо смотрятся в портфолио

    Ниже идеи, которые напрямую используют темы курса.

  • Консольный трекер задач
  • - хранение задач в JSON-файле - функции для CRUD-операций - тесты на бизнес-логику

  • Клиент к публичному API
  • - requests + обработка ошибок - сохранение результата в файл - отчёт по данным (агрегации списков/словарей)

  • Мини-магазин
  • - товары и заказ через ООП - скидки через композицию - тесты на расчёт итоговой цены

    Критерий “как у Junior”: проект должен быть небольшим, но аккуратно оформленным и проверяемым.

    Как связать все инструменты в один рабочий процесс

    Ниже реалистичный цикл разработки фичи на учебном проекте.

  • Создайте ветку под задачу:
  • Реализуйте код небольшими шагами, делайте коммиты.
  • Запустите форматирование и линтинг:
  • Прогоните тесты:
  • Запушьте ветку и откройте Pull Request (если ведёте проект на GitHub).
  • Такой процесс показывает, что вы умеете работать по стандартам индустрии, а не просто писать “скрипты”.

    Что дальше

    После этого урока у вас есть важный набор “инструментов джуна”:

  • Git как базовый способ работы с историей и командой
  • pytest как способ подтверждать корректность
  • стиль кода через PEP 8 и автоинструменты
  • оформление проекта так, чтобы его можно было запускать и проверять
  • Дальше лучший путь — взять 1–2 мини-проекта из идей выше и довести их до состояния: чистая структура, README, зависимости, тесты и аккуратная история в Git.