writing to existing CSV file and saving its data - python

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.

Related

How do i read from a csv file I created

I'm a self taught programmer and im trying to make a ticketing system in Python with csv. However, the reading function doesn't seem to be working after trying out different solutions.
The output I get is:
['Name\tAge\tGender']
[]
['as\t12\tf']
[]
The desired output id like to get is:
Name Age Gender
Jack 25 Male
I've attached the code of this program below. Any help would be greatly appreciated. Thank you.
import sys, select, os, csv
from os import system
def option_1():
with open(input("\nInput file name with .csv extension: "), 'w+') as f:
people = int(input("\nHow many tickets: "))
name_l = []
age_l = []
sex_l = []
for p in range(people):
name = str(input("\nName: "))
name_l.append(name)
age = str(input("\nAge: "))
age_l.append(age)
sex = str(input("\nGender: "))
sex_l.append(sex)
field_names = ['Name', 'Age', 'Gender']
writer = csv.DictWriter(f, fieldnames = field_names, delimiter = '\t')
writer.writeheader()
writer = csv.writer(f, delimiter = '\t')
for row in [p]:
writer.writerow([name, age, sex])
def option_2():
with open(input('Input file name with .csv extension: '), 'a+') as f:
fileDir = os.path.dirname(os.path.realpath('__file__'))
people = int(input("\nHow many tickets: "))
name_l = []
age_l = []
sex_l = []
for p in range(people):
name = str(input("\nName: "))
name_l.append([name])
age = int(input("\nAge: "))
age_l.append([age])
sex = str(input("\nGender: "))
sex_l.append([sex])
writer = csv.writer(f, delimiter = '\t')
for row in [p]:
writer.writerow([name, age, sex])
def option_3():
with open(input("\nInput file name with .csv extension: "), 'r') as f:
fileDir = os.path.dirname(os.path.realpath('__file__'))
f_reader = csv.reader(f)
for row in f_reader:
print(row)
def main():
system('cls')
print("\nTicket Booking System\n")
print("\n1. Ticket Reservation")
print("\n2. Append to an existing file")
print("\n3. Read from an existing file")
print("\n0. Exit Menu")
print('\n')
while True:
option = int(input("Choose an option: "))
if option < 0 or option > 3:
print("Please choose a number according to the menu!")
else:
while True:
if option == 1:
system('cls')
option_1()
user_input=input("\nPress ENTER to return to main menu: \n")
if((not user_input) or (int(user_input)<=0)):
main()
elif option == 2:
system('cls')
option_2()
user_input=input("\nPress ENTER to return to main menu: \n")
if((not user_input) or (int(user_input)<=0)):
main()
elif option == 3:
system('cls')
option_3()
user_input=input("\nPress ENTER to return to main menu: \n")
if((not user_input) or (int(user_input)<=0)):
main()
else:
exit()
if __name__ == "__main__":
main()
When writing data to the file, you explicitly change the default behavior of the csv writer to use tabs as the field delimiter. A similar instruction should be passed to the reader as well, so it knows how to separate between the values in each row. The output you are seeing is a result of the reader's default behavior - it looks for commas to distinguish between each value, but as it finds none, it treats the entire row as a single value, and includes the tab character (\t) as part of the value itself. Instructing the reader to use the same delimiter used for writing the file would allow it to properly parse each field as its own value.
Once the values are properly parsed, you'll notice that the output is still not quite as you desire; the object that is printed in print(row) is actually a list of the items in that row, which is why the output you see now is enclosed with square brackets ([]) for each printed line. Regardless of how the file is stored, you will need to format the output when printing it as required. There are many ways to do so, following is just one possibility:
f_reader = csv.reader(f, delimiter = '\t')
for row in f_reader:
print('\t'.join(row))
According to csv.reader docs:
Each row read from the csv file is returned as a list of strings.
So what you are seeing is the expected behavior. You can join the list of strings with ', '.join(row) if you like.

How to delete only one row of a csv and save the changes in the same csv? [Python]

I'm making a login script in Python.
in this script, if you input the wrong password too many times, your account becomes locked.
Your username is put in a csv file called 'lockedaccounts.csv'
Once the user enters their recovery key, the account is unlocked.
I need the username to be deleted from the lockedaccounts.csv once they enter their recovery key.
Here is my current code
for k in range(0, len(col0)):
if col0[k] == username_recovery and col1[k] == recoverykeyask:
messagebox.showinfo('Account Recovery Successful', "Your account has been recovered.")
break
else:
accountscanningdone = False
else:
accountrecovered = False
Thank you for your time.
The simplest code would be something like this:
import csv
#when you want to add
with open('lockedaccounts.csv', 'w', newline='') as file:
writer = csv.writer(file)
writer.writerow(["username2"])
#when you want to delete
rows = []
with open('lockedaccounts.csv', 'r') as csvfile:
csvreader = csv.reader(csvfile)
for row in csvreader:
rows.append(row)
rows.remove(['username2'])
with open('lockedaccounts.csv', 'w') as file:
writer = csv.writer(file)
writer.writerows(rows)

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

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.")

Transfering specific rows from one cvs file to another cvs file

So, I'm trying to transfer rows[0,1,2,9,10] from what I've designated as "e_file" to "no_file"
When I print "data" I am given the exact information I want, I was just wondering how I should proceed with transferring this data to a corresponding CSV file?
Thank you.
e_file = '/Users/massive/Desktop//NO/hour.csv'
no_file = '/Users/massive/Desktop/NO/combined.csv'
with open(e_file,'r') as e_r:
state_code = input("Enter state code: ")
county_code = input("Enter county code: ")
station_number = input("Enter station number: ")
csv_reader_2 = csv.reader(e_r)
for row in csv_reader_2:
if row[0] == str(state_code).zfill(2) and row[1] ==str(county_code).zfill(3) and row[2] == str(station_number).zfill(4):
data = [row[0],row[1],row[2],row[9],row[10]]
print(data)
Maybe something like (I cannot test it unless you provide a working example):
with open(newFile, 'wb') as csvfile:
fwriter = csv.writer(csvfile)
for line in data:
fwriter.writerow(line)

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()

Categories

Resources