@YuriyCherniy

Как сделать код более элегантным и правильным в конкретном примере?

Пишу Telegram бота на Python - словарные карточки для изучения иностранных слов. В коде ниже пугает своей монструозностью функция button_handler. Она обрабатывает пользовательский ввод с клавиатуры. Когда прикручу базу данных она станет еще ужаснее если продолжу в том же стиле, несколько elif'ов получат дополнительно по несколько строк. Какие есть подходы для решения этой проблемы? Как сделать код более элегантным и правильным?
import random
import time
import requests
from bot_token import token
from bot_keyboard import start_keyboard, main_keyboard
import wordshandler

URL = f'https://api.telegram.org/bot{token}/'
word = None  # this variable will hold value for button_handler function
words_list = None  # this variable will hold value for button_handler function

handler = wordshandler.WordsHandler()


def get_updates(offset=None):
    url = f'{URL}getupdates?timeout=100'
    if offset:
        url = f'{URL}getupdates?offset={offset}&timeout=100'
    response = requests.get(url)
    return response.json()


def get_offset(updates):
    return updates['result'][-1]['update_id'] + 1


def send_message(chat_id, text, keyboard=''):
    requests.get(
        f'{URL}sendmessage?chat_id={chat_id}'
        f'&text={text}&reply_markup={keyboard}'
    )


def button_handler(updates):
    '''this function handles user input from custom telegram keyboards'''
    global word, words_list
    for updates in updates['result']:
        chat_id = updates['message']['chat']['id']
        text = updates['message']['text']
        if text == '/start':
            send_message(chat_id, 'Я пришлю тебе слово, а ты ответь знаешь '
                         'его или нет.', start_keyboard)
        elif text == 'начать':
            handler.copy_words()
            words_list = handler.words_handler()
            word = random.choice(list(words_list.keys()))
            send_message(chat_id, f'{word}   ❓', main_keyboard)
        elif text == 'знаю':
            send_message(chat_id, f'{words_list[word]}   ✅')
            del words_list[word]
            if len(words_list) == 0:
                send_message(chat_id, 'Ты выучил все слова. Сбросить прогресс'
                             ' и начать сначала?', start_keyboard)
            else:
                words_list = handler.words_handler()
                word = random.choice(list(words_list.keys()))
                send_message(chat_id, f'{word}   ❓', main_keyboard)
        elif text == 'не знаю':
            send_message(chat_id, f'{words_list[word]}   ❌')
            word = random.choice(list(words_list.keys()))
            send_message(chat_id, f'{word}   ❓', main_keyboard)
        elif text == 'ru >< en':
            handler.translate_reverse()
            send_message(chat_id, 'Направление перевода изменено')
            words_list = handler.words_handler()
            word = random.choice(list(words_list.keys()))
            send_message(chat_id, f'{word}   ❓', main_keyboard)


def main():
    offset = None
    while True:
        updates = get_updates(offset)
        if len(updates['result']) > 0:
            offset = get_offset(updates)
        button_handler(updates)
        time.sleep(0.5)


if __name__ == '__main__':
    main()
  • Вопрос задан
  • 91 просмотр
Решения вопроса 1
netpastor
@netpastor
Python developer
Используй dict case, ниже пример
def start():
    pass

def begin():
    pass

switcher = {
    '/start' : start,
    'начать' : begin
}

text = updates['message']['text']
action = switcher.get(text)
if action:
    action()
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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