mehrere Objekte oder "intelligentes" Objekt

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
Benutzeravatar
mobby
User
Beiträge: 76
Registriert: Donnerstag 17. April 2014, 09:43

Hey Leute ich steh wie üblich vor einer Aufgabe, bei der ich nicht weiter komme. Hier erst mal der Code, Erklärung folgt darunter.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*- 


import read_ec as ec #Meine zwei Unterskripte werden als Module geladen. 
import read_s0 as s0
from time import sleep
from threading import Lock
from threading import Thread


class Counter(object): #Hier wird ein Counter Objekt erstellt, um den Status des Zählers zu loggen, Erklärung später. 
    def __init__(self,value=0):
    self.value = value
    self.lock = Lock()

    def set_on(self):
        with self.lock:
            self.value = 1
            result = self.value
        return result

    def set_off(self):
        with self.lock:
            self.value = 0
            result = self.value
        return result

    def get_status(self):
        with self.lock:
            result = self.value
        return result


def read_config(): #liest meine Konfigurationsdatei, in der Serverdaten, Emaildaten, und die Stati der Zähler enthalten sind 
    config_content = []
    with open("konfiguration.txt") as one_file:
        for line in one_file:
            config.append(line.rstrip())
    return config_content


"""Die Start-Funktion der Zähler. Hier ändert sich nur der Tabellennname 
und der letzte Wert der Konfigurationsdatei wird aus einer anderen Zeile gezogen. 
"""

def start_s0(config_content, number):
    intervall = 900
    frequency = 100
    digital_input = 0
    led_output = 0
    table_name = "S0_Zaehler_0" + number
    s0.main(
        intervall,
        frequency,
        table_name,
        digital_input, 
        led_output,
        config_content[0], 
        config_content[1], 
        config_content[2], 
        config_content[3],  
        config_content[4],
        config_content[5], 
        config_content[6], 
        config_content[7], 
        config_content[8], 
        config_content[9]
    )


"""Jetzt wird der Start-Prozess gefahren. Die config Datei wird gelesen und immer die für den
jeweiligen Zähler interessante Zeile wird überprüft, kann active oder inactive sein. 
Ist sie active, wird der Zähler-Prozess gestartet. Ist sie inactive wird der nächste überprüft.
"""


def initiation_process(count):
    config_content = read_config()
    for x in range(8):
        n = 10 + x
        number = x + 1
        status = count.get_status()
        if status = 1:
            break
        elif config_content[n] = "active":
            start_s0_thread(config_content, number)
            count.set_on()
        else:
            continue


def start_s0_thread():
    thread = Thread(target=start_s0, args=(config_content, number))
    thread.setDaemon(True)
    thread.start


def main():
    count = Counter()
    while True:
        initiation_process(count)
        sleep(300)

	
if __name__ == '__main__':
    main()
Jetzt die Frage: Mit dem Counter Objekt will ich, sobald einmal gestartet, markieren ob ein Zähler gestartet wurde oder nicht. Dazu in einer separaten Funtion ständig die config datei überprüfen und somit den Objektstatus überprüfen, sprich sobald sich der Objekt status ändert von 1 zu 0 also active zu inactive, den Zähler beenden, also die jeweilige Funtion schließen. Dies wird dann denke ich gut über Threads machbar sein, dass ich sie aktivieren und deaktivieren kann. Nur wie mache ich das mit dem Counter Objekt? Muss ich jetzt 8 Counter Objekte erstellen oder kann ich irgendwie mit einem Objekt alle 8 Stati loggen?

Zum Nachvollziehen, hier noch die Konfigurationsdatei:

Code: Alles auswählen

db_host
db_user
db_password
db_database
em_host
em_fromaddr
em_toaddr
em_port
em_login
em_password
active
inactive
inactive
inactive
inactive
inactive
inactive
inactive
BlackJack

@mobby: Die Konfigurationsdatei und die Argumente für `read_s0` sehen sehr fragil und unflexibel aus. Da muss man ja wissen was in welcher Zeile steht, und wenn man mal etwas ändern will/muss, dann muss man durch das gesamte Programm gehen und anhand von magischen Indexzahlen überprüfen ob da noch das richtige verwendet wird, oder man den Index anpassen muss. Ich würde da als erstes mal Struktur in die Konfiguration bringen und die zum Beispiel als Python-Modul oder als JSON-Dokument speichern.

Code: Alles auswählen

{
    "db": {
        "host": "...",
        "user": "...",
        "password": "...",
        "database": "..."
    },
    "email": {
        "host": "...",
        "fromaddr": "...",
        "toaddr": "...",
        "port": "...",
        "login": "...",
        "password": "..."
    },
    "counterStates": [
        "active",
        "inactive",
        "inactive",
        "inactive",
        "inactive",
        "inactive",
        "inactive",
        "inactive"
    ]
}
Damit könnte man dann auch gleich die Anzahl der Argumente von `read_s0.main()` etwas reduzieren in dem man dort für den Datenbank- und für den E-Mail-Zugang nur noch jeweils das Wörterbuch mit den Konfigurationswerten übergibt, und sich die Funktion dort die relevanten Informationen selber heraus pickt.

Variable, durchnummerierte Tabellennamen klingen nach einem Entwurfsfehler. Wenn die Struktur dieser Tabellen jeweils gleich ist, dann gehört das eher alles in *eine* Tabelle mit einer Spalte in der die Zählernummer zu jedem Datensatz gespeichert ist.

Was Du mit dem `Counter` machen willst erschliesst sich mir jetzt nicht so ganz. Der Name ist irreführend weil das Ding nix zählt. Und vielleicht würde auch ein `threading.Event` reichen. Je nach dem was tatsächlich damit erreicht werden soll.

Der `Counter` selber ist auch viel zu kompliziert geschrieben. Man braucht da weder ein `Lock` noch den Rückgabwert. Der ist ja konstant und steht um Grunde schon fest *bevor* man die jeweilige Methode aufgerufen hat.
Benutzeravatar
mobby
User
Beiträge: 76
Registriert: Donnerstag 17. April 2014, 09:43

@BlackJack: Danke fürs Feedback.
Ich würde da als erstes mal Struktur in die Konfiguration bringen und die zum Beispiel als Python-Modul oder als JSON-Dokument speichern.
Klingt gut, werde ich umsetzen.
Variable, durchnummerierte Tabellennamen klingen nach einem Entwurfsfehler. Wenn die Struktur dieser Tabellen jeweils gleich ist, dann gehört das eher alles in *eine* Tabelle mit einer Spalte in der die Zählernummer zu jedem Datensatz gespeichert ist.
Kein Entwurfsfehler, nicht alle Zähler existieren gleichzeitig, bedeutet jeder braucht eine eigene Tabelle.
Was Du mit dem `Counter` machen willst erschliesst sich mir jetzt nicht so ganz. Der Name ist irreführend weil das Ding nix zählt. Und vielleicht würde auch ein `threading.Event` reichen. Je nach dem was tatsächlich damit erreicht werden soll.

Der `Counter` selber ist auch viel zu kompliziert geschrieben. Man braucht da weder ein `Lock` noch den Rückgabwert. Der ist ja konstant und steht um Grunde schon fest *bevor* man die jeweilige Methode aufgerufen hat.
Ja das muss ich mir alles nochmal anschauen, danke aber.

Was mich noch beschäftigt ist, dass ich so viele Argumente übergeben muss. Ich muss so ja in allen "sub" Funktionen immer alle Arguemente mitschleifen. Gibt es da keine Alternative?
Sowas Funktion in Funktion, wobei ich nur der übergeordneteten Funktion alle Argumente übergebe?!
BlackJack

@mobby: Ziemlich sicher ein Entwurfsfehler und die Begründung ist irgendwie keine.
Benutzeravatar
mobby
User
Beiträge: 76
Registriert: Donnerstag 17. April 2014, 09:43

@BlackJack: Ja ne, wird ein Zähler angelegt, bekommt er eine eigene Tabelle, wird er wieder gelöscht wird auch die Tabelle gelöscht. Hätte ich eine große Tabelle wären die meisten Spalten meist leer, weil keine Einträge drin wären, ist ja auch sinnfrei oder?
BlackJack

@mobby: Da wären keine Spalten lehr, denn natürlich kommen die Zählerdaten nicht in verschiedene Spalten sondern Zeilen. Und es gibt eine Spalte in der steht für welchen Zähler der jeweilige Datensatz ist. So lassen sich problemlos neue Zähler hinzufügen oder alle Daten eines alten Zähler löschen. Und zwar für beliebig viele Zähler und ganz ohne jedes mal irgend etwas am Schema ändern zu müssen.
Benutzeravatar
mobby
User
Beiträge: 76
Registriert: Donnerstag 17. April 2014, 09:43

@BlackJack: Nochmal zu dem Thema "abrufen der Daten aus Modul", wie kann ich diese Bibliothek auf Moduleben denn über das Modul laden? Ich bin jetzt echt ewig am rumprobieren und es geht nix ... müssen dazu noch Funktionen bzw. ein Modul-Objekte, wie __getitem__ definiert werden? Oder wie kann ich die Bibliothek sonst lesen?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Ich finde deinen letzten Beitrag irgendwie etwas wirr. Mir wird überhaupt nicht klar, was nun dein Problem ist. Vielleicht könntest du ein wenig ausführlicher und konkreter werden was "das Modul" ist und was denn nun wie abgerufen werden soll und was es mit dem __getitem__ auf sich hat. Vielleicht könntest du von deinen Versuchen auch etwas Code zeigen, dann wird die Intention vielleicht deutlicher.
Das Leben ist wie ein Tennisball.
Benutzeravatar
mobby
User
Beiträge: 76
Registriert: Donnerstag 17. April 2014, 09:43

@EyDu: Im oben aufgezeigten Code Beispiel von BlackJack sind Informatonen in einer Datei gespeichert. Lade ich diese Datei in einem Skript als Modul, stellt sich mir die Frage, wie ich direkt über das Modul die Infos aus der Bibliothek hole. Ich hoffe jetzt ist es etwas verständlicher.
BlackJack

@mobby: Mein Code-Beispiel ist JSON, das lädt man mit dem `json`-Modul aus der Standardbibliothek.
Antworten