Home > front end >  What is wrong with my python code that seaches through a csv?
What is wrong with my python code that seaches through a csv?

Time:04-06

I'm very new to Python and have only been learning it for a week. I am trying to make a "username selection process" but can't work out how to search a CSV (without errors) to make sure that the name hasn't been used before. Below is my code:

def customusername():
    cust = input('Please Enter Custom Username: ')
    import csv
    import sys

    csv_file = csv.reader(open('usernamedatabase.csv', "r", 
encoding='utf-8'), delimiter=",")
            
    for row in csv_file:
            if cust == row[1]:
                    print("Username Taken, Try a different name")
                    customusername()
            else:
                    print("Username Selected")
                    #I will use code here to place the username 
into the database but I already know how to do that

The errors recieved: Traceback (most recent call last): File "(the file path)", line 16, in <module> customusername() File "(the file path)", line 9, in customusername if cust == row[1]: IndexError: list index out of range

BTW I am using visual studio code

I have tried using code from many different websites, all returned errors

CodePudding user response:

You use recursion where you could use a loop. The call stack has a limit and this can cause your code to error out. You should read the file first, and then loop until you get a valid username. Remember that IO is expensive, so reading the file every time an invalid username is selected is going to take a lot longer than reading it once and remembering it.

import csv
import sys


def customusername():
    with open('usernamedatabase.csv', "r", encoding='utf-8') as fh:
        # One strategy is to load all rows into a list
        csv_file = csv.reader(fh, delimiter=",")
        csv_rows_list = list(csv_file) 

    with open('usernamedatabase.csv', "r", encoding='utf-8') as fh:
        # Another is to load all rows into a dict, 
        # indexed by the 1th column which is presumably the username
        csv_file = csv.reader(fh, delimiter=",")
        csv_rows_dict = {row[1]: row for row in csv_file}

    # Then, you can simply check if the input is in your list or dict:
    # 1. List:
    while True: # Keep asking for a username until you break
        cust = input("Enter your custom username: ")
        # if any of the 1th element of the items in 
        # csv_row_list are equal to username, it is taken
        if any(row[1] == cust for row in csv_rows_list):
            print("That username is taken. Pick another one.")
        else: # Username is available, so end the loop
            break
    print(f"Hello {username}!")

    # 2. Dict:
    while True:
        cust = input("Enter your custom. username: ")
        if cust in csv_rows_dict:
            print("That username is taken. Pick another one.")
        else: # Username is available, so end the loop
            break
    print(f"Hello {username}!")

The second approach, with the dict is much better because it is much faster to look up a key in a dict than an item in a list.

If you have memory constraints and can't afford to load the entire csv file, you can simply keep the usernames from it as a set, and check for membership in that set the same way you check if the key exists in the dict.

    with open('usernamedatabase.csv', "r", encoding='utf-8') as fh:
        csv_file = csv.reader(fh, delimiter=",")
        # A set comprehension is subtly different from a dict comprehension
        csv_rows_set = {row[1] for row in csv_file} 

Note the use of the context manager with to handle automatically closing the file. I also moved the imports outside the function because this.

CodePudding user response:

This is my solution!

import csv

header = ['UserName']
data = [["Mark"], ["Josh"], ["Lillo"]]

with open("userneame.csv",'w',newline='') as user:
    writer=csv.writer(user)
    writer.writerow(header)
    writer.writerows(data)

NickName = input("username: ").title()

with open('userneame.csv', 'r', newline='') as users:
    reader = csv.reader(users)
    next(reader) #skips the header
    usernames = []
    for data in reader: #prints [Mark],[Josh] ecc
        for names in data:#Printing all the names in the csv file
            usernames.append(names) #just saving the names in the csv file, in a list

if NickName in usernames:
    print(f"Sorry {NickName} is not available")
else:
    print(f"Nice to meet you {NickName}")
  • Related