DaftAcademy / daftacademy-python4beginners-autumn2021

6 stars 3 forks source link

Polynominal - test: methods (test_from_iterable) #18

Open vbaaccess opened 2 years ago

vbaaccess commented 2 years ago

o co chodzi w punkcie

# * Klasa `Polynominal` posiada metodę `from_iterable` umożliwiającą
#   instancjonowanie obiektów z wykorzystaniem iterowalnych kolekcji
#   współczynników
#   Polynominal.from_iterable([1, 2, 3]) == Polynominal(1, 2, 3)
#   Polynominal.from_iterable((1, 1, 5)) == Polynominal(1, 2, 3)
#
# * Współczynniki są liczbami całkowitymi

czy o to ze klasa ma mieć możliwość przyjmowania jako argumentu listy ? czyli że zamiast deklarować wielomian Polynominal(1, 2, 3) można to zrobić podają listę argumentów Polynominal.from_iterable((1, 1, 5)) (czyli jeden argument typ lista) a klasa sobie ma z tym poradzić

na tą chwilę próbuje po prostu przekazać mu parametr i później odpalić swoje przeliczanie

    def from_iterable(self, listaNowychWspolczynnikow):
        self.listaWspolczynnikowWielomianu = listaNowychWspolczynnikow # tu ustawiam nowe współczynniki
        self.przetworzDaneDlaNowejListyWspolczynnikowWielomianu()

i dzięki temu widać że zmienia się wielomian

domyślam że powiązane komunikaty błędów to:

.
======================================================================
ERROR: test_from_iterable (coding_rooms_unit_tests.TestPolynominalMethods) (iterable=[], expected_coeffs=())
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usercode/coding_rooms_unit_tests.py", line 35, in test_from_iterable
    Polynominal.from_iterable(iterable), Polynominal(*expected_coeffs)
TypeError: from_iterable() missing 1 required positional argument: 'list'
----------------------------------------------------------------------
  ... (iterable=(1, 2, 3), expected_coeffs=(1, 2, 3))
  ... (iterable=range(0, 5), expected_coeffs=(0, 1, 2, 3, 4))
  ... (iterable=<list_iterator object at 0x7f52e4a5ca90>, expected_coeffs=(1, 1, 1, 1))
----------------------------------------------------------------------
Ran 2 tests in 0.001s

FAILED (errors=4)

błąd jest ten sam: .. nie do końca rozumie jak mam mu przekazać współczynniki? jeśli nie przez metodę from_iterable to jak ? No i ma być to wywołanie samego from_iterable czy może nie, albo czegoś brakuje?

krwiozercza-szynszyla commented 2 years ago

o co chodzi

Mając poprawnie zadeklarowaną klasę Polynominal powinno dać się jej użyć w taki sposób:

>>> poly = Polynominal.from_iterable([1, 2, 3])
>>> poly2 = Polynominal(1, 2, 3)
>>> poly == poly2
True

czy o to ze klasa ma mieć możliwość przyjmowania jako argumentu listy

Klasa ma mieć metodę, która przyjmie jako argument iterable -> https://docs.python.org/3/glossary.html#term-iterable Lista jest iterable ale nie każdy iterable jest listą.

czyli że zamiast deklarować wielomian Polynominal(1, 2, 3) można to zrobić podają listę argumentów Polynominal.from_iterable((1, 1, 5))

Nie tylko listę, ale tak, powinno dać się utworzyć nową instancję Polynominal albo standardowo poprzez __init__ (Polynominal(1, 2, 3)) albo poprzez wywołanie metody from_iterable (Polynominal.from_iterable([1, 2, 3])). Patrz przykład kodu który wkleiłem na początku.

na tą chwilę próbuje po prostu przekazać mu parametr i później odpalić swoje przeliczanie

Z tego co widzę starasz się zaimplementować metodę, która będzie aktualizować współczynniki istniejącej instancji Polynominal. Da to możliwość czegoś takiego:

>>> poly = Polynominal(0)
>>> poly.from_iterable([1, 2, 3])
>>> poly2 = Polynominal(1, 2, 3)
>>> poly == poly2
True

ale to nie o to tu chodzi. Porównaj to z poprzednim fragmentem.

vbaaccess commented 2 years ago

trochę pozmieniałem no i teraz mam inne błędy

.
======================================================================
ERROR: test_from_iterable (coding_rooms_unit_tests.TestPolynominalMethods) (iterable=[], expected_coeffs=())
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usercode/coding_rooms_unit_tests.py", line 34, in test_from_iterable
    self.assertEqual(
  File "/usr/lib/python3.8/unittest/case.py", line 912, in assertEqual
    assertion_func(first, second, msg=msg)
  File "/usr/lib/python3.8/unittest/case.py", line 902, in _baseAssertEqual
    if not first == second:
  File "/usercode/task8.py", line 118, in __eq__
    return self.expression == other.expression
AttributeError: 'str' object has no attribute 'expression'

======================================================================
ERROR: test_from_iterable (coding_rooms_unit_tests.TestPolynominalMethods) (iterable=<list_iterator object at 0x7fcef0c53a30>, expected_coeffs=(1, 1, 1, 1))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usercode/coding_rooms_unit_tests.py", line 35, in test_from_iterable
    Polynominal.from_iterable(iterable), Polynominal(*expected_coeffs)
  File "/usercode/task8.py", line 142, in from_iterable
    if len(self)>0:
TypeError: object of type 'list_iterator' has no len()

----------------------------------------------------------------------
Ran 2 tests in 0.009s

co w tych 2 przypadkach jest testowane ? w 1 błędzie rozumie że chodzi o pustą listę, tylko co ma być zwrócone ? pusty set ? w 2gim ??? jakiś adres pamięci ??

krwiozercza-szynszyla commented 2 years ago
  File "/usercode/task8.py", line 118, in __eq__
    return self.expression == other.expression
AttributeError: 'str' object has no attribute 'expression'

wygląda jak źle zaimplementowana metoda __eq__ lub implementacja from_iterable nie zwróciła obiektu Polynominal

  File "/usercode/task8.py", line 142, in from_iterable
    if len(self)>0:
TypeError: object of type 'list_iterator' has no len()

a tu już na 100% zła implementacja from_iterable, TypeError: object of type 'list_iterator' has no len() jest dosyć jednoznaczny

vbaaccess commented 2 years ago

trochę udało się wyeliminować "przypadku" ale za pomocą

try:
    ...
except:
    ...

... czy tak można ? dokładnie po prostu obsłguje przypadki gdzie nie łapie obiektu

    def __str__(self):
        try:
            ...
        except:
            return ''

    def __eq__(self, other):
        try:
            ...
        except:
            return False

nie niej i tak zostaje mi jeszcze jeden błąd... który jest związany ze zwracaniem obiektu w sytuacji gdy chyba obiekt nie ma argumentów (pusta lista) możliwe że try + exception będzie zbyteczne jak ten błąd wyeliminuje no i moge je usunąć bo procentowo to i tak nie zmienia mi wyniku tylko skraca listę błędów :P

======================================================================
FAIL: test_from_iterable (coding_rooms_unit_tests.TestPolynominalMethods) (iterable=<list_iterator object at 0x7f3a3d9679d0>, expected_coeffs=(1, 1, 1, 1))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usercode/coding_rooms_unit_tests.py", line 34, in test_from_iterable
    self.assertEqual(
AssertionError: <task8.Polynominal object at 0x7f3a3d967ca0> != <task8.Polynominal object at 0x7f3a3d967dc0>

... ale nie wiem jak "wychwycić błąd" tym bardziej że to coś wynika jakby z samego testu

krwiozercza-szynszyla commented 2 years ago

jak ktoś chce używać try/excep w tym zadaniu to można ale da się bez

... ale nie wiem jak "wychwycić błąd" tym bardziej że to coś wynika jakby z samego testu

to coś wynika prawdopodobnie ze złej implementacji, najłatwiej to sprawdzić w lokalnej sesji interpretera np:

>>> Polynominal.from_iterable(range(5)) == Polynominal(0, 1, 2, 3, 4)
True
vbaaccess commented 2 years ago
pA = Polynominal.from_iterable(range(5))
pB = Polynominal(0, 1, 2, 3, 4)
print ('1) pA =>',pA)
print ('2) type(pA) =>',type(pA))
print ('3) id(pA) =>',id(pA))
print ('4) pB =>',pB)
print ('5) type(pB) =>',type(pB))
print ('6) id(pB) =>',id(pB))
print ('7) Polynominal.from_iterable(range(5)) == Polynominal(0, 1, 2, 3, 4) =>', Polynominal.from_iterable(range(5)) == Polynominal(0, 1, 2, 3, 4))
1) pA => x + 2x^2 + 3x^3 + 4x^4
2) type(pA) => <class '__main__.Polynominal'>
3) id(pA) => 55057872
4) pB => x + 2x^2 + 3x^3 + 4x^4
5) type(pB) => <class '__main__.Polynominal'>
6) id(pB) => 55057840
7) Polynominal.from_iterable(range(5)) == Polynominal(0, 1, 2, 3, 4) => True

w Thonny lub pyChar wygląd ok :| więc nie mam do końca pomysłu ... poza przepisaniem :(