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

OOP w Pythonie, klasa nie daje takich samych wyników jak przy zastosowaniu funkcji

+1 głos
319 wizyt
pytanie zadane 25 lipca 2022 w Python przez gblaze Nowicjusz (240 p.)

Ostatnio w Pythonie probowalem rozwiazac pewne zadanie, które polegało na tym, aby uzyć domyślnej biblioteki "random" i jej metody "choice", aby wygenerować 4 znakowy ciąg znaków z listy [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 'a', 'b', 'c', 'd', 'e']. Jeden taki ciąg miał być ciągiem którego wylosowanie gwarantuje wygranie nagrody, a drugi (użytkownika) jesli jest taki sam, prowadzi do wygranej.

Używając funkcji, program sprawdza ten warunek poprawnie:

from random import choice
import time
 
def prize():
    random_characters = [1,2,3,4,5,6,7,8,9,0,'a','b','c','d','e']
    selected_characters = []
 
    for i in range(0,4):
        character = choice(random_characters)
        selected_characters.append(character)
        random_characters.remove(character)
 
    message = ""
 
    for character in selected_characters:
        message += str(character)
 
    return message
 
active = True
 
while active:
    message = prize()
    winning_message = prize()
    if message == winning_message:
        active = False
 
    print(f"Any ticket matching these four characters: {message} will win the prize!")
    print(f"My ticket: {winning_message}")
    time.sleep(1)

Rezultat:

Natomiast kiedy chciałem zastosowac podejście obiektowe i zainicjować funkcje, ciag znakow dodaje sam do siebie poprzedni ciag znaków z poprzedniej iteracji pętli. Czy ktoś byłby mi w stanie wytlumaczyć dlaczego?

Kod:

from random import choice
import time
 
class Prize():
    def __init__(self):
        self.random_characters = [1,2,3,4,5,6,7,8,9,0,'a','b','c','d','e']
        self.selected_characters = []
        self.message = ""
 
    def randomize(self):
        for i in range(0,4):
            character = choice(self.random_characters)
            self.selected_characters.append(character)
            self.random_characters.remove(character)
 
        for i in self.selected_characters:
            self.message += str(i)
 
        return self.message
 
active = True
message = Prize() 
winning_message = Prize()
 
while active:
    random_ticket = message.randomize()
    my_ticket = winning_message.randomize()
    if random_ticket == my_ticket:
        active = False
 
    print(f"Any ticket matching these four characters: {random_ticket} will win the prize!")
    print(f"My ticket: {my_ticket}")
    time.sleep(1)

Wynik:

Z góry dziękuję za odpowiedź!

1 odpowiedź

+3 głosów
odpowiedź 25 lipca 2022 przez Nelson89 Dyskutant (7,720 p.)
edycja 25 lipca 2022 przez Nelson89

Cześć,

dzieje się tak dlatego, że przy pierwszej metodzie, w ciele funkcji zostaje utworzona lista na wylosowane znaki. Za każdym razem, gdy wywołujesz tą funkcje lista jest tworzona od nowa.

W drugim przypadku, gdy tworzysz obiekt, tworzona jest lista na wylosowane obiekty. Ta lista jest tworzona tylko i wyłącznie, gdy tworzysz obiekt tej klasy - za każdym razem, gdy wywołujesz funkcje randomize, to do listy są dodane nowe obiekty. Listę stworzono w konstrukorze __init__, która jest wywoływana przy tworzeniu obiektu.

Aby tego uniknąć, to do każdego losowania tworzysz nowy obiekt, albo (co bardziej sensowne) listę tworzysz w ciele funkcji (podobnie jak w pierwszym przypadku) - jako zmienną lokalną, a nie atrybut klasy (czyli bez self).

Jeszcze mała podpowiedź jak połączyć elementy listy w ciąg znaków, gdy wszystkie elementy będą obiektami klasy str.

"".join(['a', 'b', 'c'])

w cudzysłowie powinien się znajdować znak, który ma oddzielać elementy z listy.

Pozdrawiam,

Nelson

1
komentarz 25 lipca 2022 przez gblaze Nowicjusz (240 p.)
Wow, super, dzięki wielkie za pomoc!

Podobne pytania

0 głosów
1 odpowiedź 266 wizyt
pytanie zadane 18 lipca 2019 w Python przez RafalS VIP (122,820 p.)
+2 głosów
1 odpowiedź 830 wizyt
pytanie zadane 22 maja 2017 w PHP przez ŁukaszD. Użytkownik (540 p.)
0 głosów
3 odpowiedzi 652 wizyt

93,424 zapytań

142,421 odpowiedzi

322,646 komentarzy

62,785 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

VMware Cloud PRO - przenieś swoją infrastrukturę IT do chmury
...