Python – How to convert this to a recursive function?

How to convert this to a recursive function?… here is a solution to the problem.

How to convert this to a recursive function?

I’m trying to create a model-based organization chart that references itself through a property called reports_to. I don’t know how many layers the org chart will go down, so I find the recursive function meaningful. Here are some currently valid code:

top_level = Person.objects.filter(reports_to=None)
org_chart = {}
for person in top_level:
    org_chart[person] = {}
    if person.has_direct_reports():
        direct_reports = Person.objects.filter(reports_to=person)
        for p in direct_reports:
            org_chart[person][p] = {}
            if p.has_direct_reports():
                direct_reports_2 = Person.objects.filter(reports_to=p)
                for q in direct_reports_2:
                    org_chart[person][p][q] = {}
                        # ... and so on

This results in shell output as follows:

>>> pp.pprint(org_chart)
{   <Person: Joe Boss>: {   <Person: John Doe>: {   <Person: John Doe Jr>: {   },
                                                          <Person: Jane Doe>: {   }}},
    <Person: Partner Mary>: {}}

That’s right. Show cleaner:

Joe Boss
- John Doe
-- John Doe Jr
-- Jane Doe
Partner Mary

I’ve been trying to convert this code to a recursive function, but my brain just can’t fix this. Thank you for any suggestions or help fixing this issue!

Edit. This is the code I’m struggling with, but I fell on myself in the process :

def direct_reports_r(person):
    if person.has_direct_reports():
        direct_reports = Person.objects.filter(reports_to=person)
        for person in direct_reports:
            org_chart[person] = {}
            if person.has_direct_reports():
                direct_reports = Person.objects.filter(reports_to=person)
                org_chart[person] = direct_reports_r(person)
            else:
                return person
    else:
        return False

top_level = Person.objects.filter(reports_to=None)
org_chart = {}
for person in top_level:
    org_chart[person] = {}
    # recursion
    org_chart[person][direct_reports_r(person)] = {}

Solution

I hope this code works.

def foo(person, tmp_root):
    tmp_root[person] = {}
    if person.has_direct_reports():
        direct_reports = Person.objects.filter(reports_to=person)
        for p in direct_reports:
            foo(p, tmp_root[person])

org_chart = {}
top_level = Person.objects.filter(reports_to=None)
for person in top_level:
    foo(person, org_chart)

Related Problems and Solutions