Что нужно изменить в коде, чтобы он заработал правильно?

Как можно улучшить код, чтобы бонус можно было активировать каждые 24 часа в телеграм-боте? Вот часть кода:
```python
@bot.message_handler(func=lambda message: message.text == 'Бонус')
def handle_message(message):
    if message.chat.type == 'private':
        telegram_id = message.from_user.id

        dt = int(datetime.now().timestamp())

        dbс = sqlite3.connect('users.db', check_same_thread=False)
        sql = dbс.cursor()
        timer_bonus = sql.execute(f"SELECT timer_bonus FROM users WHERE telegram_id LIKE '%{telegram_id}%'").fetchone()
        timer_bonus = float(timer_bonus[0])

        time_to_end = timer_bonus - dt
        time_to_end /= 4356
        time_to_end = str(time_to_end)
        time_to_end = float(time_to_end[:4])

        if dt >= timer_bonus:
            dt = datetime.now() + timedelta(minutes=1440)
            timestamp_bonus = dt.timestamp()
            db.timer_bonus_db(telegram_id, timestamp_bonus)
            dom = types.ReplyKeyboardMarkup(resize_keyboard=True)
            homes = types.KeyboardButton("Домой")
            dom.add(homes)
            conn = sqlite3.connect('users.db')
            cursor = conn.cursor()
            cursor.execute('SELECT balance FROM users WHERE telegram_id = ?;', (telegram_id,))
            balance = cursor.fetchone()
            if not balance:
                db.add_user(telegram_id)
                balance = 0
            else:
                balance = balance[0]
            balance += int(balance_promo)
            cursor.execute('UPDATE users SET balance = ? WHERE telegram_id = ?', (balance, telegram_id))
            conn.commit()
            conn.close()
```
  • 6 марта 2024 г. 9:59
Ответы на вопрос 2
1. Замените `dbс` на `db` в строках, где вы обращаетесь к базе данных.
2. Замените `if dt >= timer_bonus:` на `if dt >= timer_bonus:` для правильного сравнения времени.

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

Примерно так можно сделать это:
```python
import time

@bot.message_handler(func=lambda message: message.text == 'Бонус')
def handle_message(message):
    if message.chat.type == 'private':
        telegram_id = message.from_user.id

        dt = int(time.time())

        # Получаем время последнего использования бонуса
        dbс = sqlite3.connect('users.db', check_same_thread=False)
        sql = dbс.cursor()
        last_bonus_time = sql.execute(f"SELECT last_bonus_time FROM users WHERE telegram_id LIKE '%{telegram_id}%'").fetchone()
        last_bonus_time = float(last_bonus_time[0])

        time_since_last_bonus = dt - last_bonus_time
        hours_since_last_bonus = time_since_last_bonus / 3600

        if hours_since_last_bonus >= 24:
            # Выдаем бонус и обновляем время последнего использования
            dt = int(time.time())
            db.timer_bonus_db(telegram_id, dt)

            # Остальной код для выдачи бонуса
            # ...

        else:
            bot.reply_to(message, "Вы уже использовали бонус слишком недавно. Попробуйте позже.")
```

В этом коде будет проверяться, прошло ли уже 24 часа с последнего использования бонуса. Если прошло, бонус будет выдан и время последнего использования обновлено. Если не прошло, пользователю будет отправлено сообщение о том, что он не может использовать бонус снова на данный момент.
Что именно значит "функцию не выполняет"? Вообще ничего не срабатывает (даже хэндлер), не добавляет бонус, неправильно добавляет бонус, не выводит сообщения, или не запускается именно функция timer_bonus_db? Вариантов же много, пишите конкретнее в вопросах. 

1. Лучше вообще никогда не использовать подстановку значений в запрос через форматирование, как сделано тут:
sql.execute(f"SELECT timer_bonus FROM users WHERE telegram_id LIKE '%{telegram_id}%'")

А всегда использовать через подстановку параметров (?), как Вы уже и делали в других местах
cursor.execute('SELECT balance FROM users WHERE telegram_id = ?;', (telegram_id,))
cursor.execute('UPDATE users SET balance = ? WHERE telegram_id = ?', (balance, telegram_id))


2. После изменения данных (insert, update, delete) нужно делать commit. В основном коде вижу это делается, а вот в dp.py (timer_bonus_db) явно у вас не показано, возможно там забыли. Т.к. это отдельное соединение (судя по тому, что делаете через класс), то там и свой commit нужно не забывать делать. Если у вас в этом классе commit принудительно нигде не делается, то это скорее всего и есть причина неправильной работы вашей команды.

3. Откуда взялось число 4356 в расчете?
time_to_end /= 4356
Время (текущее и из поля базы) у вас идет в секундах, затем для перевода в часы соответственно нужно делить на (60*60 = 3600).

4. В timer_bonus_db достаете timer_bonus из запроса в виде кортежа и конвертируете в число:
с = float(timer_bonus[0])
Но затем при проверке все равно используете кортеж
if timer_bonus != 0:
Что неправильно, т.к. если даже вернет 0, то получится
(0, ) != 0
что тоже сработает
Похожие вопросы