I am working on a program that is supposed to update employees salaries by %5 and based on age:
import csv
infile = open('employee.csv')
csvreader = csv.reader(infile)
rows = []
for row in csvreader:
rows.append(row)
for i in rows:
if(int(i[2]) < 40): #LINE CAUSING A PROBLEM
i[3] = round((1.05 * float(i[3])) , 2)
else:
i[3] = round((1.10 * float(i[3])) , 2)
print('\n\nList after updation:')
#loop print the data on the compile
for row in rows:
print(row)
#open file and write the updated data
with open('employeeUpdate.csv', 'w', encoding='UTF8', newline='') as f:
writer = csv.writer(f)
for row in rows:
writer.writerow(row)
When I run it I get the following error:
ValueError Traceback (most recent call last)
---> 23 if(int(i[2]) < 40):
ValueError: invalid literal for int() with base 10: 'age'
Data Sample:
ID employee name age salary
1 Sara Wales 33 60994
2 John Smith 42 78399
3 Michael Ousley 22 58000
4 Rami Elliot 50 88382
I double-checked the data type and it was an integer-->('age', dtype('int64'))
I tried with open ('employee.csv', r) as infile
and changing the problem line to if int(float(i[2]) < 40):
but they both did not work.
It said cannot convert string to float. I don't know why it is reading the integer as a string.
But when I added an exception like this:
for i in rows:
try:
if (int(i[2]) < 40):
i[3] = round((1.05 * int(i[3])) , 2)
else:
i[3] = round((1.10 * int(i[3])) , 2)
except ValueError:
print("")
It worked, so my question is why did it only work with the exception!, and is there a way I can have it done without the exception?
CodePudding user response:
Since csv.reader()
continuously reads a stream until EOF, it doesn't have a concept of a header row. For the first iteration of rows
, i
would always be the string header row. And you're trying to convert the text "age" into int which would Python to error.
Your try-except works because it simply masks the error raised from the first row and prints a blank line instead.
To fix it, simply skip a line from the file to not include the header row, or skip the first iteration when doing the int conversion.
with open('employee.csv') as infile:
infile.readline()
csvreader = csv.reader(infile)
# do stuff with csvreader
When handling large datasets and doing complicated data manipulations, consider using the pandas library. The issue described here and dtype conversions would automatically be handled by pandas.