Задать вопрос
  • Как переделать telegram bot под serverless архитектуру?

    Viji
    @Viji
    DevOps Engineer
    В облаке selectel есть возможность запуска бессерверных функций и тебе не надо ходить ни к какому aws.

    https://selectel.ru/services/cloud/serverless/
    Ответ написан
    1 комментарий
  • В чем заключаются архитектурные ошибки моего кода?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    class Calculation():
    
      def __init__(self, calculation):
        #init
        self.calculation = calculation

    Вы сделали класс `Вычисления`, чтобы проводить вычисления, пока проводятся вычисления вычислений над вычислениями, которые вычисляются как аргумент вычислений для вычисления состояния вычислений.

    Вы бы хотя бы в предметную область нас тут погрузили хоть немножечку. Не понятно же ничерта. Обычно класс и инстанс можно называть одинаково, за исключением первой буквы, но вы тут в аргументы что-то передаёте и то нифига не понятно. Делайте докстринги.

    Используйте тайпхинтинг, это позволяет не только статичесий анализ кода делать и избегать лишних ошибок, но, к тому же, это мощный инструмент документирования кода, неотрывно связанный с самим кодом. Это значит, что документация не отстанет от кода, а, напротив, будет за счет формализма и машиночитаемости помогать IDE помогать нам писать код. К тому же ряд вопросов отпадёт у тех, кто пытается читать код. Не нужно гадать на кофейной гуще что есть что.

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

    У вас в коде полно "магических" констант. Именуйте их и выносите в начало модуля или, хотя бы, указывайте в инлайн-комментах единицы измерения для ясности. Не пренебрегайте свойствами, их можно документировать .

    Вы тут много работаете с календарными периодами. перебираете их с шагом... Это хорошее место для выделения функциональности в отдельную библиотеку, в отдельный тип данных. Возможно писать свой велосипед даже не придётся, ведь найдётся много готовых качественных протестированных библиотека для этих целей. Их будет легко и понятно инициализировать, у них будет простой, понятный и универсальный АПИ, они будут однотипно использованы в разных мемтах проекта, не придётся смешивать в одном контесте кучу переменных для обеспечения двух имплементаций одной и той же функциональности.
    Количество кода резко убавится, универсальный код будет вынесен в отдельный модуль и будет отдельно и полноценно протестирован, а в бизнес логике вы будете коротко и лаконично работать с абстракцией - понятной и простой.

    Вот тут у вас, очевидно, можно написать проще и без лишних повторений, провоцирующих ошибки:
    if i % self.inflation_indexation_period==0 and i != 0:
            if i not in range(0, self.inflation_indexation_period):
              init_indexation_inflation *= self.sales_init.inflation_indexation
            else:
              init_indexation_inflation = 1
            inflation_indexations.append(round(init_indexation_inflation, 5))
          else:
            inflation_indexations.append(round(init_indexation_inflation, 5))

    Лучше так:
    if i % self.inflation_indexation_period==0 and i != 0:
            if i in range(self.inflation_indexation_period):
              init_indexation_inflation = 1
            else:
              init_indexation_inflation *= self.sales_init.inflation_indexation
    
          inflation_indexations.append(round(init_indexation_inflation, 5))

    Функция get_inflation_indexations у вас имеет опасный побочный эффект. Она имеет префикс get_ но модифицирует контекст объекта. Это кэширование? Чем обусловлено такое поведение? Если такое делается "на всякий случай". то это плохая практика неявного внедрения побочного эффекта. Если нарочно, то такое надо документировать и корректно называть и описывать метод в докстринге.

    Опять же, get_inflation_indexations и get_value_indexations очень похожи по коду. Это повод вынести такую логику в отельную функцию, она будет проще и её будет проще тестировать!
    А у вас эти функции отличаются именами атрибутов внутри и магическими константами, которые в коде делать не хорошо, тем более без пояснений, тем более в кусках такого похожего кода.

    Перестаньте использовать i в качестве переменной для итерирования нетривиальных сущностей, отличных от протсого счетчика. i - это индекс. Используйте человеко-понятное название переменной для этого!

    Используйте декоратор итераторов enumerate. Это сделает код более прозрачным и читабельным, чем код с параллельными счетчиками. Увидев enumerate читатель кода сразу поймёт, что это простой счетчик итерируемых сущностей, что не нужно ожидать скачков этого счетчика и каких-то сложных корреляций.

    А вот здесь вообще всё плохо:
    count = 0
        revenue_list = []
        for i in total_price:
          revenue = i*total_value[count]
          revenue_list.append(revenue)
          count+=1

    count - это "количество", а вы его используете как "индекс" и никак иначе!
    i - это индекс, а вы туда суёте фактически цену!
    У вас total_price и total_value параллельные одноразмерные списки, их нужно состегнуть с помощью zip и пронумеровать с помощью enumerate (если надо, а здесь не надо!).
    Весь этот кусок понятнее, проще, короче и более питоничнее записать в такой форме:
    revenue_list = [price * value for price, value in zip(total_prices, total_values)]


    Итого вся вот эта громоздкая плохо читабельная функция:
    def get_revenue(self):
        '''Получить итоговую выручку'''
        total_price = []
        for i in self.get_inflation_indexations():
          price = self.sales_init.price*i
          total_price.append(price)
    
        total_value = []
        for i in self.get_value_indexations():
          value = self.sales_init.sales_volume*i
          total_value.append(value)
    
        count = 0
        revenue_list = []
        for i in total_price:
          revenue = i*total_value[count]
          revenue_list.append(revenue)
          count+=1
    
        return revenue_list

    Легко и читабельно для питониста заменяется на вот такую:
    def get_revenue(self):
        '''Получить итоговую выручку'''
        indexations = self.get_inflation_indexations()
    
        init_price = self.sales_init.price
        total_prices = [init_price * x for x in indexations]
    
        init_volume = self.sales_init.volume
        total_values = [init_volume * x for x in indexations]
    
        return [price * value for price, value in zip(total_prices, total_values)]


    И везде не стоит использовать параллельные счетчики, используйте итераторы, распаковку, зипы, енумервторы и функциональный стиль, ведь он сокращает код и делает его проще.

    Что это за ерунда:
    def get_interest_expenses(self):
        '''процентные расходы'''
        interest_expenses_list = []
        return interest_expenses_list


    Зачем много раз считать одно и то же целиком, чтобы взять только очередной кусочек из всего посчитанного?!
    Это вообще бред. Учитесь основам алгоритмизации и не надо программировать на питоне как не на питоне.

    Вот такое вообще жесть: self.get_revenue()[count]
    Отчего не сохранить в промежуточную переменную?!

    В общем, всё плохо.
    Если у вас есть функция, вычисляющая какой-то список, то зачем её вычислять каждый раз, когда вам нужен только один очередной элеиент этого списка, а вы перебираете его целиком?!
    И так много раз везде!
    Тут не архитектура хромает, тут основы алгоритмизации плачут. Тренируйтесь на кошках, сударь, больше решайте алгоритмических задачек. Структурируйте, декомпозируйте.

    Удачи.
    Ответ написан
    3 комментария
  • Как исправить причину стоп телеграм бота на питон?

    @IKIQ
    Телеграм для уменьшения нагрузки на свои серверы периодически банит лонгполлинги
    Решение - или автоматически перезапускать бота, или, что предпочтительнее, использовать вебхуки

    Вот есть вопрос по теме https://qna.habr.com/q/417341
    Ответ написан
  • Как построить график по массиву с данными?

    phaggi
    @phaggi Куратор тега Python
    лужу, паяю, ЭВМы починяю
    Мне кажется, вы плохо искали. Первое, что попалось в гугле, по-моему, вполне подходит.
    Ответ написан
    Комментировать
  • Как правильно создать условие в функции?

    AlexNest
    @AlexNest Куратор тега Python
    Работаю с Python/Django
    Собственно, текст сообщение будет всегда будет строкой, даже если в нем будет просто цифра, поэтому стоит проверить, является ли все символы в нем - цифры
    Ответ написан
    Комментировать
  • Как правильно создать условие в функции?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    message.text.isalpha()
    Или
    message.text.isdigit()
    Ответ написан
    1 комментарий
  • Как сделать, чтобы при нажатии кнопки выводился текст на дисплей?

    ProgrammerForever
    @ProgrammerForever
    Учитель, автоэлектрик, программист, музыкант
    Откройте пример для работы с дисплеем. Останется только добавить один if для обработки кнопки.
    Ответ написан
    Комментировать
  • Отправка документа ботом в ответ на сообщение пользователя?

    iggor-markin
    @iggor-markin
    Python Developer
    В документации есть пример работы с файлами. Это находится на главной странице репозитория. А вообще, уже отвечали.
    # sendDocument
    doc = open('/tmp/file.txt', 'rb')
    tb.send_document(chat_id, doc)
    tb.send_document(chat_id, "FILEID")
    Ответ написан
  • Что сейчас с вакансиями Front-end?

    firedragon
    @firedragon
    Не джун-мидл-сеньор, а трус-балбес-бывалый.
    Странная я бы сказал. Я не снимал лычку что работаю в компании, но за последний месяц 4 холодных звонка.
    Разошлись по ценнику. я начинаю от 240 тр. или от 200 по ТК.
    И в тот же месяц ок 350 на фрилансе. Понятно что тут я сам себе директор, программист, бизнес аналитик и прочее. Но в общем жизнь в ати есть и очень активная
    Ответ написан
    4 комментария
  • Как сделать что бы выбор был не с 0 до 2, а с 1 до 3?

    @Mootfrost
    C#, C++, JS, Python
    вычитайте 1 из ввода
    Ответ написан
    Комментировать
  • Где почитать о паттернах построения программных систем?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    "Чистый код" того же автора, "Архитектура корпоративных приложений" Фаулера и "Банда четырёх". А если в отрыве от конкретно "Чистой архитектуры", то есть десятки книг, которые стоит прочитать. Те же SICP и H2DP.
    Ответ написан
    Комментировать
  • Где почитать о паттернах построения программных систем?

    @basili4-1982
    Ну а гуглить непонятные понятия не пробовали? Там описания о каждом пару предложений. Мне кажется это лучшее решение увидели не понятное слово - гуглим
    Ответ написан
    Комментировать
  • Как сделать, чтобы программа для бота запоминала, на какие кнопки нажал пользователь?

    @twistfire92
    Python backend developer
    Если вы используете обычную клавиатуру, не inline, то советую посмотреть в сторону метода register_next_step_handler() В интернете полно примеров использования, в том числе на этом ресурсе.
    Но мало где описывается, что помимо объекта сообщения и объекта функции этот метод принимает аргументы, которые в эту функцию передает.
    Пример такого использования можете посмотреть тут
    Ответ написан
    Комментировать
  • Ошибка синтаксиса, как исправить?

    AlexNest
    @AlexNest Куратор тега Python
    Работаю с Python/Django
    Может, для разнообразия вы будете читать текст ошибки?
    if player1 == 0:                 #ошибка синтаксиса в этой строке
    IndentationError: expected an indented block after 'while' statement on line 61

    Тут три варианта:
    Вы не в состоянии прочитать/осмыслить ошибку
    Вы не в состоянии перевести ошибку (даже имея под рукой интернет с кучей переводчиков)
    Вам лень систематически изучать даже основы языка, в которых сказано, что python отсупозависимый.
    Для первых двух пунктов, увы, решения нет. Для третьего - взять волю в кулак и не просто тыкайся, в надежде найти полезный кусок знания, а найти нормальный источник (Например книга Марка Лутца) и учится по нему
    Ответ написан
    Комментировать
  • Ошибка в импорте библиотеки telebot. Как ее исправить?

    @mrsalam
    Убедитесь, что вы установили библиотеку pytelegrambotapi, а не просто telebot
    Ответ написан
    Комментировать
  • Как выйти из тупика, как поднять уровень?

    ddv88
    @ddv88
    Binance Futures
    Слабо верится в Освоил %список% в совокупности пока пилю на ноде.
    Может быть ты путаешь «освоил» с «немного пощупал, то что спроектировали другие».

    возможно я уже sinier просто я об этом не знаю.
    заучивать теорию, патерны

    Точно не синьор, пока что расслабься)

    идти в тим лиды и тех лиды

    Это так не работает. Ты можешь конечно попробовать на собесы заскочить, тебя там попустят и ты расслабишься)

    я понимаю что это разные скилы (разработчик и лид)
    есть смысл развиваться в лиды.

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

    Хочу развиваться дальше в этой карьере но не знаю как.

    Зависит от того что ты хочешь получить от этого развития.

    Кто-то хочет войти в айти. Я лично из него вышел. Я уперся в денежный потолок на позиции фула/лида и закрутил свое дело, которое мне приносит больший доход и еще позволяет заниматься своими хобби и иметь доп финансы с них. В том числе кодинг остался хобби, но перешел из разряда кодить на контору в кодить для своего бизнеса.
    Ответ написан
    Комментировать
  • Легкий вопрос по Python, но все же не могу понять, как решить задачу?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    Прописывайте условия полностью
    У вас не «(a - 1 либо a + 1) равны c», а «(a - 1) или (a+1=c)»

    т. е bool(a-1)

    if (a - 1 == c) or (a + 1 == c):
    Ответ написан
    Комментировать
  • Легкий вопрос по Python, но все же не могу понять, как решить задачу?

    if a - 1 == c or a + 1 == c
    Ответ написан
    Комментировать
  • Как научиться декомпозировать задачи?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Переодически может появиться очень крупная задача вида "нужно то не знай что". Мне приходится с ней разбираться и если с первым этапом - конкретизация требований все более-менее понятно, то с дальнейшими действиями все совсем плохо.

    Ситуация - знакомая. Во первых это - не задача. Это issue типа investigation. Его результатом должен быть не финальный продукт а просто новый сет issues. Оценивать время можно как угодно. Можно писать 1 день для начала. Все равно никто не сможет оспорить вашу оценку.

    А совсем попа когда во время разработки понимаешь, что все должно быть не совсем так как ты запроектировал и приходится переделывать.

    Это - риски и их просто надо заранее проговорить на митингах. Просто сообщайте заказчику что задача - рисковая и если что-то не так пойдет - то время надо будет сдвинуть.
    Ответ написан
    Комментировать
  • Как научиться декомпозировать задачи?

    Adamos
    @Adamos
    Дробить задачу еще на более мелкие совсем не охота

    Ну и зря. Вообще-то технологиям планирования совместной работы уже не первый век, и важнейший этап - как раз выделение тех участков работы, которые критичны для начала работы на других участках, и подтягивание их на диаграмме Ганта как можно раньше, чтобы уменьшить простой. Потом уже менее критичные задачи ложатся на свободные участки и параллелятся относительно друг друга.
    Так, например, нас учили делать генплан строительства еще 30 лет назад. До популяризации в РФ всяких там Скрамов и Канбанов.
    Ответ написан
    8 комментариев