Globale Namen definieren ???

Code-Stücke können hier veröffentlicht werden.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Samstag 24. Mai 2014, 08:08

@me: Dein Beispiel ist wirklich gelungen! :-)

(Hätte man ein Wiki, sollte man das da rein packen :mrgreen: )
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3))
assert encoding_kapiert
Zappelmann
User
Beiträge: 27
Registriert: Freitag 23. Mai 2014, 11:01

Sonntag 25. Mai 2014, 13:01

nein bisher kannte ich die Seite nicht aber ich werde mich da mal durchwühlen
also das Beispiel ok hab gerafft das es dabei nicht um die globalen Variablen geht aber wenn ich das richtig verstanden habe soll ich Module bzw. Funktionen auslagern in andere Dateien und diese dann gezielt im Programmablauf einbinden ?

ist das richtig ? bzw ist es in python üblich das man mehrere Dateien für ein Programm in der Größe erstellt ? ich mein im grunde genommen ist es ja ein kleines Script.

ich werde dann mal mich diese Woche mit der Seite beschäftigen.

danke für den Tipp

MFG

Zappelmann
BlackJack

Sonntag 25. Mai 2014, 13:09

@Zappelmann: Module sind in Python Dateien. Beziehunsgweise umgekehrt: Was in einem Modulobjekt steckt, wird normalerweise durch eine Python-Quelltextdatei definiert.

Es geht hier jetzt erst einmal nur um Funktionen. Der bereits vorhandene Code sollte sich damit vereinfachen lassen in dem man nicht sehr ähnlichen Quelltext immer wieder hinschreibt, sondern Funktionen schreibt die die Unterschiede als Argumente übergeben bekommen.
Zappelmann
User
Beiträge: 27
Registriert: Freitag 23. Mai 2014, 11:01

Montag 26. Mai 2014, 17:53

So nachdem ich mir einige Grundlagen Tutorials reingezogen habe, ich hab genau das gefunden was ich gesucht hatte.
Das hättet ihr aber auch direkt schreiben können das es so einfach ist ^^. Aber gut ich hab Euch verstanden das mir Grundlagen fehlen und ich diese für eine sinnvolle und sauber Programmierung unerlässlich sind. Jedoch hab ich das Script um 50% einkürzen können. Ich weis das ist jetzt noch immer nicht nach Euren Vorstellungen nach guten sauberen Code aber gebt mir noch ein wenig Zeit oder auch ein paar Hinweise wo man es dann noch weiter reduzieren kann. Auf manche Sachen kann ich bisher nicht versichten wie z.B. die Servo Stellungen und die Messungen da diese alle unterschiedlich sind und auch entsprechend benötigt werden. Ich bin mir sicher das Ihr der Meinung seid das es noch einfacher zu schreiben ist. So hier nochmal der bisher überarbeitete Code.


wie alles anfing: https://www.youtube.com/watch?v=oAjxtVcyods
langsam wird er autonom: https://www.youtube.com/watch?v=hN7qRw3E0Gk

Weitere Videos sind in Bearbeitung und werden in Kürze folgen.

Ich bin natürlich weiterhin für konstruktive Kritik offen.


Code: Alles auswählen

#!/usr/bin/python

from time import sleep
import time
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(19,GPIO.OUT)
GPIO.setup(7,GPIO.OUT)
GPIO.setup(22,GPIO.OUT)
GPIO.setup(11,GPIO.OUT)
GPIO.setup(26,GPIO.OUT)
GPIO.setup(12,GPIO.OUT)
GPIO.setup(16,GPIO.IN)

print "Ultraschallmessung mit HC-SR04"

#A routine to control a pair of pins

def ControlAPairOfPins(FirstPin,FirstState,SecondPin,SecondState):
  if FirstState == "1":
    GPIO.output(int(FirstPin),True)
  else:
    GPIO.output(int(FirstPin),False)
  if SecondState == "1":
    GPIO.output(int(SecondPin),True)
  else:
    GPIO.output(int(SecondPin),False)
  return

def Stop():
    ControlAPairOfPins("19","0","7","0")
    ControlAPairOfPins("22","0","11","0")

def Stop_anhalten_permanent():
    ControlAPairOfPins("19","0","7","0")
    ControlAPairOfPins("22","0","11","0")

def Vorwaerts_fahren():
    ControlAPairOfPins("19","1","7","0")
    ControlAPairOfPins("22","1","11","1")
	
def Geradeaus_vorwaerts_start():
    ControlAPairOfPins("19","1","7","0")
    ControlAPairOfPins("22","1","11","1")
	
def Links_fahren():
    ControlAPairOfPins("19","1","7","0")
    ControlAPairOfPins("22","0","11","1")
    time.sleep(1.5)
	
def Rechts_fahren():
    ControlAPairOfPins("19","1","7","1")
    ControlAPairOfPins("22","1","11","1")
    time.sleep(1.5)

def Rueckwaerts_fahren():
    ControlAPairOfPins("19","1","7","1")
    ControlAPairOfPins("22","0","11","1")
    time.sleep(1.0)

def Rueckwaerts_fahren_l():
    ControlAPairOfPins("19","1","7","1")
    ControlAPairOfPins("22","0","11","1")
    time.sleep(0.5)

def Rueckwaerts_fahren_r():
    ControlAPairOfPins("19","1","7","1")
    ControlAPairOfPins("22","0","11","1")
    time.sleep(0.5)
		
def Servo_permanent_vorn():
    p = GPIO.PWM(26,50)
    p.start(5.5)
    p.ChangeDutyCycle(5.5)
    time.sleep(True)
    p.stop(5.5)

def Servo_permanent_links():
    p = GPIO.PWM(26,50)
    p.start(5.5)
    p.ChangeDutyCycle(8.5)
    time.sleep(0.2)
    p.stop(8.5)

def Servo_permanent_rechts():
    p = GPIO.PWM(26,50)
    p.start(8.5)
    p.ChangeDutyCycle(3.5)
    time.sleep(0.2)
    p.stop(3.5)

def Servo_permanent_mitte():
    p = GPIO.PWM(26,50)
    p.start(3.5)
    p.ChangeDutyCycle(5.5)
    time.sleep(0.2)
    p.stop(5.5)

def Servo_anfang_mitte():
    p = GPIO.PWM(26,50)
    p.start(5.5)
    p.ChangeDutyCycle(5.5)
    time.sleep(0.1)
    p.stop(5.5)

def Servo_links():
    p = GPIO.PWM(26,50)
    p.start(5.5)
    p.ChangeDutyCycle(10.5)
    time.sleep(0.3)
    p.stop(10.5)

def Servo_rechts():
    p = GPIO.PWM(26,50)
    p.start(10.5)
    p.ChangeDutyCycle(1)
    time.sleep(0.3)
    p.stop(1)

def Servo_mitte():
    p = GPIO.PWM(26,50)
    p.start(1)
    p.ChangeDutyCycle(5.5)
    time.sleep(0.2)
    p.stop(5.5)

def Messung_permanent_vorn():
    GPIO.output(12, False)
    time.sleep(0.1)
    GPIO.output(12, True)
    time.sleep(0.00001)
    start = time.time()
    GPIO.output(12, False)
    while GPIO.input(16)==0:
        pass
    start = time.time()
    while GPIO.input(16)==1:
        pass
    stop = time.time()
    elapsed = stop-start
    global dist_vorn_perma
    dist_vorn_perma = elapsed * 17500
    print "Abstand_vorn: %.1f cm" % dist_vorn_perma

def Messung_permanent_links():
    GPIO.output(12, False)
    time.sleep(0.1)
    GPIO.output(12, True)
    time.sleep(0.00001)
    start = time.time()
    GPIO.output(12, False)
    while GPIO.input(16)==0:
        pass
    start = time.time()
    while GPIO.input(16)==1:
        pass
    stop = time.time()
    elapsed = stop-start
    global dist_links_perma
    dist_links_perma = elapsed * 17000
    print "Abstand_links: %.1f cm" % dist_links_perma

def Messung_permanent_rechts():
    GPIO.output(12, False)
    time.sleep(0.1)
    GPIO.output(12, True)
    time.sleep(0.00001)
    start = time.time()
    GPIO.output(12, False)
    while GPIO.input(16)==0:
        pass
    start = time.time()
    while GPIO.input(16)==1:
        pass
    stop = time.time()
    elapsed = stop-start
    global dist_rechts_perma
    dist_rechts_perma = elapsed * 17000
    print "Abstand_rechts: %.1f cm" % dist_rechts_perma

def Messung_distance_vorn():
    GPIO.output(12, False)
    time.sleep(0.5)
    GPIO.output(12, True)
    time.sleep(0.00001)
    start = time.time()
    GPIO.output(12, False)
    while GPIO.input(16)==0:
        pass
    start = time.time()
    while GPIO.input(16)==1:
        pass
    stop = time.time()
    elapsed = stop-start
    global distance
    distance = elapsed * 17500
    print "Abstand_vorn: %.1f cm" % distance

def Messung_dist_links():
    GPIO.output(12, False)
    time.sleep(1)
    GPIO.output(12, True)
    time.sleep(0.00001)
    start = time.time()
    GPIO.output(12, False)
    while GPIO.input(16)==0:
        pass
    start = time.time()
    while GPIO.input(16)==1:
        pass
    stop = time.time()
    elapsed = stop-start
    global dist_links
    dist_links = elapsed * 17000
    print "Abstand_links: %.1f cm" % dist_links

def Messung_dist_rechts():
    GPIO.output(12, False)
    time.sleep(1)
    GPIO.output(12, True)
    time.sleep(0.00001)
    start = time.time()
    GPIO.output(12, False)
    while GPIO.input(16)==0:
        pass
    start = time.time()
    while GPIO.input(16)==1:
        pass
    stop = time.time()
    elapsed = stop-start
    global dist_rechts              #Das es so einfach ist hätte man aber auch schreiben können!^^
    dist_rechts = elapsed * 17000
    print "Abstand_rechts: %.1f cm" % dist_rechts

	
while True:
    Servo_anfang_mitte()
    Vorwaerts_fahren()
    Messung_permanent_vorn()
    if dist_vorn_perma < 25:
        Stop_anhalten_permanent()
        print "STOP_VORN"
        Rueckwaerts_fahren()
        Stop()
        Servo_links()
        Messung_dist_links()
        Servo_rechts()
        Messung_dist_rechts()
        Servo_permanent_mitte()
        if dist_links > dist_rechts:
            Rueckwaerts_fahren_l()
            Links_fahren()
        else:
            Rueckwaerts_fahren_r()
            Rechts_fahren()
    else:
        Geradeaus_vorwaerts_start()
    Servo_permanent_links()
    Messung_permanent_links()
    if dist_links_perma < 12:
        Stop_anhalten_permanent()
        print "STOP_LINKS"
        Rueckwaerts_fahren()
        Stop()
        Servo_rechts()
        Messung_dist_rechts()        
        Servo_links()
        Messung_dist_links()
        Servo_permanent_mitte()
        if dist_rechts > dist_links:
            Rueckwaerts_fahren_l()
            Links_fahren()
        else:
            Rueckwaerts_fahren_r()
            Rechts_fahren()
    else:
        Geradeaus_vorwaerts_start()
    Servo_permanent_rechts()
    Messung_permanent_rechts()
    if dist_rechts_perma < 12:
        Stop_anhalten_permanent()
        print "STOP_RECHTS"
        Rueckwaerts_fahren()
        Stop()
        Servo_links()		
        Messung_dist_links()
        Servo_rechts()
        Messung_dist_rechts()
        Servo_permanent_mitte()
        if dist_links > dist_rechts:
            Rueckwaerts_fahren_l()
            Links_fahren()
        else:
            Rueckwaerts_fahren_r()
            Rechts_fahren()
    else:
        Geradeaus_vorwaerts_start()
MFG

Zappelmann
Zuletzt geändert von Zappelmann am Montag 26. Mai 2014, 18:35, insgesamt 1-mal geändert.
Zappelmann
User
Beiträge: 27
Registriert: Freitag 23. Mai 2014, 11:01

Montag 26. Mai 2014, 18:10

Ach ja da fällt mit gerade etwas ein was mich die ganzen Tage schon beschäftigt hat. Ich weis das man ein GPIO als Input definieren kann. Ich würde gern 2 Taster einsetzen. Einem zum starten der Software und einem zum stoppen der Software. Vielleicht könnt Ihr mir dazu ein Hinweis geben, wo man sowas am besten einfügt.
Im Grunde genommen möchte ich damit erreichen das der beim druck auf einem Taster das Programm an jeder Stelle sofort anhält und sämtliche GPIO Aktivitäten einstellt. Und beim Starten das das Programm natürlich von vorn abläuft.

Ich hoffe das Ihr mir da ein Tipp geben könnt.

In der Zwischenzeit werde ich weiter die Tutorialseiten wälzen um mein Wissen zu vertiefen.

MFG

Zappelmann
Sirius3
User
Beiträge: 8817
Registriert: Sonntag 21. Oktober 2012, 17:20

Montag 26. Mai 2014, 18:45

Warum nimmt `ControlAPairOfPins` Strings, wenn Du doch sowieso wieder alles in Ints umwandelst?
Das ganze ließe sich noch kürzer schreiben, wenn man statt der if-Abfragen direkt die Bedingung als Parameter einsetzt:

Code: Alles auswählen

def ControlAPairOfPins(FirstPin,FirstState,SecondPin,SecondState):
    GPIO.output(int(FirstPin), FirstState == "1")
    GPIO.output(int(SecondPin),SecondState == "1")
als nächstes solltest Du Dir angewöhnen, Dich an PEP-8 zu halten. Vor allem die Einrückung von 4 Leerzeichen.
Dann selltest Du `global` vermeiden, indem Du die Werte per `return` an den Aufrufer zurückgibst.
Zappelmann
User
Beiträge: 27
Registriert: Freitag 23. Mai 2014, 11:01

Montag 26. Mai 2014, 19:16

Sirius3 hat geschrieben:als nächstes solltest Du Dir angewöhnen, Dich an PEP-8 zu halten. Vor allem die Einrückung von 4 Leerzeichen.
Dann selltest Du `global` vermeiden, indem Du die Werte per `return` an den Aufrufer zurückgibst.
hmmmm erstmal danke für deine Anregung, aber bitte gibt es das auch in deutsch zu lesen, denn irgendwie ist ein so hochkonzentriertes Englisch nicht so ganz mein Ding....
Was die Einrückung von 4 Leerzeichen angeht, jo eigentlich versuche ich mich schon sehr daran zu halten. Aber ich hab den Bereich gefunden wo es nicht der Fall ist ich werde das dann korrigieren. Was die Codeänderung angeht. Ich werde drüber nachdenken und es mal austesten. Wenns funzt werde ich den Code daraufhin anpassen. Ja das mit dem return hab ich auch gelesen wegen Wertübergabe. Aber ich hab dabei halt auf nen Error mit global name define reagiert gehabt und deswegen das ganze ja hier überhaupt angefangen zu schreiben.

Aber ich werde mal weiter Versuche damit starten und schauen ob ich das richtig umgesetzt bekomme. Aber dieses PEP-8 Das muss ich erstmal verstehen was du mir damit sagen möchtest. Dann dahinter bin ich jetzt bisher noch nicht gekommen auser das es sich scheinbar um ein Style für Python Code geht. Aber vielleicht hast du da ja was ähnlihces was es auch auf deutsch gibt. Ansonsten werde ich später mal selber googlen.

MFG

Zappelmann
Zappelmann
User
Beiträge: 27
Registriert: Freitag 23. Mai 2014, 11:01

Montag 26. Mai 2014, 20:59

Zappelmann
User
Beiträge: 27
Registriert: Freitag 23. Mai 2014, 11:01

Dienstag 27. Mai 2014, 01:29

So das mit dem starten und stoppen des Scriptes über einen Taster hab ich schon gelöst. Ich hab dafür aber nen Schalter genommen und nen Taster zum testlauf. Jetzt konnte ich auch endlich mal das Script direkt in den Bootvorgang einbinden. Ohne das der direkt losfährt. Klappt wunderbar.

MFG

Zappelmann
EyDu
User
Beiträge: 4871
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Dienstag 27. Mai 2014, 13:17

Zappelmann hat geschrieben:Das hättet ihr aber auch direkt schreiben können das es so einfach ist ^^.
Haben wir doch. Aber du verwendest noch immer gloabl-Anweisungen.
Zappelmann hat geschrieben:Aber ich werde mal weiter Versuche damit starten und schauen ob ich das richtig umgesetzt bekomme. Aber dieses PEP-8 Das muss ich erstmal verstehen was du mir damit sagen möchtest. Dann dahinter bin ich jetzt bisher noch nicht gekommen auser das es sich scheinbar um ein Style für Python Code geht. Aber vielleicht hast du da ja was ähnlihces was es auch auf deutsch gibt.
Ja, PEP 8 ist ein Style Guide an den du dich unbedingt halten solltest. Zumindest dann, wenn andere deinen Code lesen sollen. Was hier ja der Fall ist. Ansonsten solltest du einfach die Idee vergessen, dass es Dokumentation auf Deutsch gibt. Um Englisch wirst du nicht herumkommen.
Das Leben ist wie ein Tennisball.
lackschuh
User
Beiträge: 278
Registriert: Dienstag 8. Mai 2012, 13:40

Mittwoch 25. Juni 2014, 13:14

Hallo

Ich hab auch eine kleine Frage bzgl. globale Variablen. Was wäre die 'richtige' Alternative zu folgendem Beispiel:

Code: Alles auswählen

import time

count = 0

def counter():
    while True:
        count = count + 1
        print count
        time.sleep(1)

counter()

Code: Alles auswählen

UnboundLocalError: local variable 'count' referenced before assignment
so?

Code: Alles auswählen

import time

count = 0

def counter(count):
    while True:
        count = count + 1
        print count
        time.sleep(1)

counter(count)
BlackJack

Mittwoch 25. Juni 2014, 13:19

@lackschuh: Eher so:

Code: Alles auswählen

import time

def counter():
    count = 0
    while True:
        count = count + 1
        print count
        time.sleep(1)

def main():     
    counter()


if __name__ == '__main__':
    main()
Beziehungsweise:

Code: Alles auswählen

import time
from itertools import count
 

def counter():
    for i in count(1):
        print i
        time.sleep(1)
Benutzeravatar
cofi
Moderator
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Mittwoch 25. Juni 2014, 13:21

Das kommt drauf an, was du eigentlich willst. Die beiden Fragmente tun schliesslich nicht dasselbe: #1 benutzt und veraendert die globale Variable (wenn man `global` hinzufuegt) #2 benutzt nie eine globale Variable und der Parameter `count` ist nur der Startwert.

Wenn du beabsichtigst, dass sich das globale `count` veraendert, dann gibt es keine richtige Alternative. Das Problem ist schliesslich nicht die `global` Anweisung sondern die globale Variable.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Mittwoch 25. Juni 2014, 13:25

Als erstes würde man ``count`` als Konstante *groß* schreiben, also ``COUNT``.

Und ja, man sollte an Funktionen Parameter übergeben - dabei kann man dann aber auch gerne Default-Werte statt Konstanten setzen:

Code: Alles auswählen

def counter(start=0):
    # usw.
Die Frage ist dabei ja eher, ob man einen Wert *mehrfach* benötigt. Falls ja, kann man gerne eine Konstante nehmen, falls nein, imho besser einen Default-Parameter.

"Konstanten" sind hier natürlich reine Konvention aufgrund der Schreibweise!

Idiomatischer wäre es imho auch so:

Code: Alles auswählen

from itertools import count
from time import sleep

def counter(start=0):
    for c in count(start):
        print(c)
        sleep(1)
Hier böte es sich eher / zudem an, die Wartezeit als Konstante zu hinterlegen oder auch als (Default)-Parameter zu übergeben.

Och menno, BJ war schneller :-D
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3))
assert encoding_kapiert
lackschuh
User
Beiträge: 278
Registriert: Dienstag 8. Mai 2012, 13:40

Mittwoch 25. Juni 2014, 13:27

Danke für die Infos. Vielleicht war das Beispiel nicht ganz das richtige. Angenommen ich definiere zu Beginn des Programms eine Variable mir dem Wert 0 (oder was auch immer). Diese Variable taucht aber nachfolgend in mehreren Funktionen und Klassen auf. Dann wäre nach BlackJack's Beispiel es so, dass man innerhalb einer jeden Funktion die Variable neu setzt.(?)

Ich beziehe mich auf das hier.

mfg
Antworten