I need help for my python assignment. We have to make a quiz program and I am having trouble with restarting a function.
I need something like continue, but instead runs the function again. Also, some tips on returning values from functions cant hurt! Thanks! ~Also, I just started using python 2 weeks ago, so this is pretty advanced to me. EDIT: Thanks to user: 2ps! :D
#Quiz YAY!
#
#Name Removed
#
#Version 1.0
#
score = 0;
modPassword = "200605015"
def modMode(score):
print("Entering Overide Mode");
print("Opening Overide Console")
cmd = input("Enter Command call exit{} to exit: ")
if cmd == "corr":
print("Adding one point")
score=score+1
return(score);
elif cmd== "manScoreChng":
score=int(input("What do want the score to be?"));
elif cmd == 'stop{}':
raise Exception('Quit by User')
score = modMode(score);
print(score);
To capture the return of the modMode function, just make sure you return something at the end:
score = 0;
modPassword = "200605015"
def modMode(score):
print("Entering Overide Mode")
print("Opening Overide Console")
cmd = input("Enter Command: ")
if cmd == "corr":
print("Adding one point")
score = score+1
elif cmd == "manScoreChng":
score = int(input("What do want the score to be?"))
elif cmd == 'exit':
raise Exception('Bye!')
return int(score) # MAKE SURE YOU HAVE THIS LINE HERE
To call the modScore command over and over again, use a loop.
try:
while True:
score = modMode(score) # grab the returned value from modMode by using `=`
print(score)
except Exception:
pass
This will run until the user types in exit.
Related
I have a very basic Blackjack simulator where I input whether I want to Hit or Stay. When I choose it, it then tells me the result. I want to run this over multiple times. Is there a function where after I get the result of the hand, it will restart from the top of the script?
I am using Jupyter notebook and am currently just restarting and running all cells and then input my choice
You can use a basic game play pattern such as the following to do what you want.
# Function to request input and verify input type is valid
def getInput(prompt, respType= None):
while True:
resp = input(prompt)
if respType == str or respType == None:
break
else:
try:
resp = respType(resp)
break
except ValueError:
print('Invalid input, please try again')
return resp
# function to initiate game play and control game termination
def playgame():
if getInput('Do you want to play? (y/n)').lower() == 'y':
while True:
game_input = getInput('Enter an Integer', int)
# . . . Place your game logic here . . . #
if getInput("Play Again? (y/n)").lower() == 'n':
break
print('Good bye')
class PlayerAttributes:
inventory = []
def __init__(self, name, inventory):
self.name = name
self.inventory = inventory # LIST
class Item:
def __init__(self, item_name, damage):
self.item_name = item_name
self.damage = damage
class Weapons(Item):
weapon_1 = Item("Me Sword", 100)
Player_1 = PlayerAttributes("Bob", [])
def get_name():
Player_1.name = input("Enter name here: ").capitalize()
commands()
def stats():
print("Name = " + str(Player_1.name), "\n",
"Inventory: ")
for x in Player_1.inventory:
print(str(x.item_name))
def commands():
prompt = None
prompt_choices = {"stats", "quit", "give"}
while prompt not in prompt_choices:
prompt = input("Enter Command: ").lower()
if prompt == "stats":
stats()
commands()
elif prompt == "quit":
quit()
elif prompt == "give":
Player_1.inventory.append(Weapons.weapon_1)
commands()
get_name()
PROBLEM
I'm currently getting back to the while loop for "prompt" by calling "commands()" in the if statements but was told that it's a recursion and that it's unnecessary as well as it has a side effect of growing the call stack...
QUESTION
What should I do differently??
Extra
How would it grow the call stack?
You can use an infinite loop. Instead of letting get_name and commands call commands, try putting the following at the end of the code:
get_name()
while True:
commands()
and remove all other calls commands() from your code.
Your while loop is configured for repeating the cycle until it finds a prompt. Then, the loop ends. You are restarting the cycle calling the function again but that leaves the first function running so every time this happens a new function will start and the old one will stay waiting. So as you said, the call stack is growing.
One way to solve this is to change your while loop.
Instead of:
while prompt not in prompt_choices:
You can use:
While True:
This makes the loop repeat over and over again without calling a new function.
Another solution will be to use two whiles:
condition = True
While condition:
while prompt not in prompt_choices:
This also makes the loop repeat over and over again. But if you want to finish the loop you can set condition = False within your code and that will make the current cycle the last cycle.
Hope this helps.
You can change your commands() func like below
def commands():
prompt = None
prompt_choices = {"stats", "quit", "give"}
while prompt not in prompt_choices:
prompt = input("Enter Command: ").lower()
if prompt == "stats":
stats()
elif prompt == "quit":
quit()
elif prompt == "give":
Player_1.inventory.append(Weapons.weapon_1)
prompt=None
get_name()
Please help me fix this recursive function so that I can successfully prompt the user at each stage. I am trying to make a program that allows users mix, change the playback speed and filter the signal of a wav file. To do that I need create a recursive question that continually prompts the user to use different tools in this program.
def c_function():
print("you have successfully called c_function")# These print statements are just place holders for the actual functions
return
def m_function():
print("you have successfully called m_function")
return
def f_function():
print("you have successfully called f_function")
return
def s_function():
print("you have successfully called s_function")
return
"use these functions as selection tools in the recursive function bellow"
user_question1 = input("Select one of the following four options:\n s see the sample rate of the file\n c change the playback speed\n m mix two signals together\n f filter the signal or\n q quit \n : ")
def recursive_main_function():
if user_question1 == ('c'):
c_function()
recursive_main_function()
if user_question1 == ('m'):
m_function()
recursive_main_function()
if user_question1 == ('f'):
f_function()
recursive_main_function()
else:
print("Invalid response. Please try again" + user_question1)
return
It looks like you'd want to use an infinite while loop. Using if statements with else ifs is good too because if the user input somehow fulfils more than one of the cases, the program won't call several functions at once. Let me know if you have any questions.
def recursive_main_function():
# Infinitely loops unless user presses 'q'
while(True):
# Waits for the question's input
user_question1 = input("Select one of the following four options:\n s see the sample rate of the file\n c change the playback speed\n m mix two signals together\n f filter the signal or\n q quit \n : ")
# Respond based on input provided
if user_question1 == "s":
s_function()
elif user_question1 == "c":
c_function()
elif user_question1 == "m":
m_function()
elif user_question1 == "f":
f_function()
elif user_question1 == "q":
# Breaks the user out of the while loop
break
else:
print("Invalid response. Please try again" + user_question1)
# End of function, exits script
return
# To initiate script
recursive_main_function()
This is a shorter version of my answer to a related question.
Rather than a forest of ifs, you could use a dictionary to match user input to a function.
def c_function(argv):
print("you have successfully called c_function")# These print statements are just place holders for the actual functions
return 0
def m_function(argv):
print("you have successfully called m_function")
return 0
def f_function(argv):
print("you have successfully called f_function")
return 0
def s_function(argv):
print("you have successfully called s_function")
return 0
def help_function(argv):
print('available commands:')
print(' s see the sample rate of the file')
print(' c change the playback speed')
print(' m mix two signals together')
print(' f filter the signal')
print(' help print the list of commands')
print(' quit quit')
return 0
def quit_function(argv):
env['didntQuit'] = False
return 0
def notfound_function(argv):
print('{}: {}: command not found'.format(env['replname'], argv[0]))
return -1
def print_return_value(ret, argv):
if ret != 0:
print('{}: command {} failed with return value {}'.format(env['replname'], argv[0], ret))
env = { 'replname': 'wav-processor-repl', 'prompt': '$ ', 'didntQuit': True }
command_dict = {'c': c_function, 'm': m_function, 'f': f_function, 'h': help_function, 'help': help_function, 'q': quit_function, 'quit': quit_function}
while env['didntQuit']:
argv = input(env['prompt']).strip().split() # read
command = command_dict.get(argv[0], notfound_function) # identify command
ret = command(argv) # execute command
print_return_value(ret, argv) # error message if command failed
Output:
$ c
you have successfully called c_function
$ f
you have successfully called f_function
$ g
waf-processor-repl: g: command not found
waf-processor-repl: command g failed with return value -1
$ f
you have successfully called f_function
$ h
available commands:
s see the sample rate of the file
c change the playback speed
m mix two signals together
f filter the signal
help print the list of commands
quit quit
$ m
you have successfully called m_function
$ q
I need a way to stop a loop by getting user input without blocking the loop itself which works cross-platform.
Things I have tried:
processes (closes stdin so I can't use input())
threads (can't kill a thread if the while loop terminates and I no longer need the input())
FLAG = False
def break_main_loop(): # how do I get this to execute?
global FLAG
user_in = input()
if user_in == 'stop':
FLAG = True
return
else:
break_main_loop()
def stuff():
pass
def main():
# do stuff, e.g. getting other user input()
while True:
stuff()
if FLAG:
break
return # if I return here, I need to cancel break_main_loop's input()
main()
This will work for you and simple to use. Replace main function with this
def main():
# do stuff, e.g. getting other user input()
try:
while True:
stuff()
except KeyboardInterrupt:
print("Press 1 to quit")
return # if I return here, I need to cancel break_main_loop's input()
main()
I'd love to answer your question. You see, once you are in the main-loop, you don't necessarily need to use a FLAG variable, rather, I'd suggest doing something like this :
def break_main_loop(): # how do I get this to execute?
user_in = input()
if user_in == 'stop':
return True # Returning integer 1 also works just fine
else:
return False # Returning integer 0 also works just fine
def stuff():
pass
def main():
# do stuff, e.g. getting other user input()
while True:
stuff()
if break_main_loop(): # If the user inputs stop, the loop stops via the return statement automatically
return
main()
If you wish to get out of the loop without returning anything else and keep the main() function running for doing stuff:
def break_main_loop(): # how do I get this to execute?
user_in = input()
if user_in == 'stop':
return True # Returning integer 1 also works just fine
else:
return False # Returning integer 0 also works just fine
def stuff():
pass
def main():
# do stuff, e.g. getting other user input()
while True:
stuff()
if break_main_loop():
break
#continue doing stuff
main()
Now, there's a better way to break out of the loop without using the helper function break_main_loop(), and that's done like so:
def stuff():
pass
def main():
# do stuff, e.g. getting other user input()
while True:
stuff()
if str(input("Do you wish to continue:[y/n]")) == 'n':
break
#continue doing stuff
main()
This lets you get rid of the helper function completely.
I hope this answer was helpful. :D
try this:
class new_game:
start_game = True
# end_game = False
def break_main_loop(self): # how do I get this to execute?
print("game is ending!")
def stuff(self):
print("this is stuff happening....now...game is: ", self.start_game)
def game_loop(self):
user_in = int(input("enter '2' to end game or '1' to keep playing:" ))
if user_in == 1:
self.stuff()
self.game_loop()
else:
return self.break_main_loop()
Test_game = new_game()
Test_game.game_loop()
I'm trying to run the program in the following article:
https://blockgeeks.com/guides/python-blockchain-2/
I've copied all of the code into my Spyder IDE. When i run it there's a while loop which starts up asking the user to choose a number from the list of options it prints.
After selecting a number the program should perform the requested action. When i select it though it just loops back to the start of the while loop.
It appears to be ignoring the rest of the code in the while loop (the if statement part).
Confusingly if i take the parts of the code from the program which are used in the while loop and run them separately they work i.e if i run the below code and select the number 1 for my choice it will run the code in the if statement.
Why would the if statement run here but not in the main program?
#function 1:
def get_user_choice():
user_input = input("enter a number: ")
return user_input
#function 2:
def get_transaction_value():
tx_recipient = input('Enter the recipient of the transaction: ')
tx_amount = float(input('Enter your transaction amount '))
return tx_recipient, tx_amount
while True:
print("Choose an option")
print('Choose 1 for adding a new transaction')
print('Choose 2 for mining a new block')
print('Choose 3 for printing the blockchain')
print('Choose anything else if you want to quit')
user_choice = get_user_choice()
if user_choice == '1':
tx_data = get_transaction_value()
print(tx_data)
Update:
Sorry i realise i may not have been very clear what the problem is.
The above code is part of the code from the entire program and runs as expected in isolation from the main program.
The below code is the entire program from the article in the link. It includes all of the code in the program. If i run this main program the while loop doesn't use the if statement. It appears to just be breaking straight out of the loop after i select 1, 2 or 3 (any other number should break out of the loop anyway).
Here's a link for a screen shot showing what the console looks like after i have selected the number 1 for the option.
https://ibb.co/RNy2r0m
# Section 1
import hashlib
import json
reward = 10.0
genesis_block = {
'previous_hash': '',
'index': 0,
'transaction': [],
'nonce': 23
}
blockchain = [genesis_block]
open_transactions = []
owner = 'Blockgeeks'
def hash_block(block):
return hashlib.sha256(json.dumps(block).encode()).hexdigest()
# Section 2
def valid_proof(transactions, last_hash, nonce):
guess = (str(transactions) + str(last_hash) + str(nonce)).encode()
guess_hash = hashlib.sha256(guess).hexdigest()
print(guess_hash)
return guess_hash[0:2] == '00'
def pow():
last_block = blockchain[-1]
last_hash = hash_block(last_block)
nonce = 0
while not valid_proof(open_transactions, last_hash, nonce):
nonce += 1
return nonce
# Section 3
def get_last_value():
""" extracting the last element of the blockchain list """
return(blockchain[-1])
def add_value(recipient, sender=owner, amount=1.0):
transaction = {'sender': sender,
'recipient': recipient,
'amount': amount}
open_transactions.append(transaction)
# Section 4
def mine_block():
last_block = blockchain[-1]
hashed_block = hash_block(last_block)
nonce = pow()
reward_transaction = {
'sender': 'MINING',
'recipient': owner,
'amount': reward
}
open_transactions.append(reward_transaction)
block = {
'previous_hash': hashed_block,
'index': len(blockchain),
'transaction': open_transactions,
'nonce': nonce
}
blockchain.append(block)
# Section 5
def get_transaction_value():
tx_recipient = input('Enter the recipient of the transaction: ')
tx_amount = float(input('Enter your transaction amount '))
return tx_recipient, tx_amount
def get_user_choice():
user_input = input("Please give your choice here: ")
return user_input
# Section 6
def print_block():
for block in blockchain:
print("Here is your block")
print(block)
# Section 7
while True:
print("Choose an option")
print('Choose 1 for adding a new transaction')
print('Choose 2 for mining a new block')
print('Choose 3 for printing the blockchain')
print('Choose anything else if you want to quit')
user_choice = get_user_choice()
if user_choice == 1:
tx_data = get_transaction_value()
recipient, amount = tx_data
add_value(recipient, amount=amount)
print(open_transactions)
elif user_choice == 2:
mine_block()
elif user_choice == 3:
print_block()
else:
break
[1]: https://i.stack.imgur.com/FIrn7.png
When comparing values, Python takes a stronger route regarding data types than some other languages. That means no string in Python will equal a number.
Or in other terms "1" == 1 will be False.
That means you have to consider that in Python 3 you will receive a string from input() (not necessarily so in Python 2).
You can either compare this directly to another string:
user_choice = input()
if user_choice == "1":
print("You chose item 1")
Or you can convert it into a number first and compare it to a number:
user_choice = int(input())
if user_choice == 1:
print("You chose item 1")
Note that in the former case it might not be robust if the user enters extra spaces and in the latter case it will fail very loudly with an exception if the user doesn't enter an integer (or even nothing at all).
Both ways can be handled with extra code if necessary. In the former case, you can strip whitespace with user_input = input().strip() and in the latter case you can catch the exception with a try ... except ... block.
You have only handled the case for user_choice == '1'. If you enter anything other than 1, the program will return control to the beginning of the while loop.
I'll suggest you use a debugger to see what user_choice is before the if condition. If not, just use prints.
print("user_choice: {}, type: {}".format(user_choice, type(user_choice))