Форум программистов, компьютерный форум, киберфорум
Python: API, боты
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
0 / 0 / 0
Регистрация: 10.12.2018
Сообщений: 15

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

15.02.2023, 17:07. Показов 930. Ответов 1
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день. Посмотрите, пожалуйста, на код. Задумка: заходишь в бот, выбираешь питомца, кормишь его каждый день шагами. Потом хочу добавить уровни (как это сделать пока не знаю, но буду разбираться по мере поступления).
Хоть код запустился, но всё равно не полностью работает. Сначала просит (как надо) выбрать питомца, потом спрашивает количество шагов, а вот после второе меню вообще не активно, кнопки не нажимаются, и другие кнопки не активны почему-то.
А еще данные должны сохраняться в базе на компе, но они не сохраняются. В коде ошибки?((
У меня реально голова пухнет, взгляд замылился. Посмотрите, пожалуйста, код. Может вы найдете и подскажите, что нужно исправить. Буду очень благодарна, спасибо заранее!
Код:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
import logging
import sqlite3
import asyncio
import re
 
from datetime import datetime, timedelta
from aiogram import Bot, Dispatcher, types
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters import Text
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.types import ParseMode
from aiogram.utils import executor
 
logging.basicConfig(level=logging.INFO)
 
bot_token = 'token'
 
bot = Bot(token=bot_token)
storage = MemoryStorage()
dp = Dispatcher(bot, storage=storage)
 
db = sqlite3.connect('main3.db')
 
class Pet(StatesGroup):
    waiting_for_pet_choice = State()
    waiting_for_steps_number = State()
    waiting_for_next_action = State()
    waiting_for_steps_choice = State()
    waiting_for_reminder_time = State()
    waiting_for_new_steps_number = State()
 
class PetAction(StatesGroup):
    waiting_for_action_choice = State()
    waiting_for_walk_time = State()
 
@dp.message_handler(commands=['start'])
async def welcome(message: types.Message):
    await message.answer('Добро пожаловать на наш бот!\n'
                         'Пожалуйста, выберите животное для отслеживания:', reply_markup=types.ReplyKeyboardMarkup(
        keyboard=[
            [types.KeyboardButton(text='Собака'), types.KeyboardButton(text='Кот')],
            [types.KeyboardButton(text='Кролик'), types.KeyboardButton(text='Попугай')],
            [types.KeyboardButton(text='Myself')],
        ],
        resize_keyboard=True
    ))
    await Pet.waiting_for_pet_choice.set()
 
@dp.message_handler(Text(equals=['Собака', 'Кот', 'Кролик', 'Попугай']), state=Pet.waiting_for_pet_choice)
async def choose_pet(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['pet'] = message.text
    await message.answer(f"Вы выбрали {message.text}!\n"
                         "Пожалуйста, введите количество шагов, которые вы сделали сегодня:")
    await Pet.waiting_for_steps_number.set()
 
@dp.message_handler(Text(equals=['Myself']), state=Pet.waiting_for_pet_choice)
async def choose_myself(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['pet'] = 'Myself'
    await message.answer("You have chosen to track yourself!\n"
                         "Пожалуйста, введите количество шагов, которые вы сделали сегодня:")
    await Pet.waiting_for_steps_number.set()
 
@dp.message_handler(lambda message: not message.text.isdigit(), state=Pet.waiting_for_steps_number)
async def process_steps_invalid(message: types.Message):
    await message.answer("Напишите количество шагов числом.")
 
@dp.message_handler(lambda message: message.text.isdigit(), state=Pet.waiting_for_steps_number)
async def process_steps(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['steps'] = int(message.text)
        data['username'] = message.from_user.username
        data['date'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    pet = data['pet']
    steps = data['steps']
    username = data['username']
    date = data['date']
    cursor = db.cursor()
    cursor.execute("INSERT INTO pet_tracker (pet, steps, username, date) VALUES (?, ?, ?, ?)", (pet, steps, username, date))
    db.commit()
    await message.answer(f"Отлично! Вы покормили {pet} {steps} шагами.\n"
                         "Что бы вы хотели сделать дальше?", reply_markup=types.ReplyKeyboardMarkup(
        keyboard=[
            [types.KeyboardButton(text='Проверить прогресс'), types.KeyboardButton(text='Установить напоминание')],
            [types.KeyboardButton(text='Поменять питомца'), types.KeyboardButton(text='Выйти')]
        ],
        resize_keyboard=True
    ))
    await Pet.waiting_for_next_action.set()
 
 
@dp.message_handler(Text(equals=['Проверить прогресс']), state=Pet.waiting_for_next_action)
async def check_progress(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        pet = data['pet']
        cursor = db.cursor()
        cursor.execute("SELECT sum(steps) FROM pet_tracker WHERE pet=?", (pet,))
        result = cursor.fetchone()[0]
    if result is not None:
        await message.answer(f"Вы прошли {result} шагов.")
    else:
        await message.answer("Вы еще не зарегистрировали ни одного шага для своего питомца.")
 
 
@dp.message_handler(Text(equals=['Установить напоминание']), state=Pet.waiting_for_next_action)
async def set_reminder(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        pet = data['pet']
        reminder_time = datetime.now() + timedelta(hours=24)
        reminder_text = f"Не забудьте сегодня покормить {pet}!"
    await bot.send_message(chat_id=message.chat.id, text=reminder_text, parse_mode=ParseMode.MARKDOWN)
    await message.answer(f"Для вас было установлено напоминание о необходимости зарегистрировать шаги завтра.")
    await state.finish()
 
 
@dp.message_handler(Text(equals=['Поменять питомца']), state=Pet.waiting_for_next_action)
async def change_pet(message: types.Message, state: FSMContext):
    await message.answer('Пожалуйста, выберите животное:', reply_markup=types.ReplyKeyboardMarkup(
        keyboard=[
            [types.KeyboardButton(text='Собака'), types.KeyboardButton(text='Кот')],
            [types.KeyboardButton(text='Кролик'), types.KeyboardButton(text='Попугай')],
        ],
        resize_keyboard=True
    ))
    await Pet.waiting_for_pet_choice.set()
 
 
@dp.message_handler(Text(equals=['Выйти']), state=Pet.waiting_for_next_action)
async def exit(message: types.Message, state: FSMContext):
    await message.answer('Прощайте!')
    await state.finish()
    await message.answer("Что бы вы хотели сделать дальше?", reply_markup=types.ReplyKeyboardMarkup(
        keyboard=[
            [types.KeyboardButton(text='Шаги в журнале'), types.KeyboardButton(text='Проверить прогресс')],
            [types.KeyboardButton(text='Отправить напоминание'), types.KeyboardButton(text='Поменять питомца')],
            [types.KeyboardButton(text='Выйти')],
            [types.KeyboardButton(text='Редактировать запись'), types.KeyboardButton(text='Удалить запись')],
        ],
        resize_keyboard=True
    ))
    await Pet.next()
 
 
@dp.message_handler(Text(equals=['Проверить прогресс']), state=Pet.waiting_for_steps_choice)
async def check_progress(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        pet = data['pet']
        cursor = db.cursor()
        cursor.execute("SELECT sum(steps) FROM pet_tracker WHERE pet=?", (pet,))
        total_steps = cursor.fetchone()[0]
        await message.answer(f"У вас всего {total_steps} шагов.")
 
 
@dp.message_handler(Text(equals=['Отправить напоминание']), state=Pet.waiting_for_steps_choice)
async def set_reminder(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        await message.answer(f"Когда вы хотите получать напоминание о необходимости обновить количество шагов?")
        await Pet.waiting_for_reminder_time.set()
 
 
@dp.message_handler(lambda message: not message.text.isdigit(), state=Pet.waiting_for_reminder_time)
async def process_reminder_invalid(message: types.Message):
    await message.answer("Введите число.")
 
@dp.message_handler(lambda message: message.text.isdigit(), state=Pet.waiting_for_reminder_time)
async def process_reminder(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['reminder_time'] = int(message.text)
        pet = data['pet']
        reminder_time = data['reminder_time']
        reminder_datetime = datetime.now() + timedelta(hours=reminder_time)
        reminder_text = f"Не забудьте покормить своего питомца шагами!"
        await bot.send_message(chat_id=message.chat.id, text=reminder_text, reply_at=reminder_datetime)
        await message.answer(f"Мы напомним вам через {reminder_time} часов.")
    await state.finish()
 
 
@dp.message_handler(Text(equals=['Редактировать запись']), state=Pet.waiting_for_steps_choice)
async def edit_entry(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        pet = data['pet']
        cursor = db.cursor()
        cursor.execute("SELECT steps FROM pet_tracker WHERE pet=? AND username=?", (pet, message.from_user.username))
        row = cursor.fetchone()
        if not row:
            await message.answer("Вы еще не зарегистрировали ни одного шага.")
            await state.finish()
            return
        current_steps = row[0]
        await message.answer(f"Вы сделали {current_steps} шагов сегодня.\n"
                              "Пожалуйста, введите новое уоличество шагов:")
        await Pet.waiting_for_new_steps_number.set()
 
 
@dp.message_handler(lambda message: not message.text.isdigit(), state=Pet.waiting_for_new_steps_number)
async def process_new_steps_invalid(message: types.Message):
    await message.answer("Введите число.")
 
@dp.message_handler(Text(equals=['Редактировать запись']), state=Pet.waiting_for_steps_choice)
async def edit_entry(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        pet = data['pet']
        cursor = db.cursor()
        cursor.execute("SELECT steps FROM pet_tracker WHERE pet=? AND username=?", (pet, message.from_user.username))
        row = cursor.fetchone()
        if not row:
            await message.answer("Вы еще не зарегистрировали шаги.")
            await state.finish()
            return
        current_steps = row[0]
        await message.answer(f"Вы сделали {current_steps} шагов сегодня.\n"
                             "Пожалуйста, введите новое количество шагов:")
        await Pet.waiting_for_new_steps_number.set()
 
@dp.message_handler(lambda message: message.text.isdigit(), state=Pet.waiting_for_new_steps_number)
async def process_new_steps(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['new_steps'] = int(message.text)
        pet = data['pet']
        cursor = db.cursor()
        cursor.execute("UPDATE pet_tracker SET steps=? WHERE pet=? AND username=?", 
                       (data['new_steps'], pet, message.from_user.username))
        db.commit()
        await message.answer(f"Количество шагов было обновлено: {data['new_steps']}.\n"
                             "Что бы вы хотели сделать дальше?", 
                             reply_markup=types.ReplyKeyboardMarkup(
                                 keyboard=[
                                     [types.KeyboardButton(text='Поменять питомца'), types.KeyboardButton(text='Готово')],
                                 ],
                                 resize_keyboard=True
                             ))
        await Pet.waiting_for_next_action.set()
 
 
@dp.message_handler(Text(equals=['Проверить прогресс', 'Отправить напоминание', 'Поменять питомца']), state=Pet.waiting_for_next_action)
async def process_next_action(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['next_action'] = message.text
        next_action = data['next_action']
        if next_action == 'Проверить прогресс':
            cursor = db.cursor()
            cursor.execute("SELECT sum(steps) FROM pet_tracker WHERE pet=?", (data['pet'],))
            result = cursor.fetchone()
            total_steps = result[0] if result[0] is not None else 0
            await message.answer(f"Вы зарегистрировали {total_steps} шагов.")
        elif next_action == 'Отправить напоминание':
            await message.answer("В какое время вы хотите получать напоминание? (Пожалуйста, введите в формате ЧЧ:ММ, 24-часовые часы)")
            await Pet.waiting_for_reminder_time.set()
        elif next_action == 'Поменять питомца':
            await message.answer('Выберите питомца:', reply_markup=types.ReplyKeyboardMarkup(
                keyboard=[
                    [types.KeyboardButton(text='Собака'), types.KeyboardButton(text='Кот')],
                    [types.KeyboardButton(text='Кролик'), types.KeyboardButton(text='Кролик')],
                ],
                resize_keyboard=True
            ))
            await Pet.waiting_for_pet_choice.set()
 
 
@dp.message_handler(lambda message: not re.match(r'^\d{2}:\d{2}$', message.text), state=Pet.waiting_for_reminder_time)
async def process_reminder_time_invalid(message: types.Message):
    await message.answer("Invalid format. Please enter time in HH:MM format, 24-hour clock.")
 
@dp.message_handler(lambda message: re.match(r'^\d{2}:\d{2}$', message.text), state=Pet.waiting_for_reminder_time)
async def process_reminder_time(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['reminder_time'] = message.text
        reminder_time = data['reminder_time']
        await message.answer(f"Мы будем напоминать в {reminder_time} каждый день.")
        await state.finish()
 
async def send_reminder():
    while True:
        await asyncio.sleep(60)
        cursor = db.cursor()
        cursor.execute("SELECT DISTINCT username FROM pet_tracker")
        result = cursor.fetchall()
        for row in result:
            username = row[0]
            cursor.execute("SELECT pet, sum(steps) FROM pet_tracker WHERE username=? GROUP BY pet", (username,))
            result = cursor.fetchall()
            for row in result:
                pet = row[0]
                total_steps = row[1]
                if total_steps == 0:
                    continue
                cursor.execute("SELECT reminder_time FROM user_settings WHERE username=? AND pet=?", (username, pet))
                result = cursor.fetchone()
                if result is None or result[0] is None:
                    continue
                reminder_time = result[0]
                now = datetime.now()
                if now.strftime('%H:%M') == reminder_time:
                    await bot.send_message(chat_id=username, text=f"Не забульте написать количество шагов за сегодня!")
 
 
if __name__ == '__main__':
    executor.start_polling(dp, skip_updates=True)
    db.execute("CREATE TABLE IF NOT EXISTS pet_tracker (pet text, steps integer, username text, date text)")
    db.execute("CREATE TABLE IF NOT EXISTS user_settings (username text, pet text, reminder_time text)")
    db.commit()
    loop = asyncio.get_event_loop()
С логикой что-ли проблема, никак не пойму
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.02.2023, 17:07
Ответы с готовыми решениями:

сохраняет данные по не правильному порядку в колонках в mysql через телеграм бот
Здравствуйте! Помогите с кодом, написал телеграм бота для подачи заявку, данные нужно сохранить в БД, проблема в том, что данные сохраняет...

Парсер БОТ в телеграме
Здравствуйте, хотел найти в интернете парсер готовый, чтобы немножко скрипт изменить под себя и пользоваться, но не нашёл. Пытался сам...

В 90-е годы у детей была популярная игрушка - тамагочи. Игрушка представляла собой виртуальный домашний питомец
В 90-е годы у детей была популярная игрушка - тамагочи. Игрушка представляла собой виртуальный домашний питомец. Давайте представим...

1
Модератор
Эксперт Python
 Аватар для Fudthhh
2696 / 1602 / 513
Регистрация: 21.02.2017
Сообщений: 4,210
Записей в блоге: 1
15.02.2023, 18:52
malen6273, не читабельный код, во первых вынеси все операции с бд, в отдельный файл, во вторых, зачем использовать машину состояний и сравнение по тексту одновременно?

Если уж используется машина состояний, почему бы не использовать хранилище которое встроено в aiogram?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
15.02.2023, 18:52
Помогаю со студенческими работами здесь

Виртуальный сервер сохраняет страницы
HI уважаемые форумчане!! Проблемка в следующем: некоторое время назад установил себе LAMP, успешно юзал, все было ок. Но вот возникла...

Сохраняет ли бот id моего телеграма?
Здравствуйте, добрые молодцы, пишу вам с таким интересующим меня вопросом. Если я писала в бот тех.подержки интернет-магазина, в боте...

Бот, который принимает файл от юзера и сохраняет его в папку на диске
Привет! Написал бота для телеграм, который принимает файл от юзера и сохраняет его на жесткий диск. Буду рад, если направите. Мне...

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

не сохраняет данные в БД
Здравствуйте. Сталкнулся с такой проблемой. Внутри тега form находится несколько ячеек. После заполнения все они сохраняются в БД кроме тех...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Новые блоги и статьи
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru