Solutions Protocol exercises
Ex 1: Deck of Cards
1# deck_solution.py
2
3"""
4implement the:
5
6 __len__ method
7 __add__ method
8 __repr__ method
9 __str__ method
10 __setitem__ method
11 __delitem__ method
12"""
13
14class Deck:
15 def __init__(self):
16 self.cards = ['A', 'K', 4, 7]
17
18
19 def __getitem__(self, key):
20 return self.cards[key]
21
22 def __setitem__(self, key, val):
23 self.cards[key] = val
24
25
26 def __delitem__(self, key):
27 del(self.cards[key])
28
29 def __len__(self):
30 return len(self.cards)
31
32
33 def __add__(self, other):
34 return self.cards + other.cards
35
36 def __repr__(self):
37 return str(self.cards)
38
39 def __str__(self):
40 return str(self.cards)
Ex 2: Jelly Beans
1
2"""
3 Imagine a game where different sizes of jelly beans are floating around.
4 When they bump into each other they melt together and one of them gain mass the other looses mass.
5
6 The old one does not dissapear but its mass becomes 0 (maybe a little gas like state or a ghost).
7
8 If your main Jelly Bean hits a ghost jelly bean, the ghost jelly bean should regain its original state, and the mass of that should be deducted from your main Jelly Bean (it will shrink in size).
9
10 Some Ghost Jellies are born ghosts. If you hit one of these, half of your mass will be stolen by that ghost.
11
12 The game is won when your jelly bean is the only one with a mass.
13 The Game is lost if you do not have any more mass.
14
15 YOUR JOB IS NOT TO CREATE THIS GAME, but to create a class that can be used in this game by someone else.
16 Your job is also to write pythonic code, using python protocols, properties, overloading etc.
17
18 SO:
19
20 Create a Jelly class.
21 When initialized you will create a jelly bean with a mass.
22 You should be able to add 2 or more jelly beans together thus the mass of the one of them will increese.
23 The mass of the other one will be 0, and should not remember its former state.
24
25 The class should also be able to deduct 2 jelly beans. If a gas like jelly bean hit your jelly bean it should regain its former mass and yours should decrease.
26
27 The object should be able to when asked tell its state.
28
29 X-tra assignemnets:
30 The "gas like Jelly Beans" will over time gain a little mass. Small jelly fragments are lying around and can be added with the plus operator to. the fragments are not objects of the Jelly Bean Class but of another more simple class called Jelly_fragment. This class has a fixed mass of 1, and it should not be changed. If the Jelly Bean "Ghost" at some poit regain they old mass they are only allowed to keep "over time gained mass" corosponding to 2% of the original mass. If it succeceds it is discarded.
31
32 Add the functionallity of being able to write this code in the client.
33 val = j2 in me
34 Where me and j2 are jelly objects
35
36 You can already write j == j2 -> and get a return value of True or False. Create an implementation that when writing j == j2 checks if the mass of the 2 objects are alike.
37
38
39"""
40
41
42class Jelly:
43
44 def __init__(self, mass):
45 self.mass = mass
46 self.__merge_history = {} # For saving object id and the object of the merged jelly beans {'123300668' : 80}
47
48 def __add__(self, other):
49
50 if other.mass != 0:
51 self.mass += other.mass # add mass of other to self
52 self.__merge_history[ id(other)] = other.mass # add merged object to history dictionary
53 other.mass = 0 # remove mass of other object
54 else:
55 raise Exception('The other object is a ghost and can not be added')
56
57
58 def __sub__(self, other):
59
60 if id(other) in self.__merge_history:
61 other.mass = self.__merge_history[id(other)]
62 self.mass = self.mass - other.mass
63 self.__merge_history.pop(id(other))
64 else:
65 self.mass = self.mass // 2
66 other.mass = self.mass
67
68 def __eq__(self, other):
69 if self.mass == other.mass:
70 return True
71 return False
72
73 def __contains__(self, other):
74 pass
75
76
77class Jelly_fragment:
78
79 def __init__(self):
80 Jelly_fragment.__mass = 1
81
82 @property
83 def mass(self):
84 return Jelly_fragment.__mass
85
86 def __del__(self):
87 pass
88
Ex 3: linked_list.py
1# linked_list.py (solution))
2
3# Node class
4class Node:
5
6 # Function to initialise the node object
7 def __init__(self, data):
8 self.data = data # Assign data
9 self.next = None # Initialize next as null
10
11 def __repr__(self):
12 return f'{self.__dict__}'
13
14
15
16# Linked List class contains Node objects
17class LinkedList:
18
19 def __init__(self):
20 self.head = None
21
22 def __len__(self):
23 temp = self.head
24 count = 0
25 while temp:
26 temp = temp.next
27 count += 1
28 return count
29
30 def __getitem__(self, key):
31 temp = self.head
32 count = 0
33
34 if type(key) == slice:
35 for i in range(key[0], key[1]):
36 raise NotImplementedError('To be implemented')
37
38
39 # if key/index is -x l[-1]
40 if key < 0:
41 x = len(self) + key
42 for i in range(x+1):
43 if i == x:
44 return temp
45 else:
46 temp = temp.next
47
48 else:
49 while temp:
50 if count == key:
51 return temp
52 temp = temp.next
53 count += 1
54
55 raise IndexError('index out of range')
56
57
58 def __setitem__(self, key, val):
59 if len(self) < key:
60 raise IndexError('index out of range')
61 else:
62 temp = "self.head" + ".next" * key + ".data = val"
63 exec(temp)
64
65
66 """ another option is the more direct programming approach
67 temp = self.head
68 for i in range(key+1):
69 if i == key:
70 temp.data = val
71 else:
72 temp = temp.next
73 """
74
75# Code execution starts here
76if __name__ == '__main__':
77
78 # Start with the empty list
79 llist = LinkedList()
80
81 """
82 llist.head = Node(1)
83 second = Node(2)
84 third = Node(3)
85 """
86 '''
87 Three nodes have been created.
88 We have references to these three blocks as head,
89 second and third
90
91 llist.head second third
92 | | |
93 | | |
94 +----+------+ +----+------+ +----+------+
95 | 1 | None | | 2 | None | | 3 | None |
96 +----+------+ +----+------+ +----+------+
97 '''
98
99
100 """
101
102 llist.head.next = second # Link first node with second
103 second.next = third # Link second node with the third node
104 """