1

I am trying to associate a competitor with the race that they have competed in, how would I do the show() function through inheriting the event class? I'm still wrapping my head around inheritance so I apologise if this question is obvious..

import sqlite3

print "hello"

class competitor(object):
    def __init__(self, name, dob, number, events):
        self.name = name
        self.dob = dob
        self.number = number ##this needs to check db for existing
        self.events = events

    def listEvents(self):
        for all in self.events:
            self.show()

class event(competitor):
    def __init__(self, name, distance, date, time):
        self.name = name
        self.distance = distance #meters
        self.date = date # [dd,mm,yyyy]
        self.time = time # [d,h,m,s]

    def printDate(self):
        date = str(self.date[0]) + "/" + str(self.date[1]) + "/" + str(self.date[2])
        ##print date
        return date

    def printTime(self):
        if (self.time[0] > 0):
            time = str(self.time[0]) + "." + str(self.time[1]) + ":" + str(self.time[2]) + "." + str(self.time[3])
            return time
        else:
            time = str(self.time[1]) + ":" + str(self.time[2]) + "." + str(self.time[3])
            return time

    def getKmPace(self):
        time_s = self.time[0]*3600*24 + self.time[1]*3600 + self.time[2]*60 + self.time[3]
        time_m = time_s/60.0
        pace = time_m/(self.distance/1000.0)
        return pace

    def show(self):
        print "Event: ", self.name, " Date: ", self.printDate()
        print "Distance: ",self.distance/1000.0,"KM, Time: ", self.printTime()
        print "Pace per 1 KM: ", self.getKmPace(), " minutes."


kdl = event("20KM",20000,[26,4,2014],[0,1,27,36])
kdl_bad = event("20KM",20000,[26,4,2013],[0,2,35,37])
kdl.show()

richard = competitor("Richard", 1993, 1, [kdl,kdl_bad])
richard.listEvents()
6
  • 1
    Hmm, I'm not exactly sure what you're asking. I can see that you have an event class, which inherits from the competitor class. (This seems like on odd inheritance relationship to me, since saying "an event is a competitor" doesn't really make logical sense). You also have a function called show, but it's not a part of either of those classes, at least according to the indentation in your pasted code. Is that just a copy/paste error? Should show and getkmPace actually be part of the event class? Commented May 1, 2014 at 17:32
  • 3
    Well, think about your class design more closely. Is an "event" a more specific "competitor"? Or does an "event" have "competitors? Inheritance is usually used when you're describing an "is-a" relationship, not a "has-a". Commented May 1, 2014 at 17:32
  • getKmPace(self) and show()functions are outside of the event class? Commented May 1, 2014 at 17:33
  • This is not the way to use inheritance. Commented May 1, 2014 at 17:37
  • @Santa how would I describe has-a relationship in this case? Commented May 1, 2014 at 17:40

2 Answers 2

3

Well, think about your class design more closely. Is an "event" a more specific "competitor"? Or does an "event" have "competitors? Inheritance is usually used when you're describing an "is-a" relationship, not a "has-a".

In your case, a competitor has a reference to multiple event objects. Your class design for both are already on the right track. Your use of inheritance, however, is not.

A simple fix:

class competitor(object):
    def __init__(self, name, dob, number, events):
        self.name = name
        self.dob = dob
        self.number = number ##this needs to check db for existing
        self.events = events

    def listEvents(self):
        for event in self.events:
            event.show()

class event(object):
    def __init__(self, name, distance, date, time):
        self.name = name
        self.distance = distance #meters
        self.date = date # [dd,mm,yyyy]
        self.time = time # [d,h,m,s]

    def printDate(self):
        date = str(self.date[0]) + "/" + str(self.date[1]) + "/" + str(self.date[2])
        return date

    def printTime(self):
        if (self.time[0] > 0):
            time = str(self.time[0]) + "." + str(self.time[1]) + ":" + str(self.time[2]) + "." + str(self.time[3])
        else:
            time = str(self.time[1]) + ":" + str(self.time[2]) + "." + str(self.time[3])
        return time

    def getKmPace(self):
        time_s = self.time[0]*3600*24 + self.time[1]*3600 + self.time[2]*60 + self.time[3]
        time_m = time_s/60.0
        pace = time_m/(self.distance/1000.0)
        return pace

    def show(self):
        print "Event: ", self.name, " Date: ", self.printDate()
        print "Distance: ",self.distance/1000.0,"KM, Time: ", self.printTime()
        print "Pace per 1 KM: ", self.getKmPace(), " minutes."

kdl = event("20KM",20000,[26,4,2014],[0,1,27,36])
kdl_bad = event("20KM",20000,[26,4,2013],[0,2,35,37])

print 'First event:'
kdl.show()

print 'Richard has two events:'
richard = competitor("Richard", 1993, 1, [kdl,kdl_bad])
richard.listEvents()
Sign up to request clarification or add additional context in comments.

2 Comments

thank you very much, so what would you call this if it's not inheritance?
@user1902692 It's called composition. When you describe Shape -> Rectangle -> Square, that is inheritance, as a Square is a Rectangle is a Shape. And you want a Square to inherit the fields and methods of a Rectangle (e.g. the area calculation algorithm). But when you describe a Car -> Doors -> Handles, that is composition, as a Door is not a Car, but a Car has Doors. You don't want a Door to inherit Car.RevvEngine(), for example. So you don't lump them in one class hierarchy and compose them together.
1

I don't think this is a case for inheritance. To apply inheritance in this example would be something like:

class event(object): # not inheriting from competitor
    # your code for the event
    #     ...

class 20KM_event(event):
    def __init__(self, date, time):
        super(20KM_event,self).__init__("20KM",20000, date, time)
    # if any specific methods are required for JUST the
    # 20KM event, put them here. Otherwise you're done

kdl = 20KM_event([26,4,2014],[0,1,27,36])

for your competitor, often this is something that should be handled by the event in question. They are members of the event, after all, so maybe something like:

class event(object):
    def __init__(self,name,distance,date,time):
        self.name = name
        self.distance = distance
        self.date = date
        self.time = time
        self.competitors = []
    def addCompetitor(self,*args):
        """Add a competitor to this event
USAGE: self.addCompetitor(competitor) OR
       self.addCompetitor(name, dob, number, events)"""
        if len(args) == 1 and isinstance(args[0],competitor):
            target = args[0]
        else:
            target = competitor(*args)
        target.events.append(self)
        self.competitors.append(target)

4 Comments

@Adam Smith, in your first example, what does using super(self,event) do as opposed to super(20KM_event,self).__init__("20KM",20000, date, time)?
@PadraicCunningham did I use the wrong notation? Crud I'm rusty on my supers. One sec...
@AdamSmith, I rarely use super and any time I have it has been like super(20KM_event,self).__init__("20KM",20000, date, time), I was just wondering if there were some significance. I could be wrong.
@PadraicCunningham no I just did it from memory and did it wrong. The correct notation is super(type, obj) not super(obj, parent) lol. I rarely need to worry about the parameters because I code in Python3 and have yet to need multiple inheritance. super().__init__ works fine for every use case I've had personally, but no reason not to be explicit when I'm not sure of OP's use case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.