Последнее обновление: 29 July, 2021
На одном из звонков со своим тим лидом, я спросил его про то, что я могу делать, чтобы быстрее расти, как профессионал.
Дело в том, что я достаточно много вкладываюсь в свое развитие, как человека и как программиста, поэтому регулярно ищу новые методы для того, чтобы испытать свои возможности. Я перечислил тим лиду все, что я практиковал на тот момент: книги, обучение других, практику разных языков программирования, изучение разных теорий (например, мне очень интересно читать и узнавать больше о проектировании распределенных систем и о криптографии).
Если обобщить его ответ коротко, то это было:
— Ты слишком много читаешь. А надо больше делать.
Это был драгоценный совет.
Я уже давно откладывал свои проекты в долгий ящик, и его слова сильно вдохновили меня на то, чтобы наконец этот ящик распаковать.
Первым моим проектом стала автоматизация ведения нашего семейного бюджета с помощью Notion API и Telegram API.
Итак, поехали.
Я считаю, что залог успешного ведения семейного бюджета в жесткой финансовой дисциплине. Я завожу каждый расход с категорией и со всеми единицами, которые мы приобретаем. Для этого раньше мы сохраняли каждый чек (потому что там содержатся все товары, которые мы приобрели) и заводили в ноушене карточки в которых содержится список товаров из чека. Это выглядит вот так.
Сама карточка в базе данных выглядит вот так.
Вся база данных выглядит вот так.
Такая система дает нам максимальное количество информации по поводу того, что мы покупаем и когда. Это позволяет нам покупать товары с более высокой эффективностью.
Например, очень высокая эффективность покупки у бруска пармезана или грано падано, чили перцев, банки нутеллы, киноа.
Конечно же, эффективность разных товаров для разных семей разнится, но, думаю, суть вы уловили.
Так же мы экспериментируем с разными наборами товаров и в любой момент можем восстановить историю по нашим экспериментам (заглянуть, например, что мы покупали в кризис или когда меньше зарабатывали, или когда было очень холодно, или на Новый год).
В общем, нам нравится такая система. Существенным ее недостатком было время, которое нужно потратить, чтобы позаводить все чеки, и сверка финансов план-факт. На данный момент я автоматизировал заведение всех чеков, про это и расскажу.
Я использовал flask
, python-telegram-bot
и notion-client
. Последняя имеет версию 0.4.0 на момент написания моего поста и это значит она еще не считается готовой для серьезных проектов.
Мой проект не серьезный, в нем вполне может что-то поломаться и я не буду сильно расстраиваться. Мне очень понравилось пользоваться библиотекой, в ней есть подсказки по типам и аннотации под функции.
Я поднял простенький сервер на фласке, сделал раут и установил веб хук для бота в телеграме. Таким образом, сервер телеграмма присылает обновление моему серверу каждый раз, когда они происходят, и мой бот на них как-то реагирует.
Так же я сделал регулярную задачу с помощью job_queue
(подробнее о нем можно почитать в библиотеке python-telegram-bot
), суть которой каждый день смотреть сколько у нас осталось денег на разные категории расходов и публиковать информацию об этом в наш семейный телеграм канал.
Каждый раз, как я или моя девушка, публикуем сообщение в общий телеграм канал с расходами, вот такого вида:
<категория расходов>
поездка на метро 8
...бот забирает весь текст сообщения, отделяет первую строку, сравнивает насколько она похожа на категории расходов, которые определены в моей ноушен базе данных и если название категории совпадает, то сообщение разбивается на токены.
Для сравнения строк, я использую:
SequenceMatcher(None, tokens[0], type_of_spend["title"]).ratio() > 0.6
После этого из каждого токена (строки) вытягиваются числа вот таким регулярным выражением:
re.findall(r"[-+]?\d*\.\d+|\d+", token)
Потом идет взаимодействии с апи, создается карточка и обработка нового сообщения завершается.
В библиотеке python-telegram-bot
есть один большой минус, аттрибуты у Update
из телеграмма не постоянны и есть высокий риск напороться на то, что у вашего апдейта не будет того аттрибута, который вы ожидаете, что у него будет. Поэтому я рекомендую быть очень осторожным с проверками того, что содержится в апдейте.
Вот так выглядит моя функция, которая обрабатывает обновления, которые присылает моему серверу телеграм.
def notion_card_creater(update: Update, context):
if hasattr(update, "channel_post"):
chat_id = update.channel_post.chat_id
if chat_id == our_home_chat_id:
content = update.channel_post.text
make_notion_card(content)
Я разместил свой сервер в облаке бесплатно, используя Google Cloud Run. У этого сервиса гугла достаточно жирный free tier, на домашнего бота хватает более чем.
Вот мой Dockerfile для сборки образа.
FROM python:3.8-slim
ENV PYTHONUNBUFFERED True
WORKDIR /app
COPY *.txt .
RUN pip install --no-cache-dir --upgrade pip -r requirements.txt
COPY . ./
CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 bot:app
Я пользовался отличной статьей Hosting Telegram bots on Cloud Run for free.
В Google Cloud Run можно настроить continious deployment с вашего репозитория на гитхабе. Это очень удобная штука.
Я хочу, чтобы этот пост вдохновил на создание чего-то своего.
По собственному опыту я знаю, что если в посте содержится полный код проекта — это меня абсолютно не мотивирует думать о том, как построить проект самостоятельно.
Я бы хотел, чтобы ты, мой читатель, почувствовал интерес к тому, что можно сделать что-то, что поможет тебе самому или твоей семье на пути к вашим финансовым целям. Но для того, чтобы это была твоя личная победа, я рекомендую заняться этим проектом самостоятельно.
Это очень помогает поверить в собственные силы, полюбить программирование и избежать того, что в английском называется programming tutorial hell
.
Спасибо моему тим лиду Игорю Можаровскому, который натолкнул меня на эти мысли.
Трой Кёлер - программист, живущий в Берлине, Германия. У него более 6 лет опыта работы в IT. Ранее он работал в одном из крупнейших интернет-магазинов Украины, а сейчас работает в Zalando. Он специализируется на языке программирования Rust, сложных бекенд системах, разработке продуктов и инженерных платформах.