Seite 1 von 1

Problem innerhalb Klasse mit Listen übergabe

Verfasst: Samstag 17. Oktober 2020, 19:30
von Medds
Hallo.
Bin neu hier in diesem Forum.
Hoffe die Frage ist für die Profis hier nicht zu unsinnig, aber ich finde trotz google und co keine Erklärung die meine Denkblockade löst.

Ich habe folgendes Problem:
Ich habe eine Klasse deren Funktionen funktionieren wenn ich sie nicht in eine Klasse packe.
Ich möchte die Liste "kartendeck" von Methode 1 in der Methode 2 verwenden, aber trotz zahlloser versuche bin ich zu blöd dazu.
Bin kein Schüler der seine Hausaufgaben lösen möchte (wie es im Forum steht), sondern ein 37 Jähriger Messmaschinien Programmierer der das nebenbei lernen möchte.
Mein Programmieren am Arbeitsplatz hat aber nichts im entferntesten mit einer Programmiersprache wie Python zu tun. Das nur zur Info über mich.
Also erst mal der code den ich bis jetzt habe:

class Karten:

def karten_erstellen(self):
farben = ['Herz', 'Karo', 'Pik', 'Kreuz']
werte = ['7', '8', '9', '10', 'Bube', 'Dame', 'König', 'Ass']

kartendeck = []

for w in farben:
for y in werte:
z = str(w + ' ' + y)
kartendeck.append(z)
return kartendeck

def karten_zuweisen(self):
kartendeckcopy = kartendeck.copy()
z_ass = 1
z_7 = 7
z_8 = 8
z_9 = 9
z_10 = 10
for i in kartendeckcopy:
if '7' in i:
i_neu = i
i_neu = (i_neu, z_7)
kartendeck.append(i_neu)
kartendeck.remove(i)
for i in kartendeckcopy:
if '8' in i:
i_neu = i
i_neu = (i_neu, z_8)
kartendeck.append(i_neu)
kartendeck.remove(i)
for i in kartendeckcopy:
if '9' in i:
i_neu = i
i_neu = (i_neu, z_9)
kartendeck.append(i_neu)
kartendeck.remove(i)
for i in kartendeckcopy:
if '10' in i:
i_neu = i
i_neu = (i_neu, z_10)
kartendeck.append(i_neu)
kartendeck.remove(i)
for i in kartendeckcopy:
if 'Bube' in i:
i_neu = i
i_neu = (i_neu, z_10)
kartendeck.append(i_neu)
kartendeck.remove(i)
for i in kartendeckcopy:
if 'Dame' in i:
i_neu = i
i_neu = (i_neu, z_10)
kartendeck.append(i_neu)
kartendeck.remove(i)
for i in kartendeckcopy:
if 'König' in i:
i_neu = i
i_neu = (i_neu, z_10)
kartendeck.append(i_neu)
kartendeck.remove(i)
for i in kartendeckcopy:
if 'Ass' in i:
i_neu = i
i_neu = (i_neu, z_ass)
kartendeck.append(i_neu)
kartendeck.remove(i)

return kartendeck


def __init__(self):

karten = self.karten_zuweisen()


karten = Karten()

Wäre äußerst dankbar wenn mir jemand helfen könnte

Re: Problem innerhalb Klasse mit Listen übergabe

Verfasst: Samstag 17. Oktober 2020, 20:39
von Sirius3
Problem ist, dass die Klasse `Karten` gar keinen Zustand hat, Und wahrscheinlich auch nie einen haben wird. Bleib bei Funktionen, und übergibt die Liste der Karten als Argument.

Konstanten schreibt man komplett gross. w ist ein schlechter Name für eine Farbe und y für einen Wert und z für eine Karte.

Code: Alles auswählen

FARBEN = ['Herz', 'Karo', 'Pik', 'Kreuz']
WERTE = ['7', '8', '9', '10', 'Bube', 'Dame', 'König', 'Ass']

def karten_erstellen():
    kartendeck = []

    for farbe in FARBEN:
        for wert in WERTE:
            karte = f"{farbe} {wert}"
            kartendeck.append(karte)
    return kartendeck
Statt Listen zu verändert erzeugt man eine neue Liste. Dann braucht man auch keine Listen zu kopieren. Statt acht mal die selbe Schleife zu kopieren, würde man eine Schleife programmieren.

Code: Alles auswählen

ZAHLENWERTE = {'7': 7, '8': 8, '9': 9, '10': 10, 'Bube': 10, 'Dame': 10, 'König': 10, 'Ass': 1}
def karten_zuweisen(kartendeck):
    kartendeck_mit_zahlenwert = []
    for wert, zahl in ZAHLENWERTE.items():
        for karte in kartendeck:
            if wert in karte:
                kartendeck_mit_zahlenwert.append((karte, zahl))
    return kartendeck_mit_zahlenwert
Das ist aber sehr umständlich, weil man da gar keine zwei verschachtelte Schleifen braucht:

Code: Alles auswählen

def karten_zuweisen(kartendeck):
    kartendeck_mit_zahlenwert = []
    for wert, zahl in ZAHLENWERTE.items():
        wert = karte.split()[1]
        zahl = ZAHLENWERTE[wert]
        kartendeck_mit_zahlenwert.append((karte, zahl))
    return kartendeck_mit_zahlenwert
Ist aber auch noch umständlich, weil man das ja gleich von anfang an richtig erzeugen könnte:

Code: Alles auswählen

def karten_erstellen():
    kartendeck = []
    for farbe in FARBEN:
        for wert, zahl in ZAHLENWERTE.item():
            karte = (f"{farbe} {wert}", zahl)
            kartendeck.append(karte)
    return kartendeck
oder kurz:

Code: Alles auswählen

def karten_erstellen():
    return [(f"{farbe} {wert}", zahl)
        for farbe in FARBEN
        for wert, zahl in ZAHLENWERTE.item()
    ]

Re: Problem innerhalb Klasse mit Listen übergabe

Verfasst: Sonntag 18. Oktober 2020, 14:37
von Medds
WOW
Super Erklärung. Danke

Hab zwar einige Zeit gebraucht bis ich alles verstanden habe. Dr. Google machts möglich. Und es wird auch noch etwas Übung erfordern bis ich das selbst so kurz und knackig anwenden kann, aber nochmal vielen vielen Dank.
Eine kurze Anmerkung hab ich: Ich glaub bei den letzten beiden .item fehlt ein s. :)
Ich werd mir das alles zu Herzen nehmen und umdenken wie ich das machen möchte, aber trotzdem (ich hoffe ich nerve nicht) möchte ich mein ursprüngliches Problem verstehen um Klassen besser zu verstehen zu lernen.
Hier ein anderes Beispiel:
Ich weiß das es nicht funktioniert und hätte auch schon einiges probiert um das a zu übergeben aber leider verstehe ich es nicht.

Code: Alles auswählen

class Test:
    def test_methode1(self):
        print("Ich bin die erste Methode")
        a = "zweite"
    def test_methode2(self):
        print(f"Ich bin die {a} Methode")
    def __init__(self):
        test2 = self.test_methode2()
Gibt es da keinen Weg in der Art oder (was ich eher glaube) kapier ich es einfach nicht?

Nochmal vielen Dank dafür dass du mir das so schön Schritt für Schritt erklärt hast. Soviel Zeit hat noch keiner geopfert mir das zu erklären.

Re: Problem innerhalb Klasse mit Listen übergabe

Verfasst: Sonntag 18. Oktober 2020, 14:45
von snafu
__init__() gehört immer an den Anfang und bringt die Klasseninstanz in einen nutzfähigen Zustand, d.h. es werden an der Stelle bereits alle Attribute initialisiert und ggf ein paar kleinere Vorarbeiten automatisch veranlasst. Am Ende etwas zu initialisieren, ergibt auch recht wenig Sinn, oder?

Auf "a" kannst du in der anderen Methode nicht zugreifen, weil es ein lokaler Name ist und somit nur innerhalb der test_methode1() sichtbar ist. Um das methodenübergreifend zu nutzen, musst du entweder "a" als Parameter übergeben oder (bei Klassen meist sinnvoller) "self.a" definieren und entsprechend nutzen.

Re: Problem innerhalb Klasse mit Listen übergabe

Verfasst: Sonntag 18. Oktober 2020, 14:49
von Sirius3
Du rufst test_methode1 gar nicht auf, außerdem ist `a` einfach nur eine lokale Variable. `test_methode2` liefert nichts zurück, da ist das Zuweisen an `test2` unsinnig, zudem wird die lokale Variable auch nicht weiter benutzt.
__init__ ist dazu da, allen Zustand des Objekts zu initalisieren. Da muß man also alle Attribute, die andere Methoden brauchen, anlegen.
Das ganze Beispiel hat für mich keinen Sinn, so dass es auch schwierig ist, daran etwas zu verbessern. Hier mal, wie eine Klasse aussehen sollte:

Code: Alles auswählen

class Test:
    def __init__(self, a):
        self.a = a
    def test_methode2(self):
        print(f"Ich bin die {self.a} Methode")

test = Test("zweite")
test.test_methode2()

Re: Problem innerhalb Klasse mit Listen übergabe

Verfasst: Sonntag 18. Oktober 2020, 15:07
von Medds
Danke ich glaube jetzt hab ich meinen Denkfehler gerafft.
Ich wollte eine Klasse mir mehereren Funktionen verwenden damit es aufgräumter ist.
Also das ich eine Klasse aufrufe und die dann mehrere Funktionen nacheinander abspult.
Aber dafür sind Klassen nicht da.
Klassen sind dafür da um Methoden zu konstruieren die in verschiedenen Situationen verwendet werden können.
Hab ich das jetzt einigermaßen richtig verstanden?