27

I'm trying to restart a program using an if-test based on the input from the user.

This code doesn't work, but it's approximately what I'm after:

answer = raw_input('Run again? (y/n): ') if answer == 'n': print 'Goodbye' break elif answer == 'y': #restart_program??? else: print 'Invalid input.' 

What I'm trying to do is:

  • if you answer y - the program restarts from the top
  • if you answer n - the program ends (that part works)
  • if you enter anything else, it should print 'invalid input. please enter y or n...' or something, and ask you again for new input.

I got really close to a solution with a "while true" loop, but the program either just restarts no matter what you press (except n), or it quits no matter what you press (except y). Any ideas?

6 Answers 6

51

This line will unconditionally restart the running program from scratch:

os.execl(sys.executable, sys.executable, *sys.argv) 

One of its advantage compared to the remaining suggestions so far is that the program itself will be read again.

This can be useful if, for example, you are modifying its code in another window.

Sign up to request clarification or add additional context in comments.

11 Comments

This doesn't work on windows if Python is installed in a path with spaces
@Beefster this can be solved by instead using subprocess.call(sys.executable + ' "' + os.path.realpath(__file__) + '"')
@EladAvron The problem with that solution is that it creates an endless chain of subprocesses which will eventually cause the os to run out of memory. I'm not sure what happens at that point.
This solves the problem of not being able to have a space in the python installation path. os.execl(sys.executable, '"{}"'.format(sys.executable), *sys.argv)
@JustinG Now it'd be better still if you used f-strings. Instead of '"{}"'.format(sys.executable), you can use f'"{sys.executable}"'.
|
22

Use while loops:

while True: # Re-run program # main program ... while True: # Validate user input answer = input('Run again? (y/n): ') if answer in ('y', 'n'): break print("invalid input.") if answer == 'y': continue else: print("Goodbye") break 

The inner while loop loops until the input is either 'y' or 'n'.

If the input is 'y', the outer while loop starts again (continue keyword skips the remaining code and goes straight to the next iteration). If the input is 'n', the outer while loop breaks and the program ends.

Note: I'm using input() in Python 3. In Python 2, use raw_input().

Comments

3

Using one while loop:

In [1]: start = 1 ...: ...: while True: ...: if start != 1: ...: do_run = raw_input('Restart? y/n:') ...: if do_run == 'y': ...: pass ...: elif do_run == 'n': ...: break ...: else: ...: print 'Invalid input' ...: continue ...: ...: print 'Doing stuff!!!' ...: ...: if start == 1: ...: start = 0 ...: Doing stuff!!! Restart? y/n:y Doing stuff!!! Restart? y/n:f Invalid input Restart? y/n:n In [2]: 

3 Comments

Ok, Ok. Fair enough. You don't need 2 while loops -- But I still think it's cleaner that way :) -- I actually liked my decorator solution, but that might be a little advanced for a question like this ...
@mgilson -- Maybe. But the decorator certainly is pretty neat, +1.
Good utilization of while loop
3

You can do this simply with a function. For example:

def script(): # program code here... restart = raw_input("Would you like to restart this program?") if restart == "yes" or restart == "y": script() if restart == "n" or restart == "no": print "Script terminating. Goodbye." script() 

Of course you can change a lot of things here. What is said, what the script will accept as a valid input, the variable and function names. You can simply nest the entire program in a user-defined function (Of course you must give everything inside an extra indent) and have it restart at anytime using this line of code: myfunctionname(). More on this here.

1 Comment

Of course, let me know if this fails and I will try to fix
3

It is very easy do this

while True: #do something again = input("Run again? ") if 'yes' in again: continue else: print("Good Bye") break 

Basically, in this the while loop will run the program again and again because while loops run if the condition is True so we have made the condition true and as you know True is always true and never false. So, will not stop then after this the main part comes here first we will take input from the user whether they want to continue the program or not then we will say that if user says yes i want to continue then the continue keyword will bring the loop to the top again and will run the program again too and if the user says something else or you can do it in another way if you want to only quit the program if user says no then just add this

elif 'no' in again: print("Good Bye") break else: print("Invalid Input") 

this will look that if there is the 'no' word in the input and if there is then it will break the loop and the program will quit

1 Comment

Welcome to SO. Your code may offer a solution to the question, but adding explanation as to how it works will help other users interpret it more quickly.
1

Here's a fun way to do it with a decorator:

def restartable(func): def wrapper(*args,**kwargs): answer = 'y' while answer == 'y': func(*args,**kwargs) while True: answer = raw_input('Restart? y/n:') if answer in ('y','n'): break else: print "invalid answer" return wrapper @restartable def main(): print "foo" main() 

Ultimately, I think you need 2 while loops. You need one loop bracketing the portion which prompts for the answer so that you can prompt again if the user gives bad input. You need a second which will check that the current answer is 'y' and keep running the code until the answer isn't 'y'.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.