kontrola danych przy użyciu właściwości

0

Witam, mam zagwozdkę jak poradzić sobie z kontrolą danych gdzie punkty x i y mają być liczbami i w zadaniu mam Wykorzystać właściwości, aby zabezpieczyć atrybuty przed przypisaniem im niewłaściwych danych np napisów.Problem leży w tym ze input pobiera stringa i jak rzutuje na inta to wiadomo ze jak pojawi sie napis to wywali błąd, a jesli nie rzutuje to nie dziala tak jak powinno . Mój kod wygląda tak:

import math
class Point:
    def __init__(self, x, y):
        self._x = x
        self._y = y
 
    @property
    def x(self):
        return self._x
 
    @x.setter
    def x(self, x):
        if (isinstance(x, (str))):
            print("podana współrzędna x musi być liczba")
 
    @property
    def y(self):
        return self._y
 
    @y.setter
    def y(self, y):
        if (isinstance(y, (str))):
            print("podana współrzędna y musi być liczba")
 
    def __str__(self):
        return "Wspołrzędna x: {0.x}\nWspołrzędna y: {0.y}".format(self)
 
    def __repr__(self):
        return f"{self.__class__.__name__}({self.x},{self.y})"
 
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y
 
    def distance_from_origin(self, x, y):
        odl = math.sqrt((0-x)**2+(0-y)**2)
        return odl
 
if __name__ == '__main__':
    x = int(input("podaj współrzedna x: "))
    y = int(input("podaj współrzedna y: "))
    wspol = Point(x, y)
    wspol2 = Point(5, 7)
    print(wspol)  # str
    print(repr(wspol))  # repr
    print(wspol.distance_from_origin(x, y))

0

Możesz z try except TypeError.

1

To powinno być tak:

    @x.setter
    def x(self, x):
        if not isinstance(x, int):
            raise TypeError(f"{x} is not an int")
        self._x = x
0
  1. Zamiast rzeczy typu print("podana współrzędna x musi być liczba") rób jakieś raise.

  2. Błędy chyba mają wyskakiwać -- inaczej jak się zabezpieczysz? Dopiero ich przechwycenie ma sens.

  3. Chyba, że masz jakąś procedurę awaryjną -- wtedy zamiast Twojego nieszczęsnego printa robisz awaryjne podstawienie typu self._x = 0 -- ale takie ciche działanie zwykle bywa szkodliwe w prawdziwym życiu...

1

@przypadkowy:

niestety również wyskakują błędy w momencie pobrania od użytkownika liter zamiast

Co w ogóle chcesz, żeby się działo, jak user poda zły typ danych?

0

Kod trochę się rozwinął ale problem dalej pozostał. bo wiem że pobierając inputa rzutuje go na int i wtedy to przechodzi przez właściwość, i jeśli jest tam tekst to przy obliczeniach wyrzuci program. A jeśli input nie będzie zrzutowany na int to właściwości wyrzucą błędy nawet jak bedą tam liczby..

import math


class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, x):
        if not isinstance(x, int):
            raise ValueError(f"{x} nie jest int-em")
        self._x = x

    @property
    def y(self):
        return self._y

    @y.setter
    def y(self, y):
        if not isinstance(y, int):
            raise TypeError(f"{y} nie jest int-em")
        self._y = y

    def __str__(self):
        return "Wspołrzędna x: {0.x}\tWspołrzędna y: {0.y}".format(self)

    def __repr__(self):
        return f"{self.__class__.__name__}(x:{self.x},y:{self.y})"

    def __eq__(self, other):
        if self.__class__.__name__ == other.__class__.__name__:
            return self.x == other.x and self.y == other.y
        raise TypeError("To nie jest obiekt klasy Point")

    def distance_from_origin(self, x, y):
        odl = math.sqrt((0 - x) ** 2 + (0 - y) ** 2)
        return odl


class Circle(Point):
    def __init__(self, x, y, radius):
        super(Circle, self).__init__(x, y)
        self.radius = radius

    @property
    def radius(self):
        return self._radius

    @radius.setter
    def radius(self, radius):
        if radius < 0:
            raise ValueError('Promień powinien być wiekszy od 0')
        self._radius = radius

    def __repr__(self):
        return f"{self.__class__.__name__}(x:{self.x},y:{self.y},promień:{self.radius})"

    def __str__(self):
        return "Wspołrzędna okręgu x: {0.x}\tWspołrzędna okręgu y: {0.y}\tPromień okręgu: {0.radius}".format(self)

    def area(self):
        pole = (math.pi * (self.radius ** 2))
        return pole

    def circumference(self):
        obw = 2 * math.pi * self.radius
        return obw

    def edge_distance_from_origin(self):
        odl = math.sqrt((0 - self.x) ** 2 + (0 - self.y) ** 2)
        brzeg = odl - self.radius
        return brzeg

    def __eq__(self, other):
        super().__eq__(other)
        if self.__class__.__name__ == other.__class__.__name__:
            return self.radius == other.radius
        raise TypeError("To nie jest obiekt klasy Circle")


if __name__ == '__main__':

    x = int(input("podaj współrzedna x: "))
    y = int(input("podaj współrzedna y: "))

    wspol = Point(x, y)
    wspol2 = Point(5, 7)

    okrag = Circle(5, 5, 5)
    okrag1 = Circle(3, 3, 5)
    print(wspol)  # str
    print(repr(wspol))  # repr
    print(okrag)
    print(repr(okrag))
    print("Odleglosc od srodka osi współrzędnych:", round(wspol.distance_from_origin(x, y), 2))
    print(wspol == wspol2)
    print(round(okrag.area(), 2))
    print("Odleglosc brzegu koła od srodka osi współrzędnych:", round(okrag.edge_distance_from_origin(), 2))
    print(okrag == okrag1)

1 użytkowników online, w tym zalogowanych: 0, gości: 1