Swadhikar
Swadhikar

Reputation: 2210

How to use dictionary for simpler invocation of attributes

I am exploring composition(has-a relationship) logic in python and for this I have a class Student which has an Address . I am trying to store multiple student records by using student_dict inside Student. I have a GraduateStudent subclassing Student. I make use of a dictionary and set id as key and store the corresponding details like name, age, department as value. Later if I try to add student address it becomes complicated when tried to access them. Example: student_dict.get(id)[1])[2]

My question is while adding the address I append it to the existing details of the student. This adds the address as tuple and when accessing it becomes tedious to fetch with additional indexing. You can refer this in add_address() method inside Student and get_course() method in GraduateStudent. Below is the code and invocation. Can someone have a walk through and suggest a way such that I can easily access the values rather than multi-dimensional indexing?

class Address(object):

    def __init__(self, street, pin):
        self.street = street
        self.pin = pin

    def __str__(self):
        return "Address: {} {}".format(self.street, self.pin)

class Student(object):    
    # Composition
    student_dict = {}

    def add_address(self, id, street, pin):
        self.address = Address(street, pin)
        self.student_dict[id] = self.student_dict[id], self.address

    def get_address(self, id):
        if (self.is_exists(id)):
            return self.get(id)[1]
        else:
            print "<No Student record found>"
            return ""

    def put(self, id, details):
        if id in self.student_dict.keys():
            print "Student %d already exists" %id
            return
        self.student_dict[id] = details

    ...

# class

# Class that extends Student
class GraduateStudent(Student):

    def put(self, id, *args):
        super(GraduateStudent, self).put(id, args)
    # def

    def get_course(self, id):
        if (self.is_exists(id)):
            return (self.get(id)[0])[2]
        else:
            print "<No record found>"
            return ""
    # def

# class 

Invocations:

s = GraduateStudent()
s.put(1, "Swad", 17, "Computer Science")
s.put(2, "Vish", 18, "MECH.")
s.put(3, "Vino", 18, "MECH.")

s.add_address(1, "11 vvk street", 600015)
s.add_address(2, "22 vvk street", 600015)
s.add_address(3, "33 vvk street", 600015)

print "\nStudent details::"
print 1,": COURSE: ", s.get_course(1), ",", s.get_address(1)
print 2,": COURSE: ", s.get_course(2), ",", s.get_address(2)
print 3,": COURSE: ", s.get_course(3), ",", s.get_address(3)

Result:

Student details::
1 : COURSE:  Computer Science , Address: 11 vvk street 600015
2 : COURSE:  MECH. , Address: 22 vvk street 600015
3 : COURSE:  MECH. , Address: 33 vvk street 600015    

Upvotes: 0

Views: 63

Answers (1)

Frodon
Frodon

Reputation: 3775

Just define the details of the classes Student and GraduateStudent as attributes. Each instance can have a unique id by defining a class attribute studentid:

class Student(object):   
    studentid = -1 
    def __init__(self, name, dob):
        Student.studentid += 1
        self.id = Student.studentid
        self.details = dict()
        self.name = name
        # Date of birth more useful than age :)
        self.dob = dob
        self.address = ""

    def add_address(self, street, pin):
        self.address = Address(street, pin)

    def get_address(self):
        return self.address

    def __str__(self):
        return "{}: Name {}, Address: {}".format(self.id, self.name, self.address)

class GraduateStudent(Student):
    def __init__(self, name, dob, course):
        super(GraduateStudent, self).__init__(name, dob)
        self.course = course
    def __str__(self):
        return "{}: Name: {}, Course: {}, Address: {}".format(self.id, self.name, self.course, self.address)

To keep track of the list of students, you can define a Directory class in which you will add the students:

class Directory(object):
    def __init__(self):
        self.student_dict = dict()

    def add_student(self, student):
        if student.id in self.student_dict:
            print "Student %d already exists" % student.id
            return
        self.student_dict[student.id] = student
        return student.id

    def get_student(self, id):
        try:
            return self.student_dict[id]
        except KeyError:
            print "<No Student record found: %d>" % id
            return None

    def add_address(self, id, street, pin):
        student = self.get_student(id)
        if student is not None:
            student.add_address(street, pin)

    def get_address(self, id):
        student = self.get_student(id)
        if student is not None:
            return student.get_address()

    def print_students(self):
        for student in self.student_dict.values():
            print student

Now to manipulate the student list, you can write:

>>> d = Directory()
>>> id1 = d.add_student(GraduateStudent('Swad', 1999, 'Computer Science'))
>>> id2 = d.add_student(GraduateStudent('Vish', 1998, 'MECH.'))
>>> id3 = d.add_student(GraduateStudent('Vino', 1998,  'MECH.'))
>>> d.add_address(id1, "11 vvk street", 600015)
>>> d.add_address(id2, "22 vvk street", 600015)
>>> d.add_address(id3, "33 vvk street", 600015)
>>> d.print_students()
0: Name: Swad, Course: Computer Science, Address: Address: 11 vvk street 600015
1: Name: Vish, Course: MECH., Address: Address: 22 vvk street 600015
2: Name: Vino, Course: MECH., Address: Address: 33 vvk street 600015

Upvotes: 2

Related Questions