MacOS spricht mit mir ... aber nicht wie es soll

Code-Stücke können hier veröffentlicht werden.
Antworten
Nobody0815
User
Beiträge: 16
Registriert: Dienstag 23. Februar 2021, 21:25

Hallo,
ich habe ein kleines Programm für MacOS geschrieben, was mir die Ausgaben auf dem Terminal vorlesen soll. Leider liest es nicht die Ausgabe vor, sondern den entsprechenden Fehlercode. Nachfolgend mein Code, mit der Bitte um Hinweise:

Code: Alles auswählen

# auf Systembefehle zugreifen
import os 


# Funktioniert nur unter MacOS
def who_ami(input_):
    print(f'Befehl lautet: {input_}')
    output_ = os.system(input_)
    print(output_)
    output2say = f'say {output_}'
    os.system(output2say)

# Terminalbefehl
who_ami("whoami") 
Ausgabe im Terminal:
Befehl lautet: whoami
nobody0815
0


Tonausgabe des Mac:
Null --> Ich hätte gerne, dass "nobody0815" vom Mac ausgegeben wird.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dann solltest du die Riesen dicke fette Warnung die an os.system sei Jahrzehnten dransteht ernst nehmen, und es nicht mehr verwenden. Sondern subprocess.run, bei dem du auch angeben kannst, die Ausgabe des Programms statt nur seinen returncode zu erhalten.
Nobody0815
User
Beiträge: 16
Registriert: Dienstag 23. Februar 2021, 21:25

__deets__ hat geschrieben: Mittwoch 10. März 2021, 11:34 Dann solltest du die Riesen dicke fette Warnung die an os.system sei Jahrzehnten dransteht ernst nehmen, und es nicht mehr verwenden. Sondern subprocess.run, bei dem du auch angeben kannst, die Ausgabe des Programms statt nur seinen returncode zu erhalten.
"Riesen dicke fette Warnung" hiermit ernst genommen. :wink:
Habe es jetzt mit subprocess gelöst. Hinweise willkommen:

Code: Alles auswählen

import subprocess 

def whoami_(input_):
    print(f'Befehl lautet: {input_}')
    output_ = subprocess.Popen([input_], stdout=subprocess.PIPE)
    stdout, sterr = output_.communicate()
    print(stdout.decode('utf-8'))
    subprocess.Popen(['say', stdout])
 
whoami_("whoami") 
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wie gesagt, ich würde run nehmen. Das macht das etwas kompakter. Aber so geht es auch.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wobei das `Popen` welches am Ende steht und nicht ordentlich abgeräumt wird, sehr unschön ist. Mindestens da müsste man `run()` verwenden.

Ich bin auch ein bisschen bezüglich der Unterstrich-Suffixe verwirrt. Der einzige Name wo das Sinn macht ist `input_` – der sollte aber sowieso anders heissen, denn das ist ja gar keine Eingabe sondern ein Programm- oder Kommandoname. Und auch `whoami()` ist kein guter Name weil der ja nur stimmt wenn man "whoami" als Argument übergibt. Wenn man beispielsweise "ddate" übergibt, ist der Funktionsname sehr verwirrend.

Die Kodierung kann man gleich beim `Popen`/`run()` angeben, das muss man nicht manuell dekodieren.

Code: Alles auswählen

#!/usr/bin/env python3
import subprocess

SAY_COMMAND = "say"
# SAY_COMMAND = "espeak"


def say_command_ouput(command, encoding="utf-8"):
    print(f"Befehl lautet: {command!a}")
    completed_process = subprocess.run(
        [command], stdout=subprocess.PIPE, encoding=encoding, check=True
    )
    print(completed_process.stdout)
    subprocess.run(
        [SAY_COMMAND, completed_process.stdout], encoding=encoding, check=True
    )


def main():
    say_command_ouput("whoami")
    # say_command_ouput("ddate")


if __name__ == "__main__":
    main()
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Nobody0815
User
Beiträge: 16
Registriert: Dienstag 23. Februar 2021, 21:25

__deets__ hat geschrieben: Mittwoch 10. März 2021, 13:40 Wie gesagt, ich würde run nehmen. Das macht das etwas kompakter. Aber so geht es auch.
Danke, ich schaue mir das noch mal genauer an.
Nobody0815
User
Beiträge: 16
Registriert: Dienstag 23. Februar 2021, 21:25

__blackjack__ hat geschrieben: Mittwoch 10. März 2021, 14:01 Wobei das `Popen` welches am Ende steht und nicht ordentlich abgeräumt wird, sehr unschön ist. Mindestens da müsste man `run()` verwenden.
Was meinst Du denn mit "nicht ordentlich abgeräumt"? Ich habe "subprocess" heute zum ersten Mal genutzt und kenne mich noch nicht richtig aus.
__blackjack__ hat geschrieben: Mittwoch 10. März 2021, 14:01 Ich bin auch ein bisschen bezüglich der Unterstrich-Suffixe verwirrt. Der einzige Name wo das Sinn macht ist `input_` – der sollte aber sowieso anders heissen, denn das ist ja gar keine Eingabe sondern ein Programm- oder Kommandoname. Und auch `whoami()` ist kein guter Name weil der ja nur stimmt wenn man "whoami" als Argument übergibt. Wenn man beispielsweise "ddate" übergibt, ist der Funktionsname sehr verwirrend.
Sorry, für die "wirren" Bezeichner. Ich bin noch Anfänger und hab nicht weiter drüber nachgedacht. :?
Ich habe die Unterstriche genutzt, um auszuschließen das es sich um bereits durch Python belegte Schlüsselwörter handelt. Gibt es da eine Konvention zu den Unterstrichen die ich beachten sollte?

__blackjack__ hat geschrieben: Mittwoch 10. März 2021, 14:01 Die Kodierung kann man gleich beim `Popen`/`run()` angeben, das muss man nicht manuell dekodieren.

Code: Alles auswählen

#!/usr/bin/env python3
import subprocess

SAY_COMMAND = "say"
# SAY_COMMAND = "espeak"


def say_command_ouput(command, encoding="utf-8"):
    print(f"Befehl lautet: {command!a}")
    completed_process = subprocess.run(
        [command], stdout=subprocess.PIPE, encoding=encoding, check=True
    )
    print(completed_process.stdout)
    subprocess.run(
        [SAY_COMMAND, completed_process.stdout], encoding=encoding, check=True
    )


def main():
    say_command_ouput("whoami")
    # say_command_ouput("ddate")


if __name__ == "__main__":
    main()
Danke für den Code! Ich kann den gut nachvollziehen, habe aber noch Anfängerfragen:

1. Wozu die "main()" Funktion anlegen? Ich kann doch den Code auch außerhalb der Funktion schreiben?
2. Was macht das: "if __name__ == "__main__"
Benutzeravatar
Dennis89
User
Beiträge: 1123
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

zu1.:
@__blackjack__ (und andere auch) erklärt das hier im Forum immer wieder. Dabei handelt es sich um Konventionen die festgelegt wurden. Zum Beispiel im folgenden Link wurde ein Programm von ihm unter anderen an Hand der Konventionen (siehe https://www.python.org/dev/peps/pep-0008/) begutachtet und verbessert:
viewtopic.php?f=1&t=51493

zu 2.:
Finde ich folgende Erklärung im Link gut verständlich:
https://www.freecodecamp.org/news/if-na ... n-example/

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Nobody0815
User
Beiträge: 16
Registriert: Dienstag 23. Februar 2021, 21:25

Dennis89 hat geschrieben: Mittwoch 10. März 2021, 21:42 Hallo,

zu1.:
@__blackjack__ (und andere auch) erklärt das hier im Forum immer wieder. Dabei handelt es sich um Konventionen die festgelegt wurden. Zum Beispiel im folgenden Link wurde ein Programm von ihm unter anderen an Hand der Konventionen (siehe https://www.python.org/dev/peps/pep-0008/) begutachtet und verbessert:
viewtopic.php?f=1&t=51493

zu 2.:
Finde ich folgende Erklärung im Link gut verständlich:
https://www.freecodecamp.org/news/if-na ... n-example/

Grüße
Dennis
Danke für die Links, hat mir weitergeholfen.
Antworten