GUI Variable übergeben

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
doggy
User
Beiträge: 22
Registriert: Freitag 19. September 2014, 10:32

Guten Tag liebes Forum,

Ich bin ein absoluter Python Anfänger. Ich möchte nun ein Bild anzeigen lassen und mit Hilfe einer Variable an verschiedenen Stellen meines Programms den Text im Image verändern.

Hier habe ich ein TEST Programm dazu erstellt. Dabei habe ich allerdings ein Problem. Die erste Variable wird übergeben und Das Bild wird mit "Hello" in der Mitte angezeigt. Nun kann ich allerdings keinen input mehr in meiner Konsole ausführen, um den Text zu ändern. Kann mir jemand einen Trick zeigen, wie ich auf diese Art und weise bequem einfach in meinem Programm die Variable verändern kann, so dass ich einfach nur diese eine Funktion schreiben muss?

Code: Alles auswählen

from tkinter import *

def label(a):
    root = Tk()
    logo = PhotoImage(file="Test.gif")
    explanation = a
    w = Label(root, 
              compound = CENTER,
              text=explanation, 
              image=logo).pack(side="right")

    root.mainloop()
           
b = "Hallo"
label(b)
input()
c = "JJ"
label(c)

Vielen Dank,

euer doggy
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@doggy: Du mußt Dich halt entscheiden, ob Du eine GUI machen willst, oder ein Konsolenprogramm. Beides zusammen ist unüblich und wird deshalb von keinem GUI-Framework unterstützt.
doggy
User
Beiträge: 22
Registriert: Freitag 19. September 2014, 10:32

Nun, ich will eigentlich lediglich an bestimmten stellen in meinem Consolen Programm in Bild erscheinen lassen. Ich arbeite an einem Projekt und habe schlicht nicht die Zeit noch den professionellen Umgang mit GUI zu erlernen. Daher war meine Idee lediglich Bilder erscheinen zu lassen. Nun war die Idee, einfach das Textlabel mit einer Variable umzuschreiben, wenn ich ein einer bestimmten Stelle im Programm bin. Wenn z.B. nichts ist, soll da "Willkommen bei der Ladestation der Frima XXX" stehen. Wenn ich nun aber mich als Kunde anmelde, soll dort "Die Kabine X wurde für sie freigeschaltet" stehen. usw.
BlackJack

@doggy: „Wenn ich an einer bestimmten Stelle im Programm bin soll in der GUI xy passieren” klingt nach einem Programmfluss der üblicherweise nicht mit GUI-Rahmenwerken vereinbar ist, denn da kann man keine länger laufenden Programmabschnitte haben, jedenfalls nicht ohne sich mit Threads und nebenläufiger Programmierung zu beschäftigen, also *zwei* zusätzlichen, umfangreicheren Themen. Bei GUI-Programmen ist die Ablaufkontrolle üblicherweise nicht in *deinem* Programmcode sondern in der Hauptschleife des GUI-Rahmenwerkes, und die ruft Code von Dir bei bestimmten Ereignissen auf, für die Du diesen Code registriert hast. Wie zum Beispiel „Benutzer betätigt Schaltfläche”, oder „Texteingabefeld bekommt Fokus”, oder auch nur das ablaufen eines Timers. Der Code darf nicht lange laufen, denn solange *der* läuft, ist die GUI ”tot” und reagiert nicht.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Eine Alternative - wenn auch imho vom Gesamtdesign ein wenig unelegant - wäre es, tatsächlich komplette *einzelne* "GUI"-Komponenten innerhalb einer Funktion laufen zu lassen und nach dem Beendigen der GUI im Programm weiter zu laufen. (Ähnlich wie man es gerne bei Shell-Scripten mit den diversen ``dialog``-Derivaten macht)

Allerdings muss der Anwender dann jedes Mal die GUI beenden und danach weiter in einer Text-Shell Eingaben machen und Entscheidungen treffen. Klingt verdammt nach einer Art "User-Experience"-Bruch ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
doggy
User
Beiträge: 22
Registriert: Freitag 19. September 2014, 10:32

Problem bei der Lösung, es kommt natürlich nicht in Frage das der Kunde die Konsole sieht. Er soll eigentlich nur Bilder sehen (Einfach gifs die ich mit GIMP gestalte) und darin steht dann "PIN eingeben" z.B. Das wäre erstmal ausreichend als Lösung. Wenn ich auf meinem Bildschirm Bilder sehe als Kunde und im Hintergrund die Konsole läuft
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ich fürchte dann kommst Du an einer minimalen, durchgängigen GUI-Lösung nicht vorbei!
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
doggy
User
Beiträge: 22
Registriert: Freitag 19. September 2014, 10:32

Mhhh, also das doch für mich recht komplizierte Programm kann ich nun verwerfen und muss es irgendwie mit einem GUI Programm reallisieren. Naja, wird wohl so sein :(
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Wie ist denn der schematische Ablauf des Programms? Also gibt es viele "Zustände" und "Übergänge" dazwischen? Wenn nein, ist das in der Tat nicht sehr kompliziert.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
lackschuh
User
Beiträge: 281
Registriert: Dienstag 8. Mai 2012, 13:40

Das ist ein Programm :mrgreen:
BlackJack

Ich nehme mal an es geht immer noch um dieses Projekt: http://www.python-forum.de/viewtopic.ph ... 51#p264451

Und der dort zuletzt gezeigte Quelltext ist in keiner Form die sich eignen würde von einer GUI benutzt zu werden. Da es hier Zustand gibt, läuft das auf objektorientierte Programmierung hinaus, während der Quelltext dort noch nicht einmal Funktionen verwendet.

Edit: Mist, Lackschuh war schneller. :-)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ach das Ding... ja, das wird so noch nix...

Ich würde das ja erst einmal unabhängig von einer GUI sinnvoll umsetzen. Es fehlt da ja noch komplett an Konzepten wie "Kabinen" usw., geschweige denn ist mir der Ablauf wirklich klar. Der gezeigte Code hat sich ja nur mit einer (imho immer noch falschen) PIN-Abfrage befasst, was, mit Verlaub, ja eher nebensächlich ist. Denn erst einmal müsste man doch *Funktionalität* haben, die durch den PIN (später) geschützt wird, oder nicht? Und davon war ja noch nicht im Ansatz etwas zu sehen...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
doggy
User
Beiträge: 22
Registriert: Freitag 19. September 2014, 10:32

:) Nun, das ist extrem unübersichtlich. Aber als Anfänger hatte ich nur die üblichen Funktionen offen

Hier mein Programm für die Konsole:

Code: Alles auswählen

Importieren der noetigen Module
from time import sleep
import RPi.GPIO as GPIO
from serial import Serial
#Benennen der PINS
Tuer1 = 7
Tuer2 = 11
Tuer3 = 13
Tuer4 = 15
Tuer5 = 12
Tuer6 = 16
RFID = 23
KBesetzt1 = 18
KBesetzt2 = 22
KBesetzt3 = 24
KBesetzt4 = 26
KBesetzt5 = 19
KBesetzt6 = 21
#Festlegen der Ein und Ausgaenge
GPIO.setmode(GPIO.BOARD)
GPIO.setup(KBesetzt1, GPIO.IN)
GPIO.setup(KBesetzt2, GPIO.IN)
GPIO.setup(KBesetzt3, GPIO.IN)
GPIO.setup(KBesetzt4, GPIO.IN)
GPIO.setup(KBesetzt5, GPIO.IN)
GPIO.setup(KBesetzt6, GPIO.IN)
GPIO.setup(RFID, GPIO.IN)
GPIO.setup(Tuer1, GPIO.OUT)
GPIO.setup(Tuer2, GPIO.OUT)
GPIO.setup(Tuer3, GPIO.OUT)
GPIO.setup(Tuer4, GPIO.OUT)
GPIO.setup(Tuer5, GPIO.OUT)
GPIO.setup(Tuer6, GPIO.OUT)
GPIO.output(Tuer1, GPIO.LOW)
GPIO.output(Tuer2, GPIO.LOW)
GPIO.output(Tuer3, GPIO.LOW)
GPIO.output(Tuer4, GPIO.LOW)
GPIO.output(Tuer5, GPIO.LOW)
GPIO.output(Tuer6, GPIO.LOW)
#Abfrage ob Eingabe richtig
def is_pin_valid(pin):
         return len(pin) == 4 and pin.isdigit()

#Funktion VOLL
def voll():
        voll = 0 in speicher
        return voll
#Definieren der Variablen
speicher = [0,0,0,0,0,0]
gefunden = 0
belegt1 = 0
belegt2 = 0
belegt3 = 0
belegt4 = 0
belegt5 = 0
belegt6 = 0
#Start der Endlos-Schleife
while True:
        #Abfrage RFID
        while GPIO.input(RFID) == True:
                #Begrenzung der falschen Eingaben
                for i in range(1,6):
                        #Eingabe und Oeffnen der Datei
                        pin = input("Bitte geben sie Ihren Pin ein!")
                        data = open("pin.txt").read()
                        #Abfrage ob Eingabe vorhanden ist
                        if pin in data and is_pin_valid(pin):
                                #Abfrage ob PIN bereits vorhanden ist und ueberschreiben des PIN
                                for k in range(6):
                                        if speicher[k] == pin:
                                                speicher[k] = 0
                                                gefunden = True
                                                print(speicher)
                                                break
                                #Abfrage ob Voll
                                if voll() == False:
                                        print("Voll")
                                        break
                                #Eintragen des PINS, wenn nicht vorhanden
                                for j in range(6):
                                        if speicher[j] == 0 and not gefunden:
                                                speicher[j] = pin
                                                print(speicher)
                                                break
                                #Definieren der einzelnen Speicherwerte
                                print("Richtige Eingabe")
                                belegt1 = str(speicher[0])
                                belegt2 = str(speicher[1])
                                belegt3 = str(speicher[2])
                                belegt4 = str(speicher[3])
                                belegt5 = str(speicher[4])
                                belegt6 = str(speicher[5])
                                print(speicher)
                                #Oeffnen der Tueren
                                # Kabine 1 oeffnen
                                if GPIO.input(KBesetzt1) == False and pin == speicher[0] or GPIO.input(KBesetzt1) == True and belegt1 == "0":
                                        GPIO.output(Tuer1, GPIO.HIGH)
                                        print("Tuer 1 oeffnet")
                                        sleep(5)
                                        GPIO.output(Tuer1, GPIO.LOW)
                                        sleep(2)
                                        if GPIO.input(KBesetzt1) == False and pin == speicher[0]:
                                                speicher[0] = 0
                                                print("Kein Fahrrad in Kabine 1 erkannt")
                                 #Kabine 2 oeffnen
                                elif GPIO.input(KBesetzt2) == False and pin == speicher[1] or GPIO.input(KBesetzt2) == True and belegt2 == "0":
                                        GPIO.output(Tuer2, GPIO.HIGH)
                                        print("Tuer 2 oeffnet")
                                        sleep(5)
                                        GPIO.output(Tuer2, GPIO.LOW)
                                        sleep(2)
                                        if GPIO.input(KBesetzt2) == False and pin == speicher[1]:
                                                speicher[1] = 0
                                                print("Kein Fahrrad in Kabine 2 erkannt")
                                #Kabine 3 oeffnen
                                elif GPIO.input(KBesetzt3) == False and pin == speicher[2] or GPIO.input(KBesetzt3) == True and belegt3 == "0":
                                        GPIO.output(Tuer3, GPIO.HIGH)
                                        print("Tuer 3 oeffnet")
                                        sleep(5)
                                        GPIO.output(Tuer3, GPIO.LOW)
                                        sleep(2)
                                        if GPIO.input(KBesetzt3) == False and pin == speicher[2]:
                                                speicher[2] = 0
                                                print("Kein Fahrrad in Kabine 3 erkannt")
                                #Kabine 4 oeffnen
                                elif  GPIO.input(KBesetzt4) == False and pin == speicher[3] or GPIO.input(KBesetzt4) == True and belegt4 == "0":
                                        GPIO.output(Tuer4, GPIO.HIGH)
                                        print("Tuer 4 oeffnet")
                                        sleep(5)
                                        GPIO.output(Tuer4, GPIO.LOW)
                                        sleep(2)
                                        if GPIO.input(KBesetzt4) == False and pin == speicher[3]:
                                                speicher[3] = 0
                                                print("Kein Fahrrad in Kabine 4 erkannt")
                                #Kabine 5 oeffnen
                                elif GPIO.input(KBesetzt5) == False and pin == speicher[4] or GPIO.input(KBesetzt5) == True and belegt5 == "0":
                                        GPIO.output(Tuer5, GPIO.HIGH)
                                        print("Tuer 5 oeffnet")
                                        sleep(5)
                                        GPIO.output(Tuer5, GPIO.LOW)
                                        sleep(2)
                                        if GPIO.input(KBesetzt5) == False and pin == speicher[4]:
                                                speicher[4] = 0
                                                print("Kein Fahrrad in Kabine 5 erkannt")
                                #Kabine 6 oeffnen
                                elif GPIO.input(KBesetzt6) == False and pin == speicher[5] or GPIO.input(KBesetzt6) == True and belegt6 == "0":

                                        GPIO.output(Tuer6, GPIO.HIGH)
                                        print("Tuer 6 oeffnet")
                                        sleep(5)
                                        GPIO.output(Tuer6, GPIO.LOW)
                                        sleep(2)
                                        if GPIO.input(KBesetzt6) == False and pin == speicher[5]:
                                                speicher[5] = 0
                                                print("Kein Fahrrad in Kabine 6 erkannt")
                                #Ende PIN korrekt Schleife
                                print("Naechste Eingabe moeglich")
                                gefunden = False
                                sleep(0.5)
                                break
                        #Falscher PIN eingegeben
                        else:
                                print("Dieser Pin ist nicht korrekt!")
                                if i > 4:
                                        print("5 Fehlversuche!")
                                        sleep(0.5)
Das ist das Funktionierende Programm. Da ist nur noch ein kleiner Fehler drin, welchen ich aber noch ausbügeln werde. Also ignoriert das Fl
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

doggy hat geschrieben: Das ist das Funktionierende Programm. Da ist nur noch ein kleiner Fehler drin, welchen ich aber noch ausbügeln werde.
Oha :shock: Also damit kannst Du alles bezüglich GUI vergessen :!:

Dir fehlen einfach noch zu viele Grundlagen... angefangen bei Dingen wie Datenstrukturen und Funktionen. Dazu kommt dann - als Anfänger natürlich - noch die Schwierigkeit, Programme sinnvoll zu strukturieren.

Wenn ich das nur einfach überfliege, hätte man das vermutlich in einem Drittel der Code Länge sauber implementiert. Zudem scheinen es ja eigentlich recht simple Abläufe zu sein, die man nur sauber trennen muss. Aktuell sind das ja zwei Monster-Schleifen, Copy-and-Paste if...elif...else-Kaskaden und durchnummerierte Variablen auf einem Haufen.

Mein Tipp: "Wegwerfen" und neu anfangen!

Dabei trennst Du das dann am besten sauber auf, indem Du den "Raspberry Pi"-Teil von den logischen Abläufen separierst. Schreibe einfach lauter *kleine* Funktionen, die Datentypen wie Listen oder Dictionaries (oder verschachtelten Komponenten) als Argumente entgegen nehmen oder zurückgeben. Eine Funktion, die Logik über den Ablauf enthält, darf nie direkt auf etwas zugreifen, was den "Raspi" steuert oder abfragt. Wenn Du das einhalten kannst, dann kann man später vermutlich einfach eine GUI darauf aufsetzen!

Fange am besten mit einem Modul an, welches nur die Datenstrukturen definiert und Funktionen besitzt, die den logischen Ablauf steuern oder dazu beitragen. Du hast doch offenbar so etwas wie "Kabinen". Diese wiederum können "Inhalt" besitzen oder auch leer sein. Wenn die Art des Inhalts keine Rolle spielt, reicht als Modell dafür einfach eine boolesche Variable aus. Zudem kann man solche Kabinen wohl öffnen - schließen auch? Da kann man sich überlegen, ob einem der Zustand ("offen" und "geschlossen") ausreicht. Das wäre nämlich auch nur boolesch, also ``True`` oder ``False``.

Als Identifikation für die Kabinen, können wir uns einen künstlichen Index überlegen, der von 0 bis x geht. Damit könnte man einfach eine Liste für die Sammlung von Kabinen nutzen.

Ob Du die GPIO-Id auch noch in die Datenstruktur aufnimmst, oder diese später über ein Mapping dazu fügst, kann man sich immer noch überlegen. Genauso, ob eine vorhandene PIN nicht einfach Auskunft über "besetzt" und "frei" gibt...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
doggy
User
Beiträge: 22
Registriert: Freitag 19. September 2014, 10:32

Vielen Dank für diese ausgiebige Antwort.


Gänzlich neu zu beginnen fehlt mir schlicht die Zeit. Ich habe 2 Monate gehabt um Programmieren zu lernen (Ohne jegliche Vorkenntnisse und ohne Lehrer). Nun ich versuche mal das Programm neu zu Programmieren. Aber eine andere idee als meine for-Schleifen zum Listen beschreiben habe ich nicht.

Die PINs reichen nicht als Abfrage, da ich verhindern möchte, dass jemand sich einfach durch die Eingabe seines PINS die Kabine reserviert. Das gute alte Handtuch auf die Strandliege Prinzip :).

Die Kabinen müssen nicht geschlossen werden, da ein einfacher magnetischer Türöffner mit Summer verwendet wird. Der schliesst ja automatisch
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@doggy: Du gehts das ganze falsch an. Beschreib doch mal, was passieren soll, wenn jemend so eine Kabine benutzen möchte. In der Beschreibung sollten keine Begriffe wie "for-Schleife" "GPIO" "Datei" etc. vorkommen. Also eine Beschreibung aus Benutzersicht. zB.: "Der Benutzer gibt seine PIN ein. Falls die Kabine besetzt ist, wird ihm das angezeigt. Andernfalls öffnet sich die Türe. ..."

Daraus lässt sich dann die Programmlogik (hoffentlich) ableiten, und es werden vermutlich Sachen herauspurzeln wie etwa pin = ask_pin(), verify_pin(pin), open_cabin_door(cabin_id), show_cabin_in_use(cabin_id), ... . Diese setzt man dann anhand der aus der Beschreibung gewonnenen Logik zu einem Programm zusammen. Beachte, dass bisher nirgends von for-Schleifen, Dateien oder GPIO die Rede ist. Das sind Dinge, die man zwar zur Implementierung verwenden wird, die aber in der Problembeschreibung zunächst nichts zu suchen haben.
In specifications, Murphy's Law supersedes Ohm's.
doggy
User
Beiträge: 22
Registriert: Freitag 19. September 2014, 10:32

Ja, fangen wir mal an.

Der Kunde soll an einem Bedienpult der Ladestation, die Auswahl zwischen einer Anmeldung per Anruf oder mit einer Anmeldung per PIN haben.

Als doppelte Sicherheit besitzen angemeldete Kunden mit Pin einen RFID Chip. Zunächst soll er den Chip nutzen um die Pineingabe freizuschalten. Anschließend soll der Pin eingegeben werden,welcher mit einer Textdatei verglichen wird. Nun sucht das Programm die nächste freie Kabine und öffnet diese für den Kunden. Er kann nun sein Pedelec (Elektronisches Fahrrad) in die Kabine einschieben und zum Laden anstecken. Anschließend verlässt er die Kabine. Wenn er nun erneut mit demselben Pin sich anmelden, soll die Kabine indem sein Fahrrad steht, sich öffnen und er soll sein Fahrrad wieder entnehmen können und die Kabine wird wieder als frei registriert.

Ähnlich soll der Anruf funktionieren. Hier gibt es keine RFID Abfrage vorher, der Kunde ruft an und die Nummer wird ausgelesen. Stimmt die Nummer mit einer Textdatei überein, öffnet sich ebenfalls die nächste freie Kabine. Auch hier soll ein erneuter Anruf derselben Nummer die Kabine erneut öffnen.

Habe nun auch das Programm neu geschrieben und in Funktionen verpackt. Ich hoffe, dass dies etwas besser zum umsetzen in GUI nutzbar ist.

Hier das Programm nun mit Anruf Abfrage:

Code: Alles auswählen

#Importieren der noetigen Module
from time import sleep
import RPi.GPIO as GPIO
import serial, re
#Benennen der PINS
Tuer1 = 7
Tuer2 = 11
Tuer3 = 13
Tuer4 = 15
Tuer5 = 12
Tuer6 = 16
RFID = 23  
KBesetzt1 = 18
KBesetzt2 = 22
KBesetzt3 = 24
KBesetzt4 = 26
KBesetzt5 = 19
KBesetzt6 = 21
#Festlegen der Ein und Ausgaenge
GPIO.setmode(GPIO.BOARD)
GPIO.setup(KBesetzt1, GPIO.IN)
GPIO.setup(KBesetzt2, GPIO.IN)
GPIO.setup(KBesetzt3, GPIO.IN)
GPIO.setup(KBesetzt4, GPIO.IN)
GPIO.setup(KBesetzt5, GPIO.IN)
GPIO.setup(KBesetzt6, GPIO.IN)
GPIO.setup(RFID, GPIO.IN)
GPIO.setup(Tuer1, GPIO.OUT)
GPIO.setup(Tuer2, GPIO.OUT)
GPIO.setup(Tuer3, GPIO.OUT)
GPIO.setup(Tuer4, GPIO.OUT)
GPIO.setup(Tuer5, GPIO.OUT)
GPIO.setup(Tuer6, GPIO.OUT)
GPIO.output(Tuer1, GPIO.LOW)
GPIO.output(Tuer2, GPIO.LOW)
GPIO.output(Tuer3, GPIO.LOW)
GPIO.output(Tuer4, GPIO.LOW)
GPIO.output(Tuer5, GPIO.LOW)
GPIO.output(Tuer6, GPIO.LOW)
#Definitionen
speicher = [0,0,0,0,0,0]
pin = 0
number = 0
listpin = 0
belegt1 = 0
belegt2 = 0
belegt3 = 0
belegt4 = 0
belegt5 = 0
belegt6 = 0
#Abfrage ob Eingabe richtig
def is_pin_valid(pin):
	return len(pin) == 4 and pin.isdigit()
#Funktion VOLL
def voll():
	voll = 0 in speicher
	return voll
#Beschreiben der Liste			
def Liste(listpin):
	gefunden = 0
	beschrieben = 0
	print(pin)
	for k in range(6):
		if speicher[k] == listpin:
			speicher[k] = 0
			gefunden = True
			print(speicher)
			break
	if voll() == False:
		print "Voll"
	for j in range(6):
		if speicher[j] == 0 and not gefunden:
			speicher[j] = listpin
			print(speicher)
			break
	Beschaltung(listpin)
#Abruf eines Anrufs
def Anruf():
	korrekt = 0
	#serielle Schnittstellen Einstellungen
	command_channel = serial.Serial(
        	port='/dev/ttyUSB0',
        	baudrate=115200,
        	parity=serial.PARITY_NONE,
        	stopbits=serial.STOPBITS_ONE,
        	bytesize=serial.EIGHTBITS
	)
	#serielle Schnittstellen verbindung wird geoeffnet
	command_channel.open()
	#Aktivirung der Anrufer ID
	command_channel.write("AT+CLIP=1" + "\r\n")
	#serielle Schnittstellen verbindung wird geschlossen
	command_channel.close()
	#serielle Schnittstelle Einstellungen
	ser = serial.Serial(
        	port='/dev/ttyUSB2',
        	baudrate=9600,
        	parity=serial.PARITY_NONE,
        	stopbits=serial.STOPBITS_ONE,
        	bytesize=serial.EIGHTBITS
	)
	#serielle Schnittstellen verbindung wird geoeffnet
	ser.open()
	#Anrufer ID wird ausgelesen
	pattern = re.compile('.*CLIP.*"\+([0-9]+)",.*')
	while 1:
        	buffer = ser.read(ser.inWaiting()).strip()
        	buffer = buffer.replace("\n","")
        	match = pattern.match(buffer)
        	if match:
			number = match.group(1)
                	#verifizirung der Anrufer ID
                	if number in open('userid.txt').read():
                		print "User found"
				print(number)
				listpin = number
				Liste(listpin)
				break
                	else:
                		print "User not found"
				print(number)
				break
#Pineingabe                	
def Pin():
	for versuch in range(1,6):
		pin = raw_input("Bitte geben sie ihren Pin ein")
		print(pin)
		data = open("pin.txt").read()
		if pin in data and is_pin_valid(pin):
			listpin = pin
			Liste(listpin)
			break	
		else:
			print "Falsche Eingabe"
			continue
	if versuch > 4:
		print "5 Fehlversuche"
		sleep(2)			
#Auswahl zwischen Pineingabe und Anruf
def Auswahl():
	print "Bitte Taste 1 fuer einen Anruf"
	print "Oder Taste 2 fuer eine Pin Eingabe"
	auswahl = 0
	auswahl = raw_input("Auswahl")
	if auswahl == "1":
		Anruf()
	if auswahl == "2":
		Pin()
#Beschaltung der GPIOs	
def Beschaltung(listpin):
	print(listpin)
	print(speicher)
	#Kabine 1	
	if GPIO.input(KBesetzt1) == False and speicher[0] == listpin or GPIO.input(KBesetzt1) == True and speicher[0] == "0":
		GPIO.output(Tuer1, GPIO.HIGH)
		sleep(5)
		GPIO.output(Tuer1, GPIO.LOW)
		sleep(4)
		if GPIO.input(KBesetzt1) == False and listpin == speicher[0]:
			print "Kein Fahrrad in Kabine 1 erkannt"
			speicher[0] = 0
	#Kabine 2
	elif GPIO.input(KBesetzt2) == False and speicher[1] == listpin or GPIO.input(KBesetzt2) == True and speicher[1] == "0":
                GPIO.output(Tuer2, GPIO.HIGH)
                sleep(5)
                GPIO.output(Tuer2, GPIO.LOW)
		sleep(4)
                if GPIO.input(KBesetzt2) == False and listpin == speicher[1]:
                        print "Kein Fahrrad in Kabine 2 erkannt"
			speicher[1] = 0

	#Kabine 3	
	elif GPIO.input(KBesetzt3) == False and speicher[2] == listpin or GPIO.input(KBesetzt3) == True and speicher[2] == "0":
		GPIO.output(Tuer3, GPIO.HIGH)
                sleep(5)
                GPIO.output(Tuer3, GPIO.LOW)
                sleep(4)
                if GPIO.input(KBesetzt3) == False and listpin == speicher[2]:
                        print "Kein Fahrrad in Kabine 3 erkannt"
			speicher[2] = 0
	#Kabine 4
	elif GPIO.input(KBesetzt4) == False and speicher[3] == listpin or GPIO.input(KBesetzt4) == True and speicher[3] == "0":
                GPIO.output(Tuer4, GPIO.HIGH)
                sleep(5)
                GPIO.output(Tuer4, GPIO.LOW)
                sleep(4)
                if GPIO.input(KBesetzt4) == False and listpin == speicher[3]:
                        print "Kein Fahrrad in Kabine 4 erkannt"
			speicher[3] = 0
	#Kabine 5
	elif GPIO.input(KBesetzt5) == False and speicher[4] == listpin or GPIO.input(KBesetzt5) == True and speicher[4] == "0":
                GPIO.output(Tuer5, GPIO.HIGH)
                sleep(5)
                GPIO.output(Tuer5, GPIO.LOW)
                sleep(4)
                if GPIO.input(KBesetzt5) == False and listpin == speicher[4]:
                        print "Kein Fahrrad in Kabine 5 erkannt"
			speicher[4] = 0
	#Kabine 6
	elif GPIO.input(KBesetzt6) == False and speicher[5] == listpin or GPIO.input(KBesetzt6) == True and speicher[5] == "0":
                GPIO.output(Tuer6, GPIO.HIGH)
                sleep(5)
                GPIO.output(Tuer6, GPIO.LOW)
                sleep(4)
                if GPIO.input(KBesetzt6) == False and listpin == speicher[5]:
                        print "Kein Fahrrad in Kabine 6 erkannt"
			speicher[5] = 0
	#Abfrage eines Fehlers
	else:
		print "Fehler"
#Hauptprogram	
def main():
	while True:
		Auswahl()

if __name__ == "__main__":
	main()

Vielen Dank,

euer doggy
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@doggy: zuerst ein paar formale Anmerkungen. Die Einrücktiefe ist normalerweise 4 Leerzeichen, 8 sind für mich und viele andere irritierend. Die Kommentare, die Du hast sind alle nur Beschreibungen, was in der nächsten Zeile gemacht wird, da das aber schon in der nächsten Zeile steht, bieten sie keinen Mehrwert. Kommentare sollen nicht-offensichtliche Dinge benennen. Vergleiche auf True bzw. False werden nicht explizit gemacht, da jeder Ausdruck in einem if immer schon auf Wahr verglichen wird, kann man "== True" einfach weglassen, "== False" wird durch ein vorangestelltes "not" erreicht.

Als nächstes solltest Du alle Variablen, die eine Nummer im Namen haben, durch passende Listen ersetzen und doppelten Code in "Beschaltung" durch eine for-Schleife. Die Funktion "voll" hat voll den falschen Namen.
Du hast ein ungünstiges Funktionsdesign, da Du immer lange Funktionsketten bildest, das heißt, die eine Funktion ruft zum Schluß immer die nächste und diese wieder die nächste Funktion auf; das ist nicht viel besser, als eine Funktion, die alles macht. Versuche jeder Funktion eine Aufgabe zu geben, die ihr Ergebnis an die übergeordnete Funktion übergibt und dieses dann weiterverarbeitet.

Noch konkreter: die for-Schleifen in "Liste" lassen sich durch ein "speicher.find" viel klarer schreiben. Die Abfrage nach "voll" hat keine Konsequenzen, weil danach doch wieder der ganze Speicher nach freien Plätzen durchsucht wird. Warum wird wenn eine Kabine mit Pin gefunden wurde nochmal nach einer leeren gesucht?

Im anderen Thread wurde ja schon geschrieben, dass die Suche nach User und Pin kaputt ist, weil jeder User mit einer beliebigen Pin kombiniert werden kann.

Logik und Hardwareansteuerung sind durchmischt, das solltest Du in verschiedene Funktionen trennen.
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@ doggy: Unter http://www.python-forum.de/pastebin.php?mode=view&s=403 habe ich einmal eine einigermaßen simple Version dessen gepostet, wie die Programmstruktur aussehen könnte. Das Programm läuft in der Shell und alle Eingaben müssen von Hand erledigt werden. Es gibt neben der Initialisierung nur zwei Funktionen, open_door_and_wait_for_it_to_close(cabin_id, context) und pedelec_is_in_cabin(cabin_id, context), die ausprogrammiert werden müssen. Nur dort muss mit der Hardware kommuniziert werden. Die erste soll die Tür der Kabine mit der ID cabin_id öffnen und anschließend darauf warten, dass sie wieder geschlossen wird. Die zweite soll testen, ob in der Kabine mit der ID cabin_id ein Pedelec angeschlossen ist.

Sobald du das programmiert hast und festgestellt hast, dass alles geht, wenn man sich von Hand einloggt, kann man einen anderen Loginmechanismus einbauen und eine GUI darüberlegen. Alles ist jetzt in kleinen Häppchen prgrammiert, so wie man es für GUI-Programmierung braucht.

Zentral für alles ist ein Kontextobjekt, das an alle Funktionen gereicht wird. Es ist ein Dictionary (AKA Wörterbuch), weil das erstens eine nützliche Datenstruktur für sowas ist, und außerdem leicht als JSON gespeichert und davon wieder eingelesen werden kann.

Ausprobiert habe ich es natürlich nur mit einem Mockup, denn ich habe weder ein Pedelec, noch eine Kabine, wo ich es aufladen könnte. Es kann also durchaus sein, dass Fehler drin sind.

Hier ein paar Beispiele:

Code: Alles auswählen

$ python cabin.py
Bitte Kunden-ID eingeben: 0
Bitte PIN eingeben: 1234
Lieber Kunde, sie müssen ihr Pedelec wieder mitnehmen!
$ python cabin.py
Bitte Kunden-ID eingeben: 1
Bitte PIN eingeben: 2345
$ python cabin.py
Bitte Kunden-ID eingeben: 1
Bitte PIN eingeben: hallo
Kunde konnte nicht angemeldet werden!
$ python cabin.py
Bitte Kunden-ID eingeben: 7
Kunde konnte nicht angemeldet werden!
In specifications, Murphy's Law supersedes Ohm's.
doggy
User
Beiträge: 22
Registriert: Freitag 19. September 2014, 10:32

Das ist wirklich sehr nett!!!!!!!

Ich versuche mich da rein zu lesen, wenn ich noch in letztes Problem gelöst habe und versuche es umzusetzen. Danke dir!
Antworten