Seite 1 von 2

Variablen in einer Schleife in Array eintragen

Verfasst: Donnerstag 28. Februar 2019, 13:25
von Wolle_wtal
Hallo zusammen,

ich bin neu hier und auch neu in Python und finde mich noch nicht so richtig mit der Python Syntax zurecht.
Im Prinzip ist mein Codeabschnitt funktionsfähig, allerdings würde ich meine Werte am liebsten nicht in 20 einzelne Variablen, sondern in ein Array oder eine Liste eintragen.
Das sollte nicht so schwierig sein und dazu hat mir die Suche schon einige Beispiele ausgespuckt.

Jetzt habe ich aber ein Problem, ich möchte das ganze mit wenigen Zeilen Code in eine Schleife packen und da verstehe ich leider nicht, wie ich meine Werte aus self.PIN_I_E1 … E20 dynamisch über die Schleife angesprochen bekomme.

1-20 ist auch nur als Beispiel, später werden es viel mehr inputs.

Währe nett wenn mir da jemand Hilfestellung leisten könnte.

Gruß, Wolle

Code: Alles auswählen

self.e1 = self._get_input_value(self.PIN_I_E1)
self.e2 = self._get_input_value(self.PIN_I_E2)
self.e3 = self._get_input_value(self.PIN_I_E3)
self.e4 = self._get_input_value(self.PIN_I_E4)
self.e5 = self._get_input_value(self.PIN_I_E5)
self.e6 = self._get_input_value(self.PIN_I_E6)
self.e7 = self._get_input_value(self.PIN_I_E7)
self.e8 = self._get_input_value(self.PIN_I_E8)
self.e9 = self._get_input_value(self.PIN_I_E9)
self.e10 = self._get_input_value(self.PIN_I_E10)
self.e11 = self._get_input_value(self.PIN_I_E11)
self.e12 = self._get_input_value(self.PIN_I_E12)
self.e13 = self._get_input_value(self.PIN_I_E13)
self.e14 = self._get_input_value(self.PIN_I_E14)
self.e15 = self._get_input_value(self.PIN_I_E15)
self.e16 = self._get_input_value(self.PIN_I_E16)
self.e17 = self._get_input_value(self.PIN_I_E17)
self.e18 = self._get_input_value(self.PIN_I_E18)
self.e19 = self._get_input_value(self.PIN_I_E19)
self.e20 = self._get_input_value(self.PIN_I_E20)

Re: Variablen in einer Schleife in Array eintragen

Verfasst: Donnerstag 28. Februar 2019, 14:08
von sparrow
Wie und wer definiert denn self.PIN_I_*?
Denn immer wenn Werte durchnummeriert werden (auch Konstanten) möchte man eigentlich eine Datenstruktur verwenden.

Gleiches gilt für self.e*

Re: Variablen in einer Schleife in Array eintragen

Verfasst: Donnerstag 28. Februar 2019, 14:32
von Wolle_wtal
Mag sein, aber darauf haben wir gerade keinen Einfluss.

die Definition wird durch ein Script automatisch generiert und ist für uns damit erstmal außen vor. Mir geht es nur um meine Frage, nicht um das wieso oder warum.
Aber der Vollständigkeit halber eine kurze Erklärung. Ich lege in einem Konfigurator für einen Logikbaustein der in einem Gebäudeautomationssystem verwendet wird genau fest wie viele Eingänge und Ausgänge mein Logikbaustein haben soll und wie diese heißen.
Daraus generiert mir ein Tool, auf das ich keinerlei Einfluss habe dann die Definitionen. In diesem Beispiel self.PIN_I_E1 … E20 für 20 Eingänge im Logikgatter.

Was mit den Eingangs und Ausgangswerten passiert kann man dann selber proggen und genau damit beschäftige ich mich gerade und weil mir das hinterher zu viele Zeilen Code sind, würde ich das gerne in einer Schleife abkürzen.

Gruß, Wolle

Re: Variablen in einer Schleife in Array eintragen

Verfasst: Donnerstag 28. Februar 2019, 14:38
von sparrow
Das wieso oder warum ist aber schon wichtig, sonst würde ich nicht fragen.

Dein Tool baut dir Python-Code? Dann zeig mal, was der erzeugt.

Re: Variablen in einer Schleife in Array eintragen

Verfasst: Donnerstag 28. Februar 2019, 14:51
von __deets__
Wenn du keinen Einfluss darauf hast, kannst du nur bedingt weit automatisieren. Aber das hier zb reduziert den Tipp-Auwfand schon deutlich:

Code: Alles auswählen

inputs = [
     self._get_input_value(pin)
     for pin in (
            self.PIN_I_E1, 
                ...,  
            self.PIN_I_E20
            )
       ] # achtung, du musst natuerilch alle Pins eintragen!

Re: Variablen in einer Schleife in Array eintragen

Verfasst: Donnerstag 28. Februar 2019, 14:52
von Wolle_wtal
Der obere Teil wird vom generator erzeugt.

Ich beeinflusse nur

def on_init(self):
und
def on_input_value(self, index, value):

Der generator hat ein eigenes SDK.

Das Ergebis ist in diesem Fall ein einfaches Additionsgatter mit 20 Eingängen und 2 Ausgängen von denen im Moment aber nur der erste Ausgang angesprochen wird.

Code: Alles auswählen

# coding: iso-8859-15
##!!!!##################################################################################################
#### Own written code can be placed above this commentblock . Do not change or delete commentblock! ####
########################################################################################################
##** Code created by generator - DO NOT CHANGE! **##

class Addition_HSL_2_010002(hsl20_3.BaseModule):

    def __init__(self, homeserver_context):
        hsl20_3.BaseModule.__init__(self, homeserver_context, "Test")
        self.FRAMEWORK = self._get_framework()
        self.LOGGER = self._get_logger(hsl20_3.LOGGING_NONE,())
        self.PIN_I_E1=1
        self.PIN_I_E2=2
        self.PIN_I_E3=3
        self.PIN_I_E4=4
        self.PIN_I_E5=5
        self.PIN_I_E6=6
        self.PIN_I_E7=7
        self.PIN_I_E8=8
        self.PIN_I_E9=9
        self.PIN_I_E10=10
        self.PIN_I_E11=11
        self.PIN_I_E12=12
        self.PIN_I_E13=13
        self.PIN_I_E14=14
        self.PIN_I_E15=15
        self.PIN_I_E16=16
        self.PIN_I_E17=17
        self.PIN_I_E18=18
        self.PIN_I_E19=19
        self.PIN_I_E20=20
        self.PIN_O_A1=1
        self.PIN_O_A2=2
        self.FRAMEWORK._run_in_context_thread(self.on_init)

########################################################################################################
#### Own written code can be placed after this commentblock . Do not change or delete commentblock! ####
###################################################################################################!!!##

    def on_init(self):
        pass



    def on_input_value(self, index, value):
        self.e1 = self._get_input_value(self.PIN_I_E1)
        self.e2 = self._get_input_value(self.PIN_I_E2)
        self.e3 = self._get_input_value(self.PIN_I_E3)
        self.e4 = self._get_input_value(self.PIN_I_E4)
        self.e5 = self._get_input_value(self.PIN_I_E5)
        self.e6 = self._get_input_value(self.PIN_I_E6)
        self.e7 = self._get_input_value(self.PIN_I_E7)
        self.e8 = self._get_input_value(self.PIN_I_E8)
        self.e9 = self._get_input_value(self.PIN_I_E9)
        self.e10 = self._get_input_value(self.PIN_I_E10)
        self.e11 = self._get_input_value(self.PIN_I_E11)
        self.e12 = self._get_input_value(self.PIN_I_E12)
        self.e13 = self._get_input_value(self.PIN_I_E13)
        self.e14 = self._get_input_value(self.PIN_I_E14)
        self.e15 = self._get_input_value(self.PIN_I_E15)
        self.e16 = self._get_input_value(self.PIN_I_E16)
        self.e17 = self._get_input_value(self.PIN_I_E17)
        self.e18 = self._get_input_value(self.PIN_I_E18)
        self.e19 = self._get_input_value(self.PIN_I_E19)
        self.e20 = self._get_input_value(self.PIN_I_E20)


        self.Ergebnis = self.e1 + self.e2 + self.e3 + self.e4 + self.e5 + self.e6 + self.e7 + self.e8 + self.e9 + self.e10 + self.e11 + self.e12 + self.e13 + self.e14 + self.e15 + self.e16 + self.e17 + self.e18 + self.e19 + self.e20

        self._set_output_value(self.PIN_O_A1, self.Ergebnis)



Re: Variablen in einer Schleife in Array eintragen

Verfasst: Donnerstag 28. Februar 2019, 14:56
von __deets__
Ist das in Ordnung den Anweisungen des Generators nicht zu folgen, und Code *unter* den gerenierten Kommentar zu schreiben?

Wie dem auch sei: mit dem von mir dargestellten Ansatz kannst du dann noch ein

Code: Alles auswählen

self._set_output_value(self.PIN_O_A1, sum(inputs))
dahinter packen, und has deinen bisherigen Code abgedeckt. Die explizite Auflistung der Pins aber bleibt dir nicht erspart.

Und noch ein Hinweis: das permanente an-self-gebinde ist ueberfluessig, da du die Werte ja nur fuer eine lokale Berechnung brauchst. Das gilt fuer die ganzen self.eXX ebenso wie fuer self.Ergebnis.

Re: Variablen in einer Schleife in Array eintragen

Verfasst: Donnerstag 28. Februar 2019, 15:16
von sparrow
Da die Pins einfach nur Konstanten für Zahlen sind, sollte das tun:

Code: Alles auswählen

COUNT_INPUT_PINS = 20

def on_input_value(self, index, value):
    ergebnis = 0
    for pin in range(1, COUNT_INPUT_PINS + 1):
        ergebnis += self._get_input_value(pin)
    self._set_output_value(self.PIN_O_A1, ergebnis)

Re: Variablen in einer Schleife in Array eintragen

Verfasst: Donnerstag 28. Februar 2019, 15:22
von __deets__
@sparrow: das ist ein duennes Brett, auf dem du da stehst. Ich wuerde mich zumindest nicht darauf verlassen, dass der erste im Konfigurator angelegte Pin auch dann den Eingang 1 (der ein GPIO sein wird) darstellt. Das *kann* so sein, aber das muss geprueft werden.

Re: Variablen in einer Schleife in Array eintragen

Verfasst: Donnerstag 28. Februar 2019, 15:26
von sparrow
Was __deets__ sagt ist richtig.
Es passt in diesem Fall, wenn du weißt, dass die PINs durchgehend nummeriert sind und die range alles umfasst, was du brauchst.

Deshalb ist es wichtig, den Code zu interpretieren und zu verstehen, der automatisch generiert wird. Der kann auch anders sein.

Re: Variablen in einer Schleife in Array eintragen

Verfasst: Donnerstag 28. Februar 2019, 15:33
von __blackjack__
Man könnte sich die Attribute per `getattr()` dynamisch holen:

Code: Alles auswählen

    def on_input_value(self, _index, _value):
        self._set_output_value(
            self.PIN_O_A1,
            sum(
                self._get_input_value(getattr(self, 'PIN_I_E{}'.format(i)))
                for i in range(1, 21)
            )
        )

Re: Variablen in einer Schleife in Array eintragen

Verfasst: Donnerstag 28. Februar 2019, 16:18
von Wolle_wtal
Danke erstmal für die Tips,

muss mal schauen ob ich es verstehe.

Zum Thema:
Ist das in Ordnung den Anweisungen des Generators nicht zu folgen, und Code *unter* den gerenierten Kommentar zu schreiben?
Das Problem ist, dass hier noch nicht das Ergebnis vorliegt. Wenn das Coden fertig ist, wird das ganze durch ein weiteres Tool gejagt. Dieses Tool verwandelt alles in Base 64, damit der Logikeditor des Servers das dann alles versteht, und bei diesem Vorgang, wird der ganze Kommentarblock vom Generator neu geschrieben und somit alle Änderungen in diesem Bereich überschrieben.

Gruß, Wolle

Aber ich glaube ihr seht das ganze zu kompliziert.

Alles was ich wissen möchte ist, wie ich "self.PIN_I_E1...E20" in einer Schleife durchlaufen und in ein Array schreiben kann.
Also etwas in der Art:

Schleife Durchlauf i
Array Position i = self._get_input_value(self.PIN_I_E + i)
schleifen durchlauf um 1 erhöhen.


Mehr brauche ich nicht. Habe solche Sachen in c# schon duzende Male verwendet, weiß halt nur nicht wie es bei Python aussehen muss.

Gruß, Wolle

Re: Variablen in einer Schleife in Array eintragen

Verfasst: Donnerstag 28. Februar 2019, 16:21
von sparrow
Haben wir doch oben geschrieben :)
Wobei die Lösung von __blackjack__ sehr elegant ist.

Re: Variablen in einer Schleife in Array eintragen

Verfasst: Donnerstag 28. Februar 2019, 16:30
von __blackjack__
Vielleicht noch als ergänzende Anmerkung: Wenn dann willst Du das in eine Liste schreiben, nicht in ein Array. Es gibt in Python auch Arrays, die werden aber für etwas anderes verwendet.

Re: Variablen in einer Schleife in Array eintragen

Verfasst: Donnerstag 28. Februar 2019, 16:58
von Wolle_wtal
OK, die Lösung von __blackjack__ passt.

Vielen Dank dafür.

Könnte mir jemand diese Zeile etwas genauer erklären, ich möchte ja nicht nur blöd abtippen, sonder verstehen.

self._get_input_value(getattr(self, 'PIN_I_E{}'.format(i)))

"self._get_input_value" der Rest ist nicht ganz klar, '

PIN_I_E{}'.format(i) erzeugt eine Liste ?

gettattr macht was ?

Gruß, Wolle

Re: Variablen in einer Schleife in Array eintragen

Verfasst: Donnerstag 28. Februar 2019, 17:03
von __deets__
format plaziert das i an der Stelle des Platzhalter {}. Und getattr holt ein Attribut basierend auf seinem Namen aus einem angegebenen Objekt. Also

getattr(self, "PIN_I_E1") holt die Pinnummer, die dann an _get_inputvalue uebergeben wird.

Re: Variablen in einer Schleife in Array eintragen

Verfasst: Donnerstag 28. Februar 2019, 17:11
von __blackjack__
@Wolle_wtal: 'PIN_I_E{}' ist eine Zeichenkette und `format()` ist eine Methode auf Zeichenketten. Also keine Liste. Das kann man auch interaktiv einfach ausprobieren:

Code: Alles auswählen

In [6]: 'PIN_I_E{}'.format(42)
Out[6]: 'PIN_I_E42'
Und `getattr()` ist eine dokumentierte Funktion. Damit kann man Attribute von Objekten abfragen über deren Namen in Form von einer Zeichenkette.

Code: Alles auswählen

In [7]: getattr
Out[7]: <function getattr>

In [8]: getattr?
Docstring:
getattr(object, name[, default]) -> value

Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
When a default argument is given, it is returned when the attribute doesn't
exist; without it, an exception is raised in that case.
Type:      builtin_function_or_method
Mal spasseshalber:

Code: Alles auswählen

In [9]: getattr('PIN_I_E{}', 'format')(42)
Out[9]: 'PIN_I_E42'
Die Zeile, also der gesamte Ausdruck ist der vordere Teil eines Generatorausdrucks, da gehört die nächste Zeile noch dazu die die Werte für `i` bereit stellt. Und der so erstellte Generator wird `sum()` als Argument übergeben.

Re: Variablen in einer Schleife in Array eintragen

Verfasst: Freitag 1. März 2019, 14:22
von Wolle_wtal
Hallo noch mal.

danke für die Erklärung.

Leider will mir trotzdem nicht gelingen das mal etwas umzustellen.

Folgender Codeschnipsel:

Code: Alles auswählen

self._set_output_value(self.PIN_O_A2, getattr(self, 'PIN_I_E{}'.format(1)))
liefert mir immer nur eine 1 anstatt mir den tatsächlichen Wert in PIN_I_E1 zu liefern.

Was mache ich falsch?

Gruß, Wolle

Re: Variablen in einer Schleife in Array eintragen

Verfasst: Freitag 1. März 2019, 14:31
von __blackjack__
@Wolle_wtal: Lass uns das mal vereinfachen. Da steht ja eine literale 1, also kann man das `format()` ”ausrechnen”:

Code: Alles auswählen

In [9]: 'PIN_I_E{}'.format(1)
Out[9]: 'PIN_I_E1'
Führt also zu:

Code: Alles auswählen

self._set_output_value(self.PIN_O_A2, getattr(self, 'PIN_I_E1'))
Und `getattr(obj, 'name')`` ist äquivalent zu ``obj.name``, also ist das:

Code: Alles auswählen

self._set_output_value(self.PIN_O_A2, self.PIN_I_E1)
Jetzt klar warum das immer 1 ist, beziehungsweise immer der Wert von `self.PIN_I_E1`? Wenn Du den Wert an diesem Pin haben möchtest, dann fehlt da noch etwas, nämlich den Wert an diesem Pin auch tatsächlich abzufragen.

Re: Variablen in einer Schleife in Array eintragen

Verfasst: Freitag 1. März 2019, 16:01
von Wolle_wtal
Ich denke ja, ich probiere mal den Umbau.

Danke Dir.