
# PascalCase
class Robot:
    # alle funktionen mit unterstrichen links und rechts müssen exakt so heißen
    def __init__(self, name):
        print(f"Creating a new robot named {name}")
        # __ führt dazu das ein Attribut privat ist
        #   bedeutet, es kann nur innerhalb der Klasse genutzt werden
        self.__name = name
        self.set_name(name)

    def get_name(self):
        return self.__name

    def set_name(self, name):
        if len(name) < 6:
            raise ValueError("RObot name has to have at least 6 characters")
        self.__name = name

    def say_hi(self):
        print(f"Hello, I'm a robot called {self.__name}")


r1 = Robot("Bender")  # führt die init-funktion aus
print(r1.__dict__)
r1.build_year = 2996
print(r1.__dict__)
print(r1.__dict__)



print(r1.get_name())
r1.say_hi()  # r1 -> Robot -> Robot.say_hi(r1)
Robot.say_hi(r1)  # wird so nie geschrieben
# Attribute können zu jeder Zeit geändert werden (nicht private)
r1.__name = "Calculon"
r1.say_hi()
# 2 eigene Klassen schreiben
# Circle und Rectangle
# radius
# Rectangle hat die Attribute: height, width
# beide Klassen haben die Funktionen:
#   calc_area()        # kreis: pi*radius**2  3.14
#   calc_perimeter()  # 2 * pi * radius
import math
class Circle:
    def __init__(self, radius):
        self.__radius = radius
        self.set_radius(radius)
        self.__area = 0
        self.__area_computed = False

    def get_radius(self):
        return self.__radius

    def set_radius(self, radius):
        assert radius > 0, (f"Radius {radius}, was smaller 0")
        self.__radius = radius
        self.__area_computed = False
        # area berechnen

    def get_area(self):
        if self.__area_computed:
            return self.__area
        print("Calculting the area")
        self.__area = 3.14 * self.__radius ** 2  # ^,|,& -> binäre operatoren
        self.__area_computed = True
        return self.__area

    def calc_perimeter(self):
        return 2 * 3.14 * self.__radius

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def calc_area(self):
        area = self.width * self.height
        return area

    def calc_perimeter(self):
        perimeter = 2 * (self.width + self.height)
        return perimeter

if __name__ == "__main__":
    print("-"*100)
    c1 = Circle(2)
    area = c1.get_area()  # Circle.calc_area(c1)
    print(area)
    print()
    print(c1.get_area())
    c1.set_radius(5)
    print(c1.get_area())
    # schönen weg mit properties
    c1.set_radius(c1.get_radius() + 1)
    c1.radius += 3  # fehleranfällig
    #  beides verbinden -> properties
    # als dataclasses!