I have written a fairly simple bot that provides information or additional choice based on the user's query. It runs well and does the job, however, I was wondering how can I optimize my code and use the telebot better?
Currently the main action happens in the query handler and something tells me that I am missing possible efficiency gains (when I will attempt to build more choices for example). Below is the code, simplified for demonstration purposes:
import telebot
from telebot import types
token = bottoken
bot = telebot.TeleBot(token)
@bot.message_handler(commands=['start'])
def welcome(message):
# here i give the main choice that is always visible to the user
markup = types.ReplyKeyboardMarkup(resize_keyboard=False)
item1 = types.KeyboardButton("Button1")
item2 = types.KeyboardButton("Button2")
markup.add(item1, item2)
bot.send_message(message.chat.id, "Welcome message".format(message.from_user, bot.get_me()),
parse_mode='html', reply_markup=markup)
@bot.message_handler(content_types=['text'])
def main_choice(message):
# here i develop each of the main choices and redirect to the callback handler
if message.text == 'Button1':
# Forward to callback handler
markup = types.InlineKeyboardMarkup()
item1 = types.InlineKeyboardButton("Yes", callback_data = 'demo_yes')
item2 = types.InlineKeyboardButton("No", callback_data = 'demo_no')
markup.add(item1, item2)
bot.send_message(message.chat.id, 'Some text', reply_markup=markup)
elif message.text == 'Button2':
# some logic
else :
bot.send_message(message.chat.id, 'Sorry, i dont understand. You can use /help to check how i work')
@bot.callback_query_handler(func=lambda call: True)
def tempo(call):
# here a handle the queries launched both by main buttons and the inline keyboard
if call.data == "demo_yes":
keyboard = types.InlineKeyboardMarkup()
item1 = types.InlineKeyboardButton("Text1", callback_data = 'call1')
item2 = types.InlineKeyboardButton("Text2", callback_data = 'call2')
keyboard.add(item1,item2)
bot.send_message(call.message.chat.id, 'message', reply_markup = keyboard)
elif call.data == "demo_no":
kkeyboard = types.InlineKeyboardMarkup()
item1 = types.InlineKeyboardButton("Text3", callback_data = 'call3')
item2 = types.InlineKeyboardButton("Text4", callback_data = 'call4')
keyboard.add(item1,item2)
bot.send_message(call.message.chat.id, 'message', reply_markup = keyboard)
if call.data == "call1":
keyboard = types.InlineKeyboardMarkup()
item1 = types.InlineKeyboardButton("Text5", callback_data = 'another_call1')
item2 = types.InlineKeyboardButton("Text6", callback_data = 'another_call2')
keyboard.add(item1,item2)
bot.send_message(call.message.chat.id, 'message', reply_markup = keyboard)
elif call.data == "call2":
kkeyboard = types.InlineKeyboardMarkup()
item1 = types.InlineKeyboardButton("Text7", callback_data = 'another_call3')
item2 = types.InlineKeyboardButton("Text8", callback_data = 'another_call4')
keyboard.add(item1,item2)
bot.send_message(call.message.chat.id, 'message', reply_markup = keyboard)
-
3\$\begingroup\$ "Below is the code, simplified for demonstration purposes" Next time, please don't simplify the code. We can handle big pieces of code, but we'd be wasting your and our time by providing a review that turns out to be non-applicable to your actual code because that happens to look slightly different. \$\endgroup\$Mast– Mast ♦2021年04月29日 12:06:21 +00:00Commented Apr 29, 2021 at 12:06
1 Answer 1
From my point of view you can use a visitor pattern for this with a simple dictionary, specially for your operations, here is a small example:
Insead of this
@bot.callback_query_handler(func=lambda call: True)
def tempo(call):
# here a handle the queries launched both by main buttons and the inline keyboard
if call.data == "demo_yes":
keyboard = types.InlineKeyboardMarkup()
......
Use the following
tempo_operations = {"demo_yes" : demo_yes_function,
"demo_no" : demo_no_function,
....}
@bot.callback_query_handler(func=lambda call: True)
def tempo(call):
if call.data in tempo_operations:
tempo_operations[call.data]()
else:
print("Operation not supported")
Hope you can get the idea :)
-
\$\begingroup\$ That's not a visitor pattern, it's a lookup table. Since the OP is looking for efficiency, a call to
dict.get
would be preferable to a call to both__contains__
and__getitem__
. \$\endgroup\$Andreas T– Andreas T2021年03月15日 19:58:53 +00:00Commented Mar 15, 2021 at 19:58 -
1\$\begingroup\$ While I agree on the fact that it's not exactly a visitor pattern, the proposed solution certainly answers OP's concern regarding "I am missing possible efficiency gains (when I will attempt to build more choices for example)" \$\endgroup\$IEatBagels– IEatBagels2021年04月29日 12:49:26 +00:00Commented Apr 29, 2021 at 12:49
Explore related questions
See similar questions with these tags.