0

I have a text file that looks something like this where the first column is a student's name, the second column is the number of credits, and the third is the number of points (grade times hours).

john    5    15
bill    9    30
ted    7    22

I want to create a class that extracts the relevant information and calculates gpa.

class Student:

    def __init__(self, name, hours, qpoints):
        self.name = name
        self.hours = float(hours)
        self.qpoints = float(qpoints)

    def getName(self):
        return self.name

    def getHours(self):
        return self.hours

    def getQPoints(self):
        return self.qpoints

    def gps(self):
        return self.qpoints/self.hours

used to make extract the data (based on the fact that there is a tab between each piece of information)

def makeStudent(info):
    name, hours, qpoints = info.split("\t")
    return Student(name, hours, qpoints)

here I use a for loop to create a list based on the data in the text file by appending the relevant information from each line to the list

def readStudents(filename):
    infile = open(filename, 'r')
    students = []
    for line in infile:
        students.append(makeStudent(line))
    infile.close()
    return students

the problem is that I get this error:

[<__main__.Student object at 0x01FA4AD0>, <__main__.Student object at 0x01FA4AF0>,
 <__main__.Student object at 0x01FA4B10>, <__main__.Student object at 0x01FA4B50>, 
 <__main__.Student object at 0x01FA4B30>]

Any ideas on why this is happening?

5
  • sorry....seems like the formatting is a little screwed up! Commented Mar 9, 2011 at 13:43
  • Fixed that for you. However, there is a live preview window right below the edit field, so you can check in real-time what your post looks like. Commented Mar 9, 2011 at 13:44
  • 1
    That not an error. You're printing all your student objects. I think you wanted to print Student.name, Student.hours, etc. If you just say print Student, this is what will happen. Commented Mar 9, 2011 at 13:46
  • Qadir return Student(name, hours, qpoints) returns an instance of a class. [<__main__.Student object at 0x01FA4AD0> describes an instance of a class. Commented Mar 9, 2011 at 13:47
  • Qadir You don't need the makeStudent(info) function. Write directly students.append(Student(*line.split("\t"))) Commented Mar 9, 2011 at 13:51

5 Answers 5

4

This is not an error. It is regular output. You should override the __str__ and __repr__ methods of the Student class, to tell python how to print Student objects.

Some help on your code, this is much better:

def readStudents(filename):
    with open(filename) as student_file:
        return [Student(*line.split()) for line in student_file]
Sign up to request clarification or add additional context in comments.

1 Comment

There is also __unicode__ which I believe is now preferred.
2

Like everyone says, not an error. Just implement __str__, __repr__ or __unicode__ on your Student class.

However, I have one minor suggestion. You should use the csv module to read your file.

Your readStudents function can also be re-written like this:

def readStudents(filename):
    students = []
    with open(filename) as infile:
        for line in csv.reader(infile, delimiter='\t'):  # or excel-tab if you want.
            students.append(Student(**line))
    return students

Isn't that pretty?

Don't forget to put a import csv at the beginning of your python file!

Comments

0

I strongly suggest using the csv module (import csv): it will do most of the work for you, be more flexible, more readable and less prone to bugs.

Also, to be a little more strict: what is your actual question? I just see a blurb of code and some output you do not understand. That is not an error message, by the way, it is a list of five instances of the Student class. The code seems to work as intended: you parse the file, create students, and then..? What do you want to do with them? The parsing is done, you want to move on to the handling of the data.

1 Comment

I just want to see the newly created list
0

You don't get an error, but a list of student objects. What you need to do is implement a __str__ or a __repr__ method: Special method names

Comments

0

Getter and setter methods are usually frowned on unless they are doing something active (over and above just retrieving or setting a value).

import csv

class Student(object):
    def __init__(self, name, hours, qpoints):
        super(Student,self).__init__()
        self.name    = str(name)
        self.hours   = float(hours)
        self.qpoints = float(qpoints)

    @property
    def gpa(self):
        return self.qpoints/self.hours

    @gpa.setter
    def gpa(self, value):
        raise SyntaxError('gpa property is read-only; update .qpoints or .hours instead')

    def __str__(self):
        return "{name:20} {hours:>6.2f} {qpoints:>6.2f} {gpa:>6.2f}".format(name=self.name, hours=self.hours, qpoints=self.qpoints, gpa=self.gpa)

def loadStudents(fname, *args, **kwargs):
    with open(fname) as inf:
        return [Student(*line) for line in csv.reader(inf, *args, **kwargs)]

def main():
    students = loadStudents('students.csv', delimiter='\t')
    for s in students:
        print s

if __name__=="__main__":
    main()

results in

john                   5.00  15.00   3.00
bill                   9.00  30.00   3.33
ted                    7.00  22.00   3.14

Comments