Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
im making a login system in python that gets the username then checks a line on a text file then it checks the next line until it finds it then checks the same line on a second file (password file) and confirms the password with the username. when i try to log into an account i made it continually loops till it breaks itself. the variable it cant find is line in the checkusername function
u = open('user', 'r+')
p = open('password', 'r+')
def main():
accountcheck()
def accountcheck(): # check if the user has an account
account = input('Do you have an account?\n')
if account == 'yes':
new = 0
username(new)
elif account == 'no':
new = 1
username(new)
else:
print(account, 'Is not a valid answer. Please try again')
accountcheck()
def username(new): # input username
userlist = u.read().splitlines()
user = input('Please enter your username\n')
if user in userlist and new == 0:
checkuser(user, new)
elif new == 1 and user not in userlist:
password(user, new)
elif new == 1 and user in userlist:
print('Username taken')
username(new)
else:
print('Username is not fount in our database. Please try again')
username(new)
def checkuser(user, new): # scan the username file for the username
line = 1
ulines = u.readlines(line)
if user != ulines:
line = line + 1
checkuser(user, new)
elif ulines == user:
password(user, new)
def password(user, new):
passwordlist = p.read().splitlines()
password = input('Please enter your username\n')
if password in passwordlist and password != user:
checkpassword(user, new, password)
elif new == 1 and password != user:
writelogin(user, password)
else:
print('Password is incorrect. Please try again')
password(user, new)
def checkpassword(user, line, new, password):
plines = p.readlines(line)
if plines != password:
line = line + 1
elif plines == password:
if new == 1:
writelogin(user, password)
else:
print('you have logged in')
def writelogin(user, password):
userwrite = user + '\n'
passwordwrite = password + '\n'
u.write(userwrite)
p.write(passwordwrite)
main()
if you want to run this file you need to have a user text file and a password text file in the same folder the program is. any help is appreciated
I see the following problems with your code:
Unnecessary use of recursion: this maybe is not a problem now, but python have a limit of how much you can do recursive calls, to avoid hit that limit change all yours functions to use loops.
read/readline/readlines: Looks to me that you are under the impression that when you do consecutive reads in the file you always get the same result, but that is not the case, when you do u.read() the first time you get the whole content of the file, no mystery there, but if you do u.read() again you get nothing that is because internally a file object have a read pointer that indicate where it is in the file, you can think of it as the palpitating | in a text editor when you do a read of any kind that pointer move according to kind of read you do, if it is readline it move to the next line but if its read or readlines it move to the end of the file and what you get from the operation is everything in between the previous position and the new position. But don't worry there is a way to tell it where to put say pointer with the seek method, to return to the start do u.seek(0) before any read to always get the same result from yours reads.
readline(N)/readlines(N): in the same way as before you may think that that give you a particular line in the file but that is no the case take a look a the documentation
read(size=-1)
Read and return at most size characters from the stream as a single str. If size is negative or None, reads until EOF.
readline(size=-1)
Read and return one line from the stream. If size is specified, at most size bytes will be read.
The line terminator is always b'\n' for binary files; for text files, the newline argument to open() can be used to select the line terminator(s) recognized.
readlines(hint=-1)
Read and return a list of lines from the stream. hint can be specified to control the number of lines read: no more lines will be read if the total size (in bytes/characters) of all lines so far exceeds hint.
Documentation: https://docs.python.org/3/library/io.html#high-level-module-interface
Tread carefully when using recursion: in your case, the 'line' value is always being set to '1' in the first line of the checkuser() method. This means that it will always read the first line and always call checkuser() again if the user does not match (ad infinitum).
It may be better to use a simple loop instead.
You may wish to pass 'line' to your checkuser() method instead eg:
def checkuser(user, new, line=1):
...
Related
What I'm trying to do is basically make a user input and jump into a text file with JSON.
user = ''
RepQues = {}
while(user.lower() != "quit"):
user = str(input("Type here:"))
RepQues[user] = user
if user in RepQues:
pass
else:
RepQues[user] = user
with open('Texts.txt', 'a') as file:
json.dump({user: user}, file)
with open('Texts.txt', 'r') as file:
print(file.read())
It's not working though, and I'm not getting any errors either. What am I doing wrong?
Your if condition is always true.
With the statement on line 5 (RepQues[user] = user), you're inserting the input into your dictionary immediately.
Then on line 6, you're asking if the same value is in the dictionary (if user in RepQues:) - which will always be true. It is dutifully executing the instruction in the if block and passing.
Remove line five.
I have a very simple 'login' program that I've almost got finished. I'm trying to get my make_acc() function to write the username on line 1 and the password on line 2, as well as make my login() function read those separate lines per what needs to be checked. I'm pretty sure the answer has to do with marking the readline command for which line needs to be read, but I'm not sure how to implement it in my code properly. Here's the code.
# This function has the user input a username for their account
def make_acc():
username = input('Make a username:')
file = open('acc_data.txt','w')
file.write(username)
file.close()
#password = input('Make a password:')
#file = open('acc_data.txt','w')
#file.write(password)
# This function has the user login to a preexisting account
def login():
input_user = input('Enter your username:')
file = open('acc_data.txt','r')
username = file.readline()
if input_user == username:
print('You are now logged in')
else:
print('That user does not exist')
login()
# This variable will be defined as a yes or no depending on whether or not the use has an account
acc_bool = input('Do you already have an account?:')
# This if statement runs the login() function if the user answered yes to the previous input
if acc_bool == 'yes':
login()
# This elif statement runs the make_acc() function if the user answered no to the previous input
elif acc_bool == 'no':
make_acc()
login()
This should do it:
def make_acc():
username = input('Make a username:')
password = input('Make a password:')
with open('acc_data.txt','a') as file:
file.write(username+'\n')
file.write(password)
def login():
input_user = input('Enter your username:')
with open('acc_data.txt','r') as file:
if input_user in [u for i,u in enumerate(file.readlines()) if not u%2]:
print('You are now logged in')
else:
print('That user does not exist')
login()
Instead of having the usernames and passwords all in 2 lines, you can use indexes to determine whether a line is a username or password: even indexes are for usernames, and odd ones are for passwords.
UPDATE:
This part: [u for i,u in enumerate(file.readlines()) if not u%2] lists all the strings in file.readlines() (a list of all the lines in f.read()) if the index of the string, i, doesn't leave a remainder when divided by 2.
You see, enumerate() will basically let us iterate through an array and let use easily access the index of the current iteration.
First, uncomment the part of make_acc that asks for a password and add a file.close().
Then, notice that when you've run the program and inputted the two pieces of information, only one is left in the file, this is because, when calling open(), you use the
w mode, which truncates the file before allowing you to write. The consequence of this is that when you open the file again a couple of lines later, all information previously stored is lost. The solution is to use mode r+ or a or just not close the file until the end of the function, thereby avoiding having to reopening it when writing the password.
Next, when reading from the file, you can use file.readline() just as you already are doing. Choosing what line to read happens by default, because every call to readline advances what line is being read. This means that the second time you call it since you opened the file, the second line will be read.
So basically i bought a book that teaches the basics of python and how to create a random number generator so I decided to go one step further and make a random password generator I found a tutorial online that gave me a good example of why and what is used to make a password generator but i want the output to be saved to a .txt file I do not know what i need to implement to get the result i want this is what i have i'm using python3.
import random
chars = 'abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ!, #,#$%^&*.'
number = input('Number of passwords - ')
number = int(number)
length = input('password length? - ')
length = int(length)
answer = input
for P in range(number):
password = ''
for C in range(length):
password += random.choice(chars)
print(password)
password = open("passlist.txt", "a")
password.write(password)
password.close()
file = open('passlist', 'w')
file.write(password)
file.close()
this is what i get in shell
Traceback (most recent call last):
File "C:\User\Desktop\passgen.py", line 21, in <module>
password.write(password)
TypeError: write() argument must be str, not _io.TextIOWrapper
When you open a new file and set it equal to a variable, you are actually creating an _io.TextIOWrapper object. So in this line of code, you are creating this object and storing it in password, getting rid of the password generated in the previous lines of code.
password = open("passlist.txt", "a")
You are then trying to write to the passlist.txt file with this line:
password.write(password)
You are telling password, now an _io.TextIOWrapper object, to write to the passfile.txt the _io.TextIOWrapper object, not the password generated beforehand. This function is expecting a string, and you are now passing an _io.TextIOWrapper object. Since password is no longer a string, that is why you are running into the error.
To fix this, I would suggest creating a new variable:
txtFileWriter = open("passlist.txt", "a")
txtFileWriter.write(password)
txtFileWriter.close()
You may find that after fixing this, only one value is being stored inside your text file. I would recommend properly nesting your for loops:
for P in range(number):
password = ''
for C in range(length):
password += random.choice(chars)
print(password)
The meaning of these for loops can be translated as:
For each password, set the password = ' ' and for each character, add one random character to password.
The problem with this is that you will only have one password after the for loops are complete. You are setting the password value to ' ' each time you run through the outer loop. The only password that will be saved, will be the last value. In order to fix this, I recommend using a list.
I recommend reading through this documentation
I don't want to spoon feed the answers since I realize you are learning python, so I will leave it here. You will want to create a list and then append a value to that list each time you generate a password. After some reading, hopefully this will make sense.
filename = 'passlist.txt'
with open (filename, 'a') as file_object:
file_object.write(password)
Using with will close the file once access is no longer needed.
You also need a list to append your passwords ;)
The error originates from password being re-assigned in password = open("passlist.txt", "a"). This causes and error in the next line as you are attempting to pass password as parameter to itself in password.write(password).
Some farther assistance
You have the right idea but you forgot to indent. All the lines below for P in range(number): should be indented because the program must generate and write a new password until it has satisfied the required amount of passwords.
The password = open("passlist.txt", "a")
password.write(password)
password.close() lines are unnecessary as you are overriding the generated password and assigning that password variable to something that is not a string; that is why you are getting that error.
Here is the code with the adjustments.
import random
chars = 'abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ!, #,#$%^&*.'
number = input('Number of passwords - ')
number = int(number)
length = input('password length? - ')
length = int(length)
answer = input
for P in range(number):
password = ''
for C in range(length):
password += random.choice(chars)
print(password)
password += "\n" # writes the password in a new line
file = open('passlist.tx', "a")
file.write(password)
file.close()
I am doing a project for school - and as part of it, I need to check if their username is already stored within a text file:
def checkUsername():
userName = str(input("WHAT IS YOUR NAME?"))
if userName in usernames.read():
print("WELCOME BACK" + userName)
print("LET\'S GET STARTED")
return False
else:
usernames.write(userName)
print("WELCOME TO THE SYSTEM!")
return False
Despite my efforts to resolve this issue, I cannot seem to figure it out. Can anyone help?
What you are missing is first opening the file for reading:
def checkUsername():
userName = str(input("WHAT IS YOUR NAME?"))
with open("usernames.txt", 'r') as usernames:
if userName in usernames.read():
print("WELCOME BACK" + userName)
print("LET\'S GET STARTED")
return False
else:
usernames.write(userName)
print("WELCOME TO THE SYSTEM!")
return False
with open opens the file at the specified path (change usernames.txt to the full path of the file) and 'r' signifies that the file is to be opened with reading permissions. This is usually advantageous to using python's open() method, which requires you close() the file when you are finished reading it.
Side note: notice you have returned False under both conditions of your function.
One issue with this function is that usernames is not defined, and the other is that both ends of the if block will return False.
One way you could solve these would be
def checkUsername(usernames_file):
fp = open(usernames_file, 'r') # the default mode is 'r', but it's explicit here
usernames = fp.read()
userName = str(input("WHAT IS YOUR NAME?"))
if userName in usernames:
print("WELCOME BACK" + userName)
print("LET\'S GET STARTED")
fp.close()
return True # note, not False
else:
fp.write(userName)
print("WELCOME TO THE SYSTEM!")
fp.close()
return False
That snippet above is different in a few ways, but it also ignores two likely errors you might also be facing: case sensitivity in inputs (the input(...) line could be whatever the user wants), and line separation in usernames_file. Hopefully this pushes you in the right direction though.
You need to open() the file before calling the read() method.
Check if username isn't empty after using strip()
You can use the ternary conditional operator (a if condition else b)
i.e.:
def checkUsername(user):
if user.strip():
with open("myfile") as users:
print(f"WELCOME BACK {user}\nLET'S GET STARTED") if user in users.read() else print(f"WELCOME TO THE SYSTEM!")
else:
print("Error: empty username")
user = input("WHAT IS YOUR NAME?")
checkUsername(user)
I have a program that needs a username system, I want the user to enter their username and the program checks the file 'username' to see if it is in the list. My code below works if there is only one person in the list, otherwise it prints correct and incorrect. How would I change my code so if just one line matches the input it prints correct.
username = input("enter username: ")
search = open("username", "r")
for line in search:
if username in line:
print ("correct")
else:
print ("incorrect")
You could exploit the for...else construct that python has.
with open("username") as f:
for line in f:
if username in line:
print("correct")
break
else:
print("incorrect")
The else block is run if the program exited naturally - without breaking out from the loop.
If you do not like traditional for loops, then I suggest you this solution:
with open("username") as f:
isInList = [username in line for line in f]:
if any(isInList):
print ("correct")
else:
print("incorrect")
One way of achieving this is to simply return after it finds a match. Using return and encapsulating the logic into a function would allow you to do other things with result. Also, I would suggest using the with statement for opening files as it has better error handling and automatically takes care of closing the file and cleanup. Here is a short tutorial on the with statement.
username = input("enter username: ")
def read_file():
with open("username", "r") as f:
for line in f:
if username in line:
return "correct"
else:
return "incorrect"
result = read_file()
print(result)
# Or do whatever else you want with the result