Call a function inside a function? Help to fix [duplicate] - python

This question already has answers here:
Python: Name resolution; order of function def's
(5 answers)
Closed 5 years ago.
I'm not sure how to fix my code, could someone help!
It prints this --> "NameError: free variable 'info' referenced before assignment in enclosing scope", I don't know how to make info a global variable, i think that is the problem...Someone please help!
import time
import random
admincode = ["26725","79124","18042","17340"]
stulogin = ["NikWad","StanBan","ChrPang","JaiPat","JusChan","AkibSidd","VijSam"]
teachercode = ["KGV"]
def main():
def accesscontrol():
global teachercode, stulogin, admincode
print("Enter: Student,Teacher or Admin")
option = input("--> ")
if option == "Student":
info()
elif option == "Teacher":
print("Enter you teacher code(xxx)")
option = input
if option == teachercode:
print("Access Granted")
info()
else:
print("Please input the correct code!")
accesscontrol()
elif option == "Admin":
print("Enter your admin code(xxxxx)")
option = input("--> ")
if option == admincode:
print("access granted, my master!")
else:
accesscontrol()
accesscontrol()
def info():
print("Hello, enter your information below")
usname = input("Username: ")
pwname = input("Password: ")
done = False
while not done:
print("Is this the information correct?[Y/N]")
option = input("--> ")
if option == "Y":
print("Information saved")
print("Username :",usname,"\nPassword:",pwname)
done = True
else:
main()
return info()
info()
main()

The problem is that you define accesscontrol and info as local names relative to main. So when you call info inside accesscontrol it can't find it, because it's a name "owned" by in other words local to main.
Instead of having the functions like this:
def main():
def accesscontrol():
# ...
def info():
# ...
# ...
Move them out of main() like this:
def accesscontrol():
# ...
def info():
# ...
def main():
# ...
Thus keeping main() as simply:
def main():
accesscontrol()
info()

You need to define info() before it is called. Also you had an unnecessary call to info(), which I removed.
import time
import random
admincode = ["26725", "79124", "18042", "17340"]
stulogin = ["NikWad", "StanBan", "ChrPang", "JaiPat", "JusChan", "AkibSidd", "VijSam"]
teachercode = ["KGV"]
def main():
def info():
print("Hello, enter your information below")
usname = input("Username: ")
pwname = input("Password: ")
done = False
while not done:
print("Is this the information correct?[Y/N]")
option = input("--> ")
if option == "Y":
print("Information saved")
print("Username :", usname, "\nPassword:", pwname)
done = True
else:
main()
return info()
def accesscontrol():
global teachercode, stulogin, admincode
print("Enter: Student,Teacher or Admin")
option = input("--> ")
if option == "Student":
info()
elif option == "Teacher":
print("Enter you teacher code(xxx)")
option = input
if option == teachercode:
print("Access Granted")
info()
else:
print("Please input the correct code!")
accesscontrol()
elif option == "Admin":
print("Enter your admin code(xxxxx)")
option = input("--> ")
if option == admincode:
print("access granted, my master!")
else:
accesscontrol()
accesscontrol()
main()

Related

Python login limit

i'm trying to implement login attempt system to my current code, but i don't know where i should tick it. Can someone suggest anything? I would like to give three attempts to login, if user fails to login, system will lock user out. I just dont know where to position the code properly.
granted = False
def grant():
global granted
granted = True
def login(name,password):
success = False
file = open("user_details.txt","r")
for i in file:
a,b = i.split(",")
b = b.strip()
if(a==name and b==password):
success=True
break
file.close()
if(success):
print("Login Succesful")
grant()
else:
print("wrong username or password")
The better way to do this problem is by having a JSON file instead of a txt file. You can have the file in this format:
{
"username": {
"password": "",
"attempts": 0,
}
}
In the login() function increment and write the count of attempts if the password is wrong.
And before the function begins read the JSON and check if the attempts value is greater than 3. If it is greater send an appropriate message else to continue the login action and ask for the password.
Your code had some minor errors which I have handled here:
import re
granted = False
def grant():
global granted
granted = True
def login(name,password):
success = False
file = open("user_details.txt","r")
for i in file:
if i.count(',') > 0: # check whether i has at least one ','
a,b = i.split(",")
b = b.strip()
if(a==name and b==password):
success=True
break
file.close()
if(success):
print("Login Succesful")
grant()
else:
print("wrong username or password")
def register(name,password):
file = open("user_details.txt","a")
file.write( "\n"+name[0]+","+password) # name is an array so only the first element is stored.
file.close()
grant()
def access(option):
global name
if(option=="login"):
name = input("Enter your name: ")
password = input("enter your password: ")
login(name,password)
else:
print("Enter yor name and password to register")
name = input("Please enter your name: ").lower().split()
if len(name) > 1:
first_letter = name[0][0]
three_letters_surname = name[-1][:3].rjust(3, 'x')
name = '{}{}'.format(first_letter, three_letters_surname)
print(name)
while True:
password = input("Enter a password: ")
if len(password) < 8:
print("Make sure your password is at lest 8 letters")
elif re.search('[0-9]',password) is None:
print("Make sure your password has a number in it")
elif re.search('[A-Z]',password) is None:
print("Make sure your password has a capital letter in it")
else:
print("Your password seems fine")
break
register (name,password)
def begin():
global option
print("Welcome to Main Menu")
option = input("Login or Register (login,reg): ")
if(option!="login" and option!="reg"):
begin()
begin()
access(option)
if(granted):
print("Welcome to main hub")
print("#### Details ###")
print("Username:",name)

call a 'def' with an 'input' in Python

I'm working on a project, and I got a bit stuck. I want the user the of the program to be able to call a function. But it must be easy for the user to call it. For example
def definition():
print("This is a function")
command = input("> ")
if command == definition:
definition()
else:
print("")
in this function I want the user not to write the () in the input. But I want the user just to be able to write 'definition' to call the function. Does anyone have any clue how to do this?
You are missing the quotes from around definition, therefore trying to compare an undeclared variable with an inputted string which will always equate to false.
Try:
def definition():
print("This is a function")
command = input("> ")
if command == 'definition':
definition()
else:
print("")
You are mixing up the function name (callable object in you code) and the name from your input.
For your problem I would use a dictionary of function names for the keys and function references for the value
def function1():
print ('calling function1')
def function2():
print ('calling function2')
def function3():
print ('calling function3')
functions = {}
functions['function1'] = function1
functions['function2'] = function2
functions['function3'] = function3
name = input('Enter the function name:\n')
if name in functions:
functions[name]()
else:
print ('Invalid function name. Use one of: ')
for key in functions.keys():
print (' - ' + key)
Just one command "definition"
def definition():
print("This is a function")
command = input("> ")
if command == "definition":
definition()
else:
print("Wrong command !")
More commands and functions
def definition():
print("This is definition function")
def modify():
print("This is modify function")
func = {"definition":definition, "modify":modify}
command = input("> ").strip().lower()
if command in func:
func[command]()
else:
print("Wrong command !")
You will have to implicitly define the conditions with if statement..
For ease of user you can do like this:
def definition():
#your function here
if __name__=='__main__':
print ("Choose your option:\n1. Definition")
choice = int(input("Enter choice: "))
if choice == 1:
definition ()
Try this
whitelist_funcs = ['definition', 'something else']
command = input("> ")
if command in whitelist_funcs:
exec(f"{command}()")
else:
print("")

Variable and Function help // Python

Alright so here's the code
def user_password():
input('Please Enter Password: ')
#profiles
def intercept():
user_password()
if user_password == "intercept":
print("this is working so far")
else:
print("Incorect Password")
def Jimmy():
user_password()
if user_password == "Jimmy":
print("this is working so far")
else:
print("Incorect Password")
def Tommy():
user_password()
if user_password == "Tommy":
print("this is working so far")
else:
print("Incorect Password")
#login
user_functions = dict(
intercept=intercept,
Jimmy=Jimmy,
Tommy=Tommy,
# ...
)
user_input = input("Input function name: ")
if user_input in user_functions:
user_functions[user_input]()
else:
print("Error: Unknown function.")
PROBLEMS:
My code always starts with asking for the password even though I don't want it
to.
When I change the first variable to a function it fixes this
Why does it execute when I'm just setting the variable. I'm pretty sure I shouldn't have to use a function instead of a variable
No matter what it always ends up as Incorrect Password even if I give the correct password
I think you are trying to write something like that:
def get_user_password():
return input('Please Enter Password: ')
def Jimmy():
user_password = get_user_password()
if user_password == "Jimmy":
print("this is working so far")

How to store multiple items in one pickle dictionary?

I am currently attempting to make a login/signup program on my computer that will allow for multiple sets of usernames and passwords. Right now anytime I sign up, it overwrites the previous login. I am using Python 3.4.
Is there a way I can prevent this?
My code is available below:
import os
import pickle
import sys
import time
user_name = 'default'
pass_word = '12345'
login = {'username' : user_name,
'password' : pass_word}
def cls():
os.system('cls')
def space():
print(' ')
def load():
with open('logins', 'rb') as f:
login = pickle.load(f)
def save():
with open('logins', 'wb') as f:
pickle.dump(login, f)
def MainMenu():
print('Select an Option.')
while True:
print('1) Login')
print('2) Signup')
user_input = input('Option #: ')
if user_input == '1':
cls()
login_user()
elif user_input == '2':
cls()
signup_user()
else:
cls()
continue
def signup_user():
user_chosen_name = input('Username: ')
login['username'] = user_chosen_name
user_chosen_password = input('Password: ')
login['password'] = user_chosen_password
space()
cls()
print('Setup complete. Please login.')
os.system('pause')
save()
cls()
login_user()
def login_user():
load()
while True:
print('Please Login.')
space()
user_input_name = input('Username: ')
user_input_password = input('Password: ')
if user_input_name == login['username'] and user_input_password == login['password']:
space()
print('Login Successful.')
else:
space()
print('Login Failed. Please Try Again.')
while True:
print('1) Try Again.')
print('2) Main Menu.')
user_cont = input('Continue?: ')
if user_cont == '1':
cls()
break
elif user_cont == '2':
cls()
MainMenu()
break
if __name__ == '__main__':
if os.path.isfile('logins') == False:
save()
else:
pass
MainMenu()
Here are two proposals for the login/password data model.
Use a dictionary, this is probably the simplest way ; I suggest using this.
# init with default
passwords = {user_name: pass_word}
# password look-up
if login in passwords:
print passwords[login]
else:
print 'User', login, 'is not registered'
# password set or update
password[login] = new_password
List of couples or list of dictionaries.
This may be closer to your current solution, but I would not recommend it.
I only show what the initialization would be.
# list of couples
logins = [(user_name, pass_word)]
# list of dictionaries
logins = [{'username' : user_name,
'password' : pass_word}]

Python - reuse user input on menu

What's the best way to implement this - reuse user input on menu?
Here's my sample code below:
def input():
user = raw_input('user: ')
passwd = getpass.getpass('passwd: ')
return (user,passwd)
def function1():
user, passwd, vcenter = input()
do something
def function2():
user, passwd, vcenter = input()
do something
def function3():
user, passwd, vcenter = input()
do something
def main():
while True:
if choice == 1:
function1()
elif choice == 2:
function2()
elif choice == 3:
function3()
else:
print 'Choose from the options only!'
break
I think i get what you mean, you want to use the input() once in the while loop, and not repeat calling it in every function. if so I suggest this solution:
def input():
user = raw_input('user: ')
passwd = getpass.getpass('passwd: ')
return (user,passwd)
def function1(param):
user, passwd = param
do something
def function2(param):
user, passwd = param
do something
def function3(param):
user, passwd = param
do something
def main():
while True:
if choice in [1,2,3]:
param = input()
if choice == 1:
function1(param)
elif choice == 2:
function2(param)
elif choice == 3:
function3(param)
else:
print 'Choose from the options only (1, 2, 3): '
break
hope this helps.

Categories

Resources