How do you fix this for loop to validate a username? - python

This is for my GCSE coursework and I can't figure out what I have done wrong in the code.
I have tried changing the type of CSV file opening (changing it from w to r to r+) but the for loop is not being executed.
It is supposed to check if the username is in the CSV file and if it is, it should be accepted, else, they should be able to re-enter.
The usernames in the CSV files are Test01 and Test02
Here is my code:
import csv
import random
Player1 = 0
Player2 = 0
Again = True
File = open("Dice Game.csv","r+")
File.write("Test01" + "\n")
File.write("Test02" + "\n")
while Again == True:
Input1 = str(input("Player 1, please input your username."))
Open = open("Dice Game.csv", "r")
File = csv.reader(File)
for row in File:
User = row[0]
if User == Input1:
print("That username is not authourised, please re-enter.")
Again = True
break
else:
Again = False

Your immediate problem is having your logic backward:
if User == Input1:
print("That username is not authourised, please re-enter.")
If the user name matches, the user is authorized! Switch to != here and move the break.

Try this . . . I suggest you get familiar using with statement, I noticed you don't close your files
import csv
import random
with open('DiceGame.csv', 'w', newline='') as file:
writer = csv.writer(file, delimiter=",")
writer.writerow(['Test01', 'Test02'])
again = True
while(again):
_input = str(input("Player 1, please enter your username: "))
with open("DiceGame.csv", 'r') as file:
reader = csv.reader(file)
for row in reader:
if _input in row:
# Username is valid
again = False
break
else:
print("Invalid username, please try again.")

Related

writing to existing CSV file and saving its data

I'm creating a program for online shop and I have problems with rewriting on the csv file of the users registration. I create the file and put headers(as list of information that I want).
I'm having problem with adding the new users. Every time when I run the program, enter all the information for the user, the csv file rewrites the user.
Could you help? I've tried everything, but it doesn't work...
Here is the code.
Please excuse me, I'm new to programming :)
header = ['ID', 'First Name', 'Last Name', 'Email', 'Phone', 'Date Registered', 'Password']
with open('users.csv', 'w') as f:
writer = csv.writer(f)
writer.writerow(header)
f.close()
new_user = []
user_id = 0
print(f" Welcome to the new online shop! \n")
print(f" You will need registration to enter.\n If you don't have please enter 0. \n "
f"If you already have - please enter 1.\n For ADMIN menu - please enter 9")
class UserId:
def __init__(self, id_user, new_user_fn,
new_user_ln, new_user_em,
new_user_phone, _new_user_pas,
new_user_date_reg):
self.id_user = id_user
self.new_user_fn = new_user_fn
self.new_user_ln = new_user_ln
self.new_user_em = new_user_em
self.new_user_phone = new_user_phone
self.new_user_date_reg = new_user_date_reg
self._new_user_pas = _new_user_pas
def user_registration():
now = datetime.now()
dt = now.strftime("%d/%m/%Y %H:%M:%S")
print(f" Enter your First name: ")
new_user_fn = str(input()).upper()
print(f" Enter your Last name: ")
new_user_ln = str(input()).upper()
print(f" Enter your email: ")
new_user_em = input().upper()
print(f" Enter your phone number: ")
new_user_phone = str(input())
new_user_date_reg = dt
print(f" Enter your password: ")
new_user_pas = str(input())
new_user.append(user_id + 1)
new_user.append(new_user_fn)
new_user.append(new_user_ln)
new_user.append(new_user_em)
new_user.append(new_user_phone)
new_user.append(new_user_date_reg)
new_user.append(new_user_pas)
with open("users.csv", 'a+', newline="") as e:
writer1 = csv.writer(e)
writer1.writerow(new_user)
e.close()
It looks like your problem is here
with open('users.csv', 'w') as f:
writer = csv.writer(f)
writer.writerow(header)
f.close()
By using the 'w' you are telling the program to always create a new file.So you must use 'a' instead of 'w' as you want to append to a file and not overwrite it.
Also with with open you don't need to use f.close() as with open automaticaly closes and saves the file
So the code shoud look like this
with open('users.csv','a') as f:
writer = csv.writer(f)
writer.writerow(header)
What you can do is test if your file exists :
fileName = 'users.csv'
if not os.path.exists(fileName):
with open(fileName, 'w') as f:
writer = csv.writer(f)
writer.writerow(header)
Notes :
1- using ´with’ means you do not need to close the file. All cleaning is done when exiting the inner code
2- using variable for file name variable is good so you are sure to always use the same file name; and when you have to modify it, then do it in one place.

How do I select certain lines in a text file from python script?

So I'm making a python script where you can create an account and that account is saved in a text file. When you try to log in, it will look in the text file for your username and then move down a line for the password but I don't know how to move down a line after finding the username. Any help would be appreciated. :)
Update -
import time
import sys
print ("Do you have an account?")
account = input()
if account == "Yes":
print ("Enter your username")
enterUsername = input()
with open ("Allusers.txt") as f:
if enterUsername in f.read():
print ("Enter your password")
enterpassword = input()
if enterpassword in f.read():
print ("Logged in")
if enterpassword not in f.read():
print ("Wrong password")
if account == "No":
print ("Create a username")
createUsername = input()
with open ("Allusers.txt") as f:
if createUsername in f.read():
print ("Username already taken")
sys.exit()
if createUsername not in f.read():
print ("Create a password")
createPassword = input()
with open ("Allusers.txt") as f:
if createPassword in f.read():
print ("Password not available")
sys.exit()
if createPassword not in f.read():
file_object = open ('Allusers.txt', 'a')
file_object.write("" + createUsername + "\n")
file_object.close()
file_object = open ('Allusers.txt', 'a')
file_object.write("" + createPassword + "\n")
file_object.close()
print ("Done")
This is still work in progress and most likely still has errors here and there.
Assumin that your file look like this:
Adam
password
John
12345678
Horacy
abcdefg
Romek
pass1234
You can try this example:
user = "Horacy"
password = "abcdefg"
with open( "users.txt", "r" ) as file:
for line in file:
if user == line.strip():
if password == file.readline().strip():
print( "Correct" )
break
As stated if someones password equals someones username iterating over all lines and checking may return faulty results you'll want to check only usernames as you iterate, so zipping every other line you can check the username only and return the password:
def get_password(file, username):
with open(file, "r") as f:
data = f.readlines()
for user, pw in zip(data[::2], data[1::2]):
if user.strip() == username:
return pw.strip()
def get_password(file, username):
lines = open(file, "r").readlines() # get the lines from the file
for i, line in enumerate(lines):
if line == username: # if the current is the username, return the following line
return lines[i + 1]
You should only search in usernames. The data[::2] will select usernames.
with open("filename", "r") as f:
data = f.read().splitlines()
email = "email#email"
if email in data[::2]:
id_email=data[::2].index(email)
row=id_email*2-1
password=data[row+1]

Why the context of the file cannot read from the txt file?

I have creat a new empty txt file, but the code below read and write it.
f = open('users.txt', 'r+')
users = eval(f.read()) #f.read()read a string,eval()transfer string to dict
for i in range(4):
name = input('Input Username: ')
passwd = input('Input password: ')
c_passwd = input('Confirm password again: ')
if len(name.strip()) != 0 and name not in users and len(passwd.strip()) != 0 and passwd == c_passwd:
users[name]= {'passwd':passwd, 'role':1} #insert new data, role 1: Customer; role 2: Restaurant; role 3: Admin
f.seek(0)
f.truncate() #clear file
f.writelines(str(users)) #write data to file from dict
print('Congratulations, Register Success. ')
f.close()
break
elif len(name.strip()) == 0:
print('Username could not be empty. Remain %d chance' %(3-i))
elif name in users:
print('Username repeat. Remain %d chance' %(3-i))
elif len(passwd.strip()) == 0:
print('Password could not be empty. Remain %d chance' %(3-i))
elif c_passwd != passwd:
print('Password not same. Remain %d chance' %(3-i))
#log in
f = open('users.txt', 'r', encoding='utf8')
users = eval(f.read())
for count in range(3):
name = input('Input Username: ')
password = input('Input password: ')
if name in users and password == users[name]['passwd']:
print('Log in successful!')
break
else:
print('Username or/and Password is/are wrong,You still have %d chance'%(2-count))
f.close()
The System showed
Traceback (most recent call last):
File "C:/Users/zskjames/PycharmProjects/Fit5136/Register, log in.py", line 4, in <module>
users = eval(f.read()) #f.read()read a string,eval()transfer string to dict
File "<string>", line 0
^
SyntaxError: unexpected EOF while parsing
Do anybody could tell me how to fix that? And how to avoid this mistakes in the future.
You probably want your text file to contain JSON, in order to easily interact with it and turn it into a dict.
In order to do that, you would need to replace your eval with a json.load:
import json
with open('users.txt', 'r+') as f:
users = json.load(f)
# rest of your code
In order for it to work, your text file should look something like the following:
{"John Doe": {"passwd": "somepass", "role": 1}}
In addition, you need to replace:
f.writelines(str(users)) #write data to file from dict
to:
json.dump(users, f)

Change text in file with Python

def false_to_true():
name = input("Input name: ")
file=open("users.txt","r")
lines = file.readlines()
file.close()
for line in lines:
username, lel, type = line.split("/")
while name == username:
name = input("input name again: ")
tip = True
with open("users.txt", "w") as users:
users.write(str(red))
#
#I do not know how to perform a given modification and enrollment into place in #the text.
#
#I wont to change word False to True for username i input.
#I have this text in file users:
#Marko123/male/False
#Mimi007/female/False
#John33/male/False
#Lisa12/female/False
#Inna23/female/False
#Alisa27/female/False
I won't to change word False to True for username I input.
I have this text in file users:
Marko123/male/False
Mimi007/female/False
John33/male/False
Lisa12/female/False
Inna23/female/False
Alisa27/female/False
You can just use the csv library and forget about string manipulation:
import csv
def false_to_true():
#read from user.txt file into list(data)
with open('users.txt', 'r') as userfile:
data = [row for row in csv.reader(userfile,
delimiter="/",
quoting=csv.QUOTE_NONE)]
while True:
#waiting for input until you enter nothing and hit return
username = input("input name: ")
if len(username) == 0:
break
#look for match in the data list
for row in data:
if username in row:
#change false to true
row[2] = True
#assuming each username is uniqe break out this for loop
break
#write all the changes back to user.txt
with open('users.txt', 'w', newline='\n') as userfile:
dataWriter = csv.writer(userfile,
delimiter="/",
quoting=csv.QUOTE_NONE)
for row in data:
dataWriter.writerow(row)
if __name__ == '__main__':
false_to_true()
Open the input and output files, make a set out of the user-input names (terminated by a blank line), then create a generator for strings of the proper format that check for membership in the user-input names, then write these lines to the output file:
with open('names.txt') as f, open('result.txt', 'w') as out:
names = {name for name in iter(input, '')}
f = ('{}/{}/{}'.format(a,b,'True\n' if a in names else c) for a,b,c in (line.split('/') for line in f))
output.writelines(f)
To modify a text file inplace, you could use fileinput module:
#!/usr/bin/env python3
import fileinput
username = input('Enter username: ').strip()
with fileinput.FileInput("users.txt", inplace=True, backup='.bak') as file:
for line in file:
if line.startswith(username + "/"):
line = line.replace("/False", "/True")
print(line, end='')
See How to search and replace text in a file using Python?
Ask for name and iterate throw your lines to check for username, like this:
def false_to_true():
name = input("Input name: ")
file=open("users.txt","r")
lines = file.readlines()
file.close()
users = open("users.txt", "w")
for line in lines:
username, lel, type = line.split("/")
if name == username:
type = 'True\n'# \n for new line type ends with '\n'
users.write("/".join([username, lel, type]))
users.close()
false_to_true()

importing and exporting from csv files

So I am trying to create a code which can search the data file:
By surname to retrieve and display the details for a contact
By date of birth to retrieve and display all contacts with a birthday in a particular month.
Here is the code I have created:
def search():
option = input('Please select to search by \n1. Surname\n2. D.O.B\n')
if option == '1':
surname = input('Please enter surname: ')
while not surname.isalpha():
surname = str(input('Please enter a valid surname: '))
Myfile = open('Address book.csv', 'rt')
for line in Myfile:
if ',' + str(surname) + ',' in line:
print(line)
else:
print('No contacts found')
elif option == '2':
Validmonth = False
while Validmonth == False:
month = input('Please enter the birth month')
if month >='13' and month <='0':
print('Please enter a valid month')
else:
Validmonth = True
Myfile = open ('Address book.csv', 'rt')
for line in Myfile:
if str(month) in line:
print(line)
else:
print('No contacts found')
else:
print('Error, select a valid option')
search()
search()
I keep getting this result when I try the code:
Please select to search by
1. Surname
2. D.O.B
1
Please enter surname: Vickers
No contacts found
No contacts found
No contacts found
No contacts found
No contacts found
No contacts found
No contacts found
No contacts found
I want to know why? someone please help?
You test for the surname on every row, then print No contacts found for every row that doesn't match.
Break out of the loop when you find the name, and use the else suite for the for loop instead:
for line in Myfile:
if ',' + str(surname) + ',' in line:
print(line)
break
else:
print('No contacts found')
else on a for loop only is executed if you exhausted the iterable, so when you did not break out of the loop early.
Your surnames are the first value on the line, so you would be better off testing if the line starts with the surname:
if line.startswith(surname + ','):
Pro tip: when reading CSV files, use the csv module:
import csv
with open('Address book.csv', newline='') as myfile:
reader = csv.reader(myfile)
for row in reader:
if row[0] == surname:
print(row)
break
else:
print('No contacts found')

Categories

Resources