Seite 1 von 1

Wahrheitswerte Tabelle

Verfasst: Montag 1. April 2019, 09:48
von computatrum physicus
Weiß jemand a) wie ich Random umgehe b) warum (obwohl ich es zweimal Überprüfe) manchmal mehr Elemente in der Liste sind als x? Hoffe der Code ist nicht zu unleserlich :D ( Geht darum eine Wertetabelle zu erstellen mit 2**x Zeilen und x Spalten) Danke schonmal im vorraus.

Code: Alles auswählen

from random import *

def AussagenLogik2(x):
    Zeilen = 2 ** x
    LogikFeld = []
    Klammer = []
    for q in range(Zeilen+10):
        Überprüfung = [None] * q
    Wert0 = False
    Wert1 = True
    u = 0
    while True:
        for z in range(Zeilen):
            if randint(0,1) == 0:
                Klammer.append(Wert0)
            else:
                Klammer.append(Wert1)
            try:
                fail = Klammer[x-1]
            except IndexError:
                continue
            try:
                for g in range(Zeilen+1):
                    if Überprüfung[g] == Klammer:
                        Überprüfung[u] = Klammer
                        u += 1
                        Klammer = []
                        raise IndexError
                if Klammer != []:
                    try:
                        fail = Klammer[x]
                        Klammer = []
                        break
                    except IndexError:
                        LogikFeld.append(Klammer)
                Überprüfung[u] = Klammer
                u += 1
                Klammer = []
                break
            except IndexError:
                break
        try:
            Failure2 = LogikFeld[Zeilen]
            break
        except IndexError:
            continue

    return LogikFeld




def PrintLogikFeld(x):
    Zeilen = 2 ** x
    LogikFeld = AussagenLogik2(x)

    for i in range(Zeilen):
        print(LogikFeld[i])
        i += 1



if __name__ == "__main__":
    print(PrintLogikFeld(3))
    

Re: Wahrheitswerte Tabelle

Verfasst: Montag 1. April 2019, 10:27
von __blackjack__
@computatrum physicus: Wo überprüfst Du was zweimal? Falls Du die Ausnahmebehandlung von `IndexError` meinst: Da würde ich mal sagen das Du das komplett ohne schreiben solltest und lieber per `len()` prüfen solltest. So ist das eher undurchsichtig, und wohl auch mehr Code. Das ``continue`` bricht mir das Genick. Im Job würde ich jetzt versuchen die Funktion zu verstehen, da werde ich mit Geld bedroht – aber freiwillig ist da bei mir Schluss, dieses Verwirrspiel aus Ausnahmebehandlung und ``continue`` und ``break`` für die Flusskontrolle zu verstehen. Ich bin mir ziemlich sicher dass man das *viel* einfacher und klarer mit normalen ``if``/``else``-Kontrollstrukturen ausdrücken kann.

Mir ist auch nicht klar was der Code überhaupt machen soll. Warum heisst `Klammer` `Klammer`? Und `Überprüfung` `Überprüfung`? Und `q`, `u`, `z`, und `g` sind schlechte Namen. Die verraten nichts über die Bedeutung der Werte. Und falls man tatsächlich nur einen Namen für einen generischen Index braucht, sind das eher `i`, `j`, und `k`.

Kann es sein das Du da gerade *sehr* umständlich versuchst eine ”Tabelle” mit allen Belegungsmöglichkeiten von `x` boole'schen Variablen zu erstellen? Dafür braucht man keinen Zufall, die kann man einfach aufzählen. Und wenn die am Ende in einer zufälligen Reihenfolge sein sollen, dann zählt man sie halt erst auf und mischt das Ergebnis dann zufällig.

So etwas wie ``for i in range(len(sequence)):`` nur um dann die Laufvariable nur als Index in die Sequenz zu verwenden, ist in Python ein „anti pattern“. Man kann in Python *direkt* über die Elemente von Sequenzen wie beispielsweise Listen iterieren, ohne den Umweg über einen Index.

Und es ist unüblich eine Liste mit ”Dummywerten” vorzubelegen um die dann der Reihe nach mit den tatsächlichen Werten zu ersetzen. In so einem Fall fängt man mit einer leeren Liste an und hängt die Werte die man tatsächlich in der Liste haben möchte, dann einfach an. `Überprüfung` würde dann ohne das `u` auskommen.

Auch der Test ob ein Element in einer Liste enthalten ist, muss nicht zu Fuss selbst programmiert werden. Dafür gibt es den ``in``-Operator.

Edit: Jetzt hätte ich fast den Hinweis auf den Style Guide for Python Code vergessen. Du musst an der Gross-/Kleinschreibung von Namen arbeiten.

Edit2: Ist das hier das was Du suchst?

Code: Alles auswählen

#!/usr/bin/env python3
from itertools import product
from random import shuffle


def main():
    items = list(product([False, True], repeat=3))
    for item in items:
        print(item)
    
    print('-' * 20)
    
    shuffle(items)
    for item in items:
        print(item)


if __name__ == '__main__':
    main()
Testlauf:

Code: Alles auswählen

(False, False, False)
(False, False, True)
(False, True, False)
(False, True, True)
(True, False, False)
(True, False, True)
(True, True, False)
(True, True, True)
--------------------
(True, False, False)
(False, False, True)
(False, True, False)
(True, False, True)
(False, False, False)
(False, True, True)
(True, True, False)
(True, True, True)