So at school, our teacher asked us to make a program which needs a password to grant access. I have made this however i would like to improve on it by adding a loop count which increase each time it loops round heres what i have so far for the loop count, however it doesn't work.
import time
b=0
a='apple'
def start():
print("enter password")
c=input("-> ")
if c==a:
grant()
else:
delay()
def grant():
end
def delay():
b=b+1
time.sleep(b)
start()
start()
Your problem is inside here:
def delay():
b=b+1
time.sleep(b)
start()
When you do b = b + 1, you're expecting the b variable at the top of the file to increase by 1, right?
You probably haven't learned this yet, but the reason why this doesn't work is because of something called scope.
To fix it, you need to change your delay function to look like this:
def delay():
global b
b=b+1
time.sleep(b)
start()
From looking at your code, I take it you haven't learned how to use while loops yet?
Your solution of repeatedly calling start inside of delay is actually pretty clever. However, if we use a while loop, we can rewrite your program so that it's a little cleaner and more obvious as to what you're trying to do:
import time
password = 'apple'
def start():
counter = 0
user_guess = ''
while user_guess != password:
print("enter password")
user_guess = input("-> ")
if user_guess != password:
counter += + 1 # Same thing as doing `counter = counter + 1`
time.sleep(counter)
grant()
def grant():
print "Access granted!"
start()
Python doesn't recognize b in delay() because it is in global scope.
Try this:
def delay():
global b
b=b+1
time.sleep(b)
start()
Related
I'm making an unoriginal game for a first project that just runs in my python terminal. The user is randomly given a set of 2-3 letters and the user has to come up with a real word (checked by the Webster dictionary) that contains the given set of letters within 5 seconds. For example, if the game generates "le" the user can input "elephant" within 5 seconds as a correct word and gives them a point.
The problem is that I can't seem to implement the 5 second timer function to run in the back for every time a prompt is given without messing up some other part or running into another problem. I've looked into threading and can't seem to make use of it.
Here is the code for the main game:
from letters import letter_sets_list
fhand = open("words_dictionary.json")
data = fhand.read()
global score
score = int(0)
game_over = False
while game_over is False:
import random
random_letters = random.choice(letter_sets_list)
print('Word that contains:', random_letters)
answer = input("Type a word:")
if answer in data and random_letters in answer:
score += 1
print("nice one")
else:
game_over = True
print("Game Over \n Score:", score)
fhand.close()
exit()
Here is the timer function I found off YouTube and tried to implement:
def countdown():
global my_timer
my_timer = int(5)
for x in range(5):
my_timer -= 1
sleep(1)
countdown_thread = threading.Thread(target=countdown)
countdown_thread.start()
Take a look at that. Especially check if that will work for you:
import time
from threading import Thread
answer = None
def check():
time.sleep(2)
if answer != None:
return
print("Too Slow")
Thread(target = check).start()
answer = input("Input something: ")
Edit: I tried to implement code from my previous answer to your code but with a little different approach:
import time, threading
#from letters import letter_sets_list
#import random
#fhand = open("words_dictionary.json")
#data = fhand.read()
data = ["answer"]
answer = [None]
random_letters = [None]
global score
score = int(0)
game_over = False
x = 0
def game(answer, random_letters):
#random_letters = random.choice(letter_sets_list)
print('Word that contains:', random_letters)
while True:
answer[0] = input("Type a word: ")
mythread = threading.Thread(target=game, args=(answer, random_letters))
mythread.daemon = True
mythread.start()
for increment in range(5):
time.sleep(1)
if answer[0] in data: # and random_letters in answer
score += 1
print("Good answer")
x = 1
break
if x != 1:
print("\nTime is up")
else:
x = 0
game_over = True
In this approach I didnt use time.sleep() inside threaded function but outside of it which helps with killing it. Also i assumed that if your answer is incorrect you would like to have another chance to answer untill time is up or answer is correct so I just used while loop in threaded function. The code is quite simple so I think if you spend a little time analysing your parts of the code you will figure it out.
Some parts of the code I didn't use as I dont have access to your json files ect., but if I understand correctly what you're trying to do, it shoud work. Also check how will behave your kernel. In my case sometimes it shows some problems but my PC is not the best and so it might be only problem with RAM or other part of my computer as it happens quite often with my projects.
The total cost wont print or gain value. I've tried running the subroutines separately but that didn't work. It will not print totalcost at all:
#coffee maker program
print("Welcome to the BartSucks Coffee App")
print("We will guide you through the ordering process")
print("And our amazing Barista 'Simpson' will then serve you")
name = input("Please type in your name: ")
print("Would you like small, medium or large?")
size = input("Type s for small\nType m for medium\nType l for large\n")
while size.upper() not in ("S","M","L"):
print("You must enter s, m or l")
size = input("Please try again\n")
print("Would you like zero,one, two or three spoons of sugar?")
sugars = input("Type 0 for none\nType 1 for one\nType 2 for two\nType 3 for three\n")
while sugars not in ("0","1","2","3"):
print("You must enter 0, 1, 2 or 3")
sugars = input("Please try again\n")
print("Would you like no syrup flavouring?")
print ("Or would you like almond, vanilla or butterscotch syrup?")
flavour = input("n = none\na = almond\nv = vanilla\nb = butterscotch\n")
while flavour.upper() not in ("N","A","V","B"):
print("You must enter n, a, v or b")
flavour = input("Please try again\n")
totalcost=0
def CoffeeSize(cs):
cs=cs.upper()
global totalcost
if size =="S" or size=="s":
totalcost+= 2.5
elif size=="M" or size=="m":
totalcost+=3.0
elif size=="L" or size=="l":
totalcost+= 3.5
def SugarAmount(sa):
sa=sa.upper()
global totalcost
if sugars=="0":
totalcost+= 0
elif sugars=="1":
totalcost+= 0.5
elif sugars=="2":
totalcost+= 1.0
elif sugars=="3":
totalcost+= 1.5
def flavour(fl):
fl=fl.upper()
global totalcost
if flavour=="NONE" or flavour=="none":
totalcost+= 0
elif flavour=="BS" or flavour=="bs":
totalcost+= 1.6
elif flavour=="V" or flavour=="v":
totalcost+= 0.75
elif flavour=="A" or flavour=="a":
totalcost+= 1.0
CoffeeSize(cs)
SugarAmount(sa)
flavour(fl)
print(totalcost)
sorry im quite new to this so correct me if im wrong but i think the problem is that you are calling the functions inside a function which isnt being executed?
Also, everything apart from anything under 'if','def'... etc statements should be on the first indentation level
Your code:
totalcost=0
def flavour(fl):
...
...
CoffeeSize(cs)
SugarAmount(sa)
flavour(fl)
print(totalcost)
In Python, indentations are important and define under what statement it runs over.
As you can see, you are calling the functions on the same indentation level as the code underneath the function 'flavour', therefore it wont get executed as there isnt any other place that calls that function. Try and put this at the end of your program instead:
Code:
if __name__ == '__main__':
CoffeeSize(cs)
SugarAmount(sa)
flavour(fl)
print(totalcost)
What this does is checks to see if the program is the main program instead of being imported by something else. If it is the main/'_ main _' program, it will go from the start, ask the users what they want and then check to see if this program is the main one, then executes all the functions that are listed under the if statement.
Sorry if i misinterpreted your problem but i think that's what the problem is from my perspective :)
Thanks!
Was playing with loops to prepare for my incoming project. and I found infinite loop when using while loop + main function
#1
def choice(name):
while True:
if name == "Eat"
print("I don't want to eat now")
elif name == "Drink"
print("NOPE")
else:
print("o.O?")
def main():
name = input("Eat or Drink ? :")
choice(name)
main()
#2
while True:
name = input("Eat or Drink ? :")
if name == "Eat"
print("I don't want to eat now")
elif name == "Drink"
print("NOPE")
else:
print("o.O?")
Number 2 doesn't generate infinite loops despite I don't have any return
But when I use Number 1, so that I can use the name variable into different functions in future, it generates infinite loop.
Can I know the reason why it is happening? and how do I fix it while keeping name variable nested in main function?
Thanks!
It's because in version #2 you read input from console on every loop iteration (this line: name = input("Eat or Drink ? :")). So it is still an infinite loop, but this time it waits on every iteration until you provide some input.
You can fix it by just adding this line: name = input("Eat or Drink ? :") to your choice function or use:
for i in range(100):
...
If you want to limit the number of iterations.
EDIT:
Ok, so take while True from choice function and put it into main, like this:
def main():
while True:
name = input("Eat or Drink ? :")
choice(name)
... other functions using name
I have decided to make a basic game in Python 3.3 where the a monster and a treasure is generated individually on a number from 1-100, and the user has to choose a number. The program will then inform the user if they are too close or too high or if they have hit something.
I have made a try loop with an except NameError (as I am on Mac, it would be ValueError for Windows). Before I ask anything, I would like to share with you the code that I have so far:
import time, random
def generateValues():
global treasurePos, monsterPos
while treasurePos != monsterPos:
treasurePos = random.randint(1, 100)
monsterPos = random.randint(1, 100)
print(treasurePos)
print(monsterPos)
def mainmenu():
time.sleep(0.5)
print("welcome to this game, press 1 to play or 2 to quit")
time.sleep(0.5)
try:
option = int(input("What would you like to do: "))
if option == (1):
time.sleep(0.5)
generateValues()
elif option == (2):
quit()
except NameError:
time.sleep(0.5)
print("please enter only 1 or 2")
mainmenu()
If I enter 1, my original plan was for the game to continue and generate the positons for the treasure and the monster. What the program does, instead, is loop back to this:
except NameError:
time.sleep(0.5)
print("please enter only 1 or 2")
Which further creates an infinite loop of 'please enter only 1 or 2' - even when I do enter 1.
My question is thus, is there a simple or complex command that I can do to stop this loop from continuing and to allow the program to continue to the 'generateValues' function?
I would appreciate any help or insight that you are willing to share.
Thanks in advance,
Leo
EDIT 1:
Karen Clark pointed out my while loop and I have coded an alternative solution for it below which works:
def generateValues():
global treasurePos, monsterPos
treasurePos = 0
monsterPos = 0
treasurePos = random.randint(1, 3)
monsterPos = random.randint(1, 5)
if treasurePos == monsterPos:
generateValues()
else:
print(treasurePos)
print(monsterPos)
The problem is in the generateValues() function. You need to initizalize both treasurePos and monsterPos to work. Try this:
def generateValues():
global treasurePos, monsterPos
treasurePos = 10
monsterPos = 1
while treasurePos != monsterPos:
treasurePos = random.randint(1, 100)
monsterPos = random.randint(1, 100)
print(treasurePos)
print(monsterPos)
Just make sure to give them different values. If, not the code won't enter the loop.
You have a typo when calling generateCharPosition(). The function definition is correct, but the calls are missing an "i" - generateCharPosition
Newish to python, working on a text adventure, testing out the use of functions.
def cell1():
loop = 1
while loop == 1:
print("ONE")
cave1 = input()
if cave1 == ("end?"):
print("\nthis should end program")
loop = 0
break
elif cave1 == ("TWO"):
global testvar
testvar = 1
option1()
else:
print("INVALID")
def option1():
print("TWO")
loop = 1
while loop == 1:
print("test1 definition")
print (testvar)
test1 = input()
if test1 == ("ONE"):
print("you pick up the cheese")
loop = 0
cell1()
elif test1 == ("THREE"):
option2()
else:
print("INVALID")
def option2():
print("THREE")
loop = 1
while loop == 1:
print("This is option 3")
test2 = input()
if test2 == ("ONE"):
print("testering2")
cell1()
elif test2 == ("TWO"):
global testvar
testvar = 2014
option1()
else:
print("INVALID")
run = True
while run == (True):
print ("testing 123")
cell1()
print("restart about to activate")
cont = input("Restart? ")
if (cont) != "yes":
break
This program should allow you to go between options (what would be rooms) and eventually in cell1, the program should be end-able.
if the program is run and "end?" is typed as the first input, the program goes into the continue bit at the bottom, however, if you go between the 'rooms' then back to cell1, typing "end?" will call option 2.
Ive had a look around and it is still baffling me, am i ding something wrong?
Any help is appreciated, thank you.
The reason "end?" only quits for the player when they are within the first cell is because you're only checking for that input therein. The execution contained within option1() and option2() doesn't affect the execution of cell1(). You're not returning anything from your option functions, nor are you changing a sentinel value.
So, there's two basic ways you could go about this.
First, you could return a value from your functions:
if option1() == "END":
break
Or, you could alter your while loop:
# is_running is defined globally
while is_running:
And then just set is_running to False in any of your methods whenever the user types "end?". That'd probably be the easiest way with the design you're using now.
I'm sure you can tell, though, that in general your program is going to get exponentially more complex as you add more rooms and your function calls get further nested.
I'm pretty sure that the issue you're having is because you don't always break out of the loop in one function when you call another function. For instance, if your entries were TWO, ONE then end?, you'd find yourself still in the cell1 loop. That's because when the inner call to cell1 returns, the control flow of the program goes back to where that function was called from, which is option1, since loop is now 0, the loop ends and option1 returns, to the outer call to cell1, where the loop is still running.
Unless you want the game you're designing to have a tree structure, where you can return to where you came from with different semantics than moving to some other place, I'd suggest using a different architecture. Rather than each of your functions calling the next function when appropriate, return that function instead. Then you'd write a single top level loop that calls the function. Here's an example where the function to be called by the top level loop is saved in a variable named state:
def cell1():
print("In cell1!")
while True:
choice = input("pick 'ONE' or 'TWO' (or type 'quit' to exit):")
if choice == "ONE":
return option1
elif choice == "TWO":
return option2
elif choice == "quit":
return None
else:
print("I'm sorry, I didn't understand that.")
def option1(): # these other two functions are very basic in my example
print("In option1!") # but you can make them as complex as you want
return option2
def option2():
print("in option2!")
return cell1
def control_loop(initial_state=cell1):
state = initial_state
while state is not None:
state = state() # the next state is the return value of the previous state
The problem is you are getting deeper and deeper within nested functions. For example, changing
if test1 == ("ONE"):
print("you pick up the cheese")
loop = 0
cell1()
to
if test1 == ("ONE"):
print("you pick up the cheese")
loop = 0
break
will allow you to run your program, enter room two, go back to room one, and "end?" will work properly. This won't fix your issues completely though because there is a similar problem where when you go from two to three where if you simply changed
if test2 == ("ONE"):
print("testering2")
cell1()
to
if test2 == ("ONE"):
print("testering2")
break
it would break the current function and go back into option1() (if you run your program, go to room two, then to room three, then back to one) where "end?" doesn't do anything. Hopefully this gets you on the right track.