Search code examples
pythonpython-3.xfor-loopwhile-loopaiogram

Are there ways to use while and for loops with messages from bot and user in Aiogram?


I am transfering a program working in console to telegram bot using Aiogram, and I don't where to start with one function. Here it is:

def check():
    print('Here are your dictionaries:')
    retrieve_dictionaries()
    dict_name = input('Select a dictionary: ''')
    cur = conn.cursor()
    cur.execute('''SELECT * from {tab};'''.format(tab = dict_name))
    columns = list(map(lambda x: x[0], cur.description))
    print('Here are possible directions:','\n','1.',columns[1],'--',columns[2],'\n','2.',columns[2],'--',columns[1])    
    direction = input ('From where do we start? Choose 1 or 2: ')
    if direction == '1':
        box = int(input('From which box do we take the cards? Choose from 1 to 4: '))
        cur.execute('''SELECT * from {tab} WHERE box12 == {box_value} ORDER BY RANDOM()'''.format(tab = dict_name, box_value = box))
        checkwords = cur.fetchall()
        checked = len(checkwords)
        print(checked)
        print('Excellent! There are',checked, 'words to learn. Let us start!')
        print(checkwords)
        id_correct = []
        id_forgotten = []
        id_remembered = []
        while checked > 0:
            for i in checkwords:
                if i[0] in id_correct:
                    continue
                elif i[0] in id_forgotten:
                    print(i[1])
                    answer = input('Insert answer: ')
                    if answer == i[2]:
                        print('Correct!')
                        checked = checked - 1
                        id_remembered.append(i[0])
                    else:
                        print('Nope, the correct answer is:', i[2])
                else:
                    print(i[1])
                    answer = input('Insert answer: ')
                    if answer == i[2]:
                        print('Correct!')
                        checked = checked - 1
                        id_correct.append(i[0])
                    else:
                        print('Nope, the correct answer is:', i[2])
                        id_forgotten.append(i[0])
                        
        print(id_correct)
        print(id_forgotten)
        for i in id_correct:
            cur.execute('''UPDATE {tab} SET box12 = box12 + 1 WHERE id == {word_id}'''.format(tab = dict_name, word_id = i))
    if direction == '2':
        box = int(input('From which box do we take the cards? Choose from 1 to 4: '))
        cur.execute('''SELECT * from {tab} WHERE box21 == {box_value} ORDER BY RANDOM()'''.format(tab = dict_name, box_value = box))
        checkwords = cur.fetchall()
        checked = len(checkwords)
        print(checked)
        print('Excellent! There are',checked, 'words to learn. Let us start!')
        print(checkwords)
        id_correct = []
        id_forgotten = []
        id_remembered = []
        while checked > 0:
            for i in checkwords:
                if i[0] in id_correct:
                    continue
                elif i[0] in id_forgotten:
                    print(i[2])
                    answer = input('Insert answer: ')
                    if answer == i[1]:
                        print('Correct!')
                        checked = checked - 1
                        id_remembered.append(i[0])
                    else:
                        print('Nope, the correct answer is:', i[2])
                else:
                    print(i[2])
                    answer = input('Insert answer: ')
                    if answer == i[1]:
                        print('Correct!')
                        checked = checked - 1
                        id_correct.append(i[0])
                    else:
                        print('Nope, the correct answer is:', i[1])
                        id_forgotten.append(i[0])
        print(id_correct)
        print(id_forgotten)
        for i in id_correct:
            cur.execute('''UPDATE {tab} SET box21 = box21 + 1 WHERE id == {word_id}'''.format(tab = dict_name, word_id = i))

    conn.commit()
    cur.close()

There are various for and while loops, and I don't understand whether FSM can do anything with it (if it can, I'd be glad to get some advices). Maybe there are some other ways to ensure a sequential execution of the function?

I tried to execute it as one state, as well as divide it in various states, however, did not succeed.


Solution

  • IT would be hard for me to translate all this to functional in Aiogram without access your full codebase - but here is what i can suggest for you by experience:

    First, create a models.py to contain all your database functions with all your queries. Remember everything needs to be async.

    i assume check() is gonna be a command /check. Make it more clean by creating a small function for each task to not endpoint with pipelines like this. I used to have this habit before where i didnt, and its a PITA to debug errors or to have modularity in the future.

    the absolute start for the check would be something like this:

    @dp.message_handler(commands=['check'])
    async def check(message: types.Message):
    

    Examples would be for your database methods would be:

        def get_dictionaries():
        return
    
        def get_words_from_box(dict_name, box_column, box_value):
        return 
        
        def update_word_box(dict_name, word_id, box_column):
        return
    

    also for the lines like this:

    if direction == '1':
         // LOTS OF CODE 
    

    do for example

    if direction == '1':
         directionOne()
    

    im sorry i didnt do it all for you, but i wanted to help you get started instead. i hope this will put you in the correct direction on how to do split your code into a more modular and clean style for your aiogram bot.

    EDIT: If there is something im missing to answer you, please let me know