Python для начинающих
1.24K subscribers
546 photos
3 videos
232 files
74 links
Python для начинающих
Download Telegram
- Введение в библиотеку Twisted для работы с сетевыми протоколами.
## Введение в библиотеку Twisted для работы с сетевыми протоколами

Всем привет! С вами Иван, и сегодня у нас на повестке настоящая магия асинхронных сетевых программ — библиотека Twisted. Запомните это название: если вам нужно написать свой сервер или клиент для работы по сети, Twisted зачастую оказывается одним из самых мощных и гибких решений.

### Что такое Twisted?

Twisted — это фреймворк для создания сетевых приложений различных видов: от маленьких чатиков до крупных серверов по собственным протоколам. Главное отличие Twisted — асинхронность. Приложение не "зависает" в ожидании ответа по сети, а продолжает работу, что критично, если вы хотите обслуживать много соединений одновременно.

### Чем отличается от стандартного socket?

Стандартная библиотека socket — это низкоуровневая работа с соединениями, ручное управление потоками, куча шаблонного кода. Twisted же берет это всё на себя и ещё добавляет целую армию готовых реализаций популярных протоколов: HTTP, SMTP, SSH, IRC, POP3, и многие другие.

### Простой TCP-сервер на Twisted

Для примера — создадим TCP-сервер, который шлёт "Hello, client!" при подключении.

from twisted.internet import protocol, reactor

class HelloServer(protocol.Protocol):
def connectionMade(self):
self.transport.write(b"Hello, client!\n")
self.transport.loseConnection()

class HelloFactory(protocol.Factory):
def buildProtocol(self, addr):
return HelloServer()

reactor.listenTCP(1234, HelloFactory())
reactor.run()


Пояснения:
- connectionMade — срабатывает при установке соединения.
- self.transport.write — отправка данных клиенту.

### Асинхронный TCP-клиент на Twisted

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

from twisted.internet import protocol, reactor

class HelloClient(protocol.Protocol):
def dataReceived(self, data):
print("Server says:", data.decode())
reactor.stop()

class HelloClientFactory(protocol.ClientFactory):
def buildProtocol(self, addr):
return HelloClient()

reactor.connectTCP("localhost", 1234, HelloClientFactory())
reactor.run()


Как видите, код короткий и лаконичный. Не нужно морочиться с потоками или вручную ловить пакеты!

### Twisted: простота и мощность

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

Если вы хотите уверенно чувствовать себя в мире Python-сетевого программирования — обязательно попробуйте Twisted!
- Как работать с большими файлами с помощью генераторов Python.
# Как работать с большими файлами с помощью генераторов Python

Всем привет! С вами Иван, и сегодня я расскажу, как Python помогает легко справляться даже с очень большими файлами — и всё это благодаря генераторам.

## Проблема: мало памяти, большой файл

Часто новички пытаются считать весь файл в память с помощью readlines() или просто перебирают каждую строку в цикле. Но что, если ваш файл весит десятки гигабайт? Оперативка быстро заканчивается, появляется жуткий тормоз, а иногда и крах программы.

## Решение: ленивые генераторы

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

Вместо:

with open('bigfile.txt', 'r') as file:
lines = file.readlines() # опасно для больших файлов!
for line in lines:
process(line)


Подход генератора:

with open('bigfile.txt', 'r') as file:
for line in file:
process(line)

Здесь файл читается построчно — это уже генератор!

## Польза от собственных генераторов

Допустим, вы хотите читать по кусочкам, не по строкам, а по блокам данных. Легко!

def chunk_reader(file_obj, chunk_size=1024):
while True:
data = file_obj.read(chunk_size)
if not data:
break
yield data

with open('bigfile.txt', 'r') as f:
for chunk in chunk_reader(f, 2048):
process(chunk)


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

## Более сложные сценарии

Иногда нужно фильтровать строки:

def filtered_lines(file_obj, keyword):
for line in file_obj:
if keyword in line:
yield line

with open('bigfile.txt', 'r') as f:
for match in filtered_lines(f, 'Python'):
process(match)


## Итоги

Генераторы — простое и эффективное средство для обработки больших данных: читаем аккуратно, экономим память, код выглядит лаконично. Теперь вы знаете, что даже огромные файлы Python "по зубам"!
👍1
- Основы работы с модулями heapq для минимальных и максимальных куч.
# Минимальные и максимальные кучи в Python: магия модуля heapq

Привет, я Иван! Сегодня разберём, как быстро манипулировать минимальными и максимальными кучами на Python с помощью стандартного модуля heapq. Если выражаться проще — этот модуль превращает обычный список в эффективную структуру для извлечения самого маленького (или большого) элемента за минимальное время.

## Как это работает?

heapq реализует минимальную кучу (min-heap). Это значит, что первый элемент списка (heap[0]) — всегда наименьший. Максимальная куча (max-heap) не поддерживается "из коробки", но её легко построить самому — об этом расскажу чуть дальше.

### Пример 1: Базовые операции с min-heap

import heapq

numbers = [7, 2, 5, 1, 8, 3]
heapq.heapify(numbers)
print(numbers) # Видим преобразованный список: [1, 2, 3, 7, 8, 5]

smallest = heapq.heappop(numbers)
print(smallest) # 1 (минимальный элемент)
print(numbers) # [2, 5, 3, 7, 8]


- heapify: превращает обычный список в кучу O(n)
- heappop: извлекает и удаляет минимальный элемент O(log n)
- heappush: добавляет новый элемент и поддерживает кучу O(log n)

### Пример 2: Получаем k минимальных элементов

Например, хотим топ-3 наименьших числа:

import heapq

data = [6, 14, 3, 8, 2, 10]
top3 = heapq.nsmallest(3, data)
print(top3) # [2, 3, 6]


Аналогично можно получить k наибольших элементов — но тут весь фокус в "max-heap".

### Пример 3: Max-heap через отрицание

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

import heapq

data = [4, 7, 1, 8, 5]
max_heap = [-x for x in data]
heapq.heapify(max_heap)
largest = -heapq.heappop(max_heap)
print(largest) # 8


Таким образом, heapq станет "думать", что -8 минимален; отрицаем обратно при извлечении — и получаем максимум!

## Когда применять кучи?

- При поиске k наименьших/наибольших элементов в массиве
- Для реализации приоритетных очередей
- В задачах типа "онлайн сортировки" (например: постоянно поступают числа, нужен минимум в любой момент)

heapq работает быстро и сразу же доступен в стандартной библиотеке Python. Так что, если вы ещё не пробовали кучи на практике — пришло время потренироваться!

На этом всё — экспериментируйте!
👍2🔥1
- Создание системы управления задачами с помощью ToDo-листов на JSON.
# Создаем ToDo-лист на Python с хранением задач в JSON

Привет, на связи Иван — сегодня мы напишем небольшую, но полезную систему управления задачами, используя Python и формат хранения данных JSON. Не секрет, что ToDo-листы неизменно помогают держать свои дела под контролем, а JSON — отличный выбор для простой и эффективной работы с данными.

## Почему JSON?

JSON (JavaScript Object Notation) — универсальный текстовый формат, который легко читается как человеком, так и машиной. В Python работа с JSON реализована модулем json из стандартной библиотеки. Все гениальное — просто!

## Минимальный проект ToDo manager

Сделаем простое CLI-приложение: можно добавить, отметить выполненной или удалить задачу. Начнем с хранилища — файл todo.json.

1. Считываем задачи:

import json
import os

def load_tasks(filename):
if not os.path.exists(filename):
return []
with open(filename, 'r') as f:
return json.load(f)


2. Сохраняем задачи:

def save_tasks(filename, tasks):
with open(filename, 'w') as f:
json.dump(tasks, f, indent=2)


3. Добавляем задачу:

def add_task(tasks, text):
tasks.append({'task': text, 'done': False})


4. Отмечаем задачу завершенной:

def complete_task(tasks, index):
if 0 <= index < len(tasks):
tasks[index]['done'] = True


5. Удаляем задачу:

def delete_task(tasks, index):
if 0 <= index < len(tasks):
del tasks[index]


## Пример использования

FILENAME = 'todo.json'
tasks = load_tasks(FILENAME)

add_task(tasks, 'Learn about JSON module')
add_task(tasks, 'Write a ToDo app')
complete_task(tasks, 0)
delete_task(tasks, 1)

save_tasks(FILENAME, tasks)


## А что внутри файла?

После выполнения этих команд, в todo.json будет что-то вроде:

[
{
"task": "Learn about JSON module",
"done": true
}
]


## Почему это классно?

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

Попробуйте изменить код задачи: реализуйте фильтрацию по невыполненным задачам, добавьте сортировку или поиск. Модуль json открывает простор для экспериментов — и это отличная практика для начинающих питонистов!
1👍1
- Введение во фреймворк Streamlit: создание интерактивных веб-приложений.
Введение во фреймворк Streamlit: создание интерактивных веб-приложений

Привет! С вами Иван, и сегодня я расскажу о Streamlit — фреймворке, который способен превратить ваш скрипт на Python в работающую веб-страницу буквально за пару минут. Если вы часто работаете с анализом данных или машинным обучением, но идея разбираться с HTML/CSS/JS вас пугает, Streamlit — это глоток свежего воздуха.

Что такое Streamlit?
Это библиотека, позволяющая создавать веб-приложения на Python без глубокой веб-разработки. Всё, что нужно — обычный питоновский скрипт! Streamlit автоматически создает интерфейс, позволяя спокойно тестировать гипотезы и делиться результатами с коллегами.

### Как начать?

Установите библиотеку:
pip install streamlit


Создайте файл, например app.py, и добавьте простой код:
import streamlit as st

st.title("Streamlit Demo")
st.write("Hello, world! This is my first Streamlit app.")

Затем запускаем командой:
streamlit run app.py


Откроется браузер — и вы уже видите свой первый веб-апп!

### Немного интерактива

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

import streamlit as st

st.header("Simple Calculator")
num = st.slider("Choose a number", 1, 100, 25)
st.write(f"Square of your number: {num ** 2}")

if st.button("Show Magic!"):
st.balloons()


Каждое изменение значения слайдера сразу вызывает перерасчет — никакого обновления страницы! А если нажать кнопку, экран украсится анимацией шариков.

### Загрузка и визуализация данных

Streamlit отлично дружит с Pandas и Matplotlib. Вот пример, как загрузить CSV-файл и построить график:

import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt

uploaded_file = st.file_uploader("Upload CSV", type="csv")
if uploaded_file:
df = pd.read_csv(uploaded_file)
st.write(df.head())

fig, ax = plt.subplots()
df.hist(ax=ax)
st.pyplot(fig)


Пользователь загружает файл, таблица и гистограмма появляются тут же — попробуйте сами!

---

Streamlit — это быстрый старт, минимум кода и максимум наглядности. Отличный инструмент, чтобы показывать результаты работы или делать прототипы. Не тратьте время на фронтенд там, где важнее суть данных!
🔥2
- Использование PEP8: как писать более чистый код.
# Использование PEP8: как писать более чистый код

Привет, меня зовут Иван, и сегодня мы поговорим о PEP8 — вашем надежном компасе в мире чистого Python-кода. Возможно, вы уже слышали: “Пишите читаемый код!”, “Соблюдайте стиль!”. Но что за стиль, и зачем он вообще нужен? Давайте разберёмся.

## Что такое PEP8?

PEP8 — это стиль кодирования, одобренный Python-сообществом. Его цель — сделать код понятным не только вам, но и вашим коллегам. Представьте код с разным отступом, непонятными именами, хаотичными пробелами — это как лабиринт. PEP8 превращает этот лабиринт в аккуратную дорогу.

## Главные правила PEP8

### Отступы

Используйте 4 пробела на каждый уровень вложенности. Табуляции? Забываем! Python обожает пробелы:

def greet(name):
print(f"Hello, {name}!")


### Имена переменных и функций

Функции и переменные — маленькие змейки: snake_case. Классы — CamelCase:

def calculate_area(radius):
return 3.14 * radius ** 2

class CircleAreaCalculator:
pass


### Пробелы

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

x = 1  # правильно
y=2 # неправильно!
z = y+1 # тоже нехорошо


### Длина строки

PEP8 рекомендует не превышать 79 символов в строке. Во-первых, код помещается на экран. Во-вторых, не приходится горизонтально скроллить:

result = magic_function(param1, param2, param3, param4, param5, param6)


Если длинно — переносим:

result = magic_function(
param1, param2, param3, param4,
param5, param6
)


### Импортируем красиво

Импорты — с новых строк. Сначала стандартные модули, потом сторонние, потом ваши собственные:

import os
import sys

import requests

from mymodule import my_function


## Проверяем себя

Хватит ли помнить все правила наизусть? Нет. Используйте автоматические инструменты:
- flake8 — проверяет стиль кода
- black — автоматически форматирует код

## Заключение

PEP8 — не занудное ограничение, а инструмент вашего профессионализма. Чистый код экономит время, спасает нервы и даже делает друзей! Не стесняйтесь открывать PEP8 чаще обычного — и ваш Python будет не только работать, но и радовать глаз.
👍2
Работа с аудиофайлами: основное введение в модуль wave
Работа с аудиофайлами: основное введение в модуль wave
Работа с аудиофайлами: основное введение в модуль wave

Представьте, что вы хотите прочитать или обработать аудиофайл формата WAV в Python. Где-то на жестком диске томно покоится классическая мелодия “Moonlight.wav”, и вашей задачей становится: узнать её параметры или скопировать пару секунд звука в новый файл. Как это сделать? Представляю простое, но очень полезное оружие из стандартной библиотеки — модуль wave.

### В чём суть формата WAV?

WAV — это контейнер для хранения необработанных (raw) аудиоданных, обычно с минимальным сжатием. Как правило, это PCM-звук: каждая секунда — это тысячи отсчётов-чисел, определяющих амплитуду сигнала.

### Простое чтение WAV-файла

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

import wave

with wave.open('Moonlight.wav', 'rb') as audio:
n_channels = audio.getnchannels()
sample_width = audio.getsampwidth()
frame_rate = audio.getframerate()
n_frames = audio.getnframes()
duration = n_frames / frame_rate

print(f'Channels: {n_channels}')
print(f'Sample width: {sample_width} bytes')
print(f'Frame rate: {frame_rate} Hz')
print(f'Duration: {duration:.2f} seconds')


Всё, что между with ... as audio:, работает с открытым файлом: считаем параметры и даже узнаём длительность!

### Извлечение и сохранение кусочка аудио

Допустим, нужно вырезать первые 5 секунд аудио и записать их в новый WAV файл.

import wave

with wave.open('Moonlight.wav', 'rb') as original:
frame_rate = original.getframerate()
n_frames_to_copy = frame_rate * 5
frames = original.readframes(n_frames_to_copy)

with wave.open('Snippet.wav', 'wb') as snippet:
snippet.setnchannels(original.getnchannels())
snippet.setsampwidth(original.getsampwidth())
snippet.setframerate(frame_rate)
snippet.writeframes(frames)


Модуль wave работает только с несжатым PCM-звуком, но зато позволяет управлять WAV-файлами без лишних зависимостей.

### Секреты и ограничения модуля wave

wave — это абсолютный минималист. Он не умеет работать с mp3/flac и не воспроизводит звук. Но если хочется быстро проанализировать структуру WAV или сделать простейшее редактирование, — это именно ваш инструмент.

Используйте wave, если вам нужно: узнать, как устроена “под капотом” музыка, или написать свою первую аудиопрограмму на Python!
1👍1
- Как организовать модульную структуру проекта Python с помощью init.py.
- Как организовать модульную структуру проекта Python с помощью init.py.
Python для начинающих: как приручить __init__.py и навести порядок в проекте

Когда скрипт разрастается до 500+ строк, появляется соблазн «просто дописать еще чуть-чуть». А потом — боль: сложно найти нужную функцию, тестировать, переиспользовать код. Время знакомиться с модульной структурой и файлом __init__.py.

---

### Что такое пакет и зачем нужен __init__.py

Пакет — это просто папка с Python-кодом, которую интерпретатор воспринимает как модуль. Классический пакет содержит:

my_app/
__init__.py
models.py
services.py
utils/
__init__.py
validators.py
formatters.py


Наличие __init__.py говорит Python: «это пакет, его можно импортировать».

---

### Простейший пример: группируем логику

Пусть у нас мини-приложение для работы с пользователями.

my_app/models.py:

class User:
def __init__(self, username: str):
self.username = username


my_app/services.py:

from .models import User

def create_user(username: str) -> User:
return User(username=username)


Теперь сделаем пакет удобным с помощью __init__.py.

my_app/__init__.py:

from .models import User
from .services import create_user

__all__ = ["User", "create_user"]


Теперь в основном скрипте:

from my_app import User, create_user

user = create_user("alice")
print(user.username)


Мы спрятали внутреннюю структуру (файлы models.py, services.py), оставив аккуратный публичный интерфейс.

---

### Вложенные пакеты и точечный импорт

Добавим утилиты:

my_app/utils/validators.py:

def is_valid_username(username: str) -> bool:
return len(username) >= 3


my_app/utils/__init__.py:

from .validators import is_valid_username

__all__ = ["is_valid_username"]


И обновим my_app/__init__.py:

from .models import User
from .services import create_user
from .utils import is_valid_username

__all__ = ["User", "create_user", "is_valid_username"]


Теперь в любом месте проекта:

from my_app import is_valid_username

print(is_valid_username("ab")) # False
print(is_valid_username("alex")) # True


---

### Зачем вообще заморачиваться с __init__.py

1. Чистый публичный API
Через __all__ вы явно решаете, что можно импортировать снаружи, а что считается «внутренней кухней».

2. Сокрытие структуры
Можно переименовать файл services.py в logic.py, не ломая внешний код — если __init__.py сохраняет те же имена.

3. Удобные групповые импорты
Вместо:

   from my_app.models import User
from my_app.services import create_user


достаточно:

   from my_app import User, create_user


4. Инициализация пакета
В __init__.py можно разместить код, который выполнится при первом импорте пакета: настройка логгера, загрузка конфигурации (без фанатизма).

---

### Маленькое правило напоследок

Если модулей становится слишком много, и __init__.py превращается в свалку импортов — это сигнал, что пакет пора логически разбивать дальше. Хорошая структура проекта — та, где содержимое видно «с первого взгляда», а __init__.py помогает, а не запутывает.
👍1
- Создание базового TCP-сервера с использованием сокетов Python.
Создание базового TCP‑сервера с использованием сокетов Python

Иногда хочется почувствовать себя чуть ближе к «низам» интернета — туда, где нет Flask и Django, а есть только чистые сокеты и байты. Давайте напишем свой минимальный TCP‑сервер и разберёмся, что вообще происходит «под капотом».

### Что такое сокет?

Сокет — это конечная точка сетевого соединения. У простого TCP-сервера есть три основных шага:

1. Создать сокет.
2. Привязать его к адресу и порту.
3. Слушать входящие подключения и обрабатывать клиентов.

Используем стандартный модуль socket.

### Самый простой TCP‑сервер

Напишем сервер, который принимает соединение и отсылает клиенту приветствие:

import socket

HOST = "127.0.0.1" # localhost
PORT = 5000 # любой свободный порт > 1024

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen(1) # максимальная очередь из 1 клиента

print(f"Server is listening on {HOST}:{PORT}...")

conn, addr = server_socket.accept()
print(f"Connected by {addr}")

message = "Hello from TCP server!\n"
conn.sendall(message.encode("utf-8"))

conn.close()
server_socket.close()


Кратко по шагам:

- socket.AF_INET — IPv4;
- socket.SOCK_STREAM — протокол TCP;
- bind — говорим ОС: «Этот сервер живёт на HOST:PORT»;
- listen — включаем режим ожидания подключений;
- accept — блокируется, пока клиент не подключится, и возвращает новый сокет conn только для этого клиента.

Проверить можно через telnet 127.0.0.1 5000 или написать маленького клиента.

### Эхо‑сервер: отвечаем на сообщения

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

import socket

HOST = "127.0.0.1"
PORT = 5001

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen(5)
print(f"Echo server on {HOST}:{PORT}")

while True:
conn, addr = server_socket.accept()
print(f"Client connected: {addr}")
with conn:
while True:
data = conn.recv(1024) # читаем до 1024 байт
if not data:
break # клиент закрыл соединение
print(f"Received: {data!r}")
conn.sendall(data) # отправляем назад


Здесь важно:

- recv возвращает bytes; пустые b"" означают разрыв соединения;
- sendall гарантирует отправку всего буфера;
- цикл while True позволяет обслуживать клиентов один за другим.

### О чём стоит помнить

- Порт должен быть свободен, иначе будет ошибка OSError: [Errno 98] Address already in use.
- При разработке удобно использовать 127.0.0.1, для внешнего доступа — "0.0.0.0".
- Такой сервер однопоточен: пока он общается с одним клиентом, другие ждут. Для реальных задач нужны потоки (threading) или asyncio.

Через такие простые примеры становится понятнее, что веб‑фреймворки всего лишь надстройка над таким же socket, который вы сейчас написали сами.
👍3