0
class Runner:
    """
    information of registered runners
    Attributes:
        @type email: str
        email of the registered runner
        @type category: str
        the speed they estimate that they can finish the race
        @type list: clist
        the list of runners in the same category

    """
    under_twenty_min = []
    under_thirty_min = []
    under_forty_min = []
    forty_and_above = []

    def __init__(self, email, category):
        """Register the email and the speed estimation of runners

            @type self: Runner
            @type email: str
            @type speed: int
            @type category:str
            @type clist: list
            @rtype: list

        >>>runner1=Runner('gerhard@mail.utoronto.ca','under 40 min')
        >>>runner1.email
        'gerhard@gmail.utoronto.ca'
        >>>runner1.category
        'under 40 min'
        """
        self.email = email
        self.category = category
        if category=='under 20 min':
            self.clist=under_twenty_min
        elif category=='under 30 min':
            self.clist = under_twenty_min
        elif  category=='under 40 min':
            self.clist = under_forty_min
        elif category=='40 min and over':
            self.clist = forty_and_over
        renew(self,clist)
        return clist

basically i have to return a list of runners with the same speed category when initialize a runner, but I can't assign the lists I defined above to the class attribute, is there anyway to fix it?

wwii
  • 23,232
  • 7
  • 37
  • 77
Maggie H
  • 1
  • 2
  • 1
    to acceess class namespace attributes use this notation `self.clist=Runner.under_twenty_min` – Alexey Smirnov Jan 16 '17 at 14:54
  • ```return clist``` --> ```return self.clist``` and ```renew(self,clist)``` --> ```renew(self,self.clist)```. You should probably show us ```renew``` - is it a method of the class or a *standalone* function? – wwii Jan 16 '17 at 16:18
  • 1
    It's odd that ```__init__`` needs to return a list - http://stackoverflow.com/a/2491831/2823755 – wwii Jan 16 '17 at 16:25
  • https://docs.python.org/3/reference/datamodel.html#object.__init__ – wwii Jan 16 '17 at 16:31

4 Answers4

4

You have to explicitly specify the class when accessing class variables:

if category == 'under 20 min':
    self.clist = Runner.under_twenty_min
elif category == 'under 30 min':
    self.clist = Runner.under_twenty_min
elif category == 'under 40 min':
    self.clist = Runner.under_forty_min
elif category == '40 min and over':
    self.clist = Runner.forty_and_over
Tamas Hegedus
  • 28,755
  • 12
  • 63
  • 97
1

You can use a dict, set each catgory name as a key and the value is a list of all the runners in that category.
here is a simple implementation

from collections import defaultdict

#runners is a list of all your runners

def get_runners_by_cat():
    d = defaultdict(list)
    for runner in runners:
        dict[runner.category].append(runner)
    return d
taoufik A
  • 1,439
  • 11
  • 20
0

There are couple of things you have to modify in your code:

  1. The indentation of the init method needs to be indented within the class definition.
  2. As @Tamas points out you need to explicitly state that the variables are class variable.
  3. As @taoufik mentions, it might be convenient to define a dictionary instead.
  4. A init method should not return anything (except None). Since your requirement is to return the runners, you could add an additional method as @taofik suggested (or you can just print them once created as shown below).

Here's an updated version of the code. Hope it helps.

class Runner:
    """
    information of registered runners
    Attributes:
        @type email: str
        email of the registered runner
        @type category: str
        the speed they estimate that they can finish the race
        @type list: clist
        the list of runners in the same category

    """
    clist = {
        'under_twenty_min': [],
        'under_thirty_min': [],
        'under_forty_min':[],
        'forty_and_above': []
    }

    def __init__(self, email, category):
        """Register the email and the speed estimation of runners

            @type self: Runner
            @type email: str
            @type speed: int
            @type category:str
                @type clist: list
            @rtype: list

        >>>runner1=Runner('gerhard@mail.utoronto.ca','under 40 min')
        >>>runner1.email
        'gerhard@gmail.utoronto.ca'
            >>>runner1.category
        'under 40 min'
        """
        self.email = email
        self.category = category

        if category=='under 20 min':
            Runner.clist['under_twenty_min'].append(self)
            print Runner.clist['under_twenty_min']
        elif category=='under 30 min':
            Runner.clist['under_thirty_min'].append(self)
            print Runner.clist['under_thirty_min']
        elif  category=='under 40 min':
            Runner.clist['under_forty_min'].append(self)
            print Runner.clist['under_forty_min']
        elif category=='40 min and over':
            Runner.clist['forty_and_above'].append(self)
            print Runner.clist['forty_and_above']
José Sánchez
  • 1,126
  • 2
  • 11
  • 20
0
#get class name, convert it to class object
if category=='under 20 min':
    self.clist= eval(self.__class__.__name__).under_twenty_min
elif category=='under 30 min':
    self.clist = eval(self.__class__.__name__).under_thirty_min
elif  category=='under 40 min':
    self.clist = eval(self.__class__.__name__).under_forty_min
elif category=='40 min and over':
    self.clist = eval(self.__class__.__name__).forty_and_above
Ari Gold
  • 1,528
  • 11
  • 18