CSV error when trying to write - python

import csv
name = input(': ')
password = input(': ')
age = input(': ')
hello = [name, password, age]
length = len(hello[0])
with open('db.csv', 'a') as testfile:
csv_writer = csv.writer(testfile)
for y in range(length):
csv_writer.writerow([x[y] for x in hello])
When I run the code above on a separate python file alone it works but whenever I try to put it in my full code it doesn't work.
What I am trying to do is basically make a register that when I put input it writes to the csv file. I also added a captcha thing for verification because why not.
csv_writer.writerow([x[y] for x in hello]):
Line 33 ^
The full code v
import random
import csv
def reg2():
print('wip')
def reg1():
ok = False
while not ok:
try:
name = input('Enter your name: ')
age = int(input('Enter your age:'))
password = input('Enter your password: ')
confirm = input('Confirm Password: ')
if confirm == password:
alphabet =''.join(random.choice('0PQRSTUVefghij56789WXYZabcdABCDEFCDrstuvwEFGJ234NOKLMkHImnopqxyz') for i in range(7))
print(alphabet)
captcha = input('Enter the words shown above (Not Case Sensitive): ')
if captcha.capitalize() == alphabet.capitalize() or 'admin'.capitalize():
print('Name: ' + name)
print('Age: {}'.format(age))
print('Password: ' + password)
option = input('Enter No to register again. Enter Yes to login.')
if option.startswith('N') or option.startswith('n'):
reg1()
elif option.startswith('Y') or option.startswith('y'):
hello = [name, password, age]
length = len(hello[0])
with open('db.csv', 'a') as testfile:
csv_writer = csv.writer(testfile)
for y in range(length):
csv_writer.writerow([x[y] for x in hello])
else:
captcha = input('Try again: ')
if captcha == alphabet:
print('Confirmed. ')
else:
print('You have tried too many times. Please register again.')
reg1()
else:
print('Your password is incorrect. Please register again.')
except ValueError:
print('Error 666: Please register again.')
reg1()
How do I fix this?
The full traceback error is http://pastebin.com/zshHji8i

[...]
length = len(hello[0])
with open('db.csv', 'a') as testfile:
csv_writer = csv.writer(testfile)
for y in range(length):
csv_writer.writerow([x[y] for x in hello])
So here, "length" is the number of characters in the name variable, a few lines later, for y in range(length) you're "enumerating" the letters, say you have 6 letters you're getting 0, 1, 2, 3, 4, 5 in y. A line later [x[y] for x in hello] you're asking for the letter y for the name, password, age, that has no sense for me.
What about a simple:
name = input(': ')
password = input(': ')
age = input(': ')
hello = [name, password, age]
with open('db.csv', 'a') as testfile:
csv.writer(testfile).writerow(hello)
Oh, and "hello" is a badly chosen name (we can't deduce what it contains). Oh and "x", "y", and "length" are badly chosen too, (length of what ?). Just choose a nice name for your variables and your bug will become obvious.

Why don't you just write:
with open('db.csv', 'a') as testfile:
csv_writer = csv.writer(testfile)
csv_writer.writerow(hello)
hello is already a list, there is no need for the construction you used.

Related

ValueError: too many values to unpack (expected 2) on a simple Python function

I'm coding this password manager program and keep getting this error message when I use the view function:
File "c:\Users\user\Desktop\password_manager.py", line 7, in view
user, passw = data.split("|")
ValueError: too many values to unpack (expected 2)
This is the program so far:
master_pwd = input("What is the master password?")
def view():
with open("passwords.txt", "r") as f:
for line in f.readlines():
data = line.rstrip()
user, passw = data.split("|")
print("User:", user, "Password:", passw)
def add():
name = input("Account name: ")
pwd = input("Password: ")
with open("passwords.txt", "a") as f:
f.write(name + "|" + pwd + "\n")
while True:
mode = input("Would you like to add a new password or view existing ones (view, add)? Press q to quit. ").lower()
if mode == "q":
break
if mode == "view":
view()
elif mode == "add":
add()
else:
print("Invalid mode.")
continue
I tried using the .split() method to one variable at a time but it also resulted in the error.
I thought the problem could be caused by the comma in user, passw = data.split("|") being deprecated, but I failed to find an alternative.
The .split() function is returning more than 2 values in a list and therefore cannot be unpacked into only 2 variables. Maybe you have a password or username with a | in it which would cause that.
I suggest to simply print(data.split('|')) for a visual of what is happening. It will probably print out a list with more than two values.
Check your password file to be sure there aren't "|" characters in a username or password that are creating additional splits.
If your data is good, you could catch the remaining elements in a list:
user, passw, *other = data.split("|")

What am I missing in this python login function?

I am trying to write a login function using python. However, I can't seem to write the code for checking the username and password against the ones stored in a file. The specific error is NameError: name 'adusername' is not defined. How do I fix this?
def adminlogindetails():
adusername = input("Admin Username: ")
adpassword = input("Admin Password: ")
adfile = open("adlogindetails.txt", "a")
adfile.write(adusername)
adfile.write(",")
adfile.write(adpassword)
adfile.write("\n")
adfile.close()
def adminverification():
adun = input("Enter your username:")
adpw = input("Enter your password:")
adinfo = open("adlogindetails.txt", "r")
for line in adinfo:
adun, adpw = line.split(",")
if adun == adusername and adpw == adpassword:
print("Login successful!")
adminoptions()
else:
print("Incorrect username/password")
roleselection()
adminverification()
You have not declared adusername and adpassword in adminverification(). So, it is causing the error. If you want to use the variables from adminlogindetails(), change the variables name since you have stored the details in adlogindetails.txt.
The below code should be changed as line variable contains the already stored username and password:
adun, adpw = line.split(",")
Change above piece of code to the shown below:
adusername, adpassword = line.split(",")
you can use this:
def adminlogindetails():
adusername = input("Admin Username: ")
adpassword = input("Admin Password: ")
adfile = open("adlogindetails.txt", "a")
adfile.writelines(adusername + ',' + adpassword )
adfile.close()
def adminverification():
adun = input("Enter your username:").strip()
adpw = input("Enter your password:").strip()
with open("adlogindetails.txt", "r") as f:
lines = f.readlines()
i = 0
for line in lines:
adusername, adpassword= line.split(",")
adusername = str(adusername).strip()
adpassword = str(adpassword).strip()
if (adun == adusername) and (adpw == adpassword):
print("Login successful!()")
adminoptions()
break
else:
i += 1
if i >= len(lines): #If no any match upto last line, this will be true
print("Incorrect username/password")
roleselection()
break
adminverification()
First of all you are not calling adminlogindetails().
Also adusername is a local variable and you should either make it global using global adusername in the adminlogindetails function or declare it outside of the functions in the global scope.
See this - https://www.w3schools.com/python/python_scope.asp
This line is your problem:
adun, adpw = line.split(",")
"adun" and "adpw" are your inputs and you are overwriting them. Replace with this and it will be ok:
adusername, adpassword = line.replace("\n", "").split(",")
Note: "\n" needs to be removed for your comparison to be ok.

Compare login info to csv data and grant access

My program asks the user whether they have an account or not. If the user doesn't have an account, then the program creates a new account for the user and stores their details in a csv file. This part works fine. But if the user runs the program again (after account creation) and tries to log in with the same details (username, password), it doesn't work. How do I compare the login info to csv data and grant access?
##Two Subjects----> Computer Science and History
import csv
def main():
userAccount()
def userAccount():
print('-------------------------------')
userAccount = input('Do you already have an account: ')
if userAccount == 'No' or userAccount== 'N' or userAccount == 'no' or userAccount == 'n':
userSName = input('Name : ')
userSAge = input('Age : ')
userSYgroup = input('Year Group : ')
userGname = userSName[:3] + userSAge
print('Your username is : ',userGname.lower())
userSword = input('Password: ')
detail1 = [userSName,userSAge,userSYgroup,userGname,userSword]
with open('userData.csv','w',newline = '') as csvfile:
w = csv.writer(csvfile,delimiter = ',')
w.writerow(detail1)
elif userAccount == 'Yes' or userAccount == 'Y' or userAccount == 'yes' or userAccount == 'y':
userLName = input('Username: ')
passLWord = input('Password: ')
f = open('userData.csv','r',newline = '')
for i in f:
if userLName == f[0,3] and passLWord == f[0,4]:
print('Log In Successfull')
else:
print('Incorrect Username or Password')
main()
main()
Here's a fully working version with slight changes. Add it to your original code. Though it might break your current code, because I changed a few variables name. Rename them accordingly.
##Two Subjects----> Computer Science and History
import csv
def main():
userAccount()
print("rest of the code")
input() # keep window open
def userAccount():
print('-------------------------------')
# group possible inputs; no need for individual checks
noAccount = ["no", "NO", "n", "N"]
yesAccount = ["yes", "YES", "y", "Y"]
hasAccount = input('Do you already have an account: ')
if hasAccount in noAccount:
userName = input('Name : ')
userAge = input('Age : ')
userYear = input('Year Group : ')
userLogin = (userName[:3] + userAge).lower()
print('Your username is : ', userLogin)
userPW = input('Password: ')
details = [userName, userAge, userYear, userLogin, userPW]
# open file with 'a' instead of 'w' so multiple records can be added to csv
with open('userData.csv', 'a', newline='') as csvfile:
writer = csv.writer(csvfile, delimiter=',')
writer.writerow(details)
# once the account is created, return to beginning
main()
elif hasAccount in yesAccount:
userLogin = input('Username: ')
userPW = input('Password: ')
granted = None
with open('userData.csv', 'r', newline='') as csvfile:
reader = csv.reader(csvfile, delimiter=',')
# loop every row (record) in the csv file
for row in reader:
csvLogin = row[3]
csvPW = row[4]
if userLogin == csvLogin and userPW == csvPW:
granted = True
print('Log In Successfull')
# a user is matched; no need to check other records
break
# if input doesn't match any csv record, return to beginning
if granted is None:
print('Incorrect Username or Password')
main()
else:
# if user enters something other than yes/no, return to beginning
main()
main()

Finding Hash's in text files

I'm am trying to verify users using a text document but not having much success. Can someone please point me in the right direction? Here is my code. What I want to do is have have python look on the line which contains the hash and then verify the hash. It is able to verify the first hash but nothing after that. Does anyone know how to fix this?
def passwordVerify():
global hashOne
f = open("maindata.txt")
s = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
numberOne = userConfirm + 2
numberTwo = userConfirm + 1
for line in islice(f, numberTwo, numberOne):
hashOne = line
hashStripped = str.rstrip(hashOne)
hashchecker = sha256_crypt.verify(passWord, hashStripped)
f.close()
if hashchecker is True:
loggedIn()
else:
print "Please try again!"
time.sleep(2.5)
userLogin()
def userRegister():
screenClear()
print "!King of Hearts Registration System!"
realName = raw_input("What is your real name: ")
userName = raw_input("Choose a Username: ")
passWord = getpass.getpass("Please enter a password: ")
passHash = sha256_crypt.encrypt(passWord)
writeUser = "\n" + userName + "\n"
writePass = passHash
userDB = open("maindata.txt", "a")
userDB.write(str(writeUser))
userDB.write(str(writePass))
userDB.close()
print passHash
userLogin()

python: Adding to username

I am fairly new to python and I need to make a program to ask 10 questions, save the score into a file and allow someone to read the scores in from the file.
My problem: I need to check if the person who has done the quiz already has a record in the file, and if so, I need to add their score to the end of their record.
The records should look like this:
name,score,score,score,score,
etc so they can be split using commas.
I am also looking for the simplest answer, not the most efficient. Also, if you could comment the code, it would make it much easier. Here is my code so far:
import random
import math
import operator as op
import sys
import re
def test():
num1 = random.randint(1, 10)
num2 = random.randint(1, num1)
ops = {
'+': op.add,
'-': op.sub,
'*': op.mul,
}
keys = list(ops.keys())
rand_key = random.choice(keys)
operation = ops[rand_key]
correct_result = operation(num1, num2)
print ("What is {} {} {}?".format(num1, rand_key, num2))
while True:
try:
user_answer = int(input("Your answer: "))
except ValueError:
print("Only enter numbers!")
continue
else:
break
if user_answer != correct_result:
print ("Incorrect. The right answer is {}".format(correct_result))
return False
else:
print("Correct!")
return True
print("1. Are you a student?")
print("2. Are you a teacher?")
print("3. Exit")
while True:
try:
status = int(input("Please select an option:"))
except ValueError:
print("Please enter a number!")
else:
if status not in {1,2,3}:
print("Please enter a number in {1,2,3}!")
else:
break
if status == 1:
username=input("What is your name?")
while not re.match("^[A-Za-z ]*$", username) or username=="":
username=input(str("Please enter a valid name (it must not contain numbers or symbols)."))
print ("Hi {}! Wellcome to the Arithmetic quiz...".format(username))
while True:
try:
users_class = int(input("Which class are you in? (1,2 or 3)"))
except ValueError:
print("Please enter a number!")
else:
if users_class not in {1,2,3}:
print("Please enter a number in {1,2,3}!")
else:
break
correct_answers = 0
num_questions = 10
for i in range(num_questions):
if test():
correct_answers +=1
print("{}: You got {}/{} {} correct.".format(username, correct_answers, num_questions,
'question' if (correct_answers==1) else 'questions'))
if users_class == 1:
class1 = open("Class1.txt", "a+")
newRecord = username+ "," + str(correct_answers) + "," + "\n"
class1.write(newRecord)
class1.close()
elif users_class == 2:
class2 = open("Class2.txt", "a+")
newRecord = username+ "," + str(correct_answers) + "," + "\n"
class2.write(newRecord)
class2.close()
elif users_class == 3:
class3 = open("Class3.txt", "a+")
newRecord = username+ "," + str(correct_answers) + "," + "\n"
class3.write(newRecord)
class3.close()
else:
print("Sorry, we can not save your data as the class you entered is not valid.")
EDIT:
Add this function before your "test" function:
def writeUserScore(file, name, score):
with open (file, "r") as myfile:
s = myfile.read()
rows = s.split("\n")
data = {}
for row in rows:
tmp = row.split(",")
if len(tmp) >= 2: data[tmp[0]] = tmp[1:]
if name not in data:
data[name] = []
data[name].append(str(score))
output = ""
for name in data:
output = output + name + "," + ",".join(data[name]) + "\n"
handle = open(file, "w+")
handle.write(output)
handle.close()
After that, where you have "if users_class == 1:" do this:
writeUserScore("Class1.txt", username, str(correct_answers))
Do the same for the other two else ifs.
Let me know what you think!
Try using a dictionary to hold the existing file data.
Read the file in a variable called "str" for example. And then do something like this:
rows = str.split("\n")
data1 = {}
for row in rows:
tmp = row.split(",")
data1[tmp[0]] = tmp[1:]
When you have a new score you should then do:
if username not in data1:
data1[username] = []
data1[username] = str(correct_answers)
And to save the data back to the file:
output = ""
for name in data1:
output = outupt + name + "," + ",".join(data1[name]) | "\n"
And save the contents of "output" to the file.
PS: If you are not bound by the file format you can use a JSON file. I can tell you more about this if you wish.
Hope that helps,
Alex
First, define these functions:
from collections import defaultdict
def read_scores(users_class):
"""
If the score file for users_class does not exist, return an empty
defaultdict(list). If the score file does exist, read it in and return
it as a defaultdict(list). The keys of the dict are the user names,
and the values are lists of ints (the scores for each user)
"""
assert 0 <= users_class <= 3
result = defaultdict(list)
try:
lines =open("Class%d.txt"%users_class,'r').readlines()
except IOError:
return result
for line in lines:
# this line requires python3
user, *scores = line.strip().split(',')
# if you need to use python2, replace the above line
# with these two lines:
# line = line.strip().split(',')
# user, scores = line[0], line[1:]
result[user] = [int(s) for s in scores]
return result
def write_scores(users_class, all_scores):
"""
Write user scores to the appropriate file.
users_class is the class number, all scores is a dict kind of dict
returned by read_scores.
"""
f = open("Class%d.txt"%users_class,'w')
for user, scores in all_scores.items():
f.write("%s,%s\n"%(user, ','.join([str(s) for s in scores])))
def update_user_score(users_class, user_name, new_score):
"""
Update the appropriate score file for users_class.
Append new_score to user_name's existing scores. If the user has
no scores, a new record is created for them.
"""
scores = read_scores(users_class)
scores[user_name].append(new_score)
write_scores(users_class, scores)
Now, in the last portion of your code (where you actually write the scores out) becomes much simpler. Here's an example of writing some scores:
update_user_score(1, 'phil', 7)
update_user_score(1, 'phil', 6)
update_user_score(1, 'alice', 6)
update_user_score(1, 'phil', 9)
there will be two lines in Class1.txt:
phil,7,6,9
alice,6
We read the whole file into a dict (actually a defaultdict(list)),
and overwrite that same file with an updated dict. By using defaultdict(list), we don't have to worry about distinguishing between updating and adding a record.
Note also that we don't need separate if/elif cases to read/write the files. "Scores%d.txt"%users_class gives us the name of the file.

Categories