Python для начинающих
1.12K subscribers
327 photos
3 videos
232 files
63 links
Python для начинающих
Download Telegram
- Как автоматизировать отправку электронной почты с smtplib
Привет! С вами Иван, и сегодня мой Python-блог посвящён суперполезной фишке — автоматизации отправки email с помощью модуля smtplib. Почта — штука незаменимая: ежедневные отчёты, рассылки новостей, уведомления клиентам… Зачем делать это вручную, если можно поручить задачу питону?

## smtplib — твой email-робот

smtplib входит в стандартную библиотеку Python, так что ничего дополнительно устанавливать не нужно. С его помощью можно подключаться к почтовым серверам через SMTP-протокол и слать письма хоть ежедневно, хоть ежечасно.

### Минимальный рабочий пример

Вот простой скрипт, который отправляет email через Gmail:

import smtplib

sender = "your_email@gmail.com"
password = "your_password"
recipient = "recipient_email@example.com"
message = "Subject: Hello from Python!\n\nThis is an automated email."

with smtplib.SMTP("smtp.gmail.com", 587) as smtp_server:
smtp_server.starttls() # Защищённое соединение
smtp_server.login(sender, password)
smtp_server.sendmail(sender, recipient, message)


Меняем email и пароль — и письмо уже в пути! Но помни о безопасности: для временных скриптов лучше использовать отдельные почтовые аккаунты и специальные пароли приложений.

### Отправляем HTML и вложения

Текстовое письмо — это скучно. Хотите добавить форматирование или вложить файл? Вот пример с email.message.EmailMessage:

import smtplib
from email.message import EmailMessage

msg = EmailMessage()
msg["Subject"] = "Automated report"
msg["From"] = "your_email@gmail.com"
msg["To"] = "recipient_email@example.com"
msg.set_content("See attached report.")

with open("report.pdf", "rb") as file:
msg.add_attachment(file.read(), maintype="application", subtype="pdf", filename="report.pdf")

with smtplib.SMTP("smtp.gmail.com", 587) as smtp:
smtp.starttls()
smtp.login("your_email@gmail.com", "your_password")
smtp.send_message(msg)


Теперь письмо придёт с красивым вложением, что удобно для отправки отчётов.

### В чём подвох?

Автоматизация — это мощь, но есть нюансы:
- Gmail и Яндекс требуют включения паролей приложений или разрешения для сторонних приложений.
- Частая массовая отправка может привести к блокировке.
- Логи, try-except и проверки — ваши друзья при работе с отправкой email.

А теперь — создавай свои рассылки, поздравления и уведомления, ведь с smtplib Python справится за тебя!
👍2
- Использование timeit для измерения производительности кода
Привет! Иван на связи — сегодня поговорим о невероятно полезном инструменте Python для измерения производительности кода: модуле timeit. Даже самый красивый код может оказаться медленным, если не следить за временем выполнения. Timeit позволяет объективно сравнить разные реализации алгоритмов и найти узкие места.

### Почему именно timeit?

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

### Пример 1: Сравнение двух способов сложить список

import timeit

setup = "numbers = list(range(1000))"
sum_builtin = "total = sum(numbers)"
sum_loop = '''
total = 0
for num in numbers:
total += num
'''

print("Built-in sum:", timeit.timeit(stmt=sum_builtin, setup=setup, number=10000))
print("For loop sum:", timeit.timeit(stmt=sum_loop, setup=setup, number=10000))


Результаты покажут неожиданный разрыв — встроенный sum почти всегда быстрее ручного цикла.

### Пример 2: Как измерить время выполнения функции?

Timeit умеет работать и с реальными функциями. Например:

def multiply():
result = 1
for i in range(1, 100):
result *= i

print(timeit.timeit(multiply, number=10000))


Передавайте функцию прямо в timeit.timeit.

### Пример 3: Сравнение list comprehension и генератора

setup = "numbers = range(1000)"
list_comp = "[x * 2 for x in numbers]"
gen_expr = "list(x * 2 for x in numbers)"

print("List comprehension:", timeit.timeit(stmt=list_comp, setup=setup, number=10000))
print("Generator expression:", timeit.timeit(stmt=gen_expr, setup=setup, number=10000))


Проверьте сами — не всегда интуиция правильна!

### Коротко: как пользоваться timeit

- Пишите тестируемый код как строку или функцию.
- Используйте параметр number — сколько раз выполнить ваш код.
- Изучайте результат — время в секундах. Меньше — лучше!

Timeit — ваш главный друг, если хотите, чтобы код работал максимально быстро. Экспериментируйте, оптимизируйте, удивляйтесь результатам!
👍1
- Как строить композитные структуры данных с модулем collections
Привет! На связи Иван, и сегодня расскажу, как модуль collections из стандартной библиотеки Python превращает скучное “списки и словари” в настоящее поле для экспериментов.

## Почему collections?

Казалось бы — зачем что-то придумывать, если уже есть list, tuple, dict? На деле, стандартные структуры не всегда удобны. Когда нужно быстро реализовать стек, очередь, счетчик, вложенный словарь или именованный кортеж, collections спасает время и нервы.

### 1. namedtuple: кортеж с именами, как у взрослого структуры!

Безумно удобно, когда к элементам можно обращаться по имени, а не по индексу:

from collections import namedtuple

Point = namedtuple('Point', ['x', 'y'])
p = Point(3, 5)
print(p.x, p.y) # 3 5


Идеально для хранения данных с фиксированной структурой — теперь ошибки с перепутанными индексами будут реже!

### 2. defaultdict: избавь себя от KeyError

Когда хочется вложенных словарей, но надоело вручную проверять на наличие ключа:

from collections import defaultdict

tree = defaultdict(lambda: defaultdict(int))
tree['fruits']['apple'] += 1
tree['fruits']['banana'] += 2
print(dict(tree))
# {'fruits': {'apple': 1, 'banana': 2}}


Это настоящая магия — никаких проверок, всё создаётся "на лету".

### 3. Counter: простейший анализ данных

Считать количество элементов — привычная задача. С Counter не надо писать лишний код:

from collections import Counter

colors = ['red', 'blue', 'red', 'green', 'blue', 'blue']
color_counts = Counter(colors)
print(color_counts)
# Counter({'blue': 3, 'red': 2, 'green': 1})


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

### 4. deque: очередь и стек в одном лице

Когда нужна быстрая вставка и удаление с обоих концов:

from collections import deque

history = deque(maxlen=3)
history.extend([1, 2, 3])
history.append(4)
print(history) # deque([2, 3, 4])
history.appendleft(0)
print(history) # deque([0, 2, 3])


deque — must-have для реализации очередей, поиска в ширину и undo-операций.

---

collections — это не просто "очередной модуль", а настоящий швейцарский нож для работы со структурами данных. Освой эти инструменты — и твой код станет чище, понятнее и быстрее!
👍2
- Работа с файлами Excel: основные приемы использования openpyxl
Привет! Я — Иван, и сегодня приглашаю погрузиться в магию работы с Excel-файлами через Python с помощью библиотеки openpyxl. Excel для программиста — как волшебная тетрадь с секретами: большие таблицы, автоотчеты и автоматизация рутины. Давайте посмотрим, как легко приручить этот мощный инструмент!

1. Открываем книгу Excel и читаем данные

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

from openpyxl import load_workbook

workbook = load_workbook('example.xlsx')
sheet = workbook.active # Получаем первый лист

for row in sheet.iter_rows(min_row=1, max_row=3, values_only=True):
print(row)


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

2. Создаем и наполняем файл Excel

Создать новый Excel-файл — проще простого. Добавим пару строк данных «на лету»:

from openpyxl import Workbook

workbook = Workbook()
sheet = workbook.active
sheet['A1'] = 'Name'
sheet['B1'] = 'Score'
sheet.append(['Alice', 90])
sheet.append(['Bob', 82])
workbook.save('new_report.xlsx')


Здорово, правда? Таблицы с отчетами теперь можно генерировать автоматически.

3. Форматирование ячеек: цвета и стили

Рутина без красоты — скучна. В openpyxl можно добавлять стили, чтобы выделить важные данные.

from openpyxl.styles import Font, PatternFill

sheet['A1'].font = Font(bold=True, color="FFFFFF")
sheet['A1'].fill = PatternFill(start_color="4F81BD", end_color="4F81BD", fill_type = "solid")


Теперь ваша «шапка» таблицы засияет как положено!

4. Итог

openpyxl — это гибкий инструмент для работы с Excel внутри Python. Он экономит время, автоматизирует рутину, а возможности форматирования делают ваши отчеты по-настоящему профессиональными. Главное — не бойтесь экспериментировать! Даже если не любите таблички, с openpyxl они становятся подatливой частью ваших проектов.

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

## Почему именно backoff?

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

Здесь-то и приходит на помощь backoff — маленький, но мощный помощник для автоматического повторения операций с задержками (и увеличением этих задержек после неудачи, если потребуется).

## Быстрое знакомство

Установить backoff можно так:

pip install backoff


Представим, что у нас есть функция, которая тянет данные с внешнего API:

import requests

def fetch_data():
response = requests.get('https://api.example.com/data')
response.raise_for_status()
return response.json()


А теперь магия! С помощью backoff превращаем это в устойчивый к сбоям вызов:

import backoff

@backoff.on_exception(backoff.expo, requests.exceptions.RequestException, max_tries=5)
def fetch_data():
response = requests.get('https://api.example.com/data')
response.raise_for_status()
return response.json()


Теперь при ошибке запроса будет предпринято до 5 попыток с увеличивающейся задержкой между ними (exponential backoff: 1, 2, 4, 8 сек...).

## Когда это особенно полезно?

- Интеграции с ненадежными внешними API
- Микросервисы в облаке
- Скачивание файлов
- Любые случаи, когда «падать» неудобно

## Индивидуальные настройки

Вы можете тонко управлять поведением backoff — например, отреагировать только на определённые коды ответа:

@backoff.on_predicate(backoff.expo, lambda r: r.status_code != 200, max_time=30)
def fetch_status():
return requests.get('https://status.example.com/check')


## Итог

backoff — отличный инструмент для тех, кто делает Python-программы «с характером» и не хочет бояться временных сетевых проблем. Он легко интегрируется, конфигурируется на любой вкус и просто спасает в критические моменты. Если хотите писать надежный код — попробуйте backoff в деле!
👍1
- Как организовать модульное тестирование с использованием pytest
Привет! На связи Иван — сегодня поговорим о тестировании кода в Python с помощью библиотеки pytest. Современный программист не может позволить себе писать код без тестов — баги стоят времени, денег и, иногда, нервов. Разберёмся, что делает pytest таким удобным для модульного тестирования, и как легко организовать процесс проверки вашего кода.

Прежде всего, установка:
pip install pytest


Представим, у нас есть простой модуль calculator.py:
def add(a, b):
return a + b

def divide(a, b):
return a / b


Теперь создадим файл тестов — по традиции, его имя начинается с test_. Пусть это будет test_calculator.py:
from calculator import add, divide

def test_add():
assert add(3, 2) == 5

def test_divide():
assert divide(10, 2) == 5


Pytest автоматически найдёт функции, начинающиеся на test_, и выполнит их. Запуск:
pytest


Вы сразу увидите лаконичный и понятный отчёт: миновала функция тест или нет, почему провалена, если что-то пошло не так. Деталь — если вы ждёте ошибку, используйте конструкцию pytest.raises:
import pytest
from calculator import divide

def test_divide_by_zero():
with pytest.raises(ZeroDivisionError):
divide(5, 0)


Pytest поддерживает параметризацию, благодаря чему можно протестировать одну функцию сразу на разных данных:
import pytest
from calculator import add

@pytest.mark.parametrize("a, b, expected", [
(1, 1, 2),
(5, 2, 7),
(0, -1, -1),
])
def test_add_various(a, b, expected):
assert add(a, b) == expected


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

Мои лайфхаки: держите тесты в отдельной папке tests/, запускайте их автоматом после каждого коммита, и никогда не игнорируйте красные строки — баги надо исправлять сразу.

Тестируйте свой Python-код, и он отблагодарит вас стабильностью!
👍1
- Управление контекстами выполнения с помощью asynccontextmanager
Привет! С вами Иван, и сегодня я расскажу о приемах управления контекстами выполнения в асинхронном Python с помощью asynccontextmanager. Если вы когда-нибудь хотели элегантно управлять ресурсами во время выполнения асинхронного кода, эта тема для вас!

## Немного о контекстах

Классический контекстный менеджер (with ...:) позволяет безопасно работать с файлами, сокетами и другими ресурсами. Казалось бы — зачем нам что-то еще? А вот зачем: когда мы ныряем в мир асинхронности (async/await), обычный with становится бесполезен — тут требуется свой асинхронный вариант.

## asynccontextmanager — ваш друг

Модуль contextlib из стандартной библиотеки с версии Python 3.7 предлагает декоратор @asynccontextmanager. Он позволяет создавать асинхронные контекстные менеджеры без необходимости писать полноценные классы.

### Пример: асинхронная блокировка

Рассмотрим пример, где мы хотим управлять семафором для ограничения числа одновременных задач:

import asyncio
from contextlib import asynccontextmanager

@asynccontextmanager
async def acquire_semaphore(semaphore):
await semaphore.acquire()
try:
yield
finally:
semaphore.release()

async def limited_task(semaphore):
async with acquire_semaphore(semaphore):
print("Resource acquired")
await asyncio.sleep(1)
print("Resource released")

async def main():
sem = asyncio.Semaphore(2)
await asyncio.gather(*(limited_task(sem) for _ in range(4)))

asyncio.run(main())


В этом коде мы создали элегантный асинхронный менеджер, который гарантирует освобождение ресурса даже при ошибках.

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

- @asynccontextmanager делает функцию генератором с асинхронной поддержкой.
- До yield выполняется код инициализации (например, получение блокировки).
- После yield — освобождение ресурса (release, закрытие файла, отключение соединения и др.).

### Асинхронные файлы

А если нам нужно работать с файлами (например, через aiofiles)? Можно обернуть открытие файла в ваш асинхронный контекст:

import aiofiles
from contextlib import asynccontextmanager

@asynccontextmanager
async def open_async_file(file_path, mode):
file = await aiofiles.open(file_path, mode)
try:
yield file
finally:
await file.close()

async def read_file():
async with open_async_file("example.txt", "r") as f:
content = await f.read()
print(content)


## Вывод

С помощью @asynccontextmanager вы пишете лаконичный, читаемый и безопасный асинхронный код, не боясь утечек ресурсов даже при возникновении исключений. Попробуйте интегрировать его в свои проекты — и асинхронная жизнь станет проще!
👍2
- Как анализировать и кластеризовать текст с помощью sklearn
Привет! Я Иван, программист, и сегодня расскажу, как можно анализировать и даже кластеризовать текст с помощью Python и магического инструмента — библиотеки scikit-learn (sklearn). Это будет идеальный первый шаг, если вы хотите автоматизировать обработку отзывов, статей или любой другой текстовой информации.

## 1. Векторизация текста

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

from sklearn.feature_extraction.text import TfidfVectorizer

texts = [
"Python is easy to learn",
"Python and sklearn are powerful",
"Data science is fun"
]
vectorizer = TfidfVectorizer()
features = vectorizer.fit_transform(texts)
print(features.shape) # (3, 8): 3 документа, 8 уникальных слов


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

## 2. Кластеризация: учим машину находить похожее

Допустим, у нас куча текстов, и надо понять — какие из них говорят об одном и том же. Для этого идеально подходит KMeans:

from sklearn.cluster import KMeans

num_clusters = 2
kmeans = KMeans(n_clusters=num_clusters, random_state=42)
kmeans.fit(features)

print(kmeans.labels_) # Например: [0 0 1]


Каждому тексту присваивается номер кластера — теперь похожие тексты собраны вместе!

## 3. Мини-применение

Посмотрим, как распределились наши тексты:

for idx, label in enumerate(kmeans.labels_):
print(f"Text: '{texts[idx]}' — Cluster: {label}")


Теперь вы знаете, как можно быстро превратить тексты в числа, и даже найти в них скрытые группы! Модули TfidfVectorizer и KMeans — отличный старт для анализа текстов: они просты в использовании, но мощные по возможностям.

Творите с Python — и пусть тексты больше не будут "тёмным лесом"!
👍2
- Создание сетевых классных комнат с использованием Jitsi API
Привет! С вами Иван, и сегодня мы будем говорить о создании собственной сетевой "классной комнаты" с помощью Python и могучего Jitsi API. Если вы не слышали о Jitsi — это бесплатная и открытая платформа для видеоконференций, которую можно интегрировать в свой проект буквально "на коленке". А ведь сколько возможностей открывается: онлайн-уроки, дистанционные кружки, даже занятия английским по вечерам!

Jitsi: Видеозвонки из Python

Jitsi не имеет нативного Python SDK, но у него есть REST API и iframe интеграция. Самый простой путь — создавать "комнаты" и управлять ими через web-интерфейс Jitsi Meet, генерируя ссылки через Python.

### Создаём комнату и отправляем приглашение

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

import random
import string

def generate_room_name(length=10):
chars = string.ascii_lowercase + string.digits
return ''.join(random.choices(chars, k=length))

room_name = generate_room_name()
jitsi_url = f"https://meet.jit.si/{room_name}"
print("Classroom link:", jitsi_url)


Этот код генерирует уникальное имя класса и выдаёт ссылку. Осталось только отправить её ученикам — хоть по email, хоть через чат-бота!

### Добавляем управление через API

А вот пример запроса к Jitsi Videobridge для получения статистики о комнатах (необходима авторизация):

import requests

server = "https://your-jitsi-server.com"
stats_url = f"{server}/colibri/stats"
response = requests.get(stats_url, auth=('user', 'password'))
print(response.json())


Используя такие запросы, можно отслеживать загруженность сервера: если классов стало слишком много — поднимаем ещё один инстанс.

### Встраиваем Jitsi в веб-приложение

Jitsi легко добавляется на сайт через iframe. Python-проекты на Flask или Django могут генерировать HTML-шаблон с вашей уникальной комнатой:

<iframe allow="camera; microphone; fullscreen; display-capture"
src="https://meet.jit.si/{{ room }}"
style="height: 500px; width: 100%;"></iframe>

Подставьте в {{ room }} имя, которое сгенерировал ваш Python-скрипт — и ваша собственная видеоклассная комната готова!

Вывод:
С помощью пары строк Python и мощи Jitsi можно быстро настроить интерактивные уроки, не разбираясь в сложных API и видеостримах. Экспериментируйте, и пусть ваши виртуальные классы всегда будут полны энтузиазма!
2
- Работа с session объектами для управления состоянием пользователей
Привет, друзья! На связи Иван — сегодня поговорим о магии управления состоянием пользователей в Python с помощью session-объектов.

### Сессии: что это вообще такое?

Когда пользователь взаимодействует с веб-приложением, серверу часто нужно "помнить", кто этот пользователь и что он делал минуту назад. Именно в этом случае на сцену выходят session-объекты: они позволяют сохранить состояние между запросами, создавая иллюзию постоянного соединения клиента с сервером.

### Flask и сессии

Один из самых простых способов работы с сессиями в Python — использовать микрофреймворк Flask. Здесь сессии реализованы очень удобно:

from flask import Flask, session, redirect, url_for, request

app = Flask(__name__)
app.secret_key = 'super_secret_key' # Необходима для криптографии!

@app.route('/login', methods=['POST'])
def login():
user = request.form['username']
session['username'] = user
return redirect(url_for('profile'))

@app.route('/profile')
def profile():
if 'username' in session:
return f"Hello, {session['username']}!"
return 'You are not logged in.'

# Для запуска: app.run()


Здесь благодаря session['username'] сохранится имя пользователя, и при следующем запросе сервер быстро узнает, кто к нему пришел.

### Requests и cookies

Если вам нужно управлять состоянием не на сервере, а в клиенте (например, писать бота для сайта), пригодится модуль requests. В нем есть Session-объект, который автоматически сохраняет cookies:

import requests

s = requests.Session()
login_payload = {'user': 'bob', 'password': 'qwerty'}
s.post('https://example.com/login', data=login_payload)

resp = s.get('https://example.com/profile')
print(resp.text) # Профиль Bob'а, если логин успешен!


Сессия позволяет использовать одни и те же cookies для всех запросов, сразу открывая большие возможности для автоматизации.

### На что обратить внимание:

- Всегда храните секретные ключи вне кода!
- Сессии — не лучший способ хранить крупные объекты или большие объемы данных.
- Удалять данные из session можно с помощью session.pop('key', None) или session.clear().

### Итоги

Сессии — это сердце любого сложного веб-приложения: без них ни аутентификацию, ни корзину покупок реализовать не получится. Используйте возможности Flask и requests на полную катушку, не забывая о безопасности. Удачного кодинга!
👍2