编程辅导 CSC148, Winter 2022

“””Assignment 2: Society Hierarchy (all tasks)

CSC148, Winter 2022

Copyright By PowCoder代写 加微信 powcoder

This code is provided solely for the personal and private use of students
taking the CSC148 course at the University of Toronto. Copying for purposes
other than this use is expressly prohibited. All forms of distribution of this
code, whether as given or with any changes, are expressly prohibited.

Authors: , , , , and

All of the files in this directory and all subdirectories are:
Copyright (c) 2022 , , , , and

=== Module description ===
This module contains all of the classes necessary to model the entities in a
society’s hierarchy.

REMINDER: You must NOT use list.sort() or sorted() in your code. Instead, use
the merge() function we provide for you below.
from __future__ import annotations
from typing import List, Optional, TextIO, Any

def merge(lst1: list, lst2: list) -> list:
“””Return a sorted list with the elements in and .

Preconditions:
> is sorted and is sorted.
– All of the elements of and are of the same type, and they
are comparable (i.e. their type implements __lt__).

>>> merge([1, 2, 5], [3, 4, 6])
[1, 2, 3, 4, 5, 6]

new_list = []

while i1 < len(lst1) and i2 < len(lst2): if lst1[i1] < lst2[i2]: new_list.append(lst1[i1]) new_list.append(lst2[i2]) new_list.extend(lst1[i1:]) new_list.extend(lst2[i2:]) return new_list ########################################################################### # TODO Task 1: Citizen and Society ########################################################################### class Citizen: """A Citizen: a citizen in a Society. === Public Attributes === The ID number of this citizen. manufacturer: The manufacturer of this Citizen. model_year: The model year of this Citizen. The name of this Citizen's job within the Society. The rating of this Citizen. === Private Attributes === _superior: The superior of this Citizen in the society, or None if this Citizen does not have a superior. _subordinates: A list of this Citizen's direct subordinates (that is, Citizens that work directly under this Citizen). === Representation Invariants === - 0 <= rating <= 100 - self._subordinates is in ascending order by the subordinates' IDs - If _superior is a Citizen, this Citizen is part of its _subordinates list - Each Citizen in _subordinates has this Citizen as its _superior manufacturer: str model_year: int rating: int _superior: Optional[Citizen] _subordinates: List[Citizen] def __init__(self, cid: int, name: str, model_year: int, job: str, rating: int) -> None:
“””Initialize this Citizen with the ID , manufacturer
, model year , job , and rating .

A Citizen initially has no superior and no subordinates.

>>> c1 = Citizen(1, “Starky Industries”, 3042, “Labourer”, 50)
>>> c1.cid
>>> c1.rating
self.cid = cid
self.manufacturer = name
self.model_year = model_year
self.job = job
self.rating = rating
self._superior = None
self._subordinates = []

def __lt__(self, other: Any) -> bool:
“””Return True if is a Citizen and this Citizen’s cid is less
than ‘s cid.

If other is not a Citizen, raise a TypeError.

>>> c1 = Citizen(1, “Starky Industries”, 3042, “Labourer”, 50)
>>> c2 = Citizen(2, “Hookins National Lab”, 3042, “Manager”, 30)
>>> c1 < c2 if not isinstance(other, Citizen): raise TypeError return self.cid < other.cid def __str__(self) -> str:
“””Return a string representation of the tree rooted at this Citizen.
return self._str_indented().strip()

def _str_indented(self, depth: int = 0) -> str:
“””Return an indented string representation of this tree.

The indentation level is specified by the parameter.
me = f'{str(self.cid)} (rating = {self.rating})’
if isinstance(self, DistrictLeader):
me += f’ –> District Leader for {self._district_name}’
s = ‘ ‘ * depth + me + ‘\n’
for subordinate in self.get_direct_subordinates():
# Note that the ‘depth’ argument to the recursive call is
# modified.
s += subordinate._str_indented(depth + 1)

def get_superior(self) -> Optional[Citizen]:
“””Return the superior of this Citizen or None if no superior exists.

>>> c1 = Citizen(1, “Starky Industries”, 3024, “Labourer”, 50)
>>> c1.get_superior() is None
>>> c2 = Citizen(2, “Hookins National Lab”, 3024, “Manager”, 30)
>>> c1.become_subordinate_to(c2)
>>> c1.get_superior().cid
return self._superior

def set_superior(self, new_superior: Optional[Citizen]) -> None:
“””Update the superior of this Citizen to

>>> c1 = Citizen(1, “Starky Industries”, 3024, “Labourer”, 50)
>>> c2 = Citizen(2, “Hookins National Lab”, 3024, “Manager”, 30)
>>> c1.set_superior(c2)
>>> c1.get_superior().cid
self._superior = new_superior

def get_direct_subordinates(self) -> List[Citizen]:
“””Return a new list containing the direct subordinates of this Citizen.

>>> c1 = Citizen(1, “Starky Industries”, 3024, “Labourer”, 50)
>>> c2 = Citizen(2, “Hookins National Lab”, 3024, “Manager”, 30)
>>> c3 = Citizen(3, “S.T.A.R.R.Y Lab”, 3010, “Commander”, 60)
>>> c1.become_subordinate_to(c2)
>>> c2.become_subordinate_to(c3)
>>> c3.get_direct_subordinates()[0].cid
return self._subordinates[:]

###########################################################################
# TODO Task 1.1 (Helper methods)
# While not called by the client code, these methods may be helpful to
# you and will be tested. You can (and should) call them in the other
# methods that you implement when appropriate.
###########################################################################

def add_subordinate(self, subordinate: Citizen) -> None:
“””Add to this Citizen’s list of direct subordinates,
keeping the list of subordinates in ascending order by their ID.

Update the new subordinate’s superior to be this Citizen.

>>> c1 = Citizen(1, “Starky Industries”, 3024, “Labourer”, 50)
>>> c2 = Citizen(2, “Hookins National Lab”, 3024, “Manager”, 30)
>>> c2.add_subordinate(c1)
>>> c2.get_direct_subordinates()[0].cid
>>> c1.get_superior() is c2

def remove_subordinate(self, cid: int) -> None:
“””Remove the subordinate with the ID from this Citizen’s list
of subordinates.

Furthermore, remove that (former) subordinate from the hierarchy by
setting its superior to None.

Precondition: This Citizen has a subordinate with ID .

>>> c1 = Citizen(1, “Starky Industries”, 3024, “Labourer”, 50)
>>> c2 = Citizen(2, “Hookins National Lab”, 3024, “Manager”, 30)
>>> c1.become_subordinate_to(c2)
>>> c2.get_direct_subordinates()[0].cid
>>> c2.remove_subordinate(1)
>>> c2.get_direct_subordinates()
>>> c1.get_superior() is None

def become_subordinate_to(self, superior: Optional[Citizen]) -> None:
“””Make this Citizen a direct subordinate of .

If this Citizen already had a superior, remove this Citizen from the
old superior’s list of subordinates.

If is None, just set this Citizen’s superior to None.

>>> c1 = Citizen(1, “Starky Industries”, 3024, “Labourer”, 50)
>>> c2 = Citizen(2, “Hookins National Lab”, 3024, “Manager”, 30)
>>> c1.become_subordinate_to(c2)
>>> c1.get_superior().cid
>>> c2.get_direct_subordinates()[0].cid
>>> c1.become_subordinate_to(None)
>>> c1.get_superior() is None
>>> c2.get_direct_subordinates()

def get_citizen(self, cid: int) -> Optional[Citizen]:
“””Check this Citizen and its subordinates to find and return the
Citizen that has the ID .

If neither this Citizen nor any of its subordinates (both direct and
indirect) have the ID , return None.

>>> c1 = Citizen(1, “Starky Industries”, 3024, “Labourer”, 50)
>>> c2 = Citizen(2, “Hookins National Lab”, 3024, “Manager”, 30)
>>> c3 = Citizen(3, “S.T.A.R.R.Y Lab”, 3010, “Commander”, 60)
>>> c1.become_subordinate_to(c2)
>>> c2.become_subordinate_to(c3)
>>> c3.get_citizen(1) is c1
>>> c2.get_citizen(3) is None
# Note: This method must call itself recursively

###########################################################################
# TODO Task 1.2
###########################################################################

def get_all_subordinates(self) -> List[Citizen]:
“””Return a new list of all of the subordinates of this Citizen in
order of ascending IDs.

>>> c1 = Citizen(1, “Starky Industries”, 3024, “Labourer”, 50)
>>> c2 = Citizen(2, “Hookins National Lab”, 3024, “Manager”, 30)
>>> c3 = Citizen(3, “S.T.A.R.R.Y Lab”, 3010, “Commander”, 60)
>>> c1.become_subordinate_to(c2)
>>> c2.become_subordinate_to(c3)
>>> c3.get_all_subordinates()[0].cid
>>> c3.get_all_subordinates()[1].cid
# Note: This method must call itself recursively

# – Recall that each Citizen’s subordinates list is sorted in ascending
# order.
# – Use the merge helper function.

def get_society_head(self) -> Citizen:
“””Return the head of the Society (i.e. the top-most superior Citizen,
a.k.a. the root of the hierarchy).

>>> c1 = Citizen(1, “Starky Industries”, 3024, “Labourer”, 50)
>>> c2 = Citizen(2, “Hookins National Lab”, 3024, “Manager”, 30)
>>> c3 = Citizen(3, “S.T.A.R.R.Y Lab”, 3010, “Commander”, 60)
>>> c1.become_subordinate_to(c2)
>>> c2.become_subordinate_to(c3)
>>> c1.get_society_head().cid
# Note: This method must call itself recursively

def get_closest_common_superior(self, cid: int) -> Citizen:
“””Return the closest common superior that this Citizen and the
Citizen with ID share.

If this Citizen is the superior of , return this Citizen.

>>> c1 = Citizen(1, “Starky Industries”, 3024, “Labourer”, 50)
>>> c2 = Citizen(2, “Hookins National Lab”, 3024, “Manager”, 30)
>>> c3 = Citizen(3, “S.T.A.R.R.Y Lab”, 3010, “Commander”, 60)
>>> c4 = Citizen(4, “Starky Industries”, 3022, “Manager”, 55)
>>> c5 = Citizen(5, “Hookins National Lab”, 3023, “Engineer”, 50)
>>> c1.become_subordinate_to(c2)
>>> c2.become_subordinate_to(c3)
>>> c4.become_subordinate_to(c3)
>>> c5.become_subordinate_to(c4)
>>> c3.get_closest_common_superior(1) == c3
>>> c3.get_closest_common_superior(3) == c3
>>> c1.get_closest_common_superior(5) == c3
# Note: This method must call itself recursively

###########################################################################
# TODO Task 2.2
###########################################################################
def get_district_name(self) -> str:
“””Return the immediate district that the Citizen belongs to (or

If the Citizen is not part of any districts, return an empty string.

>>> c1 = Citizen(1, “Starky Industries”, 3024, “Labourer”, 50)
>>> c2 = DistrictLeader(2, “Hookins National Lab”, 3024, “Manager”, \
30, “District A”)
>>> c1.get_district_name()
>>> c1.become_subordinate_to(c2)
>>> c1.get_district_name()
‘District A’
# Note: This method must call itself recursively

def rename_district(self, district_name: str) -> None:
“””Rename the immediate district which this Citizen is a part of to
.

If the Citizen is not part of a district, do nothing.

>>> c1 = Citizen(1, “Starky Industries”, 3024, “Labourer”, 50)
>>> c2 = DistrictLeader(2, “Hookins National Lab”, 3024, “Manager”, \
30, “District A”)
>>> c1.become_subordinate_to(c2)
>>> c1.rename_district(‘District B’)
>>> c1.get_district_name()
‘District B’
>>> c2.get_district_name()
‘District B’
# Note: This method must call itself recursively

###########################################################################
# TODO Task 3.2 Helper Method
###########################################################################
def get_highest_rated_subordinate(self) -> Citizen:
“””Return the direct subordinate of this Citizen with the highest

Precondition: This Citizen has at least one subordinate.

>>> c1 = Citizen(1, “Starky Industries”, 3024, “Labourer”, 50)
>>> c2 = DistrictLeader(2, “Hookins National Lab”, 3024, “Manager”, 30,
… “District A”)
>>> c3 = DistrictLeader(3, “S.T.A.R.R.Y Lab”, 3000, “Commander”, 60,
… “District X”)
>>> c1.become_subordinate_to(c2)
>>> c2.become_subordinate_to(c3)
>>> c3.get_highest_rated_subordinate().manufacturer
‘Hookins National Lab’
>>> c1.become_subordinate_to(c3)
>>> c3.get_highest_rated_subordinate().manufacturer
‘Starky Industries’
# Hint: This can be used as a helper function for `delete_citizen`

class Society:
“””A society containing citizens in a hierarchy.

=== Private Attributes ===
The root of the hierarchy, which we call the “head” of the Society.
If _head is None, this indicates that this Society is empty (there are
no citizens in this Society).

=== Representation Invariants ===
– No two Citizens in this Society have the same cid.
_head: Optional[Citizen]

def __init__(self, head: Optional[Citizen] = None) -> None:
“””Initialize this Society with the head .

>>> o = Society()
>>> o.get_head() is None
self._head = head

def __str__(self) -> str:
“””Return a string representation of this Society’s tree.

For each node, its item is printed before any of its descendants’
items. The output is nicely indented.

You may find this method helpful for debugging.
return str(self._head)

###########################################################################
# You may use the methods below as helper methods if needed.
###########################################################################
def get_head(self) -> Optional[Citizen]:
“””Return the head of this Society.
return self._head

def set_head(self, new_head: Citizen) -> None:
“””Set the head of this Society to .
self._head = new_head

###########################################################################
# TODO Task 1.3
###########################################################################
def get_citizen(self, cid: int) -> Optional[Citizen]:
“””Return the Citizen in this Society who has the ID . If no such
Citizen exists, return None.

>>> o = Society()
>>> c1 = Citizen(1, “Starky Industries”, 3024, “Labourer”, 50)
>>> o.add_citizen(c1)
>>> o.get_citizen(1) is c1
>>> o.get_citizen(2) is None
# Hint: Recall that self._head is a Citizen object, so any of Citizen’s
# methods can be used as a helper method here.

def get_all_citizens(self) -> List[Citizen]:
“””Return a list of all citizens, in order of increasing cid.

>>> o = Society()
>>> c1 = Citizen(1, “Starky Industries”, 3024, “Manager”, 50)
>>> c2 = Citizen(2, “Hookins National Lab”, 3024, “Manager”, 65)
>>> c3 = Citizen(3, “Starky Industries”, 3024, “Labourer”, 50)
>>> c4 = Citizen(4, “S.T.A.R.R.Y Lab”, 3024, “Manager”, 30)
>>> c5 = Citizen(5, “Hookins National Lab”, 3024, “Labourer”, 50)
>>> c6 = Citizen(6, “S.T.A.R.R.Y Lab”, 3024, “Lawyer”, 30)
>>> o.add_citizen(c4, None)
>>> o.add_citizen(c2, 4)
>>> o.add_citizen(c6, 2)
>>> o.add_citizen(c1, 4)
>>> o.add_citizen(c3, 1)
>>> o.add_citizen(c5, 1)
>>> o.get_all_citizens() == [c1, c2, c3, c4, c5, c6]

def add_citizen(self, citizen: Citizen, superior_id: int = None) -> None:
“””Add to this Society as a subordinate of the Citizen with
ID .

If no is provided, make the new head of this
Society, with the original head becoming the one and only subordinate
of .

Preconditions:
– citizen.get_superior() is None.
– if is not None, then the Society contains a Citizen with
ID .
– Society does not already contain any Citizen with the same ID as
.

>>> o = Society()
>>> c1 = Citizen(1, “Starky Industries”, 3024, “Labourer”, 50)
>>> c2 = Citizen(2, “Some Lab”, 3024, “Lawyer”, 30)
>>> o.add_citizen(c2)
>>> o.get_head() is c2
>>> o.add_citizen(c1, 2)
>>> o.get_head() is c2
>>> o.get_citizen(1) is c1
>>> c1.get_superior() is c2

def get_citizens_with_job(self, job: str) -> List[Citizen]:
“””Return a list of all citizens with the job , in order of
increasing cid.

>>> o = Society()
>>> c1 = Citizen(1, “Starky Industries”, 3024, “Manager”, 50)
>>> c2 = Citizen(2, “Hookins National Lab”, 3024, “Manager”, 65)
>>> c3 = Citizen(3, “Starky Industries”, 3024, “Labourer”, 50)
>>> c4 = Citizen(4, “S.T.A.R.R.Y Lab”, 3024, “Manager”, 30)
>>> c5 = Citizen(5, “Hookins National Lab”, 3024, “Labourer”, 50)
>>> c6 = Citizen(6, “S.T.A.R.R.Y Lab”, 3024, “Lawyer”, 30)
>>> o.add_citizen(c4, None)
>>> o.add_citizen(c2, 4)
>>> o.add_citizen(c6, 2)
>>> o.add_citizen(c1, 4)
>>> o.add_citizen(c3, 1)
>>> o.add_citizen(c5, 1)
>>> o.get_citizens_with_job(‘Manager’) == [c1, c2, c4]

###########################################################################
# TODO Task 2.3
###########################################################################
def change_citizen_type(self, cid: int,
district_name: Optional[str] = None) -> Citizen:
“””Change the type o

程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com