diff --git a/19.3.py b/19.3.py new file mode 100644 index 0000000..06b9ec9 --- /dev/null +++ b/19.3.py @@ -0,0 +1,109 @@ +"""Описати абстрактний клас Shape (геометрична фігура) та +його нащадки Circle (коло), Rectangle (прямокутник), Triangle +(трикутник). Передбачити у Shape властивості обчислення +периметру та площі фігури а також метод, що перевіряє, чи +перетинаються дві фігури. +З використанням цих класів розв’язати задачу. Дано список +геометричних фігур, що не перетинаються. Перевірити, чи +справді вони не перетинаються та порахувати їх сумарну площу.""" + +from abc import ABCMeta, abstractmethod +import math + +class Shape(metaclass=ABCMeta): + + @abstractmethod + def perimeter(self): + pass + + @abstractmethod + def area(self): + pass + + @abstractmethod + def intersect(self, other): + pass + +class Circle(Shape): + + def __init__(self, x, y, r): + self.x = x + self.y = y + self.r = r + + def perimeter(self): + return 2 * math.pi * self.r + + def area(self): + return math.pi * self.r**2 + + def intersect(self, other): + if isinstance(other, Circle): + return (other.x - self.x)**2 + (other.y - self.y)**2 < (self.r+other.r)**2 + + return False + +class Rectangle(Shape): + + def __init__(self, x, y, w, h): + self.x = x + self.y = y + self.w = w + self.h = h + + def perimeter(self): + return 2*(self.w + self.h) + + def area(self): + return self.h * self.w + + def intersect(self, other): + if isinstance(other, Rectangle): + x1 = min(other.x, self.x) + x2 = max(other.x + other.w, self.x + self.w) + + y1 = max(other.y, self.y) + y2 = min(other.y + other.h, self.y + self.h) + + if x1<=x2 and y1<=y2: + return True + else: + return False + + elif isinstance(other, Circle): + return False + + return False + + +if __name__ == '__main__': + + n = int(input('n = ')) + + figures = [] + for _ in range(n): + choice = input('Input rect(r) or circle(c) or quit(q)') + + CHOICES = ('r', 'c', 'q') + while choice not in CHOICES: + choice = input('Input rect(r) or circle(c) or quit(q)') + + if choice == 'c': + x, y, r = map(float, input().split()) + c = Circle(x, y, r) + figures.append(c) + + elif choice == 'r': + x, y, w, h = map(float, input().split()) + r = Rectangle(x, y, w, h) + figures.append(r) + + else: break + + sum_area = 0 + for item in figures: + sum_area += item.area() + + sum_area_1 = sum([f.area() for f in figures]) + + print(f'sum area {sum_area}, {sum_area_1}') diff --git a/19.5.py b/19.5.py new file mode 100644 index 0000000..0758699 --- /dev/null +++ b/19.5.py @@ -0,0 +1,57 @@ +"""Описати декоратор класу, який модифікує клас для +перевірки, чи належать параметри, що використовуються при +ініціалізації об’єкта цього класу, заданим типам. Вважати, що +клас має поле _field_types – словник, що містить імена полів в +якості ключів та типи полів в якості значень. Якщо типи +невідповідні, то ініціює виключення ValueError. +Застосувати цей декоратор до класів Point та Circle (див. тему +«Класи та об’єкти»), та виконати зображення та переміщення +точок та кіл. +""" + +class CheckType: + + def __init__(self, cls): + self.cls = cls + + def __call__(self, **kwargs): + for k, v in kwargs.items(): + for var, t in self.cls._field_types.items(): + if k == var and type(v) != t: + raise ValueError + return self.cls.__call__(**kwargs) + +@CheckType +class Point: + _field_types = {'x': int, 'y': int} + + def __init__(self, x, y) -> None: + self.x = x + self.y = y + + def __str__(self) -> str: + return f'Point({self.x}, {self.y})' + + def move(self, dx, dy): + self.center.move(dx, dy) + +@CheckType +class Circle: + _field_types = {'center': Point, 'radius': int} + + def __init__(self, center, radius) -> None: + self.center = center + self.radius = radius + + def __str__(self) -> str: + return f'Circle({self.center}, {self.radius})' + + def move(self, dx, dy): + self.center.move(dx, dy) + + +if __name__ == '__main__': + p = Point(x=1, y=2) + print(p) + c = Circle(center=Point(x='a',y=2), radius=3) + print(c) \ No newline at end of file diff --git a/19.6.py b/19.6.py new file mode 100644 index 0000000..a0243e6 --- /dev/null +++ b/19.6.py @@ -0,0 +1,52 @@ +"""Описати декоратор класу, який здійснює модифікацію +класу з метою трасування виклику усіх власних (не спеціальних) +методів класу. Під час трасування показувати ім’я методу, +значення параметрів до виклику, а також результат після +виклику. Застосувати цей декоратор до класів Person та Student +(див. тему «Класи та об’єкти») та виконати програму обчислення +стипендії студентам""" + +def trace(func): + + def _trace(*args, **kwargs): + + print(f'Name of function: {func.__name__}') + for x in args: + print(x) + for k, v in kwargs.items(): + print(f'{k} = {v}') + y = func(*args, **kwargs) + print(y) + return y + + return _trace + +def class_tracing(cls): + for name, attr in cls.__dict__.items(): + if not name.startswith('__') and callable(attr): + setattr(cls, name, trace(attr)) + + return cls + +@class_tracing +class Functions: + + def __init__(self, a, b, c) -> None: + self.a = a + self.b = b + self.c = c + + def factorial(self, n): + if n <= 1: + return 1 + else: + return n*self.factorial(n-1) + + def const(self, const): + return const + + +if __name__ == '__main__': + a = Functions(1,2,3) + a.factorial(5) + a.const(77) \ No newline at end of file