user637965
user637965

Reputation:

creating a list from a text file in python

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?

Upvotes: 0

Views: 3607

Answers (5)

Hugh Bothwell
Hugh Bothwell

Reputation: 56624

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

Upvotes: 0

Mahmoud Abdelkader
Mahmoud Abdelkader

Reputation: 24919

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!

Upvotes: 2

Bj&#246;rn Pollex
Bj&#246;rn Pollex

Reputation: 76778

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]

Upvotes: 4

Ocaso Protal
Ocaso Protal

Reputation: 20237

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

Upvotes: 0

Hraban Luyat
Hraban Luyat

Reputation: 669

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.

Upvotes: 0

Related Questions