Seite 1 von 2

mehrere dict nacheinander nach Keys durchsuchen.

Verfasst: Samstag 27. September 2025, 18:23
von kiaralle
Hallo,

ich hätte ein kleines Problemchen.

Folgendes möchte ich realisieren.
In einem Geber können bis zu vier Fehlernummern hinterlegt sein.
Laut Beschreibung, können diese nacheinander ausgelesen werden.
Also dachte ich mir, ich bastle mir ein dict in denen die Fehlerbereiche aufgetrennt werden und ein dict_ fehler_request sendet mir die 4 zu erhaltenen Fehlermeldungen zurück.

Das Dict muss also dynamisch erstellt werden. Geht so etwas?
Meine Versuche sind nicht zielführend.

Kann sich einer mich annehmen?

Gruß Ralf

Code: Alles auswählen

import sick_error

fehlercode = "01" # Beispiel für Fehlercode

print(sick_error.sks_skm(fehlercode))


Code: Alles auswählen

#Datei sick_error


def sks_skm(a):
    initialisierung = {
        "00" :"der Geber hat keinen fehler erkannt",
        "01" :"abgleichdaten fehlerhaft",
        "02" :"interner Winkeloffset fehlerhaft",
        "03" :"tabelle über datenfeldpartitionierung zerstört",
        "04" :" analoge grenzwerte nicht verfügbar",
        "05" :"interner i2c-Bus nicht funktionsfähig",
        "06" :"interner checksummenfehler"             
        }

  
    protokoll = {
        "07":" geberreset durch Programmüberwachung aufgetreten",
        "09":" Parityfehler",
        "0a":" checksumme der übertragenen daten ist falsch",
        "0B" :"unbekannter Befehlscode",
        "0c" :"anzahl der übertragenen daten ist falsch",
        "0d" :"übertragenes Befehlsargument ist unzulässig",
        }
  
    daten = {
        "0e" :"das selektierte datenfeld darf nicht beschrieben werden",
        "0f":"falscher Zugriffscode",
        "10":"angegebenes datenfeld in seiner größe nicht veränderbar",
        "11":" angegebene Wortadresse außerhalb datenfeld",
        "12" :"Zugriff auf nicht existierendes datenfeld"
        }
       
    position = {
        "01":"Analogsignale außerhalb Spezifikation",
        "1f":"drehzahl zu hoch, keine Positionsbildung möglich",
        "20":"Position Singleturn unzuverlässig",
        "21":"Positionsfehler multiturn",
        "22":"Positionsfehler multiturn",
        "23":"Positionsfehler multiturn"
        }
    
   
    andere = {
        "1c":"Betragsüberwachung der Analogsignale (Prozessdaten)",
        "1d":"Senderstrom kritisch (Verschmutzung, Senderbruch)",
        "1e":"gebertemperatur kritisch",
        "08":"überlauf des Zählers"
        }   
 
    fehlerbereiche=[
        "initialisierung" ,
        "protokoll" ,
        "daten" ,
        "position" ,
        "andere"
        ]
    
   
    i=0
    
   

    while i <=4:

    	bau mir ein Dict
	

        i = i+1
    

    return fehler_request



Re: mehrere dict nacheinander nach Keys durchsuchen.

Verfasst: Samstag 27. September 2025, 19:20
von kiaralle
Ich hänge hier voll danaben....

warum funktioniert das so nicht?

Code: Alles auswählen


    i=0
    fehlercode = "00"


    while i <4:

        if fehlercode in fehlerbereiche[0].keys():
            ,,,,,
        i = i+1


Fehlermeldung:

if fehlercode in fehlerbereiche[0].keys():
AttributeError: 'str' object has no attribute 'keys'

Ja sicher. das Element aus der Liste hat ja kein key.

fehlerbereiche[0] soll ja mein Dict sein aus dem ich abfrage. :roll:

Re: mehrere dict nacheinander nach Keys durchsuchen.

Verfasst: Samstag 27. September 2025, 19:23
von sparrow
Das Konstrukt ist in Python auf jeden Fall ein Antipattern:

Code: Alles auswählen

    i=0

    while i <=4:
    	bau mir ein Dict
        i = i+1
Ich verstehe nicht, was "fehlerbereiche" sein soll. Ist das die dynamische Benennung der Namen der Dicts?

Und aus dem Namen der Funktion geht leider auch gar nicht hervor, was da passieren soll. Keine Ahnung welche Buchstaben da bei sks_skm verschluckt wurden. Steht das für Schaukelstuhl Sakrament?
Lange Rede kurzer Sinn: Du solltes das Problem beschreiben, das du lösen möchtest - nicht das, was du für die Lösung hälst. Die Lösung sieht sehr falsch aus.

Re: mehrere dict nacheinander nach Keys durchsuchen.

Verfasst: Samstag 27. September 2025, 19:27
von Dennis89
Hallo,

wieso schreibst du das nicht einfach gleich so?

Code: Alles auswählen

def sks_skm(a):
    key_to_value = {
        "initialisierung": {
            "00": "der Geber hat keinen fehler erkannt",
            "01": "abgleichdaten fehlerhaft",
            "02": "interner Winkeloffset fehlerhaft",
            "03": "tabelle über datenfeldpartitionierung zerstört",
            "04": " analoge grenzwerte nicht verfügbar",
            "05": "interner i2c-Bus nicht funktionsfähig",
            "06": "interner checksummenfehler",
        },
        "protokoll": {
            "07": " geberreset durch Programmüberwachung aufgetreten",
            "09": " Parityfehler",
            "0a": " checksumme der übertragenen daten ist falsch",
            "0B": "unbekannter Befehlscode",
            "0c": "anzahl der übertragenen daten ist falsch",
            "0d": "übertragenes Befehlsargument ist unzulässig",
        },
        "daten": {
            "0e": "das selektierte datenfeld darf nicht beschrieben werden",
            "0f": "falscher Zugriffscode",
            "10": "angegebenes datenfeld in seiner größe nicht veränderbar",
            "11": " angegebene Wortadresse außerhalb datenfeld",
            "12": "Zugriff auf nicht existierendes datenfeld",
        },
        "position": {
            "01": "Analogsignale außerhalb Spezifikation",
            "1f": "drehzahl zu hoch, keine Positionsbildung möglich",
            "20": "Position Singleturn unzuverlässig",
            "21": "Positionsfehler multiturn",
            "22": "Positionsfehler multiturn",
            "23": "Positionsfehler multiturn",
        },
    }
    print(list(key_to_value["initialisierung"].keys()))
Edit: Ah ich glaube ich verstehe, du hast einen Fehlercode, der wird der Funktion als Argument `a` übergeben und die Funktion soll die Beschreibung des Fehlercodes zurück geben und dadurch das ganze Wörterbuch durchsuchen?

Re: mehrere dict nacheinander nach Keys durchsuchen.

Verfasst: Samstag 27. September 2025, 19:32
von kiaralle
Meine Frage wäre:

ich Frage ein Dict mit dict_name(dict_key) ab. Ich erhalte das Value aus dem Wert. Richtig?
Wie könnte ich den Nahmen des Dict durch ein dynamischen Namen ersetzen. eventuell aus einer Liste.

also so in etwa:

list_name(i)(dict_key)

Re: mehrere dict nacheinander nach Keys durchsuchen.

Verfasst: Samstag 27. September 2025, 19:36
von kiaralle
@Dennis89
Edit: Ah ich glaube ich verstehe, du hast einen Fehlercode, der wird der Funktion als Argument `a` übergeben und die Funktion soll die Beschreibung des Fehlercodes zurück geben und dadurch das ganze Wörterbuch durchsuchen?
Genau.
Ich dachte ich könnte das dict(initialisierung) in print(list(key_to_value["initialisierung"].keys())) dynamisch ersetzen.

Re: mehrere dict nacheinander nach Keys durchsuchen.

Verfasst: Samstag 27. September 2025, 19:38
von kiaralle
sparrow hat geschrieben: Samstag 27. September 2025, 19:23 Ich verstehe nicht, was "fehlerbereiche" sein soll. Ist das die dynamische Benennung der Namen der Dicts?
Richtig gedacht.

Re: mehrere dict nacheinander nach Keys durchsuchen.

Verfasst: Samstag 27. September 2025, 19:40
von Dennis89
Ja.
So:

Code: Alles auswählen

SECTOR_TO_ERROR = {
    "initialisierung": {
        "00": "der Geber hat keinen fehler erkannt",
        "01": "abgleichdaten fehlerhaft",
        "02": "interner Winkeloffset fehlerhaft",
        "03": "tabelle über datenfeldpartitionierung zerstört",
        "04": " analoge grenzwerte nicht verfügbar",
        "05": "interner i2c-Bus nicht funktionsfähig",
        "06": "interner checksummenfehler",
    },
    "protokoll": {
        "07": " geberreset durch Programmüberwachung aufgetreten",
        "09": " Parityfehler",
        "0a": " checksumme der übertragenen daten ist falsch",
        "0B": "unbekannter Befehlscode",
        "0c": "anzahl der übertragenen daten ist falsch",
        "0d": "übertragenes Befehlsargument ist unzulässig",
    },
    "daten": {
        "0e": "das selektierte datenfeld darf nicht beschrieben werden",
        "0f": "falscher Zugriffscode",
        "10": "angegebenes datenfeld in seiner größe nicht veränderbar",
        "11": " angegebene Wortadresse außerhalb datenfeld",
        "12": "Zugriff auf nicht existierendes datenfeld",
    },
    "position": {
        "01": "Analogsignale außerhalb Spezifikation",
        "1f": "drehzahl zu hoch, keine Positionsbildung möglich",
        "20": "Position Singleturn unzuverlässig",
        "21": "Positionsfehler multiturn",
        "22": "Positionsfehler multiturn",
        "23": "Positionsfehler multiturn",
    },
}


def change_names(names):
    return dict(zip(names, SECTOR_TO_ERROR.values()))
        


print(change_names(["a", "b", "c", "d"]))

Willst du das als Ergebnis?

Code: Alles auswählen

SECTOR_TO_ERROR = {
    "initialisierung": {
        "00": "der Geber hat keinen fehler erkannt",
        "01": "abgleichdaten fehlerhaft",
        "02": "interner Winkeloffset fehlerhaft",
        "03": "tabelle über datenfeldpartitionierung zerstört",
        "04": " analoge grenzwerte nicht verfügbar",
        "05": "interner i2c-Bus nicht funktionsfähig",
        "06": "interner checksummenfehler",
    },
    "protokoll": {
        "07": " geberreset durch Programmüberwachung aufgetreten",
        "09": " Parityfehler",
        "0a": " checksumme der übertragenen daten ist falsch",
        "0B": "unbekannter Befehlscode",
        "0c": "anzahl der übertragenen daten ist falsch",
        "0d": "übertragenes Befehlsargument ist unzulässig",
    },
    "daten": {
        "0e": "das selektierte datenfeld darf nicht beschrieben werden",
        "0f": "falscher Zugriffscode",
        "10": "angegebenes datenfeld in seiner größe nicht veränderbar",
        "11": " angegebene Wortadresse außerhalb datenfeld",
        "12": "Zugriff auf nicht existierendes datenfeld",
    },
    "position": {
        "01": "Analogsignale außerhalb Spezifikation",
        "1f": "drehzahl zu hoch, keine Positionsbildung möglich",
        "20": "Position Singleturn unzuverlässig",
        "21": "Positionsfehler multiturn",
        "22": "Positionsfehler multiturn",
        "23": "Positionsfehler multiturn",
    },
}


def get_error(error_code):
    for sector in SECTOR_TO_ERROR.values():
        if error_code in sector:
            print(f"Fehlercode <{error_code}> bedeutet:\n{sector[error_code]}")


get_error("23")

Re: mehrere dict nacheinander nach Keys durchsuchen.

Verfasst: Samstag 27. September 2025, 19:41
von Sirius3
@kiaralle: so wie es Dennis89 doch zeigt, Du packst alle Deine Wörterbücher in eine andere Datenstruktur. Wobei es ja nicht eindeutig ist, weil der selbe Fehlercode in mehreren Fehlerbereichen vorkommt.

Code: Alles auswählen

for fehlerbereich, fehler_bezeichnung in key_to_value.items():
    if fehler in fehler_bezeichnung:
        print(fehlerbereich, fehler_bezeichnung[fehler])
Gewöhn Dir am besten von Anfang an gute Variaben- und Funktionsnamen, `a` ist völlig nichtssagend und was `sks_skm` bedeuten soll, erschließt sich auch nicht.

Re: mehrere dict nacheinander nach Keys durchsuchen.

Verfasst: Samstag 27. September 2025, 19:43
von noisefloor
Hallo,

was ist denn ein "dynamischer Name"? Namen sind immer an ein Objekt gebunden, die Bindung kannst du zur Laufzeit ändern. Und du dann mehrere Namen an ein Objekt binden.

Am besten zeigst du mal den Code, den du hast (=der nicht das macht, was du gerne hättest) und schreibst an der Stelle, wo das Programm nicht den von dir gewünschten Wert liefert, dazu, was du da gerne hättest.

Gruß, noisefloor

Re: mehrere dict nacheinander nach Keys durchsuchen.

Verfasst: Samstag 27. September 2025, 19:48
von kiaralle
@noisefloor
dynamischer Name" ist ein Überbleibsel von PHP. Da geht so was.

Code: Alles auswählen

Schleife:
  name_$i;
 .....
 $i ++; 
 
name_1, name_2......

Re: mehrere dict nacheinander nach Keys durchsuchen.

Verfasst: Samstag 27. September 2025, 19:55
von noisefloor
Ok - aber wo brauchst du denn jetzt in Python "dynamische Name"? Bei den Schlüsseln für das neue Dict? Wenn du als Schlüssel eine String nimmst kannst du den String mit den Bordmitteln von Python dynamisch Zusammenbauen.

Gruß, noisefloor

Re: mehrere dict nacheinander nach Keys durchsuchen.

Verfasst: Samstag 27. September 2025, 19:57
von kiaralle
@Dennis89
dein zweiter Code kommt meinem Wunsch schon sehr nahe.
Vor allem weil beim Fehlercode "01" der kommt ja zweimal vor, beide Fehler gemeldet werden.
Danke darauf kann ich weiter aufbauen.

Re: mehrere dict nacheinander nach Keys durchsuchen.

Verfasst: Samstag 27. September 2025, 19:58
von kiaralle
noisefloor hat geschrieben: Samstag 27. September 2025, 19:55 Ok - aber wo brauchst du denn jetzt in Python "dynamische Name"? Bei den Schlüsseln für das neue Dict? Wenn du als Schlüssel eine String nimmst kannst du den String mit den Bordmitteln von Python dynamisch Zusammenbauen.

Gruß, noisefloor

Daran bin ich ja gescheitert.
Mein Wissensstand ist eben noch sehr mager :D

Re: mehrere dict nacheinander nach Keys durchsuchen.

Verfasst: Samstag 27. September 2025, 20:05
von noisefloor
Aha... aber das ist doch nicht wirklich anders als in PHP:

Code: Alles auswählen

>>> some_dict = {}
>>> for i in range(1, 4):
...     some_dict[f'key_{i}'] = 'foo'
...
>>> some_dict
{'key_1': 'foo', 'key_2': 'foo', 'key_3': 'foo'}
>>>
Ob das sinnvoll ist, ist ein anderes Thema. Wenn man in Python irgendwas durchnummeriert, dann braucht man i.d.R. eine Liste, worauf man per Index zugreift. Wenn das 2. Beispiel von @Dennis89 fast das macht, was du brauchst, dann hat das aber nix mit dynamischen Namen zu tun. Dann fehlt dir eher noch das Verständnis von passenden Datenstrukturen und Iteration darüber. Iteration ist in Python ziemlich wichtig, weil Python Iteratoren an vielen Stellen unterstützt.

Gruß, noisefloor

Re: mehrere dict nacheinander nach Keys durchsuchen.

Verfasst: Samstag 27. September 2025, 20:12
von sparrow
@kiaralle: Ich würde das gar nich so machen. Deshalb auch meine Frage, welches Problem du eigentlich lösen willst. Wenn es dir um das Mappen von Fehlercodes auf Fehlermeldungen (also Text) geht, ist das, was du hier versuchst, super kompliziert und wirkt so wie ich das Problem verstehe auch falsch.

Du brauchst auf jeden Fall den Kontext, um eine Fehlermeldung zuordnen zu können. Den hast du aber in deiner Funktion gar nicht. Also rätst du irgendwas.
Woher bekommst du den Kontext? Woher weißt du, dass "01" in den Daten oder in der Initialisierung aufgetreten ist? _Dort_ musst du auf die Meldungen zugreifen. Nicht in einer Funktion in der du das alles zusammenwürfelst.

Deshalb gehen die Vorschläge hier, die das ganz ohne Funktion machen und die Dicts als Konstanten definieren, in meinen Augen eher in die richtige Richtung.

Re: mehrere dict nacheinander nach Keys durchsuchen.

Verfasst: Samstag 27. September 2025, 20:14
von kiaralle
Ja, das von Dennis89 ist eine andere Herangehensweise.

"dynamische Name" benötige ich eigentlich nicht. Ist etwas falsch beschrieben.
Ich möchte die das aufzurufende Dict aus einer Liste heraus aufrufen.

Liste ----- > fehlerbereiche=["initialisierung","protokoll","daten","position","andere"] ----> Dict_Name

Ob das jetzt noch Sinnvoll erscheint... Ich weiß es gerade nicht.

Re: mehrere dict nacheinander nach Keys durchsuchen.

Verfasst: Samstag 27. September 2025, 20:24
von kiaralle
@sparrow

Du könntest hier etwas rechte haben. Mit meinen doch recht begrenzten Wissen habe ich ein Projekt am laufen, was auch zum Teil schon funktioniert.
Ich rufe von Gebern des Herstellers Sick, Protokoll Hiperface, Daten ab und richte den Geber am Servomotor neu ein. Das läuft super.
Ein Programm habe ich etwas rudimentär mit Tkinter am laufen.

Nun hat jeder Gebertyp seine eigenen Fehlerwerte. Die übernehme ich aus dem jeweiligen Datenblatt des Gebers in dein Typen-gebundenes Dict. Deshalb zum Bleistift srs_skm.
Nach der Abfrage sende ich den Gebertyp und den Fehlercode an meine Lib sick_error.
Ich erhalte die Beschreibung des Fehlercodes.

Jedenfalls habe ich wieder etwas gelernt ;-)

Re: mehrere dict nacheinander nach Keys durchsuchen.

Verfasst: Samstag 27. September 2025, 20:32
von sparrow
Aber weißt du denn in dem Moment der Abfrage, welchen Gebertyp du ansprichst?

Re: mehrere dict nacheinander nach Keys durchsuchen.

Verfasst: Samstag 27. September 2025, 20:42
von kiaralle
sparrow hat geschrieben: Samstag 27. September 2025, 20:32 Aber weißt du denn in dem Moment der Abfrage, welchen Gebertyp du ansprichst?
jo, weiß ich

Am beispiel von denny89 müsste ich etwas ändern.

Warum kann ich für model keinen String übergeben. Oder wie löse ich das?


Code: Alles auswählen

srs_skm = {
    "initialisierung": {
        "00": "der Geber hat keinen fehler erkannt",
        "01": "abgleichdaten fehlerhaft",
        "02": "interner Winkeloffset fehlerhaft",
        "03": "tabelle über datenfeldpartitionierung zerstört",
        "04": " analoge grenzwerte nicht verfügbar",
        "05": "interner i2c-Bus nicht funktionsfähig",
        "06": "interner checksummenfehler",
    },
    "protokoll": {
        "07": " geberreset durch Programmüberwachung aufgetreten",
        "09": " Parityfehler",
        "0a": " checksumme der übertragenen daten ist falsch",
        "0B": "unbekannter Befehlscode",
        "0c": "anzahl der übertragenen daten ist falsch",
        "0d": "übertragenes Befehlsargument ist unzulässig",
    },
    "daten": {
        "0e": "das selektierte datenfeld darf nicht beschrieben werden",
        "0f": "falscher Zugriffscode",
        "10": "angegebenes datenfeld in seiner größe nicht veränderbar",
        "11": " angegebene Wortadresse außerhalb datenfeld",
        "12": "Zugriff auf nicht existierendes datenfeld",
    },
    "position": {
        "01": "Analogsignale außerhalb Spezifikation",
        "1f": "drehzahl zu hoch, keine Positionsbildung möglich",
        "20": "Position Singleturn unzuverlässig",
        "21": "Positionsfehler multiturn",
        "22": "Positionsfehler multiturn",
        "23": "Positionsfehler multiturn",
    },
}


def get_error(model,error_code):
    for sector in model.values():
        if error_code in sector:
            print(f"Fehlercode <{error_code}> bedeutet:\n{sector[error_code]}")
            
model = "srs_skm"
error_code = "00" 
get_error(model,error_code)