Rozwiązanie zadania "Ilorazy pierścienia wielomianów" #35

Closed
s426211 wants to merge 15 commits from (deleted):zad4 into master
First-time contributor
No description provided.
Owner

Dziękuję, kod wygląda ok.

Kilka uwag/pytań:

  1. Dlaczego zdecydował się Pan zaimplementować wielomiany na zbiorze? (a nie np. na liście elementów?
  2. kilka razy używa Pan deg = len(self.elements) - 1; to oczywiście nie jest poprawnie, bo najwyższy współczynnik może być 0 (mod int_mod). Przy dodawaniu, mnożeniu itd. nie sprawia to problemu, natomiast metoda __eq__ w ogóle nie bierze pod uwagę istnienia zerowych współczynników. Co więcej metoda __eq__ jest niezwrotna:
>>> import main
>>> main.Poly(5, [1, 1]) == main.Poly(5, [1])
False
>>> main.Poly(5, [1]) == main.Poly(5, [1,1])
True

całe szczęście że jej Pan nie używa ;-) gdyby ją dobrze zaimplementować, możnaby uniknąć potworków takich jak np. ta kaskada w invertibles() i pisać po prostu
(f*g) % self.poly_modulo == Poly(self.int_modulo, [1])

  1. Powyższy problem się jednak manifestuje:
$ python main.py 2 "[1,2,3]"
[
        [[0, 1], [1]], # odwracalne
        [[0], [1, 1]], # dzielniki zera
        [[0]], # nilpotenty
        [[0], [1]] # idempotenty
]

jest ok, ale

$ python main.py 3 "[1,2,3]"

skutkuje nieskończoną pętlą:

^CTraceback (most recent call last):
  File "main.py", line 337, in <module>
    print(field)
  File "main.py", line 318, in __str__
    str_form += str(self.invertibles()) + ", # odwracalne\n\t"
  File "main.py", line 273, in invertibles
    if (e * f % self.poly_modulo).elements == {"x0": 1}:
  File "main.py", line 179, in __mod__
    if coefficient * i % poly.int_mod == poly.elements[f"x{fdeg}"]:
KeyboardInterrupt
Dziękuję, kod wygląda ok. Kilka uwag/pytań: 1. Dlaczego zdecydował się Pan zaimplementować wielomiany na zbiorze? (a nie np. na liście elementów? 2. kilka razy używa Pan `deg = len(self.elements) - 1`; to oczywiście nie jest poprawnie, bo najwyższy współczynnik może być `0 (mod int_mod)`. Przy dodawaniu, mnożeniu itd. nie sprawia to problemu, natomiast metoda `__eq__` w ogóle nie bierze pod uwagę istnienia zerowych współczynników. Co więcej metoda `__eq__` jest niezwrotna: ```python >>> import main >>> main.Poly(5, [1, 1]) == main.Poly(5, [1]) False >>> main.Poly(5, [1]) == main.Poly(5, [1,1]) True ``` całe szczęście że jej Pan nie używa ;-) gdyby ją dobrze zaimplementować, możnaby uniknąć potworków takich jak np. ta kaskada w `invertibles()` i pisać po prostu (f*g) % self.poly_modulo == Poly(self.int_modulo, [1]) 3. Powyższy problem się jednak manifestuje: ```bash $ python main.py 2 "[1,2,3]" [ [[0, 1], [1]], # odwracalne [[0], [1, 1]], # dzielniki zera [[0]], # nilpotenty [[0], [1]] # idempotenty ] ``` jest ok, ale ```bash $ python main.py 3 "[1,2,3]" ``` skutkuje nieskończoną pętlą: ```python ^CTraceback (most recent call last): File "main.py", line 337, in <module> print(field) File "main.py", line 318, in __str__ str_form += str(self.invertibles()) + ", # odwracalne\n\t" File "main.py", line 273, in invertibles if (e * f % self.poly_modulo).elements == {"x0": 1}: File "main.py", line 179, in __mod__ if coefficient * i % poly.int_mod == poly.elements[f"x{fdeg}"]: KeyboardInterrupt ```
Owner

Jeśli chce Pan to poprawić, ma Pan czas do jutra, 24:00;

Jeśli chce Pan to poprawić, ma Pan czas do jutra, 24:00;
Author
First-time contributor
  1. Odpowiedź na to pytanie jest bardzo prosta: Nie miałem pojęcia jak to zrobić na liście.

Już na samym początku tworzenia klasy wielomianu pojawiły się 2 problemy: Działania na wielomianach i prostota sprawdzenia tych działań w innych programach, czy nawet na kartce. Choć dodawanie/odejmowanie nie byłoby szczególnym problemem, bo zmieniają się tylko i wyłącznie współczynniki, tak cała reszta już jest, bo w grę wchodzi manipulacja pojawiających się i znikających indeksów w różnych miejscach listy. Słowniki pomogły na tyle ominąć ten problem, że wstawiamy tylko klucz zawierający odpowiedni stopień, nie martwiąc się o jego miejsce. Był też, tak jak wspomniałem powyżej, dodatkowy bonus: mogłem wyświetlić wielomian w postaci do jakiej jestem bardziej przyzwyczajony tj. od najwyższej potęgi i z podanym x. Zamysł głównie estetyczny, ale mogłem go wykorzystać jeszcze przed napisaniem ___str___(self).

Czy źle podszedłem do tematu? Prawdopodobnie. Na pewno istnieje bardziej optymalny sposób rozwiązania tego co napisałem wyżej i tego o czym nie napisałem bo ten post jest już wystarczająco długi, a to zaledwie pierwszy punkt.

  1. Tu z Pana strony padają celne uwagi, na które za bardzo nie mam obrony.
    Mogę tylko i wyłącznie przyznać, że o niedokładności deg zapomniałem, natomiast ___eq___(self, other) jest efektem mojego lenistwa (bo koniec końców interesuje nas tylko sprawdzenie elementów obiektu).

Postaram się napisać poprawę kodu. Dam znać jeśli będzie gotowa.

1. Odpowiedź na to pytanie jest bardzo prosta: Nie miałem pojęcia jak to zrobić na liście. Już na samym początku tworzenia klasy wielomianu pojawiły się 2 problemy: Działania na wielomianach i prostota sprawdzenia tych działań w innych programach, czy nawet na kartce. Choć dodawanie/odejmowanie nie byłoby szczególnym problemem, bo zmieniają się tylko i wyłącznie współczynniki, tak cała reszta już jest, bo w grę wchodzi manipulacja pojawiających się i znikających indeksów w różnych miejscach listy. Słowniki pomogły na tyle ominąć ten problem, że wstawiamy tylko klucz zawierający odpowiedni stopień, nie martwiąc się o jego miejsce. Był też, tak jak wspomniałem powyżej, dodatkowy bonus: mogłem wyświetlić wielomian w postaci do jakiej jestem bardziej przyzwyczajony tj. od najwyższej potęgi i z podanym x. Zamysł głównie estetyczny, ale mogłem go wykorzystać jeszcze przed napisaniem ```___str___(self)```. Czy źle podszedłem do tematu? Prawdopodobnie. Na pewno istnieje bardziej optymalny sposób rozwiązania tego co napisałem wyżej i tego o czym nie napisałem bo ten post jest już wystarczająco długi, a to zaledwie pierwszy punkt. 2. Tu z Pana strony padają celne uwagi, na które za bardzo nie mam obrony. Mogę tylko i wyłącznie przyznać, że o niedokładności ```deg``` zapomniałem, natomiast ```___eq___(self, other)``` jest efektem mojego lenistwa (bo koniec końców interesuje nas tylko sprawdzenie elementów obiektu). Postaram się napisać poprawę kodu. Dam znać jeśli będzie gotowa.
Owner

Być może Pana zaskoczę, ale Pana podejście bynajmniej nie jest błędne, a w niektórych przypadkach jest nawet lepsze (wielokrotnie szybsze) ;-)

Jeśli wiemy, że wielomian ma niewiele niezerowych współczynników przy wysokim stopniu (tj. lista współczynników jest będzie się składała głównie z zer), to Pana podejście (słownikowe, lub przez SparseArray, co na jedno wychodzi) jest wielokrotnie szybsze i oszczędniejsze (pamięciowo). Oczywiście dlatego, że nie trzeba przechowywać/manipulować zer. No i wiemy, że np. mnożenie wielomianów zachowuje ich (relatywną, względem stopnia) rzadkość.

O łatwości manipulacji wielomianów (którą Pan się kierował) nie wspomnę ;-) Byłem tylko ciekawy, czy było to Pana zamierzeniem, czy wyszło "przypadkiem".

Czekam więc na poprawiony kod, całość wygląda przyzwoicie!

Być może Pana zaskoczę, ale Pana podejście bynajmniej nie jest błędne, a w niektórych przypadkach jest nawet lepsze (wielokrotnie szybsze) ;-) Jeśli wiemy, że wielomian ma niewiele niezerowych współczynników przy wysokim stopniu (tj. lista współczynników jest będzie się składała głównie z zer), to Pana podejście (słownikowe, lub przez `SparseArray`, co na jedno wychodzi) jest wielokrotnie szybsze i oszczędniejsze (pamięciowo). Oczywiście dlatego, że nie trzeba przechowywać/manipulować zer. No i wiemy, że np. mnożenie wielomianów zachowuje ich (relatywną, względem stopnia) rzadkość. O łatwości manipulacji wielomianów (którą Pan się kierował) nie wspomnę ;-) Byłem tylko ciekawy, czy było to Pana zamierzeniem, czy wyszło "przypadkiem". Czekam więc na poprawiony kod, całość wygląda przyzwoicie!
Owner

Przy okazji: mnożenie wielomianów (które jak Pan zauważył może być łatwo wyrażone przez (nieobecną w podstawowej bibliotece pythona) operację splotu dyskretnego (convolution).

Przy okazji: mnożenie wielomianów (które jak Pan zauważył może być łatwo wyrażone przez (nieobecną w podstawowej bibliotece pythona) operację splotu dyskretnego (`convolution`).
Author
First-time contributor

Wprowadziłem kilka poprawek, teraz modulo jest wykonywane jako pierwsze więc konstruktor powinien zagwarantować, że pierwszy współczynnik nie będzie 0.
Liczę, że ta wersja będzie bardziej satysfakcjonująca.

Wprowadziłem kilka poprawek, teraz modulo jest wykonywane jako pierwsze więc konstruktor powinien zagwarantować, że pierwszy współczynnik nie będzie 0. Liczę, że ta wersja będzie bardziej satysfakcjonująca.
Owner

ok, dziękuję;

ok, dziękuję;
kalmar closed this pull request 2018-07-01 18:31:15 +02:00

Pull request closed

Sign in to join this conversation.
No reviewers
No Label
No Milestone
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: kalmar/DALGLI0#35
No description provided.