"""CSC111 Winter 2023 Assignment 3: Graphs and Interconnection Networks Instructions (READ THIS FIRST!) =============================== This Python module contains the start of three network classes you'll define for Part 1 of this assignment. You may, but are not required, to add doctest examples to check your work for this part of the assignment (and all other parts). Copyright and Usage Information =============================== This file is provided solely for the personal and private use of students taking CSC111 at the University of Toronto St. George campus. All forms of distribution of this code, whether as given or with any changes, are expressly prohibited. For more information on copyright for CSC111 materials, please consult our Course Syllabus. This file is Copyright (c) 2023 Mario Badr and David Liu. """ from python_ta.contracts import check_contracts # NOTE: Node and NodeAddress must be imported for check_contracts # to work correctly, even if they aren't being used directly in this # module. Don't remove them (even if you get a warning about them in PyCharm)! from a3_network import AbstractNetwork, Node, NodeAddress @check_contracts class AbstractRing(AbstractNetwork): """An abstract network with a ring topology. See the assignment handout for a description of this and other network topologies you're implementing. Representation Invariants: - all(isinstance(address, int) for address in self._nodes) """ def __init__(self, k: int) -> None: """Initialize this network with a ring topology of radix k. Preconditions: - k >= 3 """ super().__init__() # This equivalent to AbstractNetwork.__init__(self). (PyCharm causes issue.) for i in range(k): # I actually don't need this since channel adds automatically. self.add_node(i) for i in range(k): left_neighbour = (i - 1) % k right_neighbour = (i + 1) % k self.add_channel(i, left_neighbour) self.add_channel(i, right_neighbour) @check_contracts class AbstractTorus(AbstractNetwork): """An abstract network with a torus topology. See the assignment handout for a description of this and other network topologies you're implementing. Representation Invariants: - all(isinstance(address, tuple) for address in self._nodes) """ def __init__(self, k: int) -> None: """Initialize this network with a torus topology of radix k. Preconditions: - k >= 3 """ super().__init__() for i in range(k): # Not needed. for j in range(k): self.add_node((i, j)) for i in range(k): for j in range(k): left_neighbour = ((i - 1) % k, j) right_neighbour = ((i + 1) % k, j) up_neighbour = (i, (j - 1) % k) down_neighbour = (i, (j + 1) % k) self.add_channel((i, j), left_neighbour) self.add_channel((i, j), right_neighbour) self.add_channel((i, j), up_neighbour) self.add_channel((i, j), down_neighbour) @check_contracts class AbstractStar(AbstractNetwork): """An abstract network with a star topology. A star topology has k1 central nodes that are all adjacent to each other and k2 outer nodes that are each adjacent to all central nodes. See the assignment handout for a description of this and other network topologies you're implementing. Private Instance Attributes (in addition to _nodes from AbstractNetwork): - _num_central: the number of central nodes - _num_outer: the number of outer nodes Representation Invariants: - all(isinstance(address, int) for address in self._nodes) - self._num_central >= 1 - self._num_outer >= 1 """ _num_central: int _num_outer: int def __init__(self, k1: int, k2: int) -> None: """Initialize this network with a star topology of k1 central nodes and k2 outer nodes. Preconditions: - k1 >= 1 - k2 >= 1 Implementation note: - In addition to initialzing self._nodes, make sure to initialize the other two instance attributes described in the class docstring. """ super().__init__() self._num_central = k1 # Gotta initalize according to Imple. note. self._num_outer = k2 for i in range(k1 + k2): # Again, not needed for same reason. But the whole point is to initalize. self.add_node(i) for i in range(k1): for j in range(i + 1, k1): # address1 != address2 self.add_channel(i, j) for i in range(k1): for j in range(k1, k1 + k2): self.add_channel(i, j) if __name__ == '__main__': import doctest doctest.testmod(verbose=True) # When you are ready to check your work with python_ta, uncomment the following lines. # (In PyCharm, select the lines below and press Ctrl/Cmd + / to toggle comments.) # You can use "Run file in Python Console" to run PythonTA, # and then also test your methods manually in the console. import python_ta python_ta.check_all(config={ 'max-line-length': 120, 'extra-imports': ['a3_network'], 'disable': ['abstract-method', 'unused-import'] })