Gryandr
@Gryandr

Бот не считает формулу. Как исправить?

Бот должен принять число от пользователя и сделать расчеты по формуле.
Бот работает до момента, где пользователь делает выбор и вводит число.

from aiogram import Bot, types
from aiogram.dispatcher import Dispatcher
from aiogram.utils import executor
from config import token
from math import sqrt

bot = Bot(token)
dp = Dispatcher(bot)

async def on_startup(_):
	print('Бот онлайн.')

'''****КНОПКИ БАССЕЙНОВ***'''

@dp.message_handler(commands=['start', 'help'])
async def command_start(message : types.Message):
    markup=types.ReplyKeyboardMarkup(resize_keyboard=True)
    item1=types.KeyboardButton("Бассейн №1")
    item2=types.KeyboardButton("Бассейн №2")
    markup.add(item1)
    markup.add(item2)
    await bot.send_message(message.from_user.id, 'Привет! Какой бассейн меряем?', reply_markup=markup)

@dp.message_handler()
async def lake(message):
    if message.text == 'Бассейн №1':
        await bot.send_message(message.from_user.id, 'Введи расстояние до воды №1.')
    if message.text == 'Бассейн №2':
        await bot.send_message(message.from_user.id, 'Введи расстояние до воды №2.')

'''****ФОРМУЛЫ***'''

@dp.message_handler(content_types=['text'])
async def lake1(message):
    if message.text == 'Бассейн №1':
        b1 = int(message.text)
        h = 8 - b1
        v = (h / 3) * (2500 + (sqrt(2500 * (95 - (b1 * 110) - (b1 / 2))))) + (95 - (b1 * 110) - (b1 / 2))
        level = v / 16000 * 100
        await bot.send_message(message.from_user.id, str("Количество:" + str(v) + "м3. Глубина:" + str(h) + "м. Наполнение: " + str(level) + "%"))
    else:
        await bot.send_message(message.from_user.id, "Попробуй еще...")

@dp.message_handler(content_types=['text'])
async def lake2(message):
    if message.text == 'Бассейн №2':
        b2 = int(message.text)
        h2 = 5 - ((b2 - 1) * float(0.7))
        s2 = (90 - (b2 * 0.52)) * (100 - (b2 * 0.52)) / 2
        n = sqrt(2500 * s2)
        g = s1 + n + s2
        v2 = (h2 / 3) * g
        level2 = v2 / 17000 * 100
        await bot.send_message(message.from_user.id, str("Количество:" + str(v2) + "м3. Глубина:" + str(h2) + "м. Наполнение: " + str(level2) + "%"))
    else:
        await bot.send_message(message.from_user.id, 'Чтото не так!')

executor.start_polling(dp, on_startup=on_startup)
>
  • Вопрос задан
  • 192 просмотра
Решения вопроса 2
phaggi
@phaggi Куратор тега Python
лужу, паяю, ЭВМы починяю
Как я понял, когда бот начинает работать, он обрабатывает зарегистрированные в нем хэндлеры, и ваш хэндлер lake перехватывает всё, кроме явно start и help, поэтому дальше него и не проходит. Я глубоко не вникал, возможно этот момент я неправильно понял.
Но, в принципе, можно обойтись и этим одним хндлером, просто правильно обрабатывать то, что в него приходит. А приходить в него должно либо выбор кнопки, либо число.
При выборе кнопки фиксируем номер кнопки и ждем число. Если пришло число - вычисляем, возвращаем, сбрасываем номер кнопки и всё сначала.

lake_number = 0


@dp.message_handler()
async def lake(message: types.Message):
    global lake_number
    if message.text == 'Бассейн №1':
        await bot.send_message(message.from_user.id, 'Введи расстояние до воды №1.')
        lake_number = 1
    if message.text == 'Бассейн №2':
        await bot.send_message(message.from_user.id, 'Введи расстояние до воды №2.')
        lake_number = 2
    if bool(lake_number) and message.text.isdigit():
        b = int(message.text)
        if lake_number == 1:
            h = 8 - b
            v = (h / 3)
            level = v / 16000 * 100  # тут в формуле где-то ошибка, поэтому я ее просто убрал
            await bot.send_message(message.from_user.id,
                                   str("Количество:" + str(v) + "м3. Глубина:" + str(h) + "м. Наполнение: " + str(
                                       level) + "%"))
        if lake_number == 2:
            h2 = 5 - ((b - 1) * float(0.7))
            s2 = (90 - (b * 0.52)) * (100 - (b * 0.52)) / 2
            n = sqrt(2500 * s2)
            s1 = 1
            g = s1 + n + s2
            v2 = (h2 / 3) * g
            level2 = v2 / 17000 * 100
            await bot.send_message(message.from_user.id,
                                   str("Количество:" + str(v2) + "м3. Глубина:" + str(h2) +
                                       "м. Наполнение: " + str(level2) + "%"))
        lake_number = 0
        await bot.send_message(message.from_user.id, "Попробуй еще...")
Ответ написан
@Zo0meeer
Бот на aiogram регистрирует хендлеры сверху вниз. Сначала регистрируется хендлер lake, потому что по умолчанию в любом хендлере стоит content_type='text'. Если хотите перехватывать выбор с ReplyKeyboardMurkup, мой совет использовать FSM с одним хендлером.
И код
if message.text == 'Бассейн №1':
        b1 = int(message.text)
замените на
if message.text == 'Бассейн №1':
        b1 = int(message.text[-1])
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
AlexNest
@AlexNest Куратор тега Python
Работаю с Python/Django
if message.text == 'Бассейн №1':
        b1 = int(message.text)

Я с ТГ-ботами "на вы", но вот этот кусок выглядит как лютая дичь.
Чисто логически, переводя на "человеческий", это значит:
Если текст сообщения выглядит как 'Бассейн №1', то пусть этот текст станет числом.

Не находите противоречия?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы