import json from random import random class team: def __init__(self,na,totalgames): self.wins = 0 self.losses = 0 self.gamesleft = totalgames self.name = na # constructor def win(self): # method that records a win self.wins += 1 self.gamesleft -= 1 # win def lose(self): # method that records a loss self.losses += 1 self.gamesleft -=1 # lose def percentage(self): # calculate the team's winning percentage gamesplayed = self.wins + self.losses if gamesplayed==0: return 0 # don't divide by zero! return self.wins/(gamesplayed *1.0) # *1.0 to make it a float # percentage def project(self): # project the win-loss record of the entire seaon wp = self.percentage() # call percentage to get current percentage totalgames = self.wins + self.losses + self.gamesleft predictedwins = int(wp * totalgames) predictedlosses = totalgames - predictedwins return (predictedwins, predictedlosses) # project # note how percentage is called from within this function. def betterthan(myteam,yourteam): # see if myteam's perentage is better mp = myteam.percentage() yp = yourteam.percentage() return (mp > yp) # returns True or False # betterthan def play(myteam,yourteam): # self=myteam if random()<0.5: myteam.win() yourteam.lose() #print("I win, you suck") else: myteam.lose() yourteam.win() #print("You win, but you still suck") #play def __str__(self): # overrides default string representation return self.name+" has "+str(self.wins)+" wins and "+str(self.losses)+" losses with "+str(self.gamesleft)+" games to play" def serialize(self): # construct json-compatible serialization self.rep = {} # use dictionary self.rep["CLASS"] = "team" # store type info of object self.rep["Name"] = self.name self.rep["Wins"] = self.wins self.rep["Losses"] = self.losses self.rep["Gamestoplay"] = self.gamesleft return json.dumps(self.rep) # return a string but dict kept as self.rep # if there are pointers to other objects, you will have to call # their method to serialize them as well # end class team def team_deserialize(jsrep): # this is outside the method rep = json.loads(jsrep) # convert string to dictionary if ("CLASS" in rep) and rep["CLASS"]=="team": newteam = team(rep["Name"],rep["Gamestoplay"]) newteam.wins = rep["Wins"] newteam.losses = rep["Losses"] return newteam else: raise Exception("not a serialization of class team") # deserialize t1 = team("mets",162) t2 = team("yankees",162) for i in range(0,162): t1.play(t2) jrep = t1.serialize() print(jrep) t3 = team_deserialize(jrep) # note way this is called print(t3) """ Now we need to ask an important question: why not just use a dictionary (hash map) to represent the object in the first place. Why bother with a class. Isn't the difference just a matter of notation: """ myaccount = {"name":"prof", "balance":100, "TYPE":"account"} def withdraw(account,amt): account["balance"] -= amt def inquiry(account): return account["balance"] # etc... # If an object is just a collection of data, can't we just do the same # thing with a dictionary? I will have to write withdraw(myaccount,50) # instead of myaccount.withdraw(50). Is that really the only difference? # Why exactly is OOP so important then? The answer is that it isn't, # until we have many different types of objects and these objects are # related by INHERITANCE. # Now consider a team that can tie: class tieteam(team): # a tieteam is a team that can tie, win and lose def __init__(self,na,tg): team.__init__(self,na,tg) # calls "superclass" constructor team.ties = 0 # additional attribute of a tieteam # subclass constructor def tie(self): # additional method to win() and lose() self.gamesleft -= 1 self.ties += 1 # tie def percentage(self): # OVERRIDES superclass method games = self.wins + self.losses + self.ties if games==0: return 0.0 else: return (self.wins + 0.5*self.ties)/games # new percentage method: NOW THERE ARE TWO METHODS CALLED PERCENTAGE def play(self,other): if not(isinstance(other,tieteam)): return r = random() if r<0.49: myteam.win() yourteam.lose() #print("I win, you suck") elif r>.51 : myteam.lose() yourteam.win() #print("You win, but you still suck") else: myteam.tie() yourteam.tie() #print("we both suck") # new play method overrides team.play def serialize(self): team.serialize(self) # calls superclass version of method first self.rep["Ties"] = self.ties self.rep["CLASS"] = "tieteam" # serialize # class tieteam # def deserialize... how do I inherit existing code? NYETS = [team("mets",162), tieteam("jets",16), team("nets",82)] NYETS[0].win() NYETS[1].tie() NYETS[2].lose() for t in NYETS: print(t.percentage()) print(NYETS[0].betterthan(NYETS[1])) # which percentage() functions are called?