• Как вывести значения из базы данных без запятых скобок и т.д?

    Vindicar
    @Vindicar
    RTFM!
    fetchall() возвращает тебе список из кортежей.
    Если ты не знаешь, что это такое - бегом учить. Это абсолютно базовые структуры данных в питоне, для создания сколь-нибудь сложной программы с ними (+ещё словари) нужно уметь работать не задумываясь.
    Ответ написан
    Комментировать
  • В чем заключаются архитектурные ошибки моего кода?

    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 комментария
  • Редактирование ячеек таблицы HTML и обновление базы sqlite3?

    AlexNest
    @AlexNest
    Работаю с Python/Django
    Процесс сохранения в базу имеет 2 взаимосвязанных части:
    • клиентская, которая обрабатывает ввод данных пользователем, сериализирует введенные данные данные (по факту - приводит к одному из стандартов, например json), после чего отправляет данные на сервер.
    • Серверная часть получает данные, если нужно как-то их обрабатывает, после чего сохраняет в базу.

    Судя по коду (с js`ом я, увы, на вы) при вводе символа в ячейку, ее содержимое отправляется post-запросом по определенному адресу.
    Как этот запрос обрабатывается на сервере - непонятно, т.к. код вы не привели. В общем случае, это должно происходить так:
    1. Валидируются данные
    2. Происходит подключение к базе
    3. Данные подставляются в запрос (подготовленные запросы, PDO (актуально для php, указанного в тегах) или orm)
    4. Запрос выполняется
    5. При необходимости отдается ответ клиенту

    P.S. К тому же, непонятно как вы определяете, какие данные нужно изменить. Чтобы изменить запись в базе нужно указать какую именно запись вы собираетесь изменить (например с помощью id или какого-то другого уникального поля). При этом, поскольку вы отправляете только одну ячейку, сделать это невозможно, поскольку поле может содержать неуникальные значения по типу цены (абстрактный пример), которая может быть одинаковой для разных товаров.
    Ответ написан
    2 комментария
  • Не могу найти ошибку в коде Python?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Не надо ловить абстрактный Exception вообще никогда! Тем более игнорировать его и даже не выводить в консоль. Произошла ошибка, а какая, почему произошла - ваще непонятно.

    Какие тут могут случиться ошибки? Ну, например, если в user_dict нет записи с ключом chat_id, то случится KeyError. Или если в getRegData возвращается невалидный markdown-текст, то случится ошибка ApiException.

    А далее после обработки exception путём его игнорирования тут снова вызывается register_next_step_handler, который приводит к тому, что вводимые пользователем данные снова попадают в тот же обработчик и - вероятно - натыкаются на ту же самую ошибку. Например, KeyError: конечно, ведь как при прошлом запуске этого обработчика не было значения с таким ключом, так и при последующих не появится.

    До кучи, не надо вызывать постоянно bot.get_me(). Это каждый раз будет вызов API. Неужели имя бота меняется каждую минуту? Достаточно запомнить при запуске бота - и достаточно.
    Ответ написан
    Комментировать
  • Python, проблема вывода значения списка (не могу объяснить точнее в чем проблема, я pre-pre-pre junior developer)?

    phaggi
    @phaggi Куратор тега Python
    лужу, паяю, ЭВМы починяю
    Вопрос кажется простым. Но ответ потребует объяснения большого количества разнообразных принципов и может превратиться в целый цикл лекций.
    Набросаем путь освоения:
    1. Объектная модель языка Python
    2. Структуры данных вообще и языка Python в частности
    3. ООП вообще и понятие классов, экземпляров, атрибутов, методов, инициализации экземпляров в частности.
    4. Реализация конкретного класса User в конкретной версии библиотеки.
    5. Осмысление места, роли этого класса, его атрибутов, причин такой реализации, последствий для программирования бота;
    6. Вероятно, базы данных, их связь с классами; поля БД, их связь с атрибутами класса;
    7. Понимание, как всё это в целом работает, какие пути есть для получения искомых сведений и какие последствия могут возникнуть для работы бота, канала, Телеграма и его пользователей при работе с этими сведениями.


    Вот вам пример простейшей реализации:
    class User:
        def __init__(self, a, b, c):
            self.a = a
            self.b = b
            self.c = c
    
        def __repr__(self):
            return f'a:{self.a}\tb:{self.b}\tc:{self.c}'
    
    users = [User(1, 2, 3), User(('z', 'y', 'x'), 5, 6), User('a', 'b', None)]
    
    for user in users:
        print(user)
        print(f'a:{user.a}')
    print(users[1].a)
    print(users[2].c)

    из него можно извлечь некоторые сведения для вас.

    Но вовсе не обязательно, что в вашем классе User всё реализовано так просто. Надо посмотреть на него глазами.
    Ответ написан
    Комментировать
  • Почему цикл в рекурсии перебирает один и тот же объект?

    @twistfire92
    Python backend developer
    Основная проблема в том, что d_find принимает на вход имя ключа в виде строки и словарь в котором надо найти этот ключ.
    На первом же витке рекурсии вы передаете в функцию имя ключа по которому нужно найти значение и ИМЯ ТЕКУЩЕГО КЛЮЧА, который тоже представляет собой строку.
    Строки в питоне - итерируемые объекты. Вы начинаете итерироваться по строке 'b' и тем самым уходите в бесконечные дебри.

    def d_find(name, d):
        if name in d.keys():
            return d[name]
        else:
            for key, value in d.items():
                if isinstance(value, dict):
                    if result := d_find(name, value):
                        return result
    Ответ написан
    Комментировать
  • Как в Python разделить число по 3 символа?

    sswwssww
    @sswwssww
    number = 120360
    formatted_number = f'{number:,}'.replace(',', '.')
    print(formatted_number)
    >>> '120.360'
    Ответ написан
    Комментировать
  • Ошибка SyntaxError: invalid syntax как исправить?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Python
    Седой и строгий
    Посмотреть на строку, в которой возникла ошибка, применить знание основ синтаксиса для определения того, что в этой строке не так.
    Ответ написан
    Комментировать
  • Есть код питон. Как исправить?

    AlexNest
    @AlexNest Куратор тега Python
    Работаю с Python/Django
    Для начала отложить ботописательство и изучить python.
    Например, по книге Марк Лутц - Изучаем python. 5-e издание.
    Без знания основ вы, каждый раз как будет выскакивать ошибка, будете бежать в гугл/сюда/на stackowerflow с подобными вопросами.
    Конкретно по вашему вопросу - в указанной книге пятый раздел первого тома полностью посвящен модулям, на отсутствие которого ругается интерпритатор.
    Ответ написан
    Комментировать
  • В чем ошибка (пишет что return), но не могу понять где?

    Vindicar
    @Vindicar
    RTFM!
    Ну тебе же английским по белому написано: 'return' outside function
    Оператор return имеет смысл только в теле функции, а у тебя никакого объявления функции нет.
    Ответ написан
    2 комментария
  • Возможно ли использовать replace с символом \?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    s = s.replace('\\', "")
    Экранировать его
    Ответ написан
    2 комментария
  • Как создать симметричную матрицу из списка?

    bravebug
    @bravebug
    Только обещай понять, как это получилось, хорошо?
    l = [1, 0.6, 0.8, 0.3]
    l_len = len(l)
    res = [[l[abs(x-y)] for y in range(l_len)] for x in range(l_len)]
    print(res) # [[1, 0.6, 0.8, 0.3], [0.6, 1, 0.6, 0.8], [0.8, 0.6, 1, 0.6], [0.3, 0.8, 0.6, 1]]
    Ответ написан
    1 комментарий
  • Как проверить неопределенное количество элементов?

    AgentSmith
    @AgentSmith
    Это мой правильный ответ на твой вопрос
    Используй не массив, а список. Иди учи структуры данных, а то так и будешь вопросы на тостере задавать по каждой мелочи
    Ответ написан
  • Почему - то когда работаю с классом не через главный поток, переменные в классе не изменяются, почему?

    Vindicar
    @Vindicar
    RTFM!
    Ну второе как раз объяснимо, ты запускаешь work() для одного и того же класса.
    Пока первая копия work() спит в time.sleep(1), начинает выполняться вторая, так как всё происходит в отдельных потоках. Вторая видит isworking = 1, и останавливается.
    Ответ написан
    2 комментария
  • В чём проблема? Как решить?

    Vindicar
    @Vindicar
    RTFM!
    bot = discord.ext.commands.Bot(command_prefix = "|");
    bot.run("ТОКЕН")
    client = discord.Client()
    client.run('ТОКЕН')

    Вот скажи, ЗАЧЕМ тебе и Client и Bot?
    Впрочем, догадываюсь. Читать документацию - это ведь для ламеров, а в видяшке написано @client, значит, нужен класс Client, и не волнует.
    class discord.ext.commands.Bot
    Represents a discord bot.
    This class is a subclass of discord.Client and as a result anything that you can do with a discord.Client you can do with this bot.

    Выделение моё.
    В итоге ты регистрируешь команды на одном клиенте, запускаешь совсем другого, и удивляешься, что ничего не работает.
    Про самописную обработку команд в on_message() комментировать не буду.
    Ответ написан
    Комментировать
  • Как можно убрать лишние строки в TXT?

    fox_12
    @fox_12 Куратор тега Python
    Расставляю биты, управляю заряженными частицами
    Ну так не записывайте эти строки.
    Что тут еще без кода можно посоветовать...
    Ответ написан
    Комментировать
  • Я нашел код ассистента на python. Он работал но через некоторое время перестал. Выскочила ошибка что делать?

    AlexNest
    @AlexNest Куратор тега Python
    Работаю с Python/Django
    Выкинуть его нафиг, если не умеете читать ошибки.
    Если конкретно по вопросу:
    o = self.data[key]()
    В self.data нет указанного ключа
    Ответ написан
    2 комментария
  • Как код from datetime влияет на ошибку?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    Модуль называется datetime, в нем лежит класс datetime. Никакой разницы по сравнению с обычными библиотеками, в принципе, нет. Хотите, импортируйте полностью datetime, тогда для использования методов класса datetime, придется обращаться к классу полностью: datetime.datetime.now(). Хотите, импортируйте только класс datetime, тогда будете обращаться сразу к нему: datetime.now()

    В коде, соответственно, тоже можно использовать один из этих двух вариантов

    1.
    import datetime 
    datetime2 = datetime.datetime.now()  
    datetime2 = datetime2.strftime("%Y-%m-%d %H:%M")  
    dateFormatter = '%Y-%m-%d %H:%M' 
    dateString = "2022-02-9 20:00"
    
    spisok_start_date = datetime.datetime.strptime(dateString, dateFormatter) 
    datetime2 = datetime.datetime.strptime(datetime2, dateFormatter) 
    timedelta =  datetime2 - spisok_start_date


    2.
    from datetime import datetime 
    datetime2 = datetime.now()  
    datetime2 = datetime2.strftime("%Y-%m-%d %H:%M")  
    dateFormatter = '%Y-%m-%d %H:%M' 
    dateString = "2022-02-9 20:00"
    
    spisok_start_date = datetime.strptime(dateString, dateFormatter) 
    datetime2 = datetime.strptime(datetime2, dateFormatter) 
    timedelta =  datetime2 - spisok_start_date


    Если больше ничего не нужно, кроме класса datetime, то логично было бы сделать from datetime import datetime, чтобы избежать вот такого вот расстянутого кода
    Ответ написан
    2 комментария