I'm trying to teach myself Python and am working through some tutorials online. I've created a basic program which asks you to input a name and password (which are stored as variables). It then asks you to re-type them and if they match prints Access Granted.
I've defined some functions with global variables. However if I # out the global declaration my program still seems to work. From what I've read variables not declared as global inside a function should be local. So with the global declaration # out my program shouldn't work. But it does. What have I missed?
import sys
#password = ""
#name = ""
#inputName = ""
#inputPassword = ""
#accountAnswer = ""
def username():
#global inputName
print("What is your name?")
inputName = input()
while name != inputName:
print("Sorry, you are not a registered user.")
print("What is your name?")
inputName = input()
#return
def pwrd():
#global inputPassword
print("Please enter your password:")
inputPassword = input()
while inputPassword != password:
print("Sorry, incorrect Password:")
print("Please re-enter your password:")
inputPassword = input()
continue
#return
print("Hi there, would you like to create an account? (y/n)")
while True:
accountAnswer = input()
if accountAnswer == "y":
break
if accountAnswer == "n":
break
print("That was an incorrect response")
print("Would you like to create an account? (y/n)")
if accountAnswer == "y":
print("Great! Let's get you set up.")
else:
print("OK, no worries.")
sys.exit()
print("Choose a username")
name = input()
print("Now choose a password.")
password = input()
print("let's try logging in.")
username()
pwrd()
print("Access Granted")
print(name, password)
The thing that you should familiarize yourself with is Scope. You can find a lot of info about it on line but in short scope is where your variable is visible.
So in your example, let's try to follow the steps that interpreter is doing when entering your function.
username()
Print text
Assign value from input() to a variable named inputName. Note that it doesn't matter if the variable existed before or not. If it didn't the interpreter will create it.
Enter while loop.
Check if a variable named name is equal to inputName. The interpreter can't see the variable name in current scope, so it tries to look one lever higher, which is your main script. It finds the variable so it uses that one (which you declared in line 51).
I hope that you understand the main concept here. This however should not be used as your default method. It's better to create functions which take arguments rather than using global variables or higher scope.
One small note at the end. I do recommend you to try using an editor like PyCharm. It will warn you about such situations. It will also help you get better with following code style rules (a document is called PEP8) which include how to name variables, where to put and how many spaces etc. It may sound not needed for now but it will save you a lot of changing habits later.
Good luck!
Related
Im new to python and I'm trying to code a python login program. Instead of printing out "Welcome to the database" when the username provided is correct, it printed out both "Welcome to the database" and "Username invalid. Please try again.". May I know which part of my code needs to be corrected?
def login():
while True:
name = input("Name: ")
with open('username.txt', "r")as name_file:
for line in name_file.readlines():
if name == line.strip():
print("welcome to database")
else:
print("Username invalid. Please try again")
You are looping through all the users in the text file and for each of them printing to the console. The thing you probably want could be done like this:
def login():
while True:
loginSucessful = False
name = input("Name: ")
with open('username.txt', "r")as name_file:
for line in name_file.readlines():
if name == line.strip():
loginSucessful = True
break
if loginSucessful:
print("welcome to database")
else:
print("Username invalid. Please try again")
You could use a boolean variable to keep track of successful logins like #Michalor did. Or you can use Python's for/else loop to do the same thing without adding a new variable. If the login is successful and you break out of the loop, the "else" statement isn't executed. Using "break" also has the advantage that you don't need to test all of the other users after you have found a successful login.
def login():
while True:
name = input("Name: ")
with open('username.txt', "r")as name_file:
for line in name_file.readlines():
if name == line.strip():
print("welcome to database")
break
else:
print("Username invalid. Please try again")
Of course, this kind of function doesn't provide much security, as you can keep guessing the names in the text file until you find a valid one, or if you can get your hands on the text file itself you can just look the names up. For actual login code, it's probably best to use some kind of login library that handles the security details for you.
I am self-teaching myself python and have run into a problem that I can not seem to find a way around.
I have created a piece of code that compares an entered password to one stored in a database.
My code should have two possibilities.
1) If the password is correct.
The user is prompted to enter a new password and then the prompt to enter the password must appear again (This time accepting the new password).
2)If the password is incorrect the user will be prompted to enter the password until the correct password is entered.
In VBS I used to be able to use the GOTO command.
I am not sure if this is available in Python and if it is I would like to avoid using it as it creates a very illogical hard to follow the program.
password = "#123"
entry = input("Please Input The Password:")
if (password == entry):
entry = input("Password correct you may enter a new password.")
else:
entry = input("Password Incorrect, Try again.")
There are various ways you could complete this. Here is a simple way you could achieve it using while loop and break statement.
password = "#123"
while(True):
entry = raw_input("Please Input The Password: ")
if (password == entry):
print("Password correct you may enter a new password.")
break
else:
print("Password Incorrect, Try again.")
Hope it helped.
while password != entry: # Executes until (password == entry), and does not execute if it is met, even for the first time.
print('Sorry, wrong password.')
entry = input('Enter password >') # or other source of data
print('Correct!')
Edit: additional ways you can do this:
while True: # forever loop, but
entry = input('Enter password >') # or other source of data
if password == entry:
print('Correct!') # you can also put this outside of the loop
break # exit the loop no matter what
# do not put code after the break statement, it will not run!
print('Sorry, wrong password') # will execute only if password != entry, break ignores the rest of the code in the loop
Easiest to make a function with a while statement.
password = "#123"
def login():
while True:
answer = input("Please Input The Password:")
if answer == password:
print("Password correct you may enter a new password.")
else:
print("Password Incorrect, Try again.")
break
login()
My project is making a login server using txt files to store user info, and trace back, to complete logins.
However I am trying to use the statement, (if new_username == username). I want to use the username they already created and the one they just entered. However these 2 inputs are in different procedures. And because of this it wont let me use another input from a different procedure.
If there are any changes or edits I can make to the code to overcome this issue, I would greatly appreciate it!
my code, and with drawings to explain what im talking about
original image of my code so far
Your test is not true, you should use username and password as a global variable.
Try this :
def register():
username = input("Please enter your username ")
password = input("Please enter your password ")
file = open("login.txt","a")
file.write(username+" "+password+"\n")
file.close()
def login():
username = input("Please enter your username ")
password = input("Please enter your password ")
for line in open("login.txt","r").readlines():
login_info = line.split()
if username == login_info[0] and password == login_info[1]:
print("Correct credentials!")
return True
print("Incorrect credentials.")
return False
Within your newUser() function you will have to assign the variables you have used e.g. 'username' as global. This will allow you to use and access the variable outside of the current procedure.
def newUser():
global username
username = input("Create login name: ")
Do this with every variable you want to access outside of the current procedure.
Ideally, if you're going to be doing this a lot in your program, you might want to take a look at using classes.
So i am making a password system.
It ask for the user to enter the password, then check if it's right. I am getting a error with:
%Run HelloPython.py
File "/home/pi/Python Coding/HelloPython.py", line 17
print('Welcome home,', name,)
^
SyntaxError: expected an indented block
Something is wrong.
Code:
print('What is your name?')
# Stores everything typed up until ENTER
name = sys.stdin.readline()
print('Hello', name,'Enter password.')
password = sys.stdin.readline()
if password == ("1"):
print('Welcome home,', name,)
else:
print("Password:", password,"Is incorect. Please try again.")
SyntaxError: expected an indented block
Indent your if-else statements like below.
To check "is equal to", use == instead of = which is an assignment.
readline returns a string, so you should compare it with '1' string.
readline includes a newline \n at the end, so call strip() on it.
import sys
print('What is your name?')
# Stores everything typed up until ENTER
name = sys.stdin.readline()
print('Hello', name, 'Enter password.')
password = sys.stdin.readline().strip()
if password == '1':
print("Welcome home,", name)
else:
print("Password:", password, "Is incorrect. Please try again.")
So I've re-wrote your code. You're forgetting to indent your if-statements. http://www.secnetix.de/olli/Python/block_indentation.hawk
import sys # Import the 'sys' module
print('What is your name?')
name = sys.stdin.readline()
print('Hello ', name, '. Enter password.')
password = sys.stdin.readline()
# Use '=='
if password == 1:
print("Welcome home, ", name)
# Here you need indentation.
else:
print("Password: ", password," is incorect. Please try again.")
This is not your only error, but it is probably the most easily overlooked:
if password = 1:
What's going on here: 1 is getting stored to the variable password (Since = is the storing operator). Then if password is getting evaluated; variables are truthy in python, so that will evaluate to True, regardless of what you had stored in password above.
To remedy this, use == for comparing password, and also since password is a string, put the 1 in quotes so that it is compared as a string.
if password == "1":
You need to fix your indentation as well, python is dependent on whitespace.
I'm very new to Python and was testing myself on making a login and signup account database type thing (very basic) it's all text based.
Some reason, when I run the code and signup, it needs the accounts dictionary inside of signup(), but when I successfully create the account, it doesn't store the new account key and information in the accounts dictionary in def login() (hence why I put accounts dictionary in signup() too, because otherwise I get a error for accounts dictionary not existing) please help?
http://imgur.com/wy2vvCZ - link to code (because pasting code into this website seems a bit buggy or I'm just stupid lol)
Here's what I've got:
def main():
option = input("Login or sign up? L/S ")
if option == "L":
login()
if option == "S":
signup()
else:
print("Error - restart programm")
def login():
accounts = {"user123": ["pass123"],
"123user": ["123pass"], }
loginUser = input("Enter username: ")
loginPass = input("Enter password: ")
if loginUser in (accounts):
correct1 = 1
print("Correct")
else:
print("Incorrect")
if loginPass in (accounts[loginUser]):
correct2 = 1
print("Correct")
else:
print("Incorrect")
if correct1 and correct2 == 1:
print("")
print("Welcome to System")
print("")
def signup():
accounts = {"user123": ["pass123"],
"123user": ["123pass"], }
signUser = input("Enter custom username: ")
signPass = input("Enter custom password: ")
accounts.update({signUser: [signPass]})
main()
main()
The accounts dict in signup() is local to signup(), meaning it can only be seen within signup(). You are also creating a new accounts in login(), so even if the signup() accounts had global scope, all references to accounts in login() following the assignment would refer to its local accounts and not see changes made in signup()
Since accounts is a mutable type, you could pass it as an argument to signup(). Changes made to accounts in signup() would then be visible in the calling scope, where you could then pass the updated accounts to login().
You've got two different functions, login and signup, that each have their own local variables. The whole point of local variables is that they're only accessible within that function.
You either need to pass the values, or share the variables.
You can pass the values by using parameters (and return statements, but you don't need those for this example). Create accounts in the main function, then pass it to the other two functions; that way, they'll all have the same dictionary.
But you have another problem that you also have to fix: You should not be calling main() at the end of login and signup; just have them return, and put a loop in main. Otherwise, you're starting all over again each time; any local variables that got changed are going to go right back to their original values.
So:
def main():
accounts = {"user123": ["pass123"],
"123user": ["123pass"], }
while True:
option = input("Login or sign up? L/S ")
if option == "L":
login(accounts)
if option == "S":
signup(accounts)
else:
print("Error - restart programm")
return
def login(accounts):
print(accounts)
loginUser = input("Enter username: ")
loginPass = input("Enter password: ")
# etc.
if correct1 and correct2 == 1:
print("")
print("Welcome to System")
print("")
def signup(accounts):
signUser = input("Enter custom username: ")
signPass = input("Enter custom password: ")
accounts.update({signUser: [signPass]})
main()
I mentioned above that you need to "pass the values, or share the variables". What about the second one?
You can do this by creating global variables. (Or by creating a class, and using instance variables. Or by using nonlocal variables in a closure.) If you write global accounts at the start of all three functions, they'll all refer to the same accounts variable. But you still have to make sure not to keep reassigning it to the starting values over and over.