Mit while/If Schleife Input und Dict vergleichen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Tiffi41
User
Beiträge: 8
Registriert: Dienstag 16. Juni 2015, 09:16

Hallo,
Nach einem Python Anfänger Kurs versuche ich mich nun an meinem ersten eigenen Programm (Farb- und Typanalyse in der Kosmetik). Langsam verzweifel ich jedoch an einem mir rätselhaften und unauffindbaren Fehler. Vielleicht könnt Ihr mir einen Denkanstoß geben, ich finde einfach nichts... Hier ist eine stark gekürzte Version meines Programmes:

Code: Alles auswählen

from collections import *

a0=input("Wie schätzen Sie die Farbe Ihrer Augen ein?:")
t0=input("Wie würden Sie die Farbe Ihres Teints beschreiben?:")
h0=input("Geben Sie nun die Farbe Ihres Haares an:")


d=defaultdict(list)
d["augen"]=["blau", "blaugrau", "graugruen", "dunkelgrau", "kuehl"]
d["teint"]=["hell", "hellbeige", "rosig", "porzellanteint", "kuehl"]
d["haar"]=["dunkelbraun", "schwarz", "kuehl", "schwarzbraun"]

antwort=""
while antwort!="nein":
    if a0 in d["augen"]:
        if t0 in d["teint"]:
            if h0 in d["haar"]:
                print(a0)
    else:
        print(t0)

antwort=input("Möchten Sie einen weiteren Versuch starten?")
Selbst wenn a0="blau" ist (also ein string, der in d["augen"] offensichtlich enthalten ist), gibt es mir nur t0 aus. Offenbar kann es den Input nicht mit dem dict Wert vergleichen. Weiterhin mysteriös ist, dass t0 ohne Ende ausgegeben wird - ich dachte das Problem hätte ich mit einer While-Schleife umgangen.
Hab ich da irgendwo einen Denkfehler? Müsste nicht a0 ausgegeben werden??
Ich bin für jede Hilfe dankbar.

Liebe Grüße
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Tiffi41: Sternchenimporte sollte man nicht machen. Das defaultdict macht in diesem Programm auch gar keinen Sinn, es erschwert nur die Fehlersuche, wenn man sich beim Key verschrieben hat und sich wundert, dass Elemente nicht in einer Liste sind, wo man glaubt, dass sie drin sind.

Was soll die 0 an den Variablennamen? Variablennamen sollten aussagekräftig sein, a0, t0, h0 und d sind es nicht. Du hast eine while-Schleife, in deren Inneren nichts getan wird um die Bedingung zu verändern -> Endlosschleife.
Tiffi41
User
Beiträge: 8
Registriert: Dienstag 16. Juni 2015, 09:16

defaultdict und Sternchenimport, damit es später keine Fehler gibt, wenn mal ein Input nicht im Dict gefunden werden kann - aber da hast du wohl recht.
In dem Programm wird später der Input mit neun Dictionarys verglichen, um abzuklären in welcher dieser neun Farbypen sich der User einordnen lässt. Im fertigen Programm wird also statt print(a0), eine Datei mit dem entsprechenden Zuordnungstyp geöffnet aber um Verwirrung zu vermeiden habe ich hier im Ausschnitt alles etwas vereinfacht.
Meinst du, dass es schlicht daran liegt, dass immer wieder alles wiederholt ausgegeben wird? Das heißt, wenn ich eine Datei öffnen lasse an dieser Stelle, wird diese nicht fünfzig mal geöffnet?
Tiffi41
User
Beiträge: 8
Registriert: Dienstag 16. Juni 2015, 09:16

Übrigens heißen die Variablen a0, t0 und h0 für "Augenfarbe", "Teintbeschaffenheit" und "Haarfarbe".
Und daran liegt es sicherlich nicht, dass nichts konkretes ausgegeben wird :) sind ja nur Namen
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@Tiffi41
  1. Mit Sternchenimporten handelst Du Dir früher oder später unerwartete Probleme ein, da Du damit die Namen eines Moduls in Dein Modul übernimmst und dabei eventuell vorhandene Namen überschreibst. Wenn Du nicht das ganze Modul haben möchtest, dann wenigstens

    Code: Alles auswählen

    from collections import defaultdict
    Besser fände ich sogar

    Code: Alles auswählen

    from collections import defaultdict as DefaultDict
    um PEP8 gerecht zu werden.
  2. Warum `a0`, `t0`, `h0` und nicht gleich `augenfarbe`, `teint`, `haarfarbe`?
  3. Warum benutzt Du `defaultdict`? Ein "normales" `dict` würde hier reichen. Und auch hier ist ein Name `d` sowas von nichts sagend... `merkmale` oder etwas in der Art?
  4. Die Ausgabe von `a0` bzw. `t0` findet endlos statt, weil die Endlosschleife endlos läuft... ;-) Du möchtest die Schleife durch eine Nachfrage unterbrechen. Die Nachfrage befindet sich aber außerhalb der Schleife! Ich persönlich bevorzuge bei solchen Dingen eher das Unterbrechen mittels ``break``, also sowas in der Art:

    Code: Alles auswählen

    while True:
        if input('Continue? ') in 'nN':
            break
  5. Mir ist nicht wirklich klar, welche Ausgabe Du eigentlich erwartest. Jedenfalls glaube ich, dass diese verschachtelten ``if ...``'s nicht der richtige Weg dahin sind...
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Bei mir "klappt" das oben gezeigte Programm übrigens! Es wird brav ewig lange "blau" ausgegeben, wenn ich alle Fragen mit gültigen Werten beantworte und meine Angabe zur Augenfarbe "blau" war ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Tiffi41
User
Beiträge: 8
Registriert: Dienstag 16. Juni 2015, 09:16

Achso! Ja super das werde ich gleich direkt mal ausprobieren, vielen Dank! Im Laufe des Programms soll der Input mit neun verschiedenen Dictioanrys verglichen werden - wenn die drei Eingaben zusammen zu einem Dict passen, soll eine Datei mit Informationen zu dem jeweilig zutreffendem Farbentyp ausgegeben werden. Ich hab das hier ziemlich vereinfacht und nicht daran gedacht, dass das für Nicht-Eingeweihte keinen Sinn macht... :D...
Tiffi41
User
Beiträge: 8
Registriert: Dienstag 16. Juni 2015, 09:16

Ich weiß jetzt wo der Fehler war... tatsächlich hab ich alles mit Anführungszeichen eingegeben - was offenbar gar nicht nötig war. Vielleicht war es auch doch das Defaultdict, oder gar beides!

Code: Alles auswählen

 antwort=""



dunkelkalt=dict()
dunkelkalt["augen"]=["blau", "blaugrau", "graugruen", "dunkelgrau", "kühl", "dunkelblau"]
dunkelkalt["teint"]=["hell", "hellbeige", "rosig", "porzellanteint", "kühl"]
dunkelkalt["haar"]=["dunkelbraun", "schwarz", "kühl", "schwarzbraun"]

dunkelwarm=dict()
dunkelwarm["augen"]=["braun", "schwarzbraun", "braungrün", "grünbraun", "olivgruen", "dunkelbraun"]
dunkelwarm["teint"]=["warm", "olive", "kupfer", "bronze", "braun", "dunkel" ]
dunkelwarm["haar"]=["dunkelbraun","schwarz", "dunkel"]

dunkelwarmkalt=dict()#wird nicht angezeigt
dunkelwarmkalt["augen"]=["braun", "grün", "schwarzbraun", "dunkelbraun"]
dunkelwarmkalt["teint"]=["hell", "kühl", "mittel"]
dunkelwarmkalt["haar"]=["dunkelbraun","schwarz", "dunkel", "schwarzbraun"]

hellkalt=dict()
hellkalt["augen"]=["hell", "hellblau", "hellgrau", "graublau", "grau"]
hellkalt["teint"]=["hellbeige", "zartrosé", "hell", "blass"]
hellkalt["haar"]=["blond", "aschblond", "hellblond", "hellaschblond", "weißblond", "platinblond"]

hellwarm=dict()#wird nicht angezeigt
hellwarm["augen"]=["hellblau", "türkis", "hellgrün", "hellbraun", "goldbraun", "bernstein"]
hellwarm["teint"]=["hellmessing", "hellbeige", "sommersprossig"]
hellwarm["haar"]=["rotblond", "flachsblond", "goldbraun", "rötlich"]

hellwarmkalt=dict()#wird nicht angezeigt
hellwarmkalt["augen"]=["hellblau", "türkis", "hellgruen", "hellbraun", "graubraun"]
hellwarmkalt["teint"]=["hellbeige", "beige", "rosig"]
hellwarmkalt["haar"]=["goldblond"]

mittelkalt=dict()
mittelkalt["augen"]=["mittelblau", "graublau", "graugrün", "grau"]
mittelkalt["teint"]=["beige", "rosig"]
mittelkalt["haar"]=["mittelaschblond", "mittelblond", "hellaschbraun", "mittelaschbraun"]

mittelwarm=dict()
mittelwarm["augen"]=["petrolblau", "olivgrün", "hellbraun", "mittelbraun", "braungrün"]
mittelwarm["teint"]=["beige", "messingfarben", "rosig"]
mittelwarm["haar"]=["rot", "rotblond", "kupferrot" "kupferbraun", "hellbraun"]#kupferrot?

mittelwarmkalt=dict()
mittelwarmkalt["augen"]=["braungrün", "blaugraubraun", "grünbraungrau"]#braungrün?
mittelwarmkalt["teint"]=["beige"]
mittelwarmkalt["haar"]=["mittelgoldblond", "hellbraun", "mittelbraun"]


while antwort!="nein":
    Augenfarbe=input("Wie schätzen Sie die Farbe Ihrer Augen ein?:")
    Teint=input("Wie würden Sie die Farbe Ihres Teints beschreiben?:")
    Haarfarbe=input("Geben Sie nun die Farbe Ihres Haares an:")
    
    if Augenfarbe in dunkelkalt["augen"]:
        if Teint in dunkelkalt["teint"]:
            if Haarfarbe in dunkelkalt["haar"]:
                print("dunkelkalt")
                os.startfile("dunkel-kalt-text.pdf")
          
    elif Augenfarbe in dunkelwarm["augen"]:
        if Teint in dunkelwarm["teint"]:
            if Haarfarbe in dunkelwarm["haar"]:
                print("dunkelwarm")
                os.startfile("dunkel-warm-text.pdf")
                
    elif Augenfarbe in dunkelwarmkalt["augen"]:
        if Teint in dunkelwarmkalt["teint"]:
            if Haarfarbe in dunkelwarmkalt["haar"]:
                print("dunkelwarmkalt")
                os.startfile("dunkel-warm-kalt-text.pdf")
                
    elif Augenfarbe in hellkalt["augen"]:
        if Teint in hellkalt["teint"]:
            if Haarfarbe in hellkalt["haar"]:
                print("hellkalt")
                os.startfile("hell-kalt-text.pdf")
                
    elif Augenfarbe in hellwarm["augen"]:
        if Teint in hellwarm["teint"]:
            if Haarfarbe in hellwarm["haar"]:
                print("hellwarm")
                os.startfile("hell-warm-text.pdf")
                
    elif Augenfarbe in hellwarmkalt["augen"]:
        if Teint in hellwarmkalt["teint"]:
            if Haarfarbe in hellwarmkalt["haar"]:
                print("hellwarmkalt")
                os.startfile("hell-warm-kalt-text.pdf")
                
    elif Augenfarbe in mittelkalt["augen"]:
        if Teint in mittelkalt["teint"]:
            if Haarfarbe in mittelkalt["haar"]:
                print("mittelkalt")
                os.startfile("mittel-kalt-text.pdf")
                
    elif Augenfarbe in mittelwarm["augen"]:
        if Teint in mittelwarm["teint"]:
            if Haarfarbe in mittelwarm["haar"]:
                print("mittelwarm")
                os.startfile("mittel-warm-text.pdf")
                
    elif Augenfarbe in mittelwarmkalt["augen"]:
        if Teint in mittelwarmkalt["teint"]:
            if Haarfarbe in mittelwarmkalt["haar"]:
                print("mittelwarmkalt")
                os.startfile("mittel-warm-kalt-text.pdf")


    else:
        print("""Ihr Typ konnte nicht ermittelt werden. Bitte vergewissern Sie sich,
              dass Sie Ihre Angaben so genau wie möglich gemacht haben.
              Informieren Sie sich bei Bedarf im Infoblatt""")#pdf öffnen
        
    antwort=input("Möchten Sie einen weiteren Versuch starten?")

Es klappt jetzt fast alles so weit :) danke noch mal!
Nichtsdestotrotz gibt es immer noch einige Kombinationen, bei denen die entsprechende Datei nicht geöffnet wird. Liegt das daran, dass die Schleifen so aufwendig und umständlich verschachtelt sind? Aber dann würden es ja nicht im Großen und Ganzen funktionieren oder?
Tiffi41
User
Beiträge: 8
Registriert: Dienstag 16. Juni 2015, 09:16

aaaach oder weil ich nur Anweisungen dafür habe, falls eins zutrifft oder keins und nicht falls zwei Bedingungen in Frage kämen
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Tiffi41: Was passiert, wenn die Augenfarbe stimmt, der Taint aber nicht?

Statt der vielen Variablen solltest Du alles in eine Liste packen. Du kannst ja die Wörterbücher noch um "Typ" und "Pdf" erweitern.
Tiffi41
User
Beiträge: 8
Registriert: Dienstag 16. Juni 2015, 09:16

Wenn die Augenfarbe stimmt und der Teint nicht, soll das Programm (eigentlich :[ ) in die nächste Schleife übergehen! Um das passende Dict und den passenden Typ zu finden. Wenn ich erst mal eine fehlerfrei funktionierende Schleife raushabe, würde ich das Ganze gern mit einer Funktion gestalten, das sieht mir in Moment noch zu durcheinander aus.
Entschuldige mich bitte, ich stehe grade auf der Leitung. Du meinst, ein Dict soll alles an den entsprechenden Hautfarben, Haarfarben etc. und den Typ und die PDF enthalten? Ich kann mir momentan leider nicht richtig vorstellen, was du meinst. Ich dachte es wäre besser, Augen- Haar- und Hautfarbe jeweils getrennt im Dict zu definieren. Sodass der user diese eingeben kann, und die Schleife Dict für Dict durchgeht, bis eines für alle Variabeln zutrifft.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Und genau dieses Durchgehen wäre mit einer Liste und einer for-Schleife viel einfacher.
Tiffi41
User
Beiträge: 8
Registriert: Dienstag 16. Juni 2015, 09:16

mh ich versuchs mal, danke :)!
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@Tiffi41
Ich denke mal, Sirius3 meint eine Struktur wie diese:

Code: Alles auswählen

types = [
    {'typ': 'dunkelkalt',
     'pdf': 'dunkel-kalt-text.pdf',
     'augen': ["blau", "blaugrau", "graugrün",
               "dunkelgrau", "kühl", "dunkelblau"],
     'teint': ["hell", "hellbeige", "rosig",
               "porzellanteint", "kühl"],
     'haar': ["dunkelbraun", "schwarz", "kühl", "schwarzbraun"]},
    {'typ': 'dunkelwarm',
     'pdf': 'dunkel-warm-text.pdf',
     'augen': ["braun", "schwarzbraun", "braungrün",
               "grünbraun", "olivgruen", "dunkelbraun"],
     'teint': ["warm", "olive", "kupfer", "bronze",
               "braun", "dunkel"],
     'haar': ["dunkelbraun", "schwarz", "dunkel"]}
    ]
Sowas hat den Vorteil,
  • ... dass man sich beim Verarbeiten (z. B. durchsuchen) nicht das Genick in endlosen ``if ...`` Tiraden bricht und für veränderte Daten nicht den Code ändern muss.
  • ... dass man das aufgrund seiner Kompaktheit relativ einfach z. B. als JSON Datei speichern kann und somit Code von Daten trennt, was immer eine gute Idee ist.
  • ... man die Daten recht einfach auch erweitern kann, z. B.:

    Code: Alles auswählen

    def define_type():
        typ = input('Bezeichnung: ')
        augen = input('Zu {} passende Augenfarben: '.format(typ)).split()
        teint = input('Zu {} passende Teints: '.format(typ)).split()
        haar = input('Zu {} passende Haarfarben: '.format(typ)).split()
        pdf = input('Dateiname der zu {} gehörigen PDF: '.format(typ))
        return {
            'typ': typ, 'augen': augen, 'teint': teint, 'haar': haar, 'pdf': pdf
        }

    Code: Alles auswählen

    >>> types.append(define_type())
    Bezeichnung: dunkelwarmkalt
    Zu dunkelwarmkalt passende Augenfarben: braun grün schwarzbraun dunkelbraun
    Zu dunkelwarmkalt passende Teints: hell kühl mittel
    Zu dunkelwarmkalt passende Haarfarben: dunkelbraun schwarz dunkel schwarzbraun
    Dateiname der zu dunkelwarmkalt gehörigen PDF: dunkel-warm-kalt-text.pdf
    >>> types[-1]
    {'pdf': 'dunkel-warm-kalt-text.pdf', 'augen': ['braun', 'grün', 'schwarzbraun', 'dunkelbraun'], 'typ': 'dunkelwarmkalt', 'teint': ['hell', 'kühl', 'mittel'], 'haar': ['dunkelbraun', 'schwarz', 'dunkel', 'schwarzbraun']}
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Antworten