# Extra Questions class Link: """ >>> s = Link(1, Link(2, Link(3))) >>> s Link(1, Link(2, Link(3))) >>> len(s) 3 >>> s[2] 3 >>> s = Link.empty >>> len(s) 0 """ empty = () def __init__(self, first, rest=empty): assert rest is Link.empty or isinstance(rest, Link) self.first = first self.rest = rest def __repr__(self): if self.rest is Link.empty: return 'Link({})'.format(self.first) else: return 'Link({}, {})'.format(self.first, repr(self.rest)) def __len__(self): """ Return the number of items in the linked list. >>> s = Link(1, Link(2, Link(3))) >>> len(s) 3 >>> s = Link.empty >>> len(s) 0 """ return 1 + len(self.rest) def __getitem__(self, i): """Returning the element found at index i. >>> s = Link(1, Link(2, Link(3))) >>> s[1] 2 >>> s[2] 3 """ if i == 0: return self.first else: return self.rest[i-1] def __setitem__(self, index, element): """Sets the value at the given index to the element >>> s = Link(1, Link(2, Link(3))) >>> s[1] = 5 >>> s Link(1, Link(5, Link(3))) >>> s[4] = 5 Traceback (most recent call last): ... IndexError """ if index == 0: self.first = element elif self.rest is Link.empty: raise IndexError else: self.rest[index - 1] = element def __contains__(self, e): return self.first == e or e in self.rest def map(self, f): self.first = f(self.first) if self.rest is not Link.empty: self.rest.map(f) # Q4 def __add__(self, other): """Adds two Links, returning a new Link >>> Link(1, Link(2)) + Link(3, Link(4, Link(5))) Link(1, Link(2, Link(3, Link(4, Link(5))))) """ "*** YOUR CODE HERE ***" # Q5 def __reversed__(self): """Return a reversed version of the Link. >>> reversed(Link(1, Link(2, Link(3)))) Link(3, Link(2, Link(1))) """ "*** YOUR CODE HERE ***" # Q6 def __str__(self): """Returns a human-readable string representation of the Link >>> s = Link(1, Link(2, Link(3, Link(4)))) >>> str(s) '<1, 2, 3, 4>' >>> str(Link(1)) '<1>' >>> str(Link.empty) # empty tuple '()' """ "*** YOUR CODE HERE ***" # Q8 class IteratorRestart: """ >>> iterator = IteratorRestart(2, 7) >>> for num in iterator: ... print(num) 2 3 4 5 6 7 >>> for num in iterator: ... print(num) 2 3 4 5 6 7 """ def __init__(self, start, end): "*** YOUR CODE HERE ***" def __next__(self): "*** YOUR CODE HERE ***" def __iter__(self): "*** YOUR CODE HERE ***" # Q9 class Str: """ >>> s = Str("hello") >>> for char in s: ... print(char) ... h e l l o >>> for char in s: # a standard iterator does not restart ... print(char) """ "*** YOUR CODE HERE ***"