Test cases as below:
$ python3 >>> from quiz_8 import * >>> Point() ... quiz_8.PointError: Need two coordinates, point not created. >>> Point(0) ... quiz_8.PointError: Need two coordinates, point not created. >>> Point(0, 0, 0) ... quiz_8.PointError: Need two coordinates, point not created. >>> Point(0, 0) Point(0, 0) >>> print(Point(1, 2)) Point of x-coordinate 1 and y-coordinate 2 >>> p1 = Point(1, 2) >>> p2 = Point(4, 8) >>> p3 = Point(2, 4) >>> Triangle(point_1=p1, point_2=p2, point_3=p3) ... quiz_8.TriangleError: Incorrect input, triangle not created. >>> p3 = Point(3, 5) >>> Triangle(p1, p2, p3) ... TypeError: __init__() takes 1 positional argument but 4 were given >>> triangle = Triangle(point_1=p1, point_2=p2, point_3=p3) >>> triangle.perimeter 13.476032868131739 >>> triangle.area 1.5000000000000078 >>> p3 = Point(2, 4) >>> triangle.change_point_or_points(p3) ... TypeError: change_point_or_points() takes 1 positional argument but 2 were given >>> triangle.change_point_or_points(point_3=p3) Incorrect input, triangle not modified. >>> triangle.perimeter 13.476032868131739 >>> triangle.area 1.5000000000000078
>>> p0 = Point(0, 0) >>> p3 = Point(0, 4) >>> triangle.change_point_or_points(point_3=p3, point_1=p0) >>> triangle.perimeter 18.60112615949154 >>> triangle.area 7.999999999999994 >>> triangle.change_point_or_points(point_2=Point(4, 0)) >>> triangle.area 7.999999999999997 >>> triangle.change_point_or_points(point_3=Point(4, 0)) Incorrect input, triangle not modified. >>> triangle.change_point_or_points(point_3=Point(4, 8)) >>> triangle.area 16.0 >>> triangle.perimeter 20.94427190999916
Descriptions:
Defines two classes, Point and Triangle.
An object of classPoint
is created by passing exactly 2 integers as arguments to__init__()
.
You can assume that nothing but integers will indeed be passed as arguments to__init__()
,
but not that exactly 2 arguments will be provided; when that is not the case, aPointError
error is raised.
The point class implements the__str__()
and__repr__()
special methods.
An object of classTriangle
is created by passing exactly 3 points as keyword only arguments to__init__()
.
You can assume that exactly three points will indeed be passed as arguments to__init__()
.
The three points should not be collinear for the triangle to be created; otherwise aTriangleError
error is raised.
A triangle object can be modified by changing one two or three points thanks to the methodchange_point_or_points()
,
all of whose arguments are keyword only. At any stage, the object maintains correct values for perimeter and area.
#Not that exactly # 2 arguments will be provided; when that is not the case, # a PointError error is raised. # The point class implements the __str__() and __repr__() # special methods. from math import sqrt from math import pow # INSERT YOUR CODE HERE class Point(): # try: # # except TypeError as e: # print('quiz_8.PointError: Need two coordinates, point not created.') def __init__(self,p1, p2): self.p1 = p1 self.p2 = p2 print('quiz_8.PointError: Need two coordinates, point not created.') def __str__(self): if p1: print('Point of x-coordinate',self.p1.x ,'and y-coordinate', self.p1.y) def __repr__(self): return # class quiz_8.PointError(): # pass class Triangle(Point): def __init__(self, point_1, point_2, point_3): self.point_1 = point_1 self.point_2 = point_2 self.point_3 = point_3 self.aa = point_distance(point_1, point_2) self.bb = point_distance(point_2, point_3) self.cc = point_distance(point_1, point_3) if point_2 == None: print('quiz_8.PointError: Need two coordinates, point not created.') if aa * bb * cc == 0 or max(aa, bb, cc) == aa + bb + cc - max(aa, bb, cc): print('quiz_8.TriangleError: Incorrect input, triangle not created.') def point_distance(self, p, pp): return math.sqrt(math.pow(p[0] - pp[0], 2) + math.pow(p[1] - pp[1], 2)) def area(self): aa = point_distance(point_1, point_2) bb = point_distance(point_2, point_3) cc = point_distance(point_1, point_3) s = (aa + bb + cc) / 2 if aa * bb * cc != 0 and max(aa, bb, cc) != aa + bb + cc - max(aa, bb, cc): return math.sqrt(s * (s - aa) * (s - bb) * (s - cc)) def perimeter(self): return aa+bb+cc def change_point_or_points(self, *p): if p : p1 = p.index(0) self.a = p.index(0) self.b = p.index(1) else: pass
Another Class to implement
# Defines a class Building that defines a few special methods, # as well as the two methods: # - go_to_floor_from_entry() # - leave_floor_from_entry() # and an atribute, number_created, to keep track of # the number of Building objects that have been created. # # Also defines a function compare_occupancies() meant to take # as arguments two Building objects. # Building objects are created with statements of the form # Building(height, entries) where height is a positive integer # (possibly equal to 0) and entries is a nonempty string that # denotes all access doors to the building, with at least # one space within the string to separate entries. # You can assume that height and entries are as expected. # # If building denotes a Building object, then # building.go_to_floor_from_entry(floor, entry, nb_of_people) # takes as argument an integer, a string, and an integer. # An error of type BuildingError is raised, # all with the same message, if: # - floor is not between 0 and the building's height, or # - entry is not one of the building's entries, or # - nb_of_people is not strictly positive. # If the lift at that entry has to go down, # then by how many floors it has to go down is printed out. # # If building denotes a Building object, then # building.leave_floor_from_entry(floor, entry, nb_of_people) # takes as argument an integer, a string, and an integer. # An error of type BuildingError is raised if: # - floor is not between 0 and the building's height, or # - entry is not one of the building's entries, or # - nb_of_people is not strictly positive, or # - there are not at least nb_of_people on that floor. # The same error message is used for the first 3 issues, # and another error message is used for the last issue. # If the lift at that entry has to go up or down, then # by how many floors it has to go up or down is printed out. # # For the number of floors to go up or down, use # "1 floor..." or "n floors..." for n > 1. class BuildingError(Exception): pass class Building: number_created = 0 def __init__(self, height, entries): Building.number_created += 1 self.height = height self.entries = entries self.the_entries = entries.split() self.lifts = {entry: 0 for entry in self.the_entries} self.occupancies = {(entry, floor): 0 for entry in self.the_entries for floor in range(0, self.height) } def __repr__(self): return f"Building({self.height}, '{self.entries}')" def __str__(self): return 'Building with ' +\ (self.height == 0 and '1 floor ' or\ f'{self.height + 1} floors '\ ) + 'accessible from entries: ' + ', '.join(self.the_entries) def go_to_floor_from_entry(self, floor, entry, nb_of_people): if not 0 <= floor <= self.height\ or entry not in self.the_entries\ or nb_of_people <= 0: raise BuildingError("That makes no sense!") self.occupancies[entry, floor] += nb_of_people if floor: if self.lifts[entry]: print('Wait, lift has to go down', self.lifts[entry], self.lifts[entry] > 1 and 'floors...'\ or 'floor...' ) self.lifts[entry] = floor def leave_floor_from_entry(self, floor, entry, nb_of_people): if not 0 <= floor <= self.height\ or entry not in self.the_entries\ or nb_of_people <= 0: raise BuildingError("That makes no sense!") if self.occupancies[entry, floor] < nb_of_people: raise BuildingError("There aren't that many people on that floor!") self.occupancies[entry, floor] -= nb_of_people if floor: if self.lifts[entry] > floor: difference = self.lifts[entry] - floor print('Wait, lift has to go down', difference, difference != 1 and 'floors...' or 'floor...' ) if self.lifts[entry] < floor: difference = floor - self.lifts[entry] print('Wait, lift has to go up', difference, difference != 1 and 'floors...' or 'floor...' ) self.lifts[entry] = 0 def compare_occupancies(building_1, building_2): occupancy_1 = sum(building_1.occupancies.values()) occupancy_2 = sum(building_2.occupancies.values()) if occupancy_1 == occupancy_2: print('There is the same number of occupants in both buildings.') elif occupancy_1 > occupancy_2: print('There are more occupants in the first building.') else: print('There are more occupants in the second building.')
! test cases following!#
>>> the_horizons = Building(10, 'A B C D') >>> the_horizons Building(10, 'A B C D') >>> print(the_horizons) Building with 11 floors accessible from entries: A, B, C, D >>> Building.number_created 1 >>> the_spike = Building(37, '1') >>> the_spike Building(37, '1') >>> print(the_spike) Building with 38 floors accessible from entries: 1 >>> Building.number_created 2 >>> the_seaside = Building(6, 'A B Z') >>> the_seaside Building(6, 'A B Z') >>> print(the_seaside) Building with 7 floors accessible from entries: A, B, Z >>> Building.number_created 3 >>> the_horizons.go_to_floor_from_entry(-1, 'A', 4) ... quiz_8.BuildingError: That makes no sense! >>> the_horizons.go_to_floor_from_entry(11, 'A', 4) ... quiz_8.BuildingError: That makes no sense! >>> the_horizons.go_to_floor_from_entry(0, 'Z', 4) ... quiz_8.BuildingError: That makes no sense! >>> the_horizons.go_to_floor_from_entry(0, 'B', 0) ... quiz_8.BuildingError: That makes no sense! >>> the_horizons.go_to_floor_from_entry(0, 'B', 4) >>> compare_occupancies(the_horizons, the_spike) There are more occupants in the first building. >>> the_spike.go_to_floor_from_entry(17, '1', 4) >>> compare_occupancies(the_horizons, the_spike) There is the same number of occupants in both buildings.
>>> the_spike.leave_floor_from_entry(17, '1', 0) ... quiz_8.BuildingError: That makes no sense! >>> the_spike.leave_floor_from_entry(17, '1', 5) ...
quiz_8.BuildingError: There aren't that many people on that floor! >>> the_spike.leave_floor_from_entry(17, '1', 3) >>> the_horizons.leave_floor_from_entry(0, 'A', 1) ...
quiz_8.BuildingError: There aren't that many people on that floor! >>> the_horizons.leave_floor_from_entry(0, 'B', 1) >>> the_horizons.leave_floor_from_entry(0, 'B', 1) >>> the_horizons.leave_floor_from_entry(0, 'B', 1)
>>> compare_occupancies(the_horizons, the_spike) There is the same number of occupants in both buildings. >>> the_horizons.leave_floor_from_entry(0, 'B', 1) >>> compare_occupancies(the_horizons, the_spike) There are more occupants in the second building. >>> the_seaside.go_to_floor_from_entry(3, 'B', 1) >>> the_seaside.go_to_floor_from_entry(3, 'B', 1) Wait, lift has to go down 3 floors... >>> the_seaside.go_to_floor_from_entry(3, 'B', 1) Wait, lift has to go down 3 floors... >>> the_seaside.go_to_floor_from_entry(3, 'B', 1) Wait, lift has to go down 3 floors... >>> the_seaside.leave_floor_from_entry(3, 'B', 2) >>> the_seaside.leave_floor_from_entry(3, 'B', 2) Wait, lift has to go up 3 floors... >>> the_seaside.go_to_floor_from_entry(4, 'A', 10) >>> the_seaside.go_to_floor_from_entry(5, 'A', 10) Wait, lift has to go down 4 floors... >>> the_seaside.go_to_floor_from_entry(2, 'A', 10) Wait, lift has to go down 5 floors... >>> the_seaside.leave_floor_from_entry(4, 'A', 2) Wait, lift has to go up 2 floors... >>> the_seaside.go_to_floor_from_entry(1, 'A', 10) >>> the_seaside.leave_floor_from_entry(5, 'A', 2) Wait, lift has to go up 4 floors... >>> the_seaside.go_to_floor_from_entry(5, 'A', 10) >>> the_seaside.leave_floor_from_entry(3, 'B', 2) ... quiz_8.BuildingError: There aren't that many people on that floor! >>> the_seaside.leave_floor_from_entry(2, 'A', 2) Wait, lift has to go down 3 floors...