Introduction to Computer Science Through Programming
Smith Computer Science
Sometimes we want to build a complex relationship between elements by saving data and functions that modify it.
For example, Say we want to build a Fruit-Focused-Social-Network called Fruit-Buddy, or FB
A simple sketch would look like this:
Since we want to Represent people and their interests with data, there are a LOT of ways to construct these complex objects (using id's, names, ...)
We could use the existing lists, tuples, and dictionaries, but sometimes that gets a little cumbersome.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | # constructing social network FB: Fruit Buddies def main(): # tuple with: user id; name; favorite thing u_data = (101, "Alice", "Apples") u_contacts = [] FB_user_01 = [u_data, u_contacts] u_data = (102, "Bob", "Bananas") u_contacts = [] FB_user_02 = [u_data, u_contacts] u_data = (103, "Cathy", "Clementines") u_contacts = [] FB_user_03 = [u_data, u_contacts] u_data = (104, "Dan", "Dates") u_contacts = [] FB_user_04 = [u_data, u_contacts] # first way to add buddies FB_user_01[1].extend([101, 102, 103]) FB_user_02[1].extend([101, 102, 103]) # second way to add buddies add_buddy(FB_user_03, FB_user_02) add_buddy(FB_user_03, FB_user_03) add_buddy(FB_user_04, FB_user_04) FB_users = [FB_user_01, FB_user_02, FB_user_03, FB_user_04] print_buddies(FB_users) #adding user2's id to user1's list of id-buddies def add_buddy(user1, user2): user1[1].extend([user2[0][0]]) # prints all networked friends def print_buddies(all_users): for user in all_users: print("Buddies of {} :".format(user[0][1]), end = " ") for id in user[1]: print(id, end=" ") if len(user[1]) == 1: if user[1][0] == user[0][0]: print ("** Sad Trombone **") print() if __name__ == "__main__": main() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | class Fruit_Buddy: def __init__(self, id, name, fav_fruit, buddy_list): self.id = id self.name = name self.fav_fruit = fav_fruit self.buddies = buddy_list def add_buddy(self,other): # adding the other's id (this can be made better!) self.buddies.append(other.id) def add_buddy_list(self,buddy_list): for bud in buddy_list: self.add_buddy(bud) def print_buddies(self): print("Buddies of {} :".format(self.name), end = " ") for bud in self.buddies: print(bud, end=" ") if len(self.buddies) == 1: if self.buddies[0] == self.id: print ("** Sad Trombone **") print() # constructing social network FB: Fruit Buddies def main(): # the constructor can be improved with default vals FB_user_01 = Fruit_Buddy(101, "Alice", "Apples",[]) FB_user_02 = Fruit_Buddy(102, "Bob", "Bananas",[]) FB_user_03 = Fruit_Buddy(103, "Cathy", "Clementines",[]) FB_user_04 = Fruit_Buddy(104, "Dan", "Dates",[]) # first way to add buddies FB_user_01.add_buddy_list([FB_user_01, FB_user_02, FB_user_03]) FB_user_02.add_buddy_list([FB_user_01, FB_user_02, FB_user_03]) FB_user_03.add_buddy_list([FB_user_02, FB_user_03]) FB_user_04.add_buddy_list([FB_user_04]) FB_user_01.print_buddies() FB_user_02.print_buddies() FB_user_03.print_buddies() FB_user_04.print_buddies() if __name__ == "__main__": main() |
One may add default values to the class attributes by assigning them to the __init__ method's attributes,
However, you must place the parmeters with default values AFTER those without (right to left)
For example (DONT ADD TO THE RUNNING CODE YET):
def __init__(self, buddy_list=None, id=-1, name="NA", fav_fruit="meh"): self.id = id self.name = name self.fav_fruit = fav_fruit if buddy_list == None: self.buddies = [] else: self.buddies = buddy_list |
The calls in lines 30-33 MUST have the order of arguments in the new order!!!
Let's NOT change that now, but consider using default values for your own constructors.
Note that when adding a buddy, we can do much more than just add the id!
We can add the whole Fruit_Buddy reference as a buddy!
Activity 3 [5 minutes]:
def add_buddy(self,other): # adding the other's id (this can be made better!) self.buddies.append(other) #<-- updated here
def print_buddies(self): print("Buddies of {} :".format(self.name), end = " ") for bud in self.buddies: print(bud.name, end=" ") #<-- updated here if len(self.buddies) == 1: if self.buddies[0] == self.id: print ("** Sad Trombone **") print()
def main(): # the constructor can be improved with default vals FB_users = [] FB_users.append( Fruit_Buddy(101, "Alice", "Apples",[]) ) FB_users.append( Fruit_Buddy(102, "Bob", "Bananas",[]) ) FB_users.append( Fruit_Buddy(103, "Cathy", "Clementines",[]) ) FB_users.append( Fruit_Buddy(104, "Dan", "Dates",[]) ) # first way to add buddies FB_users[0].add_buddy_list([FB_users[0], FB_users[1], FB_users[2]]) FB_users[1].add_buddy_list([FB_users[0], FB_users[1], FB_users[2]]) FB_users[2].add_buddy_list([FB_users[1], FB_users[2]]) FB_users[3].add_buddy_list([FB_users[2]]) for bud in FB_users: bud.print_buddies()
Activity 4 [2 minutes]:
def remove_buddy(self,other): for bud in self.buddies: if bud == other: self.buddies.remove(bud) self.remove_as_buddy(other) def remove_as_buddy(self,other): other.remove_buddy(self)
We'll reproduce this example: With Dogs!
Check out the method Speak in the example above
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | class Character: def __init__(self, name="NA", player="NPC", health = 10, focus = 10): self.name = name self.player = player self.health = health self.focus = focus def print_char(self): print("{}, played by {}, has {} health and {} focus left".format(self.name, self.player, self.health, self.focus)) def apply_damage(self,damage): if self.health <= damage: self.health = 0 print ("AArrghhh! ... ** {} has died **".format(self.name)) else: self.health -= damage def apply_charm(self,charm): if self.focus <= charm: self.focus = 0 print ("Oooohhh! ... ** {} has been charmed **".format(self.name)) else: self.focus -= charm class Warrior(Character): def __init__(self,name="NA", player="NPC", health = 10, focus = 10, weapon = "punch", damage = 1): Character.__init__(self,name, player, health, focus) self.weapon = weapon self.damage = damage def set_weapon (self, weapon = "punch", damage = 1): self.weapon = weapon self.damage = damage def use_weapon(self,other): other.apply_damage(self.damage) class Bard(Character): def __init__(self,name="NA", player="NPC", health = 10, focus = 10, instrument = "voice", charm = 1): Character.__init__(self,name, player, health, focus) self.instrument = instrument self.charm = charm def set_instrument (self, instrument = "voice", charm = 1): self.instrument = instrument self.charm = charm def use_instrument(self,other): other.apply_charm(self.charm) def main(): c1 = Warrior("Orkhina", "Mariana", 20, 5) c1.set_weapon("Axe",5) c2 = Bard("Elfrank", "Pablo", 6, 20) c2.set_instrument("Flute", 10) c1.use_weapon(c2) c2.print_char() c2.use_instrument(c1) c1.print_char() if __name__ == "__main__": main() |
Check out this article on Inheritance
Also this one with a Polymorphism