[Tutor] OOP design (w/ example :-)

alan.gauld@bt.com alan.gauld@bt.com
Mon, 26 Mar 2001 11:46:51 +0100


> Specifically, I often want to put my students in 
> small groups to work on class work, labs, or
> whatever we're working on that day. It's too time 
> consuming to go through a big process every day 
> and I want to rearrange the groups often. 


> To keep things simple for now, I'm storing the students in a 
> simple text file with last name, first name, and gender. 

Seems fine. Maybe you want to store the current groupings 
too? Can they be in more than one group at a time? 
eg for different class periods or projects? If not then 
a single extra field with the current group name should 
do it.

> I'd like to try a OOP approach, but one of the things I 
> struggle with is the initial design stage. I've asked 
> about this before and I've done some reading, but I 
> still haven't found a way of thinking about problems 
> like this that make a lot of sense to me.

As ever you need to have an idea of the functionality 
of the system. What do you want to do with the various 
objects - then on that basis assign their responsibilities.

For examnple you need to assign students to groups and 
move students from one group to another. You probably 
want to list the students in a group. Applying the 
principle that objects should "do it to themselves" 
(sometimes known as the law of demeter(sp?)) then 
students probably need a method to setGroup() and/or 
moveGroup(group). The group objects need a listStudents() 
method too.

What else do you need?

> My program, it would seem, would logically have classes the 
> correspond to individual students, groups, and perhaps 
> the class as a whole. 

Maybe. To list available groups perhaps? What would be 
the class' job?


> I've come up with so far:
> 
> class Student:
> 	def __init__(self, ln, fn, gender):
> 		self.ln = ln
> 		self.fn = fn
> 		self.gender = gender
            self.group = ???
      def setGroup(aGroup):
            ...

> class Group:
> 	def __init__(self, studentList):
> 		self.studentList = studentList
> 	def display(studentList):
> 		pass

No need to parameterise studentlist its already an 
attribute. It would be very strange to ask one group to 
display another groups studentList!

> class Roster:
> 	def __init__(self):
> 		pass
> 	def loadFile(self, filename):

Now why would the roster hold all the students?
It may be sensible depending on what you want to do. 
If the roster generates a set of new groups then 
its perfectly valid. 

Although a more OO way to do this might be to have 
the __init__ of Student take a filename parameter 
so that if filename != '' it reads the values from 
the file. Another case of student doing it to 
themselves. (One big thing I'd like in Python is 
the ability to overload constructors ala Delphi/OP, 
sigh)


> 		f = open(filename, 'r')
> 		while 1:
> 				record = f.readline()
> 				student = string.split(record, ',')
> 				ln = student[0]
> 				fn = student[1]

If this fails it suggest a faulty input string. Have you 
tried putting a print statement in after the split to see 
what the list looks like? Does it fact have 3 fields for 
the line that fails?

>   File "group.py", line 29, in loadFile
>     fn = student[1]
> IndexError: list index out of range

As suggested is the problem here...

Alan G
(catching up on 3 days digests...)