For, if, else statements - python

So I have a multilayered problem. I am trying to I am trying to just print out 'input was jack' if the raw_input was 'jack' and also subtract 'tries' by 1, and then run the function again and print out amount of 'tries' at the end of both the first 'if' statement and the 'else' statement, and if the raw_input wasn't 'jack' it adds 1 to 'tries' and if 'tries' reaches a total of 4 the function prints stop. I have run into a couple of different problems. Either the counter seems to reset every single time so it's always just '1' or I can't just keep running the function. It just doesn't seem like it's following the 'if or else' theory I thought it would be. So I have the following code:
tries = 0
def usrinfo():
name = raw_input('input name ')
a = ('jill','jack',name,'meg')
for element in a:
if element == 'jack':
print('input was jack')
tries =-1
print(tries)
usrinfo()
else:
if element != 'jack':
tries =+ 1
return tries
print(tries)
usrinfo()
if tries == 4:
print('stopped')
usrinfo()
If I type 'jack' I get:
Nothing...as in a blank output
I want:
input was jack
-1
Then I want the function to run again...and get
input was jack
-2
And so on.
If I type anything other than 'jack' I get:
Nothing...as in a blank output
I want to get:
1
Then for the function to run again....and get
2
Then if I type anything other than 'jack'. I want with each attempt to print the increasing level of tries from 1 - 4 such as below:
1
2
3
4
Then when it reaches 4 it prints 'stopped' or runs whatever command. I want to essentially keep the code running and control the value of 'tries' according to whether or not the input is 'jack' or something else. Because even when I create an even simpler code like this:
def userinput():
tries = 0
username = raw_input('input username ')
if username == 'jack':
tries -=1
print(username + ' '+ str(tries) + ' success')
userinput()
else:
if username != 'jack':
tries +=1
print('tries ' + str(tries))
userinput()
userinput()
My results on this code with input of 'f' are:
input username f
tries 1
input username f
tries 1
input username f
Instead I want to get:
input username f
tries 1
input username f
tries 2
input username f
tries 3
And with input of 'jack' I want:
input username jack
jack -1 success
input username jack
jack -2 success
input username jack
jack -3 success
input username jack
jack -4 success
And so on. Any help is much appreciated. I'm not sure what I'm doing wrong. It just seems like 'tries' is constantly resetting itself.
Hopefully this is clear...I've spent a lot of time trying to make code just to be able to demonstrate to someone with more knowledge where my misunderstanding might be...
Thanks guys and gals.

Here's what I came up with, no loops required
#!python3
from os import sys
def usrinfo(tries):
name = input('input name: ')
if tries == 4:
print('end of program because tries equals 4')
sys.exit()
elif name == 'jack':
tries -= 1
print('input was jack')
print('tries ' + str(tries) + '\n')
usrinfo(tries)
elif name != 'jack':
tries += 1
print('tries ' + str(tries) + '\n')
usrinfo(tries)
usrinfo(0) # 'tries' will be initialized to zero

When you are taking user input it is stored in the name variable so you need to do if with 'name' not 'element'. Secondly call the function after you have checked the condition
if tries == 4:
print('stopped')
return
usrinfo()
Here is the correct code:
tries = 0
def usrinfo():
global tries
name = raw_input('input name ')
a = ('jill','jack','meg')
#to check the input against the strings of list a go for
#if name in a:
if name == 'jack':
print('input was jack')
tries =-1
print(tries)
usrinfo()
else:
tries+=1
print(tries)
if tries == 4:
print('stopped')
return
usrinfo()
usrinfo()

Related

Non callable variable

I'm trying to make a password generator with Python. Everything else seems to work correctly, but when I try to save the password in a .txt file, the program crashes, telling me that ok_to_save is "non callable". Why does this happen, and how do I fix it?
PS: Don't mind option 6 I'm still experimenting with it.
import random
import string
print('Hi, would you like me to create a password that no one can guess ?')
confirmation=input()
print('If you want a password with only letters press 1 and then enter, for one with only numbers press 2 and then enter.')
print('For a password with both press 3 and then enter.')
print('For a password with letters, numbers and symbols press 4 and then enter.')
print('To remember a password you previously saved in this application press 5 and then enter.')
print('To save a password you made yourself press 6 and then enter')
a=input()
b=''
ok_to_save=''
if a=='1':
b=input = ''.join([random.choice(string.ascii_letters) for x in range(12)])
print(b)
print('Would you like me to save this password ?')
ok_to_save=input()
elif a=='2':
b=input = ''.join([random.choice(string.digits) for n in
range(12)])
print(b)
print('Would you like me to save this password ?')
ok_to_save=input()
elif a=='3':
b=input = ''.join([random.choice(string.ascii_letters + string.digits) for n in
range(12)])
print(b)
print('Would you like me to save this password ?')
ok_to_save=input()
elif a=='4':
b=input = ''.join([random.choice(string.ascii_letters + string.digits + '!' + '#' + '#' + '$' + '%' + '^' + '&' + '*' + '(' + ')') for n in range(12)])
print(b)
print('Would you like me to save this password ?')
ok_to_save=input()
elif a=='5':
f=open("database.txt","r")
f=open('database.txt','r')
print(f.read())
elif a=='6':
print('What is the password ?')
alt_b=input()
if ok_to_save=='Yes' or ok_to_save=='yes':
print('What is this password for ? ')
c=input()
f=open('database.csv','w')
password=''+b+','+c
f.write(password)
f.close()
Ok so from my experimenting, the issue comes in here. When you do
b=input= ''.join([random.choice(string.ascii_letters + string.digits) for n in
range(12)])
What this does is it creates a variable named 'input' and stores the result of the join method in the variable input as well as in the varible b. The reason you get an error at the ok to save line is because you're doing
ok_to_save = input()
The python interpreter sees input and is thinking that you're referring to the variable that you created above and not the function which takes input and therefore says 'str object not callable' because the str object is not a function that you can call.
As a future reference, avoid creating variables with the same name as functions. To solve your issue that you have now, wherever you have
b = input = ...
remove the input and make it
b = ...
or just change input to input1 or something else.
This should resolve the problem.

How do I check if a name is among a list of names in python?

I am writing Oregon trail game and this is the code I have that is causing issues, I don't know why it is having issues. What I want to do is if they enter a name that contains a word that is in a list it will set the variable easter_mode to 1 if they don't then it will set easter_mode to 0. The words that need to be in the list are: (Sturtz, sturtz, Nate, nate)
Thank you
#asking name
player_name = input('What is your name:')
while len(player_name) >= 0:
if len(player_name) > 1:
print("Weclome" + str(player_name))
print('Which mode do you want to play?')
mode_choice = input('(easy) More modes comming soon:')
break
if len(player_name) == 1:
player_name_choice = input(str(player_name)+"? Are you kidding me? Only one letter? You might regreat it (Y/N):")
if player_name_choice == "y" or player_name_choice == "Y":
print("Ok Your Choice!!...")
mode_choice = 'easter'
break
if player_name_choice == "n" or player_name_choice == "N":
player_name = input('What is your name:')
else:
print("You do not type anything, try again")
player_name = input('What is your name:')
#Check Easter Egg Names
easter_names = ["nate sturtz", "Nate Sturtz", "Nate", "nate", "Sturtz", "sturtz"]
if player_name in easter_names:
easter_mode = 1
else:
easter_mode = 0
#easter eggs for name
if easter_mode == 1:
year_set = 2005
mode_choice = 'easter'
else:
year_set = input('Enter a year whatever you like:')
if year_set.isdigit():
return_num = 0
else:
return_num = 1
while return_num == 1:
print('Error,please try again!')
year_set = input('Enter a year whatever you like:')
if year_set.isdigit():
return_num = 0
else:
return_num = 1
year_set = int(year_set)
When I run the full file I get
Traceback (most recent call last):
File "Oregon.py", line 64, in <module>
player_name = input('What is your name:')
File "<string>", line 1, in <module>
NameError: name 'nate' is not defined
You can view the full code on Github
https://raw.githubusercontent.com/nsturtz/Oregon-Trail/master/Oregon.py
You'll get this error in Python 2. In Python 2, input() uses the exact value as your enter it.
In your example, you're typing nate and not 'nate'. The former value is a variable name (which is undefined in your code, hence the NameError), whereas the latter is a string.
In Python 3, input() behaves as you assume, and passes a string to your code.
If you are sure that you want to use Python 2, you can replace input() with raw_input() and it will interpret your input as a string rather than a variable name.
Under Python 2, you can use raw_input instead of input to prevent Python from interpreting the user input as Python code.
However, since Python 2 is deprecated, I strongly recommend against using it1. Use Python 3 instead, where input works as expected.
1 Except of course to maintain legacy products. But that doesn’t seem relevant here.

why does this python while loop not work in the program?

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))

Python 3 Game Bug: Holding down the enter key

I have another question related to this game, here it is:
https://stackoverflow.com/questions/28545444/python-3-game-bug-message-repeating
I made a game thats a knock off of Cookie Clicker (just for coding practice!). And I ran into a problem where the user can hold down the enter key, and get coins really fast. I'd like to prevent that. here is my code:
coin = 0
keepgoing = True
while keepgoing == True:
print('You have ' + str(coin) + ' cmd-coins' )
response = input('Press enter to get a coin!')
if response == 'q':
keepgoing = False
print('Thanks for playing!')
coin = coin + 1
I wrote a rather "gimmicky" solution to your problem, which works to an extent but definitely isn't flawless. Based on your compiler you may have to change the conditional value for start-end such that it is a value which allows you to static press as fast as humanly possible without breaking but not allow the user to hold the enter key. For me in WingIde, 0.03 is the optimal value.
Were you to import a module such as Pygame you would find this sort of game much easier to make.
import time
coins = 0
keepgoing = True
end = -1
while keepgoing:
print('You have ' + str(coins) + ' cmd-coins' )
response = input('Press enter to get a coin!')
start = time.time()
if start-end < 0.03:
print ("Don't hold down the Enter key you cheater!")
keepgoing = False
if response == 'q':
print('Thanks for Playing!')
keepgoing = False
coins = coins + 1
end = time.time()
NOTE: This solution is for Python 3, for < Python 3 you'll have to substitute raw_input() for input(). Also, I wouldn't advise trying to use it on an online compiler.
G Force dog,
You could change your game a bit by making a few changes till someone or I figure out a good solution(Mom gave orders to go to bed). Till we don't find a solution, use this code which isn't exactly a solution.
coins = 0
real = 0
while real == 0:
if True:
print('You have ' + str(coins) + ' cmd-coins' )
response = input('Press c to get a coin, then press ENTER!')
if response == 'c' or response == 'C':
coins = coins + 1
if response == 'q':
print('Thanks for playing!')
real = 1
And 2 things:-
Nice answer Yeniaul! Good try!
Elizion, nice try but your method isn't working. But it is a good idea.
I have used time too, but it seems that when one presses ENTER key for a long time, it just comes out on the screen all together.
I think I do have somewhat of an idea forming... if we make another while loop, after importing 'time', with a condition which makes the loop active every 2 seconds by assigning a variable 'time.clock()' and when its value is a multiple of 2, it activates!
Got it? I know what to do, but can't seem to put it in code. See if you can, reader(especially Elizion and Yeniaul)
Try using time.sleep(seconds of delay) for slowdown
So you could do
coin = 0
keepgoing = True
while keepgoing == True:
time.sleep(0.25)
print('You have ' + str(coin) + ' cmd-coins' )
response = input('Press enter to get a coin!')
if response == 'q':
keepgoing = False
print('Thanks for playing!')
coin = coin + 1
This would make it a quarter-second delay before they could get another coin.

Problems transferring information from one part of a function to another

While working on my program I have run into a problem where the information stored in Menu option 1 is not being transferred to Menu option 2. As you can see it is correctly stored when in menu one. When it returns to go to menu option 2 its like it never went to option 1.
update #1:
some suggestions I've had is to understand scope? from what I can tell the program is not passing the data along to its parent program even though I've typed out return in each of the definitions.
#Must be able to store at least 4 grades
#Each class can have up to 6 tests and 8 hw's
#Weighted 40%*testavg 40% hw average attendance is 20%
#User must be able to input a minimum grade warning
#after each test the your program must calculate the students average and issue warning if necessary
##Define the Modules##
import math
def menu (a): #2nd thing to happen
menuend = 'a'
while menuend not in 'e':
menuend = raw_input("Type anything other then 'e' to continue:\n")
print "What would you like to do ?"
menudo = 0
print "1 - Enter Courses\n2 - Select Course to Edit\n3 - Save File\n4 - Load File\n5 - Exit\n"
menudo = input("Enter Selection:")
if (menudo == 1):
menuchck = 0
menuchck = raw_input("\nYou have entered #1 (y/n)?:\n")
if menuchck in ["Yes","yes","y","Y"]:
x = m1()
else:
print "I'm sorry,",nam,",for the confusion, lets try again\n"
menu()
elif (menudo == 2):
menuchck1 = 0
menuchck1 = raw_input("\nYou have entered #2 (y/n)?:\n")
if menuchck1 in ["Yes","yes","y","Y"]:
x = m2()
else:
print "I'm sorry,",nam,",for the confusion, lets try again\n"
menu()
elif (menudo == 3):
print "Entered 3"
elif (menudo == 4):
print "Entered 4"
else:
print "Anything Else Entered"
def course(): #3rd thing to happen
b = {}
while True:
while True:
print "\n",name,", please enter your courses below ('e' to end):"
coursename = raw_input("Course Name:")
if (coursename == 'e'):
break
will = None
while will not in ('y','n'):
will = raw_input('Ok for this name : %s ? (y/n)' % coursename)
if will=='y':
b[coursename] = {}
print "\n",name,", current course load:\n",b
coursechck = None
while coursechck not in ('y','n'):
coursechck = raw_input("Are your courses correct (y/n)")
if coursechck =='y':
return b
else:
b = {}
print
##Menu Options##
def m1():
a = course()
return a
def m2():
print "Excellent",name,"lets see what courses your enrolled in\n"
print x
return x
###User Input Section###
name = raw_input("Enter Students Name:\n")
a = {}
menu(a)
raw_input("This is the end, my only friend the end")
In your if-elif blocks in the do==1 case, you write m1(), but for the last case, you write x=m1(). You should have the latter everywhere (by typing m1() you only run the function, but do not store the returned x anywhere).
By the way, you can avoid this if-elif confusion using if chck in ["Yes","yes","Y","y"]:

Categories