Python re - running a program from the top without while - python

I wanted to ask,
Is there a way that you can re - run any sort of program on Python 3.x or 2.x without the need for a while loop?
For instance, is there any block of code that I can use to do this:
if user says yes:
re - run code from top
else:
end program
For instance, take this example:
output Hello what would you like to do?
if user says internet
response = go to internet.
if response = true
go to start.
else
end program
def internet
open web page.
output Would you like to do anything else?
if input is yes
return True
else
return False
Thanks,
Judy.
Note, the code above is a mock - up.

This works...
>>> from itertools import count
>>> c = count()
>>> for i in c:
... i = input("what is your input? ")
... if str(i) == "internet":
... print "internet"
... elif i == True:
... continue
... else:
... break
...
what is your input? True
what is your input? "internet"
internet
what is your input? "foo"
>>>
But it's still much better as a while loop.

The while is actually the best and cleanest solution here. Remember to place all re-usable functionality in functions or classes. E.g.:
def main():
while True:
fun()
ask user
if user says no:
break
def fun():
# your functionality goes here
if __name__ == "__main__":
main()

while user says no:
if user says yes:
do stuff
break
This gets rid of one of the statements.

You can restart the execution of a script with os.exec*()
Hope this helps!

Related

Why is this script repeating itself?

I'm trying to teach myself python, I recently learned how to use raw input in an if statement (yes or no). However, when I answer yes, the program asks me the same if question.
Can anyone help? I'm not really good at programming but love doing it.
import time
name = raw_input("what is your name? ")
print "Hello " + name
#yes no statement with raw input
while True:
yesno = raw_input("would you like to play hangman?")
if yesno.lower().startswith("n"):
print("ok bye")
exit()
elif yesno.lower().startswith("y"):
print("cool, let me prep for e second")
time.sleep(5)
# this is where it goes wrong
# below is what is supposed to follow
word = "kaasblok"
guesses = ''
turns = 6
while turns > 0:
If you use a while true loop, your program will keep on running.
In Python, the tabs or whitespace tell the interpreter when a loop ends.
So what happens in your code is this:
While True is running,
It asks if you want to play
If you write no it works as intended
If you write yes, it sees that the loop is over so it restarts.
Also your code has several errors, like syntax from both Python 3 and Python 2 and a while loop that doesn't terminate.
I wrote some updates to make the code sort of work but it is not "good" code because I tried to keep it as similar as possible. Also I chose a syntax (python 3) so make sure to change that if you're using Python 2.
I recommend you modularize your code and look at other people's code, it'll make your code better. Avoid using a while True loop, at least at the beginning. The code I wrote sort of tries to address it, but it probably doesn't do such a great job.
Maybe try editing the code a bit and updating with an answer later? I think you meant to write input, not raw_input but it could be that's the way you do it in Python 2. You should really learn Python 3 if you're trying to pick up Python btw as Python 2 is at its end of life cycle.
Place your game in the loop and it'll run. Try something like this:
import time
name = input("what is your name? ")
word = "kaasblok"
turns = 6
print("Hello " + name)
#yes no statement with raw input
trueorfalse = True
while trueorfalse:
yesno = input("would you like to play hangman?")
if yesno.lower().startswith("n"):
print("ok bye")
#trueorfalse = False
break
elif yesno.lower().startswith("y"):
print("cool, let me prep...")
time.sleep(1)
# Place your code in the elif block
while turns > 0:
guess = input("what is the word")
if guess == word:
print('win')
#trueorfalse = False
break
else:
turns -=1
print("you have these many turns left", turns)
print("you lost")
break
All that's missing is a way to break out of the while loop. So, use the break command.
import time
name = raw_input("what is your name? ")
print "Hello " + name
#yes no statement with raw input
while True:
yesno = raw_input("would you like to play hangman?")
if yesno.lower().startswith("n"):
print("ok bye")
exit()
elif yesno.lower().startswith("y"):
print("cool, let me prep for e second")
time.sleep(5)
break # <-- break out of of the current loop
print "made it!"

python pytest occasionally fails with OSError: reading from stdin while output is captured

While running a particular unittest with pytest, it occasionally fails with this error (mentioned in the title) and from the stack trace it happens on the line
choice = input().lower()
when the control reaches this statement, the entire function is:
def prompt_to_activate(bear, printer):
PROMPT_TO_ACTIVATE_STR = ('program has found {} to be useful '
'based of dependencies discovered from your '
'project files. \n Would you like to activate '
'it? (y/n)')
printer.print(PROMPT_TO_ACTIVATE_STR)
choice = input().lower()
if choice.startswith('y'):
return True
elif choice.startswith('n'):
return False
else:
return prompt_to_activate(bear, printer)
for i in range(0, 3):
a = i
print(a)
I tried adding some time.sleep(x) before that statement but that wouldn't fix it. Can somebody tell me the exact reason why this is happening and how to fix it?
Since input() is an interactive function, you'll want to mock out the return value in your automated tests. Something like this:
def test_prompt(capsys, monkeypatch):
monkeypatch.setattr('path.to.yourmodule.input', lambda: 'no')
val = prompt_to_activate(bear=..., printer=...)
assert not val
You might also receive this if you set a breakpoint, but didn't use the -s flag with pytest.
In case someone else stumbles upon this, this error will also be raised if you forgot a pdb breakpoint (import ipdb; ipdb.set_trace()) in your code.

Best way to quit a python programme?

I feel like an idiot asking this but is doing quit() the best way to terminate a python programme? Or is there a better way that could gradually stop all while True loops ect instead of just instantly stopping it all? Once again, I feel like an idiot asking this but I'm just curious.
I don't know why you don't want to use quit() but you can use this:
import sys
sys.exit()
Or this:
raise SystemExit(0)
To halt a while loop you can use the break statement. For example:
while True:
if True:
do something #pseudocode
else:
break
The break statement will immediately halt the while loop as soon as the else statement is read by python
You can use the break statement to stop a while loop. Eg:
while True:
if True:
<do something>
else:
break
Generally, the best way to end a Python program is just to let the code run to completion. For example, a script that looks for "hello" in a file could look like this:
# import whatever other modules you want to use
import some_module
# define functions you will use
def check_file(filename, phrase):
with open filename as f:
while True:
# using a while loop, but you might prefer a for loop
line = f.readline()
if not f:
# got to end of file without finding anything
found = False
break
elif phrase in line:
found = True
break
# note: the break commands will exit the loop, then the function will return
return found
# define the code to run if you call this script on its own
# rather than importing it as a module
if __name__ == '__main__':
if check_file("myfile.txt", "hello"):
print("found 'hello' in myfile.txt")
else:
print("'hello' is not in myfile.txt")
# there's no more code to run here, so the script will end
# -- no need to call quit() or sys.exit()
Note that once the phrase is found or the search comes to the end of the file, the code will break out of the loop, and then the rest of the script will run. Eventually, the script will run out of code to run, and Python will exit or return to the interactive command line.
If you want to stop a while True loop, you could set a variable to True and False, you could even work with a counter if you loop has to stop after a specific amount of loops.
for example
x = 0
y = True
while y == True:
<do something>
x = x + 1
if x == 9:
y = False
just a quick example of what you could do, without using a while loop(basically what i wrote above, but then in 1 line.)
x = 10
for i in range(x):
<do something>
To stop a program, I normally use exit() or break.
I hope this somehow helped you, if not; please comment and I'll try helping you!

How to print one character at a time in python within an input command?

So I know how to print one character at a time and the basic code I have for that is:
import time
import sys
def delay_print(s):
for c in s:
sys.stdout.write(c)
sys.stdout.flush()
time.sleep(0.2)
delay_print("hello world")
But I'm making a game and I'm using delay_print for all of my code and need a way to run it within user inputs without getting this result (there is no error but I don't really want a random "None" there).
GetUp=input (delay_print("\nGET UP? Y/N: "))
And when run it displays:
GET UP? Y/N: NoneN
Which isn't exactly what I want.
So what I need is for someone to tell me how to use delay_print without the "None" appearing. Other than that it runs correctly.
Just brake it into two lines and leave input() without a prompt:
delay_print("\nGET UP? Y/N: ")
GetUp = input()
That way, your print will behave the way you want it and the input will read the user input unobstructed.
Do not complicate your life when you don't have to ;)
If you insist on doing it in a single line you have to modify the definition of delay_print by adding a return '' statement. That way, instead of the default None it will return and empty string instead.
Note however, that GetUp=input(delay_print("\nGET UP? Y/N: ")) is not a very clean coding style. In my opinion that is.
You can return "" from delay_print, so input(delay_print("whatever")) will print slowly, then print an empty input prompt at the end of the line, which seems to be what you want.
The current behavior happens because delay_print returns None, and that is printed by input as a prompt.
See built-in function input:
If the prompt argument is present, it is written to standard output without a trailing newline.
You gave an argument (delay_print("\nGET UP? Y/N: ")) to it (as prompt). So, the interpreter first evaluates the argument. At this time, the program does the write, flush and sleep. Then it returns None (implied when running to the end of a function). That was then provided as the prompt of input().
Your code works like this one:
temp = delay_print("\nGET UP? Y/N: ")
# assert temp is None
GetUp = input(temp)
# Same as input(None)
So, that is the mistake.
The correct should be:
delay_print("\nGET UP? Y/N: ")
GetUp = input()
The None appeared because delay_print was returning no values.
import time
import sys
def delay_print(s):
for c in s:
if c:
sys.stdout.write(c)
sys.stdout.flush()
time.sleep(0.50)
return ''
#delay_print("hello world")
GetUp=input(delay_print("\nGET UP? Y/N: "))

Example of a Sufficient MUD-Style and working Text Parser for Python

I am in the middle of programming a MUD like game, more for the experience and practice. I am trying to find an algorithm that will effectively prase text commands. If you have played MUD type games before you know what I am talking about. If not and example would be if I typed in the command: 'search' it would execute the 'search' whether you type in s, se, sea, sear, searc, search, etc...
Now I do have a algorithm already established, but the more I think about it the more problems see to arise. In code it goeslike this:
def text_parser(string, command):
string_list = []
command_list = []
for x in string:
string_list.append(x)
for x in command:
command_list.append(x)
if len(string_list) == 0: # checks to see if user have entered anything
return False
if ((string_list > command_list) - (string_list < command_list)) is 1: # returns false if string has more items than command
return False
else:
if string_list[:len(string_list)] == command_list[:len(string_list)]:
return True
else:
return False
And you can call this function by:
if text_parser('hel', 'hello') is True:
print('This returns True')
if text_parser('hel', 'Foo') is True:
print('This returns False')
Now this code works perfectly.. exactly what I need for it to do. If I type in 'se' and its other end-members for the command' search' it will always be true... but now comes my biggest problem.. Say i have two commands:
'quit' and 'quaff' and the user only inputs 'qu'
According to my algorithm it will execute both the 'quit' and the 'quaff', because my code is set up as:
if (text parser check):
blah
if (text parser check):
blach
etc.... # The only way out of this is to do nested if's and elif's.. which will look messy..
Which is not what I want to do at all. As you can see many more problems can arise the more commands you set up with the game.
What will be a good algorithm set up for text parsing? Or do I just need to change a few things in my already existing code to address the bugs that can pop up with this set up...? Thanks
I think your approach can be simplified by having a list of all available commands. And then define a function that will parse your input string and look for a command match like this:
all_commands = ['search', 'quit', 'quaff']
def find_command(string, allowed_commands=None):
if allowed_commands is None:
# if there is no restrictions, look for all commands
allowed_commands = all_commands
matching_commands = []
for command in commands:
if command.startswith(string):
matching_commands.append(command)
if len(matching_commands) == 1:
# found a match
return matching_commands[0]
# found either no match or more than one
return None
Now, the function find_command will find matches for the input string and it will either match all commands (all_commands) or a given subset (allowed_commands), in case you only want to allow certain commands in that situation.
For example:
print find_command('se') # returns search
print find_command('search') # returns search
print find_command('qu') # returns None
print find_command('quaf') # returns quaff
print find_command('qu', ['search', 'quit']) # returns quit
Did you try pyparsing? It looks good for such tasks. Check examples: http://pyparsing.wikispaces.com/Examples
You might want to consider the cmd module, which lets you define commands as methods on a class. It then provides a prompt where you can type the commands and see the results. The parsing is fairly rudimentary, but probably sufficient for you to get started.
cmd was featured on Python Module of the Week a while ago, and it has a very nice tutorial. Here's just a very brief taste:
import cmd
class HelloWorld(cmd.Cmd):
"""Simple command processor example."""
def do_greet(self, person):
"""greet [person]
Greet the named person"""
if person:
print "hi,", person
else:
print 'hi'
def do_EOF(self, line):
return True
def postloop(self):
print
if __name__ == '__main__':
HelloWorld().cmdloop()
When you run the above code you'll get a prompt where you can type commands. For example:
(Cmd) greet
hi
(Cmd) greet bob
hi, bob
(Cmd)
The module provides the command loop, and it also supports autocompletion, live help, a customizable prompt, and several other features.
Perhaps, put your commands in a list, and do
def parse(userInput):
returnList = []
for cmd in commandList:
if userInput in cmd:
cmdList.append(cmd)
return returnList
Then you have matching commands in your returned list.

Categories