Hallo,
ich versuche ein bischen meine Programmierkünste wieder aufzufrischen und habe mit Python angefangen.
Ich versuche bei unten stehendem Programm herauszufinden warum es mit einer Texteingabe ohne Leerzeichen funktioniert - aber wenn ich ein Leerzeichen in der Eingabe habe, bricht das Programm ab oder macht eine unlogische Fehlermeldung.
Das Programm startet mit einem Eingabefenster welches mit OK abgeschlossen wird. Ausgelesen wird der Test der dann im SenseHat auf der LED Matrix angezeigt wird.
Zur weiteren Erklärung: wenn ich Sound mit drin habe wird gemeldet, dass Sound nicht initialisiert ist - aber nur bei Leerzeichen Eingabe. Benutzt man keine Sound Ausgabe wird die Ausführung ohne Fehlermeldung abgebrochen. Ohne Leerzeichen im Text funktioniert alles.
Ich habe auch schon versucht das Leerzeichen mit "if" abzufangen, da z.B. chatgpt sagt, dass es mit Leerzeichen Probleme gibt, aber auch wenn ich bei Leerzeichen keine Ausgabe an den SenseHat mache, passiert das gleiche.
Programm ist inzwischen etwas chaotischer, da ich schon viele Änderungen versucht habe.
Hat jemand eine Idee?
Danke,
Grüße,
Michael
Die jetzige Fehlermeldung ist:
Traceback (most recent call last):
File "/home/pi/Python_Projekte/SenseHat_Text_ColorChange__mitFensterAbfrage_Texteingabe02b.py", line 90, in <module>
Boing.set_volume(Laut)
pygame.error: mixer system not initialized
Aber löscht man die Sound Befehle bricht das Programm ohne Fehlermeldung auch ab - nach Eingabe im Fenster.
Python Script:
#Import von Bibliotheken
from sense_hat import SenseHat
import time
import random
import pygame
from pynput import keyboard
import tkinter as tk
# Diese Funktion wird aufgerufen, wenn space erkannt wird
def on_press(key):
if key == keyboard.Key.space:
#aufäumen und schliessen
sense.clear()
pygame.quit ()
exit()
# Funktion zur Abfrage Hell-Dunkel und Lauttärke
def get_variables():
# Variablen als Liste
variablen = [None, None, None, None]
#Funktion wenn Ok Button
def submit():
variablen[0] = entry1.get()
variablen[1] = entry2.get()
variablen[2] = entry3.get()
variablen[3] = entry4.get()
Fenster.destroy() # Fenster schließen
# Hauptfenster erstellen
Fenster = tk.Tk()
w = 250 # Fensterbreite
h = 225 # Fensterhöhe
# Fensterbreite unf Höhe der Auflösung auslesen
ws = Fenster.winfo_screenwidth() # Breite
hs = Fenster.winfo_screenheight() # Höhe
# Koordinate für das Fenster
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
# Dimension des Fensters und Anzeigeort
Fenster.geometry('%dx%d+%d+%d' % (w, h, x, y))
Fenster.title("Stop beendet")
# Labels und Eingabefelder für die zwei Variablen
label1 = tk.Label(Fenster, text="Lautstärke 0-10:")
label1.pack()
entry1 = tk.Entry(Fenster)
entry1.pack()
label2 = tk.Label(Fenster, text="Dunkles Display? j/n")
label2.pack()
entry2 = tk.Entry(Fenster)
entry2.pack()
label3 = tk.Label(Fenster, text="Text: (ohne spaces)")
label3.pack()
entry3 = tk.Entry(Fenster)
entry3.pack()
label4 = tk.Label(Fenster, text="Wiederholungen:")
label4.pack()
entry4 = tk.Entry(Fenster)
entry4.pack()
# Button zum Bestätigen der Eingaben
submit_button = tk.Button(Fenster, text="Ok", command=submit)
submit_button.pack()
# Haupt-Event-Schleife starten
Fenster.mainloop()
return variablen[0], variablen[1], variablen[2], variablen[3] # Variablen an das Programm zurückgeben
#start Listener
listener = keyboard.Listener(on_press=on_press)
listener.start()
#SenseHat initialisieren
sense = SenseHat()
sense.low_light = False
#Mixer initialisieren
pygame.mixer.init(frequency=22050, size=-16, channels=2, buffer=128)
Boing = pygame.mixer.Sound("/home/pi/Python_Projekte/Sound/boing_x.wav")
# Abfrage in Fenster
variable1, variable2, variable3, variable4 = get_variables()
Laut = float(variable1)/10
Boing.set_volume(Laut)
if variable2 == "j":
sense.low_light = True
else:
sense.low_light = False
Laenge = len(variable3)
Buchstabe = variable3
Nochmal = int(variable4)
#Background Loop
for j in range (Nochmal):
#Textfarbe definiren
Hintergrundfarbe = (random. randint(1, 255), random. randint(1, 255), random. randint(1, 255))
#Text Loop
for char in Buchstabe:
#Textfarbe definieren
Textfarbe = (random. randint(1, 255), random. randint(1, 255), random. randint(1, 255))
#Sound spielen
Boing.play()
#Buchstabe anzeigen
sense.show_letter(char, text_colour=(Textfarbe), back_colour=(Hintergrundfarbe))
#Warten
time.sleep(0.7)
#Löschen
sense.clear()
Boing.stop()
pygame.quit()
Probleme bei Eingabe in Textfeld (tkinter) und Ausgabe auf Sense Hat: Space Eingabe führt zu Fehler
Hallo,
wenn ich das richtig sehe, dann bricht das Programm nicht ohne Fehlermeldung ab, sondern beendet sich nach dem die `Nochmal`-Schleifendurchgänge durchgelaufen sind.
Dass das Programm bei einem Leerzeichen abbricht, hast du ja so in `on_press()` programmiert.
Das Problem mit dem `mixer` kann ich nicht nachstellen.
Vielleicht sollten wir erst mal klären, wie der Programmablauf aussehen soll und uns dann Schritt für Schritt, mit einzelnen Funktionen und ordentlichen Namen, nähern.
Grüße
Dennis
wenn ich das richtig sehe, dann bricht das Programm nicht ohne Fehlermeldung ab, sondern beendet sich nach dem die `Nochmal`-Schleifendurchgänge durchgelaufen sind.
Dass das Programm bei einem Leerzeichen abbricht, hast du ja so in `on_press()` programmiert.
Das Problem mit dem `mixer` kann ich nicht nachstellen.
Vielleicht sollten wir erst mal klären, wie der Programmablauf aussehen soll und uns dann Schritt für Schritt, mit einzelnen Funktionen und ordentlichen Namen, nähern.
Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Hallo Dennis,
wie blöd kann man manchmal sein - der Listener war ein Überbleibsel von Copy Paste aus meinem vorigen Programm. Nach Löschen geht es natürlich. Hatte das Script wieder und wieder gelesen und ist mir nicht aufgefallen.
Vielen Dank für den Zaunpfahl
Grüße!
wie blöd kann man manchmal sein - der Listener war ein Überbleibsel von Copy Paste aus meinem vorigen Programm. Nach Löschen geht es natürlich. Hatte das Script wieder und wieder gelesen und ist mir nicht aufgefallen.
Vielen Dank für den Zaunpfahl
Grüße!
- __blackjack__
- User
- Beiträge: 13997
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Woodz42: Die Funktion ist zwar jetzt raus, aber ich wollte trotzdem noch mal anmerken, dass man *diese* `exit()`-Funktion nicht in Programmen verwenden sollte, sondern `sys.exit()`. Die `sys.exit()` aber auch nicht in irgendwelchen Funktion um das Programm zu beenden, sondern eigentlich nur im Hauptprogramm um beim beenden des Programms mindestens potentiell einen anderen Rückgabecode als 0 an das aufrufende Programm zu übermitteln, und nicht einfach nur um das Programm zu beenden, denn das hat üblicherweise das Geschmäckle, dass man sich um einen sauberen Programmablauf drücken wollte.
Der Kommentar über der jetzt entfernten Funktion ist falsch: die wird nicht aufgerufen wenn das Leerzeichen erkannt wird, die wird für *jede* Taste aufgerufen.
Kommentare über Funktionen sind oft besser Docstrings.
Kommentare sollen dem Leser einen Mehrwert über den Code geben. Faustregel: Kommentare beschreiben nicht *was* der Code macht, denn das steht da bereits als Code, sondern warum er das macht. Sofern das nicht offensichtlich ist. Offensichtlich ist in aller Regel auch was in der Dokumentation von Python und den verwendeten Bibliotheken steht.
Sonstige Anmerkungen: Auf Modulebene sollte nur Code stehen, der Konstanten, Funktionen, und Klassen definiert.
Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.
Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).
Funktionen verschachtelt man normalerweise nicht. Funktionen bekommen alles was sie ausser Konstanten benötigen als Argument(e) übergeben. Die Liste mit ”Variablen” und Dummywerten ist auch ein unsauberer Hack. Bei jeder nicht-trivialen GUI kommt man im objektorientierte Programmierung (OOP) nicht wirklich herum.
Die Fensterbreite fest als Pixelzahlen in den Quelltext zu schreiben funktioniert nicht wirklich, denn das hängt von vielen Faktoren ab. Man kann die tatsächliche Grösse vom Fenster abfragen.
Man nummeriert keine Namen. Dann will man sich entweder bessere Namen überlegen, oder gar keine Einzelnamen/-werte verwenden, sondern eine Datenstruktur. Oft eine Liste. In Falle der Entries und Variablen aber bessere Namen. Bei den `Label`-Objekten gar keinen Namen.
`Laenge` wird definiert, aber nirgends verwendet.
`Buchstabe` steht gar nicht für einen Buchstaben, sondern für eine Zeichenkette.
`Nochmal` ist ein komischer Name für eine *Anzahl* an Wiederholungen.
Das generieren einer zufälligen Farbe könnte man als Funktion heraus ziehen.
Zwischenstand (ungetestet):
Der Kommentar über der jetzt entfernten Funktion ist falsch: die wird nicht aufgerufen wenn das Leerzeichen erkannt wird, die wird für *jede* Taste aufgerufen.
Kommentare über Funktionen sind oft besser Docstrings.
Kommentare sollen dem Leser einen Mehrwert über den Code geben. Faustregel: Kommentare beschreiben nicht *was* der Code macht, denn das steht da bereits als Code, sondern warum er das macht. Sofern das nicht offensichtlich ist. Offensichtlich ist in aller Regel auch was in der Dokumentation von Python und den verwendeten Bibliotheken steht.
Sonstige Anmerkungen: Auf Modulebene sollte nur Code stehen, der Konstanten, Funktionen, und Klassen definiert.
Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.
Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).
Funktionen verschachtelt man normalerweise nicht. Funktionen bekommen alles was sie ausser Konstanten benötigen als Argument(e) übergeben. Die Liste mit ”Variablen” und Dummywerten ist auch ein unsauberer Hack. Bei jeder nicht-trivialen GUI kommt man im objektorientierte Programmierung (OOP) nicht wirklich herum.
Die Fensterbreite fest als Pixelzahlen in den Quelltext zu schreiben funktioniert nicht wirklich, denn das hängt von vielen Faktoren ab. Man kann die tatsächliche Grösse vom Fenster abfragen.
Man nummeriert keine Namen. Dann will man sich entweder bessere Namen überlegen, oder gar keine Einzelnamen/-werte verwenden, sondern eine Datenstruktur. Oft eine Liste. In Falle der Entries und Variablen aber bessere Namen. Bei den `Label`-Objekten gar keinen Namen.
`Laenge` wird definiert, aber nirgends verwendet.
`Buchstabe` steht gar nicht für einen Buchstaben, sondern für eine Zeichenkette.
`Nochmal` ist ein komischer Name für eine *Anzahl* an Wiederholungen.
Das generieren einer zufälligen Farbe könnte man als Funktion heraus ziehen.
Zwischenstand (ungetestet):
Code: Alles auswählen
# Import von Bibliotheken
import time
import tkinter as tk
from random import randint
from sense_hat import SenseHat
import pygame
class Window(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.volume = 0.5
self.low_light = False
self.text = "abc"
self.repetition_count = 1
self.title("Stop beendet")
tk.Label(self, text="Lautstärke 0-10:").pack()
self.volume_entry = tk.Entry(self)
self.volume_entry.pack()
tk.Label(self, text="Dunkles Display? j/n").pack()
self.low_light_entry = tk.Entry(self)
self.low_light_entry.pack()
tk.Label(self, text="Text: (ohne Leerzeichen)").pack()
self.text_entry = tk.Entry(self)
self.text_entry.pack()
tk.Label(self, text="Anzahl Wiederholungen:").pack()
self.repetition_count_entry = tk.Entry(self)
self.repetition_count_entry.pack()
tk.Button(self, text="Ok", command=self.on_submit).pack()
x = self.winfo_screenwidth() / 2 - self.winfo_width() / 2
y = self.winfo_screenheight() / 2 - self.winfo_height() / 2
self.geometry("+%d+%d" % (x, y))
def on_submit(self):
try:
self.volume = int(self.volume_entry.get()) / 10
except ValueError:
pass # Ignore values that are no number.
self.low_light = (
self.low_light_entry.get().strip().lower().startswith("j")
)
self.text = self.text_entry.get().replace(" ", "")
try:
self.repetition_count = int(self.repetition_count_entry.get())
except ValueError:
pass # Ignore values that are no number.
self.quit()
def generate_random_color():
return (randint(1, 255), randint(1, 255), randint(1, 255))
def main():
sense = SenseHat()
sense.low_light = False
pygame.mixer.init(frequency=22050, size=-16, channels=2, buffer=128)
boing = pygame.mixer.Sound("/home/pi/Python_Projekte/Sound/boing_x.wav")
try:
window = Window()
window.mainloop()
boing.set_volume(window.volume)
sense.low_light = window.low_light
for _ in range(window.repetition_count):
back_colour = generate_random_color()
for character in window.text:
boing.play()
sense.show_letter(
character,
text_colour=generate_random_color(),
back_colour=back_colour,
)
time.sleep(0.7)
finally:
sense.clear()
boing.stop()
pygame.quit()
if __name__ == "__main__":
main()
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis