Python для начинающих
1.11K subscribers
366 photos
3 videos
232 files
67 links
Python для начинающих
Download Telegram
Привет! Я — Иван, и сегодня мы погрузимся в одну из самых увлекательных сторон Python — работу с временными рядами в библиотеке Pandas. Даже если вы только начинаете разбираться в Python, возможности Pandas по анализу “времени” вас поразят.

### В чем фишка временных рядов?

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

#### 1. Построим временной ряд

Создадим искусственный DataFrame с датами:

import pandas as pd
import numpy as np

dates = pd.date_range("2024-06-01", periods=10, freq="D")
data = pd.DataFrame({
"value": np.random.randint(10, 100, size=10)
}, index=dates)
print(data)


Благодаря pd.date_range мы мгновенно получаем индекс из дат с шагом в 1 день.

#### 2. Ресемплирование: меняем масштаб времени

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

weekly = data.resample("W").mean()
print(weekly)


Метод resample("W").mean() вычисляет среднее значение за каждую неделю — незаменимо в задачах анализа и сглаживания.

#### 3. Временные срезы: быстро и просто

Извлечь данные за определенный промежуток? Просто используйте срез по дате:

june_data = data["2024-06-03" : "2024-06-07"]
print(june_data)


Pandas умеет распознавать строки-даты и работать с ними «по-человечески».

#### 4. Вычисления смещений и скользящих средних

А теперь представим, что хотим посчитать скользящее среднее (moving average) — классика временных рядов:

data["rolling_mean"] = data["value"].rolling(window=3).mean()
print(data)


Метод .rolling(window=3) создает окно шириной 3, а .mean() вычисляет среднее внутри этого окна для каждой точки.

### Вывод

Pandas превращает анализ временных рядов в настоящее удовольствие даже для новичков. Создавать, агрегировать, фильтровать, вычислять по времени — всё это делается с минимальным количеством кода и максимальной наглядностью. Если вы начнете работать с временными рядами, эта библиотека станет вашим любимым рабочим инструментом!
- Как использовать модуль random для имитации простых игр.
Привет, друзья! На связи Иван, и сегодня у нас на повестке дня настоящий праздник удачи и случайностей — модуль random в Python! Давайте взглянем, как с его помощью можно создавать простые, но увлекательные игры буквально за пару строк.

### Бросаем кости

Сколько раз вы мечтали бросить кубик, не имея его под рукой? С random это просто:

import random

def roll_dice():
return random.randint(1, 6)

print("Your roll:", roll_dice())


Здесь random.randint(1, 6) возвращает случайное целое число от 1 до 6 включительно, будто вы по-настоящему держите в руках шестигранный кубик.

### Монетка

Кто же не любит монетку: "Орёл или решка?" Быстро реализуемый вариант:

import random

def flip_coin():
return random.choice(["Heads", "Tails"])

print("Coin shows:", flip_coin())

random.choice выбирает случайный элемент из списка — универсальный способ для создания лотерей и викторин.

### Мини-лотерея

А теперь немного азартных ощущений! Представьте, что игроку нужно угадать число от 1 до 10.

import random

def guess_number():
number = random.randint(1, 10)
user_guess = int(input("Guess the number between 1 and 10: "))
if user_guess == number:
print("You win!")
else:
print(f"Sorry, the number was {number}")

# guess_number()

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

### Случайные события для игр

Часто random используется для имитации неожиданных событий — например, выбор врага в рогалик-игре:

enemies = ["Goblin", "Orc", "Dragon"]
random_enemy = random.choice(enemies)
print("A wild", random_enemy, "appeared!")


Выводы:
random — идеальный инструмент для создания непредсказуемости и интереса в небольших проектах. От кубиков до случайных событий — возможности безграничны. Придумывайте свои игры и пусть случай поможет сделать их веселее!
- Управление асинхронными процессами с библиотекой asyncio.
Привет, друзья! С вами Иван, и сегодня мы окунемся в мир асинхронности на Python, а конкретнее — поговорим о библиотеке asyncio.

Что такое asyncio и зачем оно нужно?

Когда ваш код долго ждет ответа от сервера или читает большой файл, обычный (синхронный) Python просто стоит и ждет. А хочется, чтобы в этот момент выполнялась еще какая-то полезная работа. Вот тут на сцену выходит asyncio — библиотека для удобной работы с асинхронными задачами.

Асинхронный код работает по принципу событийного цикла: задачи ставятся в очередь и исполняются тогда, когда «что-то произошло». Так достигается высокая скорость выполнения операций ввода-вывода.

Простой пример — симуляция одновременной загрузки нескольких веб-страниц:

import asyncio
import aiohttp

async def fetch_url(session, url):
async with session.get(url) as response:
print(f'Read {url}: {response.status}')
return await response.text()

async def main():
urls = [
'https://python.org',
'https://docs.python.org/3/library/asyncio.html',
'https://pypi.org'
]
async with aiohttp.ClientSession() as session:
tasks = [fetch_url(session, url) for url in urls]
pages = await asyncio.gather(*tasks)
print('All pages downloaded!')

asyncio.run(main())


Что здесь происходит?
Вместо того, чтобы последовательно качать каждую страницу, мы создаём задачи и запускаем их одновременно. asyncio.gather() дожидается, пока все запросы завершатся, а результат собирается в список.

Асинхронность полезна не только в сетевых операциях. Вот пример — задержка (имитация долгой работы) без блокировки кода:

import asyncio

async def do_work(name, seconds):
print(f'{name} starts working')
await asyncio.sleep(seconds)
print(f'{name} finished after {seconds} seconds')

async def main():
await asyncio.gather(
do_work('task_1', 2),
do_work('task_2', 1)
)

asyncio.run(main())


В этом примере обе задачи начинают одновременно, а вся программа завершается за 2 секунды — так быстро, как самая долгая задача!

Главное правило: асинхронные функции пишем с помощью ключевого слова async, и вызываем через await внутри другого async-функции. Методы типа asyncio.run() запускают «цикл событий», который всё разруливает.

Итак, если вам нужны быстрые одновременные операции — смело используйте asyncio. В следующих постах разберём более сложные сценарии работы и интеграцию с другими библиотеками.

До новых встреч!
👍3
- Введение в библиотеку 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 открывает простор для экспериментов — и это отличная практика для начинающих питонистов!