0

I want to produce an endless loop that would to different things depending on some user input. When the .py is executed the loop starts and does some 'main' programm and the input window opens for the user. When typing 'alt1' the loop jumps in to the function 'main_alt1' and so on.

user_input = 'main'
user_input = input()

while True:
    if user_input == 'main'
        main()
    elif user_input == 'alt1'
        main_alt1()
    elif user_input == 'exit'
        exit()

The problem here is that the input is either given once before the loop (like in the example) or it stops the loop when the input is inside the loop until the input is given. Does anyone has a smart way to do something like that. It doesn't need to be with input().

7
  • 2
    It makes sense for the input() to be inside the loop, before the if statement. Otherwise the same function will be called in an infinite loop, which I doubt you want. Commented Jan 12, 2021 at 12:10
  • No, I want the main() to be called in an infinite loop since it needs to check something every few seconds. Commented Jan 12, 2021 at 12:14
  • 1
    OK then, you are going to need multiple threads. One thread is an input loop which will set the user_input variable. The other is the main loop which reads the value of user_input, as it currently does. Check out the threading module. It might be possible using async, but I'm not too familiar with it yet. Commented Jan 12, 2021 at 12:32
  • 1
    There was a similar question I gave answer to recently here. If you look at the 2nd example, it demonstrates something pretty close to what you need, using multi-threading and listening on events in your main function. Commented Jan 12, 2021 at 12:37
  • 1
    Thank you! The 2nd example is doing exactly what I was searching for. Commented Jan 12, 2021 at 12:51

3 Answers 3

1

I think it's better to use a class to process the user input: (I updated the code with the process method)

from multiprocessing import Process
from time import sleep


class InvalidAction(Exception):
    pass


class Cmd:

    def __init__(self):
        self._active_thread = None

    def _action_hi(self):
        while True:
            print('Hi!')
            sleep(1)

    def _action_ping(self):
        while True:
            print('Pong!')
            sleep(1)

    @staticmethod
    def _get_method_name(action):
        return f'_action_{action}'

    def process(self, action: str):
        method_name = self._get_method_name(action)
        if not hasattr(self, method_name):
            raise InvalidAction

        if self._active_thread is not None:
            self._active_thread.terminate()

        self._active_thread = Process(target = getattr(self, method_name, None))
        self._active_thread.start()


def main():
    cmd = Cmd()

    while True:
        try:
            user_input = input('Action: ')
            cmd.process(user_input)

        except InvalidAction as e:
            print(f'Invalid Action!')

        except KeyboardInterrupt:
            print('Exiting the loop.')
            break

        except Exception as e:
            print(f'Something went wrong - {e}')


if __name__ == '__main__':
    main()
Sign up to request clarification or add additional context in comments.

5 Comments

Can I insert a message that gets printed every second while I am not entering anything via input? Let's say print('Waiting for input')?
No, the input method works in this way , it waits for the user input
Ok so that's exactly my problem. I don't want to wait for the user input. But when the user enters something I want to change something in the infinit loop.
You can run a thread in any action method and with the new action, stop the previous one and start the new thread.
I added the sample code with the process method.
0
user_input = 'main'
user_input = input()

while True:
    if user_input == 'main'
        main()
    elif user_input == 'alt1'
        main_alt1()
    elif user_input == 'exit'
        exit()
    user_input = input()

Taking the the input again at the end of loop works. Since it is while True it runs infinitely till user enters exit

1 Comment

This pauses the while loop until the user enter his input again. So the main() is only called once until the user gives input at the end of the loop.
0

after calling every function you can again take update from user to change variable

import keyboard 

while True:
    if keyboard.read_key() == 'a':
        main_alt1()
    elif keyboard.read_key() == 'b':
        main_alt2()
    elif keyboard.read_key() == 'e':
        exit()
    else:
        main()
    

2 Comments

This pauses the loop until the input is entered after main(). I want main() to be called in an infinite loop until I give input to do different.
try this updated code with keyboard interruption

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.