Что можно написать на Python: идеи проектов с кодом для новичка и среднего уровня

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

Что можно написать на Python после основ: скрипт, который разбирает папку «Загрузки», отчёт по своим расходам, парсер цен, телеграм-бота, веб-приложение с API и небольшую игру. У каждого из шести проектов есть список библиотек, минимальный рабочий код и вывод, который этот код дал у нас на Python 3.14.3 под Windows 10.

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

Идея проекта Уровень Библиотеки
Сортировка файлов новичок pathlib, shutil (стандартная библиотека)
Анализ расходов новичок pandas
Парсер сайта новичок requests, beautifulsoup4
Телеграм-бот средний aiogram
Веб-приложение средний fastapi, uvicorn
Игра средний pygame-ce

С чего начать: окружение и библиотеки

Для каждого проекта заведите отдельный каталог и виртуальное окружение: python -m venv .venv, затем .venv\Scripts\activate в Windows или source .venv/bin/activate в Linux и macOS. Библиотеки ставьте тем интерпретатором, который будет запускать код: python -m pip install requests beautifulsoup4 aiogram fastapi uvicorn pandas pygame-ce. Если импорт после установки всё равно падает, частая причина в том, что pip поставил пакет в другой Python; как это найти, разобрано в статье про ModuleNotFoundError.

Версии библиотек в нашем прогоне: requests 2.34.2, beautifulsoup4 4.15.0, aiogram 3.31.0, fastapi 0.143.0, uvicorn 0.54.0, pandas 3.0.6, pygame-ce 2.5.8. Каждый блок на Python запускается сам по себе, импорты в нём свои.

Руки на клавиатуре ноутбука, на экране открыт терминал с командами установки библиотек

Проекты на Python для начинающих

Скрипт автоматизации: разложить файлы по папкам

Программа на Python из 31 строки раскладывает файлы по папкам «Картинки», «Документы», «Архивы» по расширению. Для проверки функция make_demo() создаёт рядом со скриптом папку demo_downloads с пятью пустыми файлами, и сортируется только она.

from pathlib import Path
import shutil

FOLDERS = {
    ".jpg": "Картинки", ".png": "Картинки",
    ".pdf": "Документы", ".docx": "Документы", ".txt": "Документы",
    ".zip": "Архивы",
}

def sort_folder(folder: Path) -> None:
    for entry in list(folder.iterdir()):
        if not entry.is_file():
            continue
        group = FOLDERS.get(entry.suffix.lower(), "Разное")
        target_dir = folder / group
        target_dir.mkdir(exist_ok=True)
        new_path = target_dir / entry.name
        if new_path.exists():
            print(f"Пропуск: {entry.name} уже лежит в папке {group}")
            continue
        shutil.move(entry, new_path)
        print(f"{entry.name} -> {group}")

def make_demo() -> Path:
    demo = Path("demo_downloads")
    demo.mkdir(exist_ok=True)
    for name in ["отпуск.JPG", "счёт.pdf", "заметки.txt", "backup.zip", "setup.exe"]:
        (demo / name).touch()
    return demo

sort_folder(make_demo())
backup.zip -> Архивы
setup.exe -> Разное
заметки.txt -> Документы
отпуск.JPG -> Картинки
счёт.pdf -> Документы

entry.suffix.lower() превращает .JPG в .jpg, иначе фото с камеры ушло бы в «Разное». list(folder.iterdir()) снимает список заранее: код создаёт подпапки, а по документации не определено, попадут ли в перебор элементы, появившиеся во время обхода. Проверка new_path.exists() не даёт затереть одноимённый файл, который уже лежит на месте. Чтобы разобрать настоящие «Загрузки», замените последнюю строку на sort_folder(Path.home() / "Downloads"), и тогда make_demo() не вызывается. Если вы переносили папку загрузок, впишите свой путь.

Читайте также:  Декораторы Python: как работают, как написать свой и какие есть встроенные

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

Анализ данных: на что ушли деньги

Анализ своих данных хорош для новичка тем, что ответ можно проверить в уме. Семь строк расходов вписаны прямо в код, чтобы пример запускался без файла. Библиотека pandas читает таблицу, группирует строки по категориям и считает суммы.

from io import StringIO

import pandas as pd

data = """date,category,amount
2026-09-01,Продукты,1250
2026-09-02,Транспорт,320
2026-09-03,Продукты,890
2026-09-04,Кафе,640
2026-09-05,Транспорт,320
2026-09-06,Продукты,1430
2026-09-07,Кафе,410
"""

expenses = pd.read_csv(StringIO(data), parse_dates=["date"])
by_category = expenses.groupby("category")["amount"].sum().sort_values(ascending=False)
print(by_category)
print("Всего:", expenses["amount"].sum())
category
Продукты     3570
Кафе         1050
Транспорт     640
Name: amount, dtype: int64
Всего: 5260

Для своего файла замените StringIO(data) на путь: pd.read_csv("bank.csv", parse_dates=["date"]). Столбцы в чужой выгрузке называются иначе, сначала посмотрите их через print(expenses.columns). Выгрузку в Windows-1251 с «;» между полями read_csv без параметров не открывает (UnicodeDecodeError), а читает её pd.read_csv("bank.csv", sep=";", encoding="cp1251"). Суммы по категориям просятся в столбчатую диаграмму, примеры есть в статье про графики в Matplotlib.

Парсер: названия и цены со страницы

Парсинг учите на учебном сайте: правила настоящего сайта могут запрещать автоматический сбор данных, а на частые запросы сервер может ответить кодом 429 Too Many Requests. books.toscrape.com сделан для учёбы: вымышленный книжный магазин, который сам просит, чтобы его разбирали скриптами. Библиотека requests скачивает страницу, а BeautifulSoup с помощью CSS-селекторов находит нужные теги: например, article.product_pod означает тег article с классом product_pod.

import requests
from bs4 import BeautifulSoup

URL = "https://books.toscrape.com/"

response = requests.get(URL, timeout=10)
response.raise_for_status()
soup = BeautifulSoup(response.content, "html.parser")

books = soup.select("article.product_pod")
for book in books[:5]:
    title = book.h3.a["title"]
    price = book.select_one("p.price_color").text
    print(f"{price:>8}  {title}")
print("Книг на странице:", len(books))
  £51.77  A Light in the Attic
  £53.74  Tipping the Velvet
  £50.10  Soumission
  £47.82  Sharp Objects
  £54.23  Sapiens: A Brief History of Humankind
Книг на странице: 20

В BeautifulSoup передаём response.content, то есть байты. С response.text у нас вышли цены вида £51.77. Сервер отдаёт заголовок Content-Type: text/html без кодировки, и requests декодирует страницу как ISO-8859-1, хотя она в UTF-8 и пишет об этом в теге <meta>. Из байтов BeautifulSoup этот тег читает сам.

timeout=10 ставьте в каждый запрос: без него requests ждёт ответа сколько угодно, и зависший сервер подвесит программу. raise_for_status() превращает ответ 404 или 500 в исключение, чтобы вы не разбирали молча страницу с ошибкой.

Схема: блоки веб-страницы превращаются в строки аккуратной таблицы

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

Проекты Python для разработчиков среднего уровня

Телеграм-бот на aiogram

Наш бот считает слова в присланном тексте, а сам подсчёт вынесен в обычную функцию Python count_words_in. aiogram 3 асинхронный: обработчики объявлены через async def, ответ уходит через await. Токен выдаёт @BotFather в Telegram. В код его не пишите: любой, у кого он есть, может управлять вашим ботом. Программа берёт токен из переменной окружения BOT_TOKEN.

import asyncio
import os

from aiogram import Bot, Dispatcher
from aiogram.filters import CommandStart
from aiogram.types import Message

dp = Dispatcher()

@dp.message(CommandStart())
async def start(message: Message) -> None:
    await message.answer("Пришлите текст, и я посчитаю в нём слова.")

def count_words_in(text: str) -> int:
    return len(text.split())

@dp.message()
async def count_words(message: Message) -> None:
    count = count_words_in(message.text or "")
    await message.answer(f"Слов в сообщении: {count}")

async def main() -> None:
    token = os.getenv("BOT_TOKEN")
    if not token:
        print("Нет токена: задайте переменную окружения BOT_TOKEN")
        return
    bot = Bot(token=token)
    await dp.start_polling(bot)

asyncio.run(main())

Без переменной программа печатает Нет токена: задайте переменную окружения BOT_TOKEN и завершается. С выдуманным токеном Telegram отказывает, и traceback заканчивается строкой aiogram.exceptions.TelegramUnauthorizedError: Telegram server says - Unauthorized. С рабочим токеном бота мы не запускали, код собран по документации aiogram. В PowerShell переменную задают так: $env:BOT_TOKEN="ваш_токен", затем в том же окне запускают файл.

message.text or "" нужен потому, что поле text есть только у текстовых сообщений: у фото подпись лежит в caption, а message.text равен None.

Смартфон с открытым чатом бота рядом с ноутбуком, на экране ноутбука размытый код

Веб-приложение на FastAPI

Разработку веб-приложения на Python удобно начинать с маленького API: два адреса, JSON на входе и на выходе. Фреймворк FastAPI сам проверяет входные данные по модели Pydantic и строит страницу документации. Flask подходит для той же задачи, его пример мы разбирали в статье что такое фреймворк.

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()
notes: list[str] = []

class Note(BaseModel):
    text: str

@app.post("/notes")
def add_note(note: Note) -> dict:
    notes.append(note.text)
    return {"id": len(notes), "text": note.text}

@app.get("/notes")
def list_notes() -> dict:
    return {"count": len(notes), "notes": notes}

Сохраните код как notes_app.py и запустите сервер из той же папки командой python -m uvicorn notes_app:app. Он напишет Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit). Во втором терминале отправим заметку и запросим список. Команды для Git Bash, Linux и macOS:

curl -X POST http://127.0.0.1:8000/notes -H "Content-Type: application/json" -d '{"text": "buy milk"}'; echo
curl http://127.0.0.1:8000/notes; echo
{"id":1,"text":"buy milk"}
{"count":1,"notes":["buy milk"]}

В PowerShell 5.1, который входит в Windows 10, curl означает Invoke-WebRequest, и первая команда в таком виде падает с ошибкой привязки параметра Headers. Там тот же запрос отправляет Invoke-RestMethod:

Invoke-RestMethod -Method Post -Uri http://127.0.0.1:8000/notes -ContentType "application/json" -Body '{"text": "buy milk"}'
Invoke-RestMethod http://127.0.0.1:8000/notes
id text
-- ----
 1 buy milk

count notes
----- -----
    1 {buy milk}

Дойдёт ли кириллица в теле запроса, зависит от среды. В Git Bash под Windows она сломалась прямо в -d (There was an error parsing the body), а из файла в UTF-8 (-d @note.json) прошла. В PowerShell 5.1 пишите -ContentType "application/json; charset=utf-8": без charset сервер сохранил вместо букв знаки вопроса. Заметка с charset сохраняется верно, но в ответе PowerShell 5.1 всё равно показывает её кракозябрами. Запросы можно отправлять и со страницы /docs, которую FastAPI строит сам.

Читайте также:  Калькулятор на Python: от консольной версии до окна на tkinter

На запрос с пустым телом {} сервер вернул код 422 и "msg":"Field required": поля text нет, и FastAPI отклонил запрос, не вызывая нашу функцию. Заметки лежат в списке в памяти и пропадают при перезапуске сервера; следующий шаг проекта: хранить их в SQLite.

Схема: браузер отправляет запрос на сервер, сервер возвращает аккуратные блоки данных

Игра на pygame-ce

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

На Python 3.14 команда pip install pygame у нас не сработала: у последней версии pygame 2.6.1 нет готовых сборок под 3.14, и pip падает с Failed to build 'pygame'. Ставьте pygame-ce, форк от бывших разработчиков pygame. Импорт тот же: import pygame.

import random

import pygame

pygame.init()
screen = pygame.display.set_mode((480, 640))
pygame.display.set_caption("Поймай квадрат")
clock = pygame.time.Clock()

paddle = pygame.Rect(200, 600, 80, 15)
target = pygame.Rect(random.randint(0, 460), 0, 20, 20)
score = 0
running = True

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        paddle.x -= 6
    if keys[pygame.K_RIGHT]:
        paddle.x += 6
    paddle.clamp_ip(screen.get_rect())

    target.y += 4
    if target.colliderect(paddle):
        score += 1
        target.topleft = (random.randint(0, 460), 0)
    elif target.top > screen.get_height():
        print("Промах, счёт:", score)
        target.topleft = (random.randint(0, 460), 0)

    screen.fill((20, 24, 40))
    pygame.draw.rect(screen, (240, 200, 60), target)
    pygame.draw.rect(screen, (90, 200, 250), paddle)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
print("Игра окончена, пойман квадратов:", score)

Окно игры на pygame: жёлтый квадрат падает к голубой платформе внизу

pygame-ce 2.5.8 (SDL 2.32.10, Python 3.14.3)
Промах, счёт: 1
Игра окончена, пойман квадратов: 1

Первую строку печатает библиотека при импорте. Квадрат появляется в случайном месте, поэтому счёт у вас будет другим. clock.tick(60) не даёт циклу крутиться чаще 60 раз в секунду. Квадрат сдвигается на 4 пикселя за кадр, это 240 пикселей в секунду, и окно высотой 640 пикселей он проходит примерно за 2,7 секунды. clamp_ip сдвигает платформу обратно внутрь окна, меняя сам paddle.

Где используется Python: идеи для следующих проектов

Следующий проект можно выбрать по области применения Python:

Читайте также:  Декораторы Python: как работают, как написать свой и какие есть встроенные
Область Что можно написать Библиотеки
Веб-разработка серверную часть сайта, API для бота Django, Flask, FastAPI
Data science и аналитика отчёты, анализ таблиц, графики pandas, NumPy, matplotlib
Машинное обучение прогноз по прошлым данным, нейросети scikit-learn, PyTorch, TensorFlow
Компьютерное зрение обработку изображений OpenCV (пакет opencv-python)
Обработка естественного языка разбиение текста на слова и предложения, классификацию отзывов NLTK
Тестирование автотесты для своего кода pytest
Десктопные и мобильные приложения окно для своего скрипта, приложение для компьютера и телефона на одном коде tkinter, Kivy

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

Частые вопросы

Что написать на Python новичку первым?

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

Нужно ли знать HTML, чтобы написать парсер?

Нужен базовый уровень: теги, атрибуты class и id, вложенность. Этого хватает, чтобы в инструментах разработчика браузера найти нужный блок и записать селектор вроде article.product_pod.

Почему бот на aiogram падает с Unauthorized?

Telegram не принял токен. Скопируйте его из @BotFather заново целиком, без пробелов и кавычек. Если в @BotFather выпускали новый токен командой /token, берите последний.

Оцените статью
bestprogrammer.ru
Добавить комментарий