views:

91

answers:

1

Hello,

I have a class model designed for a person class in python. where a person is a student and can have 0,1 or many advisors.A person can also have other attributes like name,school,year of graduation,classification he worked on,degree he obtained and so on.

I have set and get methods for each of these attributes in the class. Ex. set_advisor(self,advisor) inserts advisor to the list of a student's advisors. set_year(self,year) sets the year of graduation of student.

similarly get_advisor(self) returns the advisor of the student. and so on..

finally I populate the objects and name it as people.

if I want to get list of students who graduated in some year I just write

print [people[p].name for p in people if people[p].year="YEAR"]

Now, I want to write a query, say..list the students who graduated in some year and whose advisor trace back to say some "abc"... eg dataset looks like this..

person a graduated in year 1990
person b graduated in year 1990
person c graduated in year 1991
person d graduated in year 1990
person a was advised by person e
person e was advised by person f
person f was advised by person g
person g was advised by person abc

person b was advised by person i
person i was advised by person abc

person c was advised by person abc

person d was advised by person h
person h was advised by person k

Now, I want to write a recursive query to track only those who graduated in 1990 and whose advisor trace back to abc.in the above case it should give me only a and b as result.

How do I go about this. I am having problems with the syntax and formulating the query.Like in the same terms as I formualted query above. Can anybody help on this.

similarly..how do I write query for..say.. to get pairs of students who worked on some classification and graduated in same year and had their advisors also working on the same classification.

Thanks.

+1  A: 

You could write a method on your class with something like:

has_advisor(self, advisor):
    if not self.advisor:
        return False
    elif advisor in self.advisor:
        return True
    else
        return self.advisor.has_advisor(advisor)

That would let you query things like:

e = people['e']
e_in_advisor_tree_and_grad_in_1990 = [p for p in people if p.has_advisor(e) and p.year == 1990]

This will get very expensive very quickly with large datasets, all of which are kept in memory at the same time.

Benj
in this case, self.advisor is likely to be a list of strings, so the recursive .has_advisor probably won't work, no?
Blair Conrad
looks promising. Would try as soon as I get back on it and update.
pythonperl
@Blair -- depends. If self.advisor is list of strings, then we could substitute `people[adv_name] for adv_name in advisors`
Benj
The bigger problem is that this code actually assumes a single advisor or else self.advisor.has_advisor doesn't work -- because self.advisor is actually a list. And once you start rewriting it for a list, the opportunities for repetitive, never-ending recursion abound, and there would need to be a mechanism for checking whether any given person had been checked already.
Benj