How do I confirm if a variable is in a csv file? - python

I get this error when I run my code and reach the csv file part:
line 96, in fieldnames
self._fieldnames = next(self.reader)
io.UnsupportedOperation: read
My code:
import csv
username = ""
global enteruser
global username
def user():
age = input("What is your age:")
year = input("What is your year group?")
name = input("What is your name?")
username = name+age+year
return username
def username_validator():
with open('usernames.csv', 'ab') as file:
reader = csv.DictReader(file)
for row in reader:
print(row)
if enteruser or username == row["usernames"]: # if the username shall be on column 3 (-> index 2)
print ("is in file")
with open("user1.csv","ab") as quiz:
quizreader = csv.DictReader(quiz,delimiter=",")
for row in quizreader:
print(row["name"])
else:
print("doesnt work")
isuser = input("Do you have a username?")
if isuser == ("yes" or "Yes"):
enteruser = input("Enter username:")
username_validator()
elif isuser == ("no" or "No"):
user()
else:
None
print(username)

Not sure if this is what is causing your problem, but make sure to be careful with your use of global variables here. As your code stands now, it will always print an empty string at the last line, since you never update username globally. As a rule of thumb, try to avoid using global variables when possible, and instead pass those variables as arguments to the functions.
Unless you explicitly tell your functions to use global variables, it will default to creating local variables. So here:
def user():
age = input("What is your age:")
year = input("What is your year group?")
name = input("What is your name?")
username = name+age+year
return username
We are actually not doing anything to the global variable username, but rather simply creating a new local variable within the function which is returned. To update the global variable, either define it as global within the function (shown below):
def user():
global username
age = input("What is your age:")
year = input("What is your year group?")
name = input("What is your name?")
username = name+age+year
Alternatively, leave the function unchanged, and simply update the variable when you call the user() function, as follows:
elif isuser == ("no" or "No"):
username=user()
else:
None
print(username)
EDIT: Take a close look at your if statements, read the link posted in the comments under OP.

Your error is caused by your file opening / closing.
You're trying to read from a file not opened for it.
From the python built in functions open function open has a declaration like:
open(name[, mode[, buffering]])
Here the arguments you can use are r: reading, w: writing, a: appending r+: read/write, w+: read/write, and a+: append/write for the mode. To these a binary tag can be added to the end like r+b
For your code you'll want to change your open lines from
with open("user1.csv","ab") as quiz:
to
with open('user1.csv', 'a+b') as quiz:
So really all you need is that + to allow append and read

Related

How to append to csv file before script is done running?

I am currently making a log in system which stores usernames and passwords in a text file.
This is my code:
import csv
Brugere = open("D:\Filer\Programmering/Profiles.txt","r+",newline="\n")
writer = csv.writer(Brugere, delimiter=",")
print("Welcome to the chat app!")
Brugernavn = "" //means username
Kodeord = "" // means password
def Signup(j,k):
print("Welcome to sign up!\n Please enter your Username")
j = input("")
if j not in Brugere:
print("Hello, " + j + ", please enter a password:")
k = input("")
line1 = [j,k]
writer.writerow(line1)
print("Great! Now you can sign in")
Signin(Brugernavn, Kodeord)
else:
print("Username already taken! try again")
Signup(Brugernavn, Kodeord)
def Signin(U,P):
print("Welcome to sign in!")
print("Do you already have an account?[y/n]")
ans = input("")
if ans == "n":
print("You will now be redirected to sign up")
Signup(Brugernavn, Kodeord)
elif ans == "y":
U = input("Username: ")
if U in Brugere:
P = input("Password: ")
print("WELCOME")
else:
print("Invalid username, try again")
Signin(Brugernavn, Kodeord)
else:
print("Please write 'y' or 'n'")
Signin(Brugernavn, Kodeord)
Signin(Brugernavn, Kodeord)
Brugere.close()
When I run it, the signup function works as it should, but when the signin function is called, it can't find the username and password from the text file. I think it's because they only get appended after the script is done running. However, 'Im not sure.
I've been struggling for a long time with this csv file thing. I want to have it like
this where each line is a list where I can find the username and password
I've heard people calling it "comma seperated values", however I have no idea how to do it.
TL;DR:
I suspect the simplest solution is:
...
if j not in brugere:
...
writer.writerow(line1)
brugere.flush() # Flush pending changes to file.
...
...
However, I've noticed a few things worthy of consideration:
Python help. You can get help on Python things within an interactive Python session:
python
> import csv
> help(csv)
CSV for this sort of usecase isn't a good idea. If it's production grade use a proper DB, if you're just playing around locally to get a feel for Python use a dict() and store as JSON. I.e.:
import json
username = "myuser"
password = "password"
filename = "data.json"
# Reads data. Requires file `data.json` to exist, with content `{}`.
with open(filename, "r") as data_stream:
data = json.load(data_stream)
if username in data:
print(f"User {username} exists.")
else:
data[username] = password # You'd usually hash and salt a password. It's a separate topic.
# Writes data to disk.
with open(filename, "w") as data_stream:
data_stream.write(json.dumps(data, indent=2)) # Makes it look pretty on disk.
Note that open() returns a stream wrapped in class io.TextIOWrapper (see python -c "import io; help(io.TextIOWrapper)"). It's basically an interface to get the data you want, not the data itself. Try open("test.txt").readlines() to actually read data from stream, for example. Note that streams are consumables.
When you call in on the stream Brugere you're calling the __contains__() dunder method on class io.TextIOWrapper which isn't implemented. But Python being Python it returns False (it's not meaningful).
The CSV interfaces are pretty straightforward:
import csv
filename = "test.txt"
f = open(filename, "w")
writer = csv.writer(f)
writer.write(["myuser", "password"])
# Flushes lines to file.
f.flush()
...
f.close()
Creating a CSV is as simple as writing a string with each value separated by a designated character, often a comma as the name implies. You don't really need the csv library for that.
Your Signup method would then look as follows:
def Signup(j,k):
print("Welcome to sign up!\n Please enter your Username")
j = input("")
if j not in Brugere:
print("Hello, " + j + ", please enter a password:")
k = input("")
line1 = [j,k]
# Write a string with a comma between the values
Brugere.write("{}, {}\n".format(j, k))
print("Great! Now you can sign in")
Signin(Brugernavn, Kodeord)
else:
print("Username already taken! try again")
Signup(Brugernavn, Kodeord)
With that being said, using CSVs to store operational data in a an application does not make all that much sense to me. Please see below for a modified version of signup using SQLite, which is much more robust and still simple to use:
import sqlite3
con = sqlite3.connect('brugere.db')
cur = con.cursor()
# Create a user table with bruger and kodeord
# I added an extra field for when the user was created as well
# which defaults to the date and time the user was created
cur.execute("""create table if not exists brugere
(brugernavn text,
kodeord text,
dato_oprettet TIMESTAMP DEFAULT CURRENT_TIMESTAMP)""")
con.close()
def signup():
con = sqlite3.connect('brugere.db')
cur = con.cursor()
with con:
print("Please enter your Username")
bruger = input()
cur.execute("select brugernavn from brugere where brugernavn =?", [bruger])
bruger_eksisterer = cur.fetchone()
if bruger_eksisterer:
print("Username already taken! Try again")
# Signup(Brugernavn, Kodeord)
else:
print("Hello, " + bruger + ", please enter a password:")
kodeord = input()
try:
cur.execute("insert into brugere (brugernavn, kodeord) values (?, ?)", (bruger, kodeord))
print("Great! Now you can sign in")
except sqlite3.Error as Err:
print("Couldn't add user.\nError: {}".format(Err))
# Signin(Brugernavn, Kodeord)
con.close()
signup()
Modifying the signin should be straighforward, but I'll leave that part up to you.

Refactor two similar functions into one? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I have this very simple sign up/log in program for learning purpose, and it works. But it feels like I have code that repeats itself. The must obvious is the check functions.
My question is, should I refactor those two so they become one or is it better to keep them seperate?
def signUp():
username = input("Give me a username: ")
if checkUser(username) == True:
print("You are already registrered, please log in with your password.")
else:
password = input("Also give me a password: ")
with open("sign-up.csv", "a", newline="") as file:
writer = csv.writer(
file, delimiter=",", quotechar='"', quoting=csv.QUOTE_MINIMAL
)
writer.writerow([username, password])
print("You are now signed up. Please log in with your credentials.")
def logIn():
username = input("Give me your username: ")
password = input("Also give me your password: ")
if checkPassword(username, password) == True:
print("Welcome, you are now logged in.")
else:
print("Username or password is incorrect please try again.")
def checkUser(username):
with open("sign-up.csv", "r") as file:
reader = csv.reader(file)
myList = dict(reader)
if username in myList:
return True
else:
return False
def checkPassword(username, password):
with open("sign-up.csv", "r") as file:
reader = csv.reader(file)
myList = dict(reader)
if username in myList and password == myList[username]:
return True
else:
return False
def get_user_choice():
print("\n[1] Sign up")
print("[2] Log in")
print("[q] Quit")
return input("What would you like to do? ")
choice = ""
while choice != "q":
choice = get_user_choice()
if choice == "1":
signUp()
elif choice == "2":
logIn()
elif choice == "q":
print("Welcome back some other day")
else:
print("That choice doesn't exists")
Function checkUser is checking if a username is already present in the csv file. This would happen at signup. The function checkPassword is used when the user is signing in. These functions should stay seperate since they do dramaticly different things with different levels of security concerns. They also expect input based on where the user is in the procces of signup/login. Meaning when you write a function that does both like doBoth(username, password) you have to call this function with a null when you wanna use it at the signup fase in the application doBoth(username, null) since password is never known at signup.
The first obvious factorisation is the common part of both functions - the part tha reads the csv file into a dict:
def read_users():
with open("sign-up.csv", "r") as file:
reader = csv.reader(file)
return dict(reader)
Then you can rewrite check_user and check_password with this function:
def check_user(username):
users = read_users()
return username in users
def check_password(username, password):
users = read_users()
# make sure we work correctly even if
# someone passes `None` as password
_notfound = object()
return users.get(username, _notfound) == password
FWIW, those functions would be better named as (resp.) 'user_exists' and 'authenticate'
Also, you may want to factor out the part that's writing to the csv file - not to reduce code duplication, but to better separate the UI / domain / persistance layers.
def add_user(username, password):
with open("sign-up.csv", "a", newline="") as file:
writer = csv.writer(
file, delimiter=",", quotechar='"', quoting=csv.QUOTE_MINIMAL
writer.writerow([username, password])
def sign_up():
username = input("Give me a username: ")
# note how good naming makes code much more explicit
if user_exists(username):
print("You are already registrered, please log in with your password.")
return # no need to go further
password = input("Also give me a password: ")
add_user(username, password)
def log_in():
username = input("Give me your username: ")
password = input("Also give me your password: ")
if authenticate(username, password):
print("Welcome, you are now logged in.")
return
# oops...
print("Username or password is incorrect please try again.")
Next step would be to replace the input() calls by dedicated ask_username() and ask_password() functions that will validate the user's input. First write them as simply as possible, then find out the common part(s) and see if you can factor them out.
Note that I renamed your functions in all_lower - this is the official coding convention, and Python users tend to strongly adhere to the official coding conventions.
Also note that I removed the useless == True tests. In Python, any expression resolves to an object (in the case of a function call, to the object returned by the function), and every object has a boolean value, so if someexpression == True: is redundant at best. FWIW this is also part of pep8 (official coding conventions). And finally, when you find yourself writing something like:
if someexperession:
return True
else:
return False
You can just simplify it to
return someexpression
Try this:
def checkBoth(username, password):
with open("sign-up.csv", "r") as file:
reader = csv.reader(file)
myList = dict(reader)
if username in myList:
u = True
if password == myList[username]:
p = True
else:
p = False
else:
u = False
p = False
return (u,p)
def checkPassword(username, password):
out = [False, False]
with open("sign-up.csv", "r") as file:
reader = csv.reader(file)
myList = dict(reader)
if username in myList:
out[0] = True
if password == myList[username]:
out[1] = True
return out
and then having a check what is true on the out.

Python Login and Register System using text files

Hey I am trying to create a system using text files where a user can sign up and log in. All the data will be stored in plain text in a text file called User_Data.txt. My code works but I would like to know if there is anything I missed or If I could improve it in any way. Sorry for the Bad code Formatting in advance.
def choices():
print("Please choose what you would like to do.")
choice = int(input("For Sigining Up Type 1 and For Signing in Type 2: "))
if choice == 1:
return getdetails()
elif choice == 2:
return checkdetails()
else:
raise TypeError
def getdetails():
print("Please Provide")
name = str(input("Name: "))
password = str(input("Password: "))
f = open("User_Data.txt",'r')
info = f.read()
if name in info:
return "Name Unavailable. Please Try Again"
f.close()
f = open("User_Data.txt",'w')
info = info + " " +name + " " + password
f.write(info)
def checkdetails():
print("Please Provide")
name = str(input("Name: "))
password = str(input("Password: "))
f = open("User_Data.txt",'r')
info = f.read()
info = info.split()
if name in info:
index = info.index(name) + 1
usr_password = info[index]
if usr_password == password:
return "Welcome Back, " + name
else:
return "Password entered is wrong"
else:
return "Name not found. Please Sign Up."
print(choices())
There is a lot of improvements You could do.
First of all, split functionality to smaller function.
PASSWORD_FNAME = "User_Data.txt"
def get_existing_users():
with open("r", PASSWORD_FNAME ) as fp:
for line in fp.readlines():
# This expects each line of a file to be (name, pass) seperated by whitespace
username, password = line.split()
yield username, password
def is_authorized(username, password):
return any((user == (username, password) for user in get_existing_users())
def user_exists(username):
return any((usr_name == username) for usr_name, _ in get_existing_users())
# above is equivalent of:
#
# for usr_name, _ in get_existing_users():
# if usr_name == username:
# return True
# return False
def ask_user_credentials():
print("Please Provide")
name = str(input("Name: "))
password = str(input("Password: "))
return name, password
def checkdetails():
name, password = ask_user_credentials()
if is_authorized(name, password):
return "Welcome Back, " + name
if user_exists(name):
return "Password entered is wrong"
return "Name not found. Please Sign Up."
def getdetails():
name, password = ask_user_credentials()
if not user_exists(name):
return "Name Unavailable. Please Try Again"
# Not sure tho what would You like to do here
It's always good to remember to always close your file if you read it.
So if you do something like:
f = open("r", "file.txt") remember to always call f.close() later.
If you use context manager and do it like:
with open("r", "file.txt") as fp:
print(fp.read())
it will automatically close the file for you at the end.
Firstly, fix the spelling error at int(input("For Sigining Up Type 1") Other than that I would add some kind of purpose, for example storing secret numbers or something.
For example you can extend your script with a simple password recovery system.
I think it could be useful to learn...
You can implement a sort of a simple hashing system in order to avoid saving the password as plain text.
If you want to add a GUI, please consider using Tkinter.
https://docs.python.org/3/library/tkinter.html
Let we know.
Good Luck and Keep Coding with <3

Python error list index out of range when reading from CSV

Hey I am trying to read data from a list that is from a CSV file
def Load(): #Loads data from the csv that can be stored in functions
global userdata
global user
userdata = []
f = open('userdata.csv','r')
data = csv.reader(f)
for row in data:
user = []
for field in row:
user.append(field)
userdata.append(user)
f.close()
This is the login function which I am looping over
def Login(): #Login function
global userdata
Load()
global user
print('Please now login to your account')
x = False
while x == False:
usernameLog = input('Please enter your username: ')
j = len(userdata)
for i in range(0,j):
if usernameLog == userdata [i][0]: #Validates username
print('Username accepted')
time.sleep(1)
My program successfully writes to the CSV but just doesn't read from it without throwing out this error. I might just be being stupid though.
You have the line user = [] inside the for loop, so you are always "cleaning" user before appending the new value, so only the last value is added, and the previous one is removed.
You should take it out of the loop, the same you are doing with userdata.
(This is what it looks like, unless your csv structure is totally different and you don't need one user per one userdata)

Custom python function is not running

names=["aaa","bbb","ccc","ddd","eee"]
itMarks=[90,98,87,98,78]
def printMainMenu():
print(" Main Menu")
print(" =========")
print(" (1)Add Student")
print(" (2)Search Student")
print(" (3)Delete Student")
print(" (4)List Student")
print(" (5)Exit")
choice = int(input("Enter Your choice[1-5]:"))
return choice
def searchStudent(names,itMarks):
name = input("Enter Name")
i = names.index(names)
print("Index is" + i)
def deleteStudent(student,itMarks):
name = input("Enter Name to remove")
student.remove(names)
print("Successfully Deleted" + names)
def removeStudent(names):
name = input("Enter name to remove")
name.remove(name)
print("Successfully deleted" + names)
def addStudent(names, itMarkas):
name = input("Enter Name")
names.append(names)
itMarks = input("Enter IT Marks")
itMarks.append(itMarks)
def listStudent(names, itMarks):
for i in range(0, len(names)):
print(names[1], "", itMarks[i])
names = []
itMarks = []
choice = 1
while choice >= 1 and choice <= 4:
choice = printMainMenu()
if choice == 1:
addStudent(names, itMarks)
elif choice == 2:
searchStudent(names, itMarks)
elif choice == 3:
deleteStudent(names, itMarks)
elif choice == 4:
listStudent(names, itMarks)
elif choice == 5:
print("Exit from the program")
else:
print("invalid choice!")
choice = 1
I am new to the programming in Python. The following Python code is written to do some tasks with the array. There are two array named names and itMarks. And there are some functions :
addStudent() - To add students to the array
searchStudent() - To search a student with in the list.
deleteStudent() - To delete the given student from the list.
listStudent() - To list out the all the names of the students in the list.
When the program runs, it asks to select a choice. Then it do the task according to their choice. But when I run this coding it shows the errors.
Please help me. Thanks in advance.
ERROR :
When I select the choice 1 (Add student) and input name after the error is yield.
Traceback (most recent call last):
File "C:\Users\BAALANPC\Desktop\new 3.py", line 59, in <module>
addStudent(names, itMarks)
File "C:\Users\BAALANPC\Desktop\new 3.py", line 42, in addStudent
name = input("Enter Name")
File "<string>", line 1, in <module>
NameError: name 'rtrt' is not defined
Their so many mistakes in naming
In addStudent
def addStudent(names, itMarkas):
name = input("Enter Name")
names.append(name) # names cant appent it should be name
itMark = input("Enter IT Marks") # here itmark not itMarks
itMarks.append(itMark)
In searchStudent
def searchStudent(names,itMarks):
name = input("Enter Name")
i = names.index(name) # try to find index of name not names
print("Index is" + i)
In deleteStudent
def deleteStudent(student,itMarks):
name = input("Enter Name to remove")
student.remove(name) # try to remove name not names
print("Successfully Deleted" + name)
after change above I run its running you have to also change the naming of the variable for all methods
Output
Main Menu
=========
(1)Add Student
(2)Search Student
(3)Delete Student
(4)List Student
(5)Exit
Enter Your choice[1-5]:1
add student
Enter Name"aaa"
Enter IT Marks111
Main Menu
=========
(1)Add Student
(2)Search Student
(3)Delete Student
(4)List Student
(5)Exit
Enter Your choice[1-5]:
I'm assuming this is the correct form:
def searchStudent(names,itMarks):
name = input("Enter Name")
i = names.index(name)
print("Index is" + i)
note that I changed names to name.
also the same mistake again
def deleteStudent(student,itMarks):
name = input("Enter Name to remove")
student.remove(name)
print("Successfully Deleted" + names)
tl;dr revise your code
searchStudent(): You shouldn't need the itMarks argument if you're not using it inside your function at all. names refers to the list of names, but you are really trying to search name. i is an integer that is attempting to be concatenated with a string. Not allowed. It should be str(i).
deleteStudent(): Better to keep your arguments consistent and use names rather than student. Again, same problem as above, should be .remove(name) and you shouldn't need the itMarks argument. print statement should refer to name not names.
removeStudent(): This is the same code as deleteStudent(), but not used, so not sure why it's there.
addStudent(): Typo in the argument, .append(name). You have a global variable and a local variable named the same thing, which are conflicting to the program. Change the input set to itMark and .append(itMark).
listStudent(): print statement has a typo, 1 should be i. Not sure why the empty string is included as well.
Underneath your function def's, you restate your variables as empty lists. This can lead to ValueErrors from a lot of your functions as you're trying to look something up or modify something in an empty list. Simply delete this code.
Additionally, any error will break your while loop. I suggest adding more booleans or using a try except clause to catch these errors.
Good luck!

Categories