Seite 1 von 2
beep auf Ubuntu mit Python aufrufen / Beispiel Morsen
Verfasst: Donnerstag 24. März 2016, 00:50
von orpidor
[Codebox=text file=Unbenannt.txt]
Ich bin Neuling und lerne gerade Python auf Ubuntu und bin stolzer Besitzer eines Tuxedo Notebooks.
Ich habe Python 3.4.3+ auf meinem Rechner und bin gerade dabei ein Morse-Listing zu bearbeiten, welches in einem Lern-Beispiel mit winsound arbeitet, was mir aber nichts nutzt.(Ich lerne Python gerade mit dem BUch "Python für Einsteiger von Thomas Theis.
Nun habe ich bereits im Internet gelesen, dass man mit os.system("beep") Piepsignale aufrufen kann. Ich habe beep bereits installiert, aber leider funktioniert es nicht. Über das Internet habe ich gelesen, dass es vielleicht am BIOS liegen kann (Beep beim Start ein-bzw. ausschalten.)
Aber auch das hat mich nicht weitergebracht.
Vielleicht kann mir jemand helfen, wie ich da jetzt weiterkomme?
Wie kann ich Beep durch Python aufrufen oder an welcher Einstellung und/oder Konfigurationsdatei könnte es vielleicht liegen, dass es bei mir nicht funktioniert?
Danke schon mal für eine Antwort...
[/Codebox]
Code: Alles auswählen
import sys, morsen, time, os
# im Listing: import winsound
# Beispieltext codieren
def tonCode(text,code):
# Zeitschema, Dauer eines Signals in msec.
signalDauer = {".":200, "-":600}
# Zeitschema, Dauer einer Pause in sec.
signalPause = 0.2
zeichenPause = 0.6
wortPause = 1.4
# Text in Worte zerlegen
alleWorte = text.split()
# Jedes Wort im Text
for w in range(len(alleWorte)):
# Übernahme eines Worts
wort = alleWorte[w]
# Jedes Zeichen im Wort
for z in range(len(wort)):
# Übernahme eines Zeichens
zeichen = wort[z]
# Kontrollausgabe des Zeichens
print(zeichen, end="")
# Versuch ein Zeichen auszugeben
try:
# Übernahme des Morsezeichens für das Zeichen
# Falls kein Eintrag im Dictionary: KeyError
alleSignale =code[zeichen]
# Jedes Signal des Morsezeichens
for s in range (len(alleSignale)):
# Übernahme eines Symbols
signal = alleSignale[s]
# Ausgabe des Symbols, kurz oder lang
os.system("beep -f 800 -l signalDauer[signal]")
# original: winsound.Beep(800, signalDauer[signal])
# Nach jedem Signal eine Signalpause
# ausser nach dem letzten Signal
if s < len(alleSignale)-1:
time.sleep(signalPause)
# Nach jedem Zeichen eine Signalpause,
# ausser nach dem letzten Zeichen
if z < len(wort)-1:
time.sleep(zeichenPause)
# Falls kein Eintrag im Dictionary: ignorieren
except KeyError:
pass
# Nach jedem Wort eine Wortpause,
# ausser nach dem letzten Wort
if w < len(alleWorte)-1:
print(" ", end = "")
time.sleep(wortPause)
# Lesefunktion aufrufen
code = morsen.leseCode()
# Schreibfunktion aufrufen
tonCode("Hallo Welt", code)
Re: beep auf Ubuntu mit Python aufrufen / Beispiel Morsen
Verfasst: Donnerstag 24. März 2016, 08:01
von miracle173
os.system("xxx ...") führt den Befehl "xxx ..." aus. Öffne ein Terminal-Fenster und führe
aus. Das sollte einen Ton ergeben, der eine Sekunde anhält.
Nun öffne die Python-Shell und versuche aus dieser den Ton zu erzeugen. Ich würde folgendes bekommen, wenn ich
beep installiert hätte.
Code: Alles auswählen
$ python
Python 2.4.3 (#1, Feb 24 2012, 13:04:26)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-50)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.system("beep -f 165.4064 -l 1000")
0
>>>
Und ein Ton würde erklingen.
0 ist der Rückgabewert von
os.system und der ist immer
0 wenn das Kommando erfolgreich ausgeführt wurde.
Ich habe aber Beep nicht installiert (und auch kein Ubuntu). Darum schaut es bei mir so aus:
Code: Alles auswählen
[oracle@upx1media01 trash]$ python
Python 2.4.3 (#1, Feb 24 2012, 13:04:26)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-50)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.system("beep -f 165.4064 -l 1000")
sh: beep: command not found
32512
>>>
Wie schaut das bei dir aus?
Ich habe deinen Code nur überflogen: er kann nicht funktionieren. Führe im Terminal-Fenster
Das wird natürlich einen Fehler ergeben, da
beep nichts mit der Zeichenkette
'signalDauer[signal]' anfangen kann. Aber genau so rufst du
beep aus Python auf. Wenn du wills, das
beep aus Python mit dem Wert von
signalDauer[signal] aufgerufen wird, musst du die entsprechende Befehlszeichenkette erzeugen, zum Beispiel so
Mehr über Zeichenketten erfährst du im Tutorial:
https://docs.python.org/3/tutorial/intr ... ml#strings
Die töne so zu erzeugen ist etwas ineffizient, da für jeden Piepser ein eigener beep-Prozess erzeugt wird. Und möglicherweise auch ein eigenes Terminal-Fenster, falls du python nicht aus so einem startes. Aber voerst kannst du es ja so versuchen. Danach könntest du versuchen, für einen Text beep nur einmal aufzurufen.
Re: beep auf Ubuntu mit Python aufrufen / Beispiel Morsen
Verfasst: Donnerstag 24. März 2016, 08:16
von Sirius3
@orpidor: Der Fehler liegt im Aufruf von beep.
Für jedes Modul solltest Du eine eigene import-Zeile schreiben. Namen sind wichtige Informationsträger. Funktionen sollten nach Tätigkeiten benannt sein, was soll ich mir also unter einer Funktion vorstellen, die tonCode heißt? morse_text ist z.B. viel aussagekräftiger. Das Argument code sagt mir gar nichts und ich mußte erst den ganzen Code lesen, um zu verstehen, dass code ein Wörterbuch ist, das Zeichen in Morsesequenzen mappt, der Name char2morsesequenze wäre damit passender. `for w in range(len(xy)):` ist in Python ein Antipattern, weil Du auch direkt über die Liste iterieren kannst: `for wort in alleWorte:` bzw. `for zeichen in wort:`.
os.system solltest Du nicht verwenden, und statt dessen subprocess.call. In Python werden nicht auf magische Weise Variablen in Strings ersetzt, das mußt Du explizit angeben:
Code: Alles auswählen
subprocess.call(['beep', '-f', '800', '-l', str(signalDauer[signal])])
Kommentare sollten im Code beschreiben, warum etwas passiert und nicht was. Der Mehrwert von "Lesefunktion aufrufen" tendiert gegen minus unendlich, weil zum einen die Information fehlt, was gelesen werden soll, zum anderen in der nächsten Zeile klar ist, dass eine Funktion aufgerufen wird.
Code: Alles auswählen
import sys
import morsen
import time
import subprocess
SIGNAL_PAUSE = 0.2
ZEICHEN_PAUSE = 0.6
WORT_PAUSE = 1.4
SIGNAL_DAUER = {".":200, "-":600}
FREQUENZ = 800
def morse_text(text, char2morsesequenz):
pause = 0
for wort in text.split():
for zeichen in wort:
print(zeichen, end="")
try:
morsesequenz = char2morsesequenz[zeichen]
except KeyError:
pass
else:
for signal in morsesequenz:
time.sleep(pause)
subprocess.call(['beep', '-f', str(FREQUENZ)), '-l', str(SIGNAL_DAUER[signal])])
pause = SIGNAL_PAUSE
pause = ZEICHEN_PAUSE
print(" ", end = "")
pause = WORT_PAUSE
char2morsesequenz = morsen.leseCode()
morse_text("Hallo Welt", char2morsesequenz)
Re: beep auf Ubuntu mit Python aufrufen / Beispiel Morsen
Verfasst: Donnerstag 24. März 2016, 09:49
von BlackJack
Zum ``beep``-Problem: Das benutzt den eingebauten PC-Lautsprecher den es nicht mehr in allen Geräten gibt. Wobei im Laptop verbaute Lautsprecher nicht zwangsläufig als „PC speaker“ angesprochen werden können, denn das sind ja echte Lautsprecher im Gegensatz zu dem ”Piepsdings” was früher in jedem PC eingebaut war. Es kann also durchaus sein, dass es letztendlich auf ein Hardwareproblem hinausläuft.
Edit: Hab's bei mir gerade mit ``sudo modprobe pcspkr`` zum ``beep``\en bekommen. Der Kerneltreiber für den „PC speaker“ war also nicht geladen. Und zwar weil der bei mir in ``/etc/modprobe.d/blacklist.conf`` auf der schwarzen Liste steht:
Code: Alles auswählen
# ugly and loud noise, getting on everyone's nerves; this should be done by a
# nice pulseaudio bing (Ubuntu: #77010)
blacklist pcspkr
Re: beep auf Ubuntu mit Python aufrufen / Beispiel Morsen
Verfasst: Donnerstag 24. März 2016, 10:06
von miracle173
Also deshalb wie beschrieben zuerst einmal mit
ausprobieren, ob das überhaupt funktioniert. Bevor
beep so nicht funktioniert brauchst du es auch in Python mit
beep nicht versuchen.
Zusätzlich solltest du beim Aufruf von
beep gleich den Pfad mit angeben. Das garantiert nicht nur, das das Programm
beep gefunden wird, es verhindert auch, dass dir irgendwer ein anderes, bösartiges
beep in einem anderen Pfad unterjubeln kann. In Python sollte der Pfad in einer Variablen gespreicher sein, das erleichtert die Anpassung and andere Systeme.
Re: beep auf Ubuntu mit Python aufrufen / Beispiel Morsen
Verfasst: Donnerstag 24. März 2016, 13:33
von mutetella
@orpidor
Ich würde ganz auf den Gebrauch von `beep` verzichten und mir statt dessen einen 'beep-sound' besorgen, diesen evtl. noch vorne und hinten kürzen und dann mit
aplay, das von den meisten Distris bereits vorinstalliert ist aufrufen oder ein
Python Paket zur Audioausgabe nutzen.
Wie BlackJack bereits schreibt stammt `beep` noch aus Zeiten, in denen ein PC diese fürchterlich nervtötenden Piepser eingebaut hatte.
Re: beep auf Ubuntu mit Python aufrufen / Beispiel Morsen
Verfasst: Donnerstag 24. März 2016, 19:04
von miracle173
mutetella hat geschrieben:@orpidor
Ich würde ganz auf den Gebrauch von `beep` verzichten und mir statt dessen (...)
Wenn er jetzt schon beep installiert hat und das ohne größeren Aufwand zum laufen bringt, wir das wohl ausreichen. Es geht vermutlich mehr um das Programmieren und um Python als um das Morsen. Der prakische Einsatz des fertigen Programms wird sich in grenzen halten.
Was das Programmieren betrifft möchte ich noch feststellen, dass bei Verwendung von os.system(), was ja laut Sirius3 eigentlich
vermieden werden sollte, noch eine Fehlerbehandlung eingebaut werden muss. Also so ähnlich wie
Code: Alles auswählen
result=os.system("beep ...")
if result:
raise RuntimeError("beep-errors %d" % result)
Re: beep auf Ubuntu mit Python aufrufen / Beispiel Morsen
Verfasst: Donnerstag 24. März 2016, 20:04
von Sirius3
@miracle173: jetzt sag mir nur noch, welchen Exitcode beep haben soll? Die Dokumentation schweigt sich dazu aus. subprocess liefert das, was Du da von Hand zusammenbaust, schon mit: check_call.
Re: beep auf Ubuntu mit Python aufrufen / Beispiel Morsen
Verfasst: Donnerstag 24. März 2016, 20:14
von miracle173
Re: beep auf Ubuntu mit Python aufrufen / Beispiel Morsen
Verfasst: Donnerstag 24. März 2016, 20:22
von Sirius3
@miracle173: was ein Exitcode ist, ist mir klar. Was es für Exitcodes bei beep gibt aber nicht.
Re: beep auf Ubuntu mit Python aufrufen / Beispiel Morsen
Verfasst: Donnerstag 24. März 2016, 22:18
von noisefloor
Hallo,
das Dekodieren von Morse-Code muss du auch nicht selber machen. Dafür gibt's fertige Module. Einfach mal nach "morse" bei PyPi suchen.
Wobei ich persönlich ja [url]
https://pypi.python.org/pypi/pyMorseCode[/ulr] gut finde
Gruß, noisefloor
Re: beep auf Ubuntu mit Python aufrufen / Beispiel Morsen
Verfasst: Donnerstag 24. März 2016, 22:55
von miracle173
@Sirius3: Mir ist eigentlich nicht ganz klar, was du jetzt eigentlich wissen willst bzw. worauf du hinaus willst.
Sirius3 hat geschrieben:
(...)
jetzt sag mir nur noch, welchen Exitcode beep haben soll?
(...)
Haben soll es natürlich 0, weil das bedeutet, dass der Befehl erfolgreich ausgeführt wurde.
Sirius3 hat geschrieben:
(...)
was ein Exitcode ist, ist mir klar. Was es für Exitcodes bei beep gibt aber nicht.
(...)
Mir ist auch nicht klar, was für Exitcodes es bei beep gibt. Allerdings ist mir das auch ziemlich egal. Die brauch ich eigentlich nicht, um das Morseprogramm zu schreiben. Ich würde da eigentlich nicht auf irgendwelche Fehlercodes eingehen.
Sirius3 hat geschrieben:
(...)
subprocess liefert das, was Du da von Hand zusammenbaust, schon mit: check_call
(...)
Das spricht zwar für subprocess, aber nicht dagegen, dass man, wenn man os.system() verwendet, eine geeignete Fehlerbehandlung einbaut.
Re: beep auf Ubuntu mit Python aufrufen / Beispiel Morsen
Verfasst: Freitag 25. März 2016, 10:44
von noisefloor
Hallo,
Das spricht zwar für subprocess, aber nicht dagegen, dass man, wenn man os.system() verwendet
Eigentlich spricht alles dagegen, dass man `os.system()` verwendet. Seit es das `subprocess` Modul gibt, gibt es sehr wenig Gründe, noch `os.system()` zu nutzen. Die offizielle Pyhton-Doku rät ja auch dazu, `subprocess` zu verwenden.
Gruß, noisefloor
Re: beep auf Ubuntu mit Python aufrufen / Beispiel Morsen
Verfasst: Samstag 26. März 2016, 06:32
von miracle173
noisefloor hat geschrieben:Hallo,
Das spricht zwar für subprocess, aber nicht dagegen, dass man, wenn man os.system() verwendet
Eigentlich spricht alles dagegen, dass man `os.system()` verwendet.
(...)
Hallo
Auch ich sehe keine Grund os.system() zu verwenden, aber viele Gründe subprocess zu verwenden. Ich habe aber auch nie für os.system() geworben. Auch mein von dir zitierte Satz tut das in keiner Weise.
Re: beep auf Ubuntu mit Python aufrufen / Beispiel Morsen
Verfasst: Samstag 26. März 2016, 07:16
von noisefloor
Hallo,
Auch mein von dir zitierte Satz tut das in keiner Weise.
Nee, du rätst aber auch nicht von der Nutzung explizit ab. Aber explizit ist besser als implizit, kennste ja
Gruß, noisefloor
Re: beep auf Ubuntu mit Python aufrufen / Beispiel Morsen
Verfasst: Samstag 26. März 2016, 23:27
von orpidor
miracle173 hat geschrieben:os.system("xxx ...") führt den Befehl "xxx ..." aus. Öffne ein Terminal-Fenster und führe
aus. Das sollte einen Ton ergeben, der eine Sekunde anhält.
Nun öffne die Python-Shell und versuche aus dieser den Ton zu erzeugen. Ich würde folgendes bekommen, wenn ich
beep installiert hätte.
Code: Alles auswählen
$ python
Python 2.4.3 (#1, Feb 24 2012, 13:04:26)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-50)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.system("beep -f 165.4064 -l 1000")
0
>>>
[/code]
Wie schaut das bei dir aus?
Danke für die tollen Hinweise.
Ich erhalte ebenfalls den Rückgabewert 0, also scheint alles ok zu sein, aber der Piepton ist nicht zu hören.
Ich habe deinen Code nur überflogen: er kann nicht funktionieren. Führe im Terminal-Fenster
Das wird natürlich einen Fehler ergeben, da
beep nichts mit der Zeichenkette
'signalDauer[signal]' anfangen kann. Aber genau so rufst du
beep aus Python auf. Wenn du wills, das
beep aus Python mit dem Wert von
signalDauer[signal] aufgerufen wird, musst du die entsprechende Befehlszeichenkette erzeugen, zum Beispiel so
Das stimmt, da habe ich den Code zu schnell übermittelt, bevor ich es nochmals überprüft habe. Danke.
Mehr über Zeichenketten erfährst du im Tutorial:
https://docs.python.org/3/tutorial/intr ... ml#strings
Die töne so zu erzeugen ist etwas ineffizient, da für jeden Piepser ein eigener beep-Prozess erzeugt wird. Und möglicherweise auch ein eigenes Terminal-Fenster, falls du python nicht aus so einem startes. Aber voerst kannst du es ja so versuchen. Danach könntest du versuchen, für einen Text beep nur einmal aufzurufen.
Ja, Danke. Ich stehe noch am Anfang meiner Python-Programmier-Karriere, bin aber schon jetzt begeistert, was ich hier im Forum für tolle Tipps und Hinweise bekomme. Echt Klasse. Ich lerne hier eine Menge.
Re: beep auf Ubuntu mit Python aufrufen / Beispiel Morsen
Verfasst: Samstag 26. März 2016, 23:36
von orpidor
[quote="Sirius3"]@orpidor: Der Fehler liegt im Aufruf von beep.
... In Python werden nicht auf magische Weise Variablen in Strings ersetzt, das mußt Du explizit angeben:
Code: Alles auswählen
subprocess.call(['beep', '-f', '800', '-l', str(signalDauer[signal])])
Kommentare sollten im Code beschreiben, warum etwas passiert und nicht was. Der Mehrwert von "Lesefunktion aufrufen" tendiert gegen minus unendlich, weil zum einen die Information fehlt, was gelesen werden soll, zum anderen in der nächsten Zeile klar ist, dass eine Funktion aufgerufen wird
.
Vielen Dank auch Dir für die vielen Hinweise und Tipps. Gerade mit der Beschreibung im Listing und der Nameswahl hast Du natürlich recht. Ich stehe ganz am Anfang und bringe mir gerade Python bei und werde darauf in Zukunft stärker achten.
Re: beep auf Ubuntu mit Python aufrufen / Beispiel Morsen
Verfasst: Samstag 26. März 2016, 23:42
von orpidor
BlackJack hat geschrieben:Zum ``beep``-Problem: Das benutzt den eingebauten PC-Lautsprecher den es nicht mehr in allen Geräten gibt. Wobei im Laptop verbaute Lautsprecher nicht zwangsläufig als „PC speaker“ angesprochen werden können, denn das sind ja echte Lautsprecher im Gegensatz zu dem ”Piepsdings” was früher in jedem PC eingebaut war. Es kann also durchaus sein, dass es letztendlich auf ein Hardwareproblem hinausläuft.
Edit: Hab's bei mir gerade mit ``sudo modprobe pcspkr`` zum ``beep``\en bekommen. Der Kerneltreiber für den „PC speaker“ war also nicht geladen. Und zwar weil der bei mir in ``/etc/modprobe.d/blacklist.conf`` auf der schwarzen Liste steht:
Code: Alles auswählen
# ugly and loud noise, getting on everyone's nerves; this should be done by a
# nice pulseaudio bing (Ubuntu: #77010)
blacklist pcspkr
Danke für Deine Hilfe. Ich habe inzwischen die gleiche Erfahrung gemacht und etliches gelesen und ausprobiert. Ich freue mich, dass es bei mir wahrscheinlich tatsächlich ein Hardware-Problem ist.
Re: beep auf Ubuntu mit Python aufrufen / Beispiel Morsen
Verfasst: Samstag 26. März 2016, 23:49
von orpidor
miracle173 hat geschrieben:Also deshalb wie beschrieben zuerst einmal mit
ausprobieren, ob das überhaupt funktioniert. Bevor
beep so nicht funktioniert brauchst du es auch in Python mit
beep nicht versuchen.
Zusätzlich solltest du beim Aufruf von
beep gleich den Pfad mit angeben. Das garantiert nicht nur, das das Programm
beep gefunden wird, es verhindert auch, dass dir irgendwer ein anderes, bösartiges
beep in einem anderen Pfad unterjubeln kann. In Python sollte der Pfad in einer Variablen gespreicher sein, das erleichtert die Anpassung and andere Systeme.
habe es ausprobiert und der Computer sagt mir, dass alles ok ist (Rückgabewert 0), aber kein Gepiepe. Ich gehe inzwischen davon aus, dass es nicht funktioniert, weil es wohl eine "Hardware-Sache" ist. Danke für die Hilfe.
Re: beep auf Ubuntu mit Python aufrufen / Beispiel Morsen
Verfasst: Samstag 26. März 2016, 23:54
von orpidor
mutetella hat geschrieben:@orpidor
Ich würde ganz auf den Gebrauch von `beep` verzichten und mir statt dessen einen 'beep-sound' besorgen, diesen evtl. noch vorne und hinten kürzen und dann mit
aplay, das von den meisten Distris bereits vorinstalliert ist aufrufen oder ein
Python Paket zur Audioausgabe nutzen.
Wie BlackJack bereits schreibt stammt `beep` noch aus Zeiten, in denen ein PC diese fürchterlich nervtötenden Piepser eingebaut hatte.
@mutetella:
Danke, ich werde mir die Sache mit aplay in Kürze ansehen. Übrigens Klasse Zitat!