Друзья, какой мини-скрипт вы хотите освоить в этом месяце? 😎 Выбирайте, а я подготовлю пример! 🧑💻
Голосуем до 20 сентября!
Голосуем до 20 сентября!
Final Results
27%
53%
40%
7%
CodeShadow pinned «Друзья, какой мини-скрипт вы хотите освоить в этом месяце? 😎 Выбирайте, а я подготовлю пример! 🧑💻
Голосуем до 20 сентября!»
Голосуем до 20 сентября!»
Программирование — это не только про таблицы и цифры. Python умеет творить искусство✨
Например, я попробовал сделать скрипт, который рисует абстрактные узоры и сохраняет их в PNG. Получается что-то вроде «генеративного искусства».
from PIL import Image, ImageDraw
import random
# создаём пустое изображение
img = Image.new("RGB", (500, 500), "white")
draw = ImageDraw.Draw(img)
# рисуем случайные круги
for _ in range(50):
x1 = random.randint(0, 500)
y1 = random.randint(0, 500)
x2 = x1 + random.randint(20, 100)
y2 = y1 + random.randint(20, 100)
color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
draw.ellipse([x1, y1, x2, y2], fill=color)
img.save("abstract.png")
print("✅ Картинка готова!")
Please open Telegram to view this post
VIEW IN TELEGRAM
⚙️ Автоматизация: твой главный козырь
Программисты-фрилансеры ценятся за то, что снимают рутину.
Пример: удаление старых файлов на сервере клиента.
Просто, но клиент доволен.
В дальнейшем обсудим работу с API, ведь это частая необходимость.
Программисты-фрилансеры ценятся за то, что снимают рутину.
Пример: удаление старых файлов на сервере клиента.
code
import os, time
folder = "logs"
now = time.time()
for f in os.listdir(folder):
path = os.path.join(folder, f)
if os.path.isfile(path) and now - os.path.getmtime(path) > 7*86400:
os.remove(path)
Просто, но клиент доволен.
В дальнейшем обсудим работу с API, ведь это частая необходимость.
🔌 Работа с API: пример погоды
Фрилансеру часто приходится работать с API.
Пример: получаем данные о погоде через OpenWeather.
API = умение подключать сервисы. Это востребовано.
Далее — где хранить данные: базы, JSON, CSV.
Фрилансеру часто приходится работать с API.
Пример: получаем данные о погоде через OpenWeather.
import requests
API_KEY = "ВАШ_API_КЛЮЧ" # получите на openweathermap.org
city = "Moscow"
url = f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={API_KEY}&units=metric&lang=ru"
response = requests.get(url)
data = response.json()
if response.status_code == 200:
temp = data["main"]["temp"]
weather = data["weather"][0]["denoscription"]
print(f"Погода в {city}: {temp}°C, {weather}")
else:
print("Ошибка:", data.get("message", "Не удалось получить данные"))
API = умение подключать сервисы. Это востребовано.
Далее — где хранить данные: базы, JSON, CSV.
Недавно я уже делал пост про автоматизацию Google Таблиц с Python — там закидывал доходы фрилансера прямо из JSON. Сегодня продолжу тему и разберу ещё один кейс, который может быть полезен каждому.
Представь, ты ведёшь Telegram-канал или чат. Каждый день хочется видеть простую статистику:
сколько человек подписалось
сколько сообщений написали
сколько лайков накликали
Обычно это где-то лежит в API, и ты смотришь раз в неделю… Но почему бы не сделать так, чтобы данные сами залетали в Google Таблицу?
import gspread
from oauth2client.service_account import ServiceAccountCredentials
import datetime
# Доступ к Google
scope = ["https://spreadsheets.google.com/feeds",
"https://www.googleapis.com/auth/drive"]
creds = ServiceAccountCredentials.from_json_keyfile_name("service_account.json", scope)
client = gspread.authorize(creds)
# Открываем таблицу
sheet = client.open("Статистика_канала").sheet1
# Данные для примера (на деле можно тянуть из Telegram API)
today = datetime.date.today().strftime("%Y-%m-%d")
new_users = 15
messages = 120
likes = 340
# Записываем строку
sheet.append_row([today, new_users, messages, likes])
print("✅ Статистика обновлена!")
каждый день таблица сама пополняется свежими цифрами
есть история за каждый день, удобно строить графики
можно сразу видеть динамику: растёшь или нет
Автоматизация таблиц = освобождение головы от рутины. Настроил один раз → и дальше система сама работает.
Please open Telegram to view this post
VIEW IN TELEGRAM
⚡1 1
В последнее время дни сильно загружены и часто путаюсь в расписании😵
Решил для себя сделать бота-планёра, чтобы не забывать о занятиях и дедлайнах.
Пишите в комменты, если для вас эта тема актуальна👨💻
Please open Telegram to view this post
VIEW IN TELEGRAM
У фрилансеров и SMM-щиков часто одна головная боль — контент. Идеи постов есть, но они теряются в заметках, Excel или просто в голове.
Что если у тебя будет бот, который сам раскладывает идеи по дням и формирует план публикаций?
Это реально полезный инструмент:
import datetime
from aiogram import Bot, Dispatcher, types
from aiogram.filters import Command
import asyncio, os
API_TOKEN = os.getenv("BOT_TOKEN")
bot = Bot(API_TOKEN)
dp = Dispatcher()
ideas = {} # {user_id: [(date, text), ...]}
@dp.message(Command("add"))
async def add_idea(msg: types.Message):
# Пример: /add 2025-09-20 Идея поста про Python
try:
parts = msg.text.split(" ", 2)
date = datetime.datetime.strptime(parts[1], "%Y-%m-%d").date()
text = parts[2]
ideas.setdefault(msg.from_user.id, []).append((date, text))
await msg.answer(f"✅ Добавлено: {text} ({date})")
except:
await msg.answer("⚠️ Формат: /add YYYY-MM-DD ТЕКСТ")
@dp.message(Command("plan"))
async def show_plan(msg: types.Message):
user_ideas = ideas.get(msg.from_user.id, [])
if not user_ideas:
await msg.answer("📭 План пуст")
else:
user_ideas.sort(key=lambda x: x[0])
text = "📅 Твой контент-план:\n\n"
for d, t in user_ideas:
text += f"— {d}: {t}\n"
await msg.answer(text)
async def main():
await dp.start_polling(bot)
if __name__ == "__main__":
asyncio.run(main())
⁉️ А у тебя уже есть свой контент-план или ты пока публикуешь «по вдохновению»?
#CodeShadow #TelegramBot #Python #Фриланс
Please open Telegram to view this post
VIEW IN TELEGRAM
CodeShadow
Друзья, какой мини-скрипт вы хотите освоить в этом месяце? 😎 Выбирайте, а я подготовлю пример! 🧑💻
Голосуем до 20 сентября!
Голосуем до 20 сентября!
Ненавязчиво напоминаю о опросе 👀
Please open Telegram to view this post
VIEW IN TELEGRAM
CodeShadow
В последнее время дни сильно загружены и часто путаюсь в расписании 😵 Решил для себя сделать бота-планёра, чтобы не забывать о занятиях и дедлайнах. Пишите в комменты, если для вас эта тема актуальна 👨💻
Пишу проект бота-планёра для телеграм. Скоро выйдет пост на тему данного бота💎
Вкратце: можно делать записи по задачам, выставлять дату и время, есть фиксированные задачи по будням и оповещения, а также отчётность за неделю👨💻
Please open Telegram to view this post
VIEW IN TELEGRAM
Привет, друзья! Недавно я упоминал, что дни стали слишком загруженными, и я часто путаюсь в дедлайнах, встречах и повторяющихся задачах. Как фрилансер, я устал от заметок в телефоне и напоминаний в календаре — они не всегда срабатывают вовремя. Решил: пора написать своего бота-планировщика, который будет держать всё под контролем.Это не просто напоминалка, а полноценный инструмент для фрилансеров, студентов или SMM-щиков. Бот поможет организовать разовые задачи (с датой, временем и описанием) и фиксированное расписание (например, еженедельные занятия или встречи). Плюс напоминания, отчёты и простая интеграция с Telegram.Представь: добавляешь задачу "/add_task Менторство с клиентом 2025-09-25 14:00", бот сохраняет её, напоминает за 30 минут (или по твоим настройкам) и даже формирует отчёт за неделю — сколько задач выполнено, сколько висит. Для повторяющихся вещей (типа "урок по Python каждую среду в 18:00") есть отдельный режим с деактивацией по команде.
Бот работает на Python с библиотеками telebot, SQLAlchemy (для базы данных) и APScheduler (для напоминаний). Всё в одном проекте, без лишних зависимостей.
⭐️ Python 3⭐️ Библиотеки: telebot, sqlalchemy, apscheduler, python-dotenv, pytz⭐️ База: SQLite (или PostgreSQL для продакшена)⭐️ Telegram API токен
—config.py: настройки (токен, таймзона, БД)
—models.py: модели задач и расписания (SQLAlchemy)
—db.py: подключение к БД
—utils.py: хелперы (парсинг дат, клавиатуры)
—scheduler.py: планировщик напоминаний
—bot_handlers.py: обработчики сообщений (добавление задач, настройки, отчёты)
—main.py: запуск бота и инициализация
В следующих постах разберём код по частям: от базы данных до напоминаний. Если тема зацепит — сделаю репозиторий на GitHub.
• Интеграцию с Google Calendar для синхронизации.
• Голосовые заметки для добавления задач.
• Графики отчётов в PNG (через Matplotlib).
• Мультипользовательский режим для команд.
Это не просто бот — это инструмент, который сэкономит часы на рутине. Я уже тестирую на себе, и это реально упрощает жизнь.💪 ☕️ А ты используешь ботов для планирования? Что бы добавил в такой проект?
#CodeShadow #TelegramBot #Python #Планировщик #Фриланс
Please open Telegram to view this post
VIEW IN TELEGRAM
📊 Хранение данных: куда девать результаты?
Фрилансер обязан уметь сохранять данные.
Пример — CSV-файл:
Аналогично можно работать с JSON и SQLite.
Далее — советы по GitHub и портфолио.
Фрилансер обязан уметь сохранять данные.
Пример — CSV-файл:
code
import csv
data = [("Анна", 90), ("Иван", 75)]
with open("scores.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerows(data)
Аналогично можно работать с JSON и SQLite.
Далее — советы по GitHub и портфолио.
По результатам опроса, парсинг сайтов самый популярный😎
В качестве примера парсинга будем писать скрипт для парсинга погоды с сайта www.gismeteo.ru🖥
Please open Telegram to view this post
VIEW IN TELEGRAM
Привет, кодеры! В прошлом посте я рассказал о своём новом проекте — Telegram-боте для планирования задач и расписания. Он помогает фрилансерам и студентам держать дела в порядке: разовые задачи с напоминаниями, еженедельные занятия, отчёты и настройки. Бот на Python, с использованием telebot для интерфейса, APScheduler для тайминга и SQLAlchemy для хранения данных.
Сегодня начинаем разбирать код по частям, как обещал. Стартуем с фундамента: базы данных. Почему SQLAlchemy? Она гибкая, поддерживает разные БД (SQLite для теста, PostgreSQL для продакшена), и ORM делает работу с данными как с объектами Python — удобно и без сырого SQL.Сначала config.py (там настройки, включая URL для БД). Вот базовый snippet:
# config.py
import os
from dotenv import load_dotenv
import pytz
load_dotenv()
BOT_TOKEN = os.getenv("BOT_TOKEN") # обязательно
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///planner.db")
TIMEZONE = os.getenv("TIMEZONE", "Europe/Moscow")
TZ = pytz.timezone(TIMEZONE)
DATABASE_URL — это строка подключения. Для SQLite просто файл, для Postgres — 'postgresql://user:pass@host/db'.
.env файл хранит токен и секреты (не коммить в Git!).
Теперь db.py: создаём движок и сессию SQLAlchemy.
# db.py
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, scoped_session
from config import DATABASE_URL
engine = create_engine(DATABASE_URL, echo=False, future=True)
SessionLocal = scoped_session(sessionmaker(bind=engine, autoflush=False, autocommit=False))
SessionLocal — это фабрика сессий. Мы используем scoped_session для thread-safety (важно для бота с многопоточностью).
Ключевой файл — models.py. Здесь определяем таблицы: пользователи, задачи и расписание (классы/занятия). Используем Enum для статусов задач.
# models.py (фрагмент)
from sqlalchemy import Column, Integer, String, DateTime, Boolean, ForeignKey, Text, Enum, Time
from sqlalchemy.orm import declarative_base, relationship
import enum
from datetime import datetime, time
Base = declarative_base()
class TaskStatus(enum.Enum):
pending = "pending"
done = "done"
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True) # internal id
tg_id = Column(Integer, unique=True, index=True, nullable=False) # telegram user id
name = Column(String, nullable=True)
default_remind_minutes = Column(Integer, default=30) # default reminder before event in minutes
tasks = relationship("Task", back_populates="user", cascade="all, delete-orphan")
classes = relationship("ClassSchedule", back_populates="user", cascade="all, delete-orphan")
class Task(Base):
__tablename__ = "tasks"
id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False)
noscript = Column(String, nullable=False)
denoscription = Column(Text, nullable=True)
starts_at = Column(DateTime, nullable=False, index=True) # <- timezone=True
remind_before_minutes = Column(Integer, nullable=True)
status = Column(Enum(TaskStatus), default=TaskStatus.pending)
user = relationship("User", back_populates="tasks")
# ClassSchedule для еженедельных занятий (фрагмент)
class ClassSchedule(Base):
__tablename__ = "class_schedules"
id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False)
noscript = Column(String, nullable=False)
weekday = Column(Integer, nullable=False) # 0..6
start_time = Column(Time, nullable=False, index=True)
duration_minutes = Column(Integer, default=90)
location = Column(String, nullable=True)
active = Column(Boolean, default=True)
remind_before_minutes = Column(Integer, nullable=True)
user = relationship("User", back_populates="classes")
Please open Telegram to view this post
VIEW IN TELEGRAM
Объясню:
В main.py инициализируем БД:
Это создаст таблицы при старте. Для миграций в проде используйте Alembic, но для MVP хватит.
⚙️ Советы:
🧩 🧩 🧩 🧩 🧩 🧩 🧩 🧩
🧩 🧩 🧩 🧩 🧩 🧩 🧩 🧩
🧩 🧩 🧩 🧩 🧩 🧩 🧩 🧩
🧩 🧩 🧩 🧩 🧩 🧩 🧩 🧩
🧩 🧩 🧩 🧩 🧩 🧩 🧩 🧩
🧩 🧩 🧩 🧩 🧩 🧩 🧩 🧩 🧩
#CodeShadow #TelegramBot #Python #SQLAlchemy #Планировщик
— User — базовая модель с Telegram ID и дефолтным временем напоминания.
— Task — разовая задача: заголовок, описание, дата/время, статус (pending/done), напоминание.
— ClassSchedule — фиксированное расписание: день недели (0=Пн), время старта, длительность, локация. Активно/неактивно для деактивации без удаления.
— Связи: one-to-many (пользователь имеет много задач/занятий), с каскадным удалением.
В main.py инициализируем БД:
# main.py (фрагмент)
from db import engine, SessionLocal
from models import Base
def init_db():
Base.metadata.create_all(bind=engine)
# ... потом запуск бота
Это создаст таблицы при старте. Для миграций в проде используйте Alembic, но для MVP хватит.
- Храните даты в UTC, но в коде используйте pytz для локальной зоны (Europe/Moscow по дефолту).
- Индексы на starts_at и start_time ускорят запросы по времени.
- Cascade="all, delete-orphan" — автоматически удаляет задачи при удалении юзера (хотя в боте юзеры не удаляются).
В следующем посте разберём utils.py и scheduler.py — хелперы, парсинг дат и как настроить напоминания с APScheduler. Если есть вопросы по БД — пишите в комментах!🧠 Что думаешь: SQLite хватит для такого бота или сразу на Postgres? Делитесь опытом!
#CodeShadow #TelegramBot #Python #SQLAlchemy #Планировщик
Please open Telegram to view this post
VIEW IN TELEGRAM
Привет, кодеры! Продолжаем разбор Telegram-бота для планирования задач. В первом посте — обзор, в Части 1 — БД и модели. Сегодня: utils.py (хелперы) и scheduler.py (напоминания с APScheduler).
Утилиты для парсинга дат, форматирования и клавиатур Telegram.
# utils.py (ключевые функции)
from datetime import datetime
from dateutil import parser
from config import TZ
from telebot import types
def parse_datetime_user(text: str) -> datetime:
formats = ["%Y-%m-%d %H:%M", "%d.%m.%Y %H:%M", "%Y-%m-%d", "%d.%m.%Y"]
for fmt in formats:
try:
dt = datetime.strptime(text, fmt)
return TZ.localize(dt)
except ValueError:
continue
return None
def format_task(task):
s = f"#{task.id} {task.noscript}\nКогда: {task.starts_at.strftime('%Y-%m-%d %H:%M')}\nСтатус: {task.status.value}"
if task.denoscription:
s += f"\n{task.denoscription}"
return s
def make_main_keyboard():
kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
kb.row(types.KeyboardButton("➕ Добавить задачу"), types.KeyboardButton("➕ Добавить пару (фикс.)"))
kb.row(types.KeyboardButton("📋 Мои задачи"), types.KeyboardButton("📅 Расписание / Календарь"))
kb.row(types.KeyboardButton("⚙️ Настройки"), types.KeyboardButton("📝 Отчёт за неделю"))
return kb
-
parse_datetime_user: парсит даты в разных форматах, добавляет таймзону.-
format_task: выводит задачу в читаемом виде.-
make_main_keyboard: главная клавиатура с кнопками.Фоновая система напоминаний на APScheduler.
# scheduler.py (основные функции)
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.date import DateTrigger
from apscheduler.triggers.cron import CronTrigger
from db import SessionLocal
from models import Task, ClassSchedule, User, TaskStatus
from config import TZ
scheduler = BackgroundScheduler(timezone=TZ)
scheduler.start()
def schedule_task_reminder(task_id: int, when: datetime, bot, message_text: str):
job_id = f"task_{task_id}"
scheduler.add_job(
func=lambda: _send_task_reminder(task_id, bot, message_text),
trigger=DateTrigger(run_date=when),
id=job_id,
replace_existing=True
)
# _send_task_reminder: отправляет сообщение, если задача pending
def schedule_weekly_class_reminder(class_id: int, bot):
# Настраивает cron для еженедельного напоминания по дню/времени
# Использует remind_before_minutes или дефолт 30 мин
pass # (полный код в репозитории)
def load_all_jobs(bot):
# При старте загружает все pending задачи и active классы в scheduler
pass
- schedule_task_reminder: разовое напоминание за N минут до задачи.
- schedule_weekly_class_reminder: еженедельные cron-задачи для занятий.
- load_all_jobs: восстанавливает задания при запуске бота.
- APScheduler в памяти; для продакшена — job store в БД.
- Проверяйте статус перед отправкой, чтобы избежать спама.
- Логируйте ошибки отправки.В следующем посте — bot_handlers.py: обработчики команд и FSM для диалогов. Вопросы по APScheduler? Пиши!🧠 Что добавить в напоминания? Идеи в комментах!
#CodeShadow #TelegramBot #Python #APScheduler #Планировщик
Please open Telegram to view this post
VIEW IN TELEGRAM
В прошлом посте («Быстрый старт») мы собрали заголовки с новостного сайта. По результатам опросника, сегодня идём дальше и напишем полезный парсер погоды с Gismeteo.
Почему именно погода?
import requests
from bs4 import BeautifulSoup
# URL страницы погоды для Москвы
url = "https://www.gismeteo.ru/weather-moscow-4368/"
# Делаем запрос (User-Agent нужен, чтобы сайт "поверил", что мы браузер)
html = requests.get(url, headers={"User-Agent": "Mozilla/5.0"}).text
# Создаём объект BeautifulSoup
soup = BeautifulSoup(html, "html.parser")
# Находим тег <temperature-value> (он хранит температуру в атрибуте "value")
temp_tag = soup.find("temperature-value")
# Забираем число и преобразуем к int
temperature = int(temp_tag["value"])
# Добавляем знак: +, − или ничего (для нуля)
if temperature > 0:
sign = "+"
elif temperature < 0:
sign = "−"
else:
sign = ""
# Выводим результат
print(f"Москва: {sign}{abs(temperature)}°C")
☀️ requests скачивает страницу;☀️ BeautifulSoup разбирает HTML;☀️ <temperature-value> имеет атрибут value, где хранится число (может быть отрицательным зимой❄️ );☀️ мы вручную добавляем знак «+» или «−»;☀️ результат выводим красиво.
☀️ добавить выбор города (через аргумент или список URL);☀️ вытягивать прогноз на несколько дней вперёд;☀️ упаковать в Telegram-бота («/weather Москва» → ответ с температурой).
Please open Telegram to view this post
VIEW IN TELEGRAM
💼 GitHub и портфолио: твой залог заказов
Фрилансер без портфолио = программист без доказательств.
Выкладывай туда:
- свои мини-проекты
- примеры парсинга
- ботов
Пусть клиент видит твои работы ещё до заказа.
Совсем скоро обсудим где искать заказы и как правильно откликаться.
Фрилансер без портфолио = программист без доказательств.
Выкладывай туда:
- свои мини-проекты
- примеры парсинга
- ботов
Пусть клиент видит твои работы ещё до заказа.
Совсем скоро обсудим где искать заказы и как правильно откликаться.
🌍 Где искать заказы: первые шаги
Популярные площадки: Kwork, Freelancehunt, Upwork.
Советы:
- бери сначала простые заказы (парсинг, боты, Excel)
- отвечай быстро и по делу
- прикрепляй похожие проекты из портфолио
И последнее — подведём итог всей серии.
Популярные площадки: Kwork, Freelancehunt, Upwork.
Советы:
- бери сначала простые заказы (парсинг, боты, Excel)
- отвечай быстро и по делу
- прикрепляй похожие проекты из портфолио
И последнее — подведём итог всей серии.
Final Results
71%
Уже жду кейсы 👨💻
29%
Пожалуй, Python достаточно 🐍
CodeShadow pinned «🤔 Стоит выкладывать кейсы по Фронтенду (HTML, CSS, создание лендингов)?🐍»