1

I have the following program that reads some data from a csv file but it seems to be resisting all attempts to either read the "marks" data as an integer or convert it to one later on. I based this program on another I have which is fully functional with the only real difference that the integer field was a float in my functioning program.

I've tried entering the following line into the findHighest function just after the "for counter..." line.

**Students[0].marks = int(Students[0].marks)**

The code runs but doesn't find the highest number in the data (it comes back with 96 when the highest number is 100, the second highest is 96). I've also tried altering the following line...

Students[counter].marks = row[3]

and changed it to...

**Students[counter].marks = int(row[3])**

This gives me the following error:

ValueError: invalid literal for int() with base 10: ''

What am I missing here? :-/

import csv

class Student:
    def __init__(self,forename,surname,form,marks):
        self.forename = ""
        self.surname = ""
        self.form = ""
        self.marks = 0

def readFile():
    Students = []
    filename = "pupils.csv"
    csv_file = open(filename, "r")
    reader = csv.reader(csv_file)
    counter = 0
    for row in reader:
        Students.append(Student("", "", "", 0)) 
        Students[counter].forename = row[0] 
        Students[counter].surname = row[1] 
        Students[counter].form = row[2] 
        Students[counter].marks = row[3]
        counter = counter + 1
    return Students


def findHighest(Students):
    position=0
    highest = Students[0].marks
    for counter in range(len(Students)):
        Students[counter].marks = int(Students[counter].marks)
        if Students[counter].marks > highest:
            highest = Students[counter].marks
            position = counter
    return highest

def displayHighest(highest):
    print("the highest pupil score was:", highest)

Students = readFile()
highest = findHighest(Students)
displayHighest(highest)

CSV File:

CSV

bhathiya-perera
  • 1,303
  • 14
  • 32
Razorbill
  • 25
  • 5
  • Possible duplicate of [How to convert strings into integers in Python?](https://stackoverflow.com/questions/642154/how-to-convert-strings-into-integers-in-python) – nullPointer Feb 04 '19 at 09:14
  • 1
    Is it possible that the csv data you're reading contain newlines (the `\n` literal)..? I suspect that, because it's the last field of your csv. This would explain it not being able to be cast using `int()`, and would be solved by something as simple as `Students[counter].marks = row[3].strip()` – hyperTrashPanda Feb 04 '19 at 09:17
  • 1
    How does the CSV looks like? post few lines of test data starting from first line, – bhathiya-perera Feb 04 '19 at 09:26
  • I've added a photo of what the file looks like in Excel if that helps any? – Razorbill Feb 04 '19 at 09:39
  • BTW if you use a library like better exceptions, you can see values when an exception occur. https://github.com/Qix-/better-exceptions – bhathiya-perera Feb 04 '19 at 10:58

2 Answers2

1

I guess you have multiple problems

def findHighest(Students):
    position=0

#highest is set to a string. You should set highest to 0
    highest = Students[0].marks
    for counter in range(len(Students)):

#why do you always set Students[0] and not Students[counter]. You always convert Students[0] to int.
        Students[0].marks = int(Students[0].marks)

#As a result you always tests string again strings:
        if Students[counter].marks > highest:
            highest = Students[counter].marks
            position = counter
    return highest

This try

Students[counter].marks = int(row[3])

should be correct but the ValueError can be a hint that your content of your CSV is not at all lines a correct integer value. Please check your CSV or handle the exception like this: Converting String to Int using try/except in Python

camen6ert
  • 101
  • 4
  • In the final code above the line is Students[counter].marks = int(Students[counter].marks) so this isn't what's causing the issue. Setting the highest to 0 also gives the same error. – Razorbill Feb 04 '19 at 09:26
  • try printing out to console which Student is processed when the ValueError occures. Like this: print(Students[counter].marks) directly after your for counter in range(...) and check in console if you have a value in our CSV that isnt a correct int – camen6ert Feb 04 '19 at 09:43
  • It prints out the list of marks fine if I make a new piece of code like so... for counter in range(len(Students)): print(Students[counter].marks) – Razorbill Feb 04 '19 at 09:48
  • I'm irrtitated because if you try: Students[counter].marks = int(row[3]) you get a ValueError. If you convert int(Students[counter].marks) there is no ValueError? – camen6ert Feb 04 '19 at 10:06
  • And now I have created a new file and it seems to be happy enough to read data from that so there must have been something odd going on with the original file. Thank you for the advice! – Razorbill Feb 04 '19 at 10:09
  • great can you set my answer as useful ? I need some reputations ;-) – camen6ert Feb 04 '19 at 10:12
  • I think I did that but if not let me know! :-) – Razorbill Feb 04 '19 at 10:21
0

It seems this was a problem with the CSV file rather than the code. I created a new file from scratch and it the Students[counter].marks = int(row[3]) line works fine.

Razorbill
  • 25
  • 5
  • Always look at CSV files from a text editor if you suspect an issue. Excel can fix the issues and show it to you, but a typical csv library is not excel. – bhathiya-perera Feb 04 '19 at 10:55