• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

nie działające properties

VPS Starter Arubacloud
0 głosów
163 wizyt
pytanie zadane 3 maja 2021 w Python przez krukWiesio Początkujący (400 p.)

Witam. Mam problem z moim programem a mianowicie po podaniu litery w inpucie program się wywala. W zadaniu jest napisane że mam kontrolować czy dane są poprawne za pomocą właściwości. Jednak jakby w ogóle program tam nie wchodzi. Proszę o pomoc.

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):
        print("x setter")
        if not isinstance(x, int):
            raise TypeError(f"{x} nie jest int-em")
        self._x = x

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

    @y.setter
    def y(self, y):
        print("y setter")
        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)

 

komentarz 3 maja 2021 przez adrian17 Ekspert (344,100 p.)
W jakim sensie się wywala, pokażesz? Bo właśnie przekleiłem ten kod, odpaliłem i zdaje się działać.
komentarz 3 maja 2021 przez krukWiesio Początkujący (400 p.)
jak podasz jakiegoś stringa przy wpisywaniu współrzędnej x bądz y
komentarz 3 maja 2021 przez adrian17 Ekspert (344,100 p.)

A, no to... nic dziwnego?

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

Tutaj bierzesz tekst z konsoli i zamieniasz na inta. Jak się nie uda, rzuca wyjątkiem.

        if not isinstance(x, int):
            raise TypeError(f"{x} nie jest int-em")

A tutaj sprawdzasz na poziomie typów... ale w Twoim konkretnym przypadku `x` zawsze jest item, bo jak by nie był to `int()` by wcześniej rzucił wyjątkiem.

komentarz 3 maja 2021 przez krukWiesio Początkujący (400 p.)
Traceback (most recent call last):

y = int(input("podaj współrzedna y: "))
ValueError: invalid literal for int() with base 10: 'abc'

wiem gdzie leży błąd ale nie potrafię go naprawić przy pomocy właściwości właśnie
komentarz 3 maja 2021 przez krukWiesio Początkujący (400 p.)

@adrian17, 

jak wywale rzutowanie to też sie wyrzuci program i takie błędne koło. Masz pomysł jak to naprawić, co gdzie wstawić?

komentarz 3 maja 2021 przez adrian17 Ekspert (344,100 p.)
Jak chcesz wszędzie mieć takie sprawdzanie `if not isinstance(x, int):` to możesz je wsadzić do konstruktora.
komentarz 3 maja 2021 przez krukWiesio Początkujący (400 p.)
właśnie musze to konkretnie za pomocą właściwości zrobić...
komentarz 3 maja 2021 przez adrian17 Ekspert (344,100 p.)
No to w konstruktorze `self.x = x`, to przejdzie przez właściwość?
komentarz 3 maja 2021 przez krukWiesio Początkujący (400 p.)
właśnie nie wchodzi do właściwości...
komentarz 3 maja 2021 przez adrian17 Ekspert (344,100 p.)
Powtórzę: teraz masz w konstruktorze `self._x = x`, a mówię żeby zamienić na `self.x = x`.
komentarz 3 maja 2021 przez krukWiesio Początkujący (400 p.)
aaa sory nie zakapowałem. już poprawiłem ale wciąż nie wiem jak rozwiązać problem inputa i kontroli danych bo wiem że to zawsze bedzie int jeśli rzutuje. ale jeśli nie rzutuje to i tak wywali program
komentarz 3 maja 2021 przez adrian17 Ekspert (344,100 p.)

No ale o to chodzi żeby wywaliło program, nie? Po to jest to

raise TypeError(f"{x} nie jest int-em")

Jak chcesz mieć wyjątek ale jednocześnie żeby "nie wywalał programu", bo go złap w bloku try/catch.

(Inna sprawa że to ogólnie dość dziwna filozofia, obecnie prędzej by się ten kod po prostu otypowało adnotacjami i w ogóle takich runtime checków nie robiło)

komentarz 3 maja 2021 przez krukWiesio Początkujący (400 p.)
masz na myśli pobranie danch w bloku try?
komentarz 3 maja 2021 przez adrian17 Ekspert (344,100 p.)
Na przykład, tak.
komentarz 3 maja 2021 przez krukWiesio Początkujący (400 p.)
try:
    x = int(input("podaj współrzedna x: "))
    y = int(input("podaj współrzedna y: "))
except ValueError:
    print("podaj dobre dane")

Nie wiem czy taki zapis ma sens jakiś bo wtedy te właściwości są trochę bezużyteczne...Nie wiem kompletnie co zrobić.....

komentarz 3 maja 2021 przez adrian17 Ekspert (344,100 p.)

Nie wiem czy taki zapis ma sens jakiś bo wtedy te właściwości są trochę bezużyteczne

Tak, bo samo zadanie jest trochę bezsensowne :P

Ale ogólnie to, że sprawdzasz typy w properties i _teraz_ nigdy to nie jest sprawdzane bo zawsze robisz int(), nie znaczy że przy 100x większym programie by się nie przydały. (inna sprawa, że jak mówiłem, ogólnie się tak nie robi, tylko się typuje kod i sprawdza statycznie przed uruchomieniem)

komentarz 3 maja 2021 przez krukWiesio Początkujący (400 p.)
Niestety takie wymogi zadania dokładnie brzmi to "wykorzystaj właściwości, aby zabezpieczyć atrybuty przed przypisaniem im niewłaściwych typów danych" i niestety dziura w głowie, 0 pomysłu na zrobienie tego..
komentarz 3 maja 2021 przez adrian17 Ekspert (344,100 p.)
No... ale jest wszystko OK? Poprawnie je wykorzystujesz. To ze konsolowe użycie input()a niezależnie też przed tym zabezpiecza nie czyni Twojego zabezpieczenia bezużytecznym, bo nie zawsze Point będzie edytowany bezpośrednio z konsoli.
komentarz 3 maja 2021 przez krukWiesio Początkujący (400 p.)
czyli inputa mam nie rzutować na inta(tylko wtedy znowu właściwości wyrzucą błędy nawet jeśli będą to liczby)??? i dopiero przed inicializowaniem obiektu go zrzutować??
komentarz 3 maja 2021 przez adrian17 Ekspert (344,100 p.)

(tylko wtedy znowu właściwości wyrzucą błędy nawet jeśli będą to liczby)???

Chodzi o typy, nie zawartość. 111 jest liczbą, "111" nie, więc to drugie będzie odrzucone przez property.

i dopiero przed inicializowaniem obiektu go zrzutować??

Nie wiem o co Ci chodzi. Albo kod jest poprawny i używasz int() jak teraz, albo nie jest poprawny i rzuci wyjątkiem. Nie możesz na raz napisać coś poprawnego i niepoprawnego, bo to nie ma sensu.

komentarz 3 maja 2021 przez krukWiesio Początkujący (400 p.)
mi dokładnie chodzi oto że jak mam int(input)) to, to zawsze przejdzie pozytywnie przez właściwość, i nie ona podniesie error a po prostu brak mozliwości zrzutowania literki "a" a chciałbym zeby to właściwość wyrzuciła komunikat.

ValueError: invalid literal for int() with base 10: 'a'
komentarz 3 maja 2021 przez adrian17 Ekspert (344,100 p.)

a chciałbym zeby to właściwość wyrzuciła komunikat.

No to nie używaj int() tylko błędnie przekaż stringa i dostaniesz komunikat o błędzie i tyle.

komentarz 3 maja 2021 przez krukWiesio Początkujący (400 p.)
Okej dobra wielkie dzięki za poświęcony czas

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
1 odpowiedź 75 wizyt
0 głosów
0 odpowiedzi 389 wizyt
0 głosów
2 odpowiedzi 1,202 wizyt

92,453 zapytań

141,262 odpowiedzi

319,086 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...