Sprachausgabe

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
toper3902

Hallo zusammen,
ich habe ein programm dass mir eine Zahlenfolge vorließt:

Code: Alles auswählen

import win32com.client as wincl

durchlauf = 0

speak = wincl.Dispatch("SAPI.SpVoice")


piges = "453456 3563"
piok = piges.replace(" ","")
pi = list(piok)

komma = int(input("Auf wieviele Nachkommastellen soll pi ausgegeben werden? (max. 5000) "))

while durchlauf-2 <= komma:
    print(pi[durchlauf])
    if durchlauf == 1:
        speak.Speak("point")
    else:
        speak.Speak(pi[durchlauf])
    durchlauf = durchlauf + 1


Weiß jemand wie man die Sprache umstellen kann?
Benutzeravatar
__blackjack__
User
Beiträge: 14036
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@toper3902: Ein paar Anmerkungen zum Code:

Man sollte ungebräuchliche Abkürzungen vermeiden. Das `win32com.client`-Modul, das nur ein einziges mal gebraucht wird, in `wincl` umzubenennen, macht den Code eher schlechter als besser verständlich.

Variablen sollten möglichst nah an der Stelle definiert werden, an der man sie benötigt. `durchlauf` wird viel zu weit von der Schleife entfernt definiert. Das macht das Programm schwerer lesbar, weil man die Initialisierung beim Lesen entweder im Kopf behalten muss, während man davon unabhängigen Code liest, oder man gelangt bei der Schleife an, und muss erst wieder zurückgehen um die erste Zuweisung zu finden. Es ist auch schwieriger Codeteile in Funktionen auszulagern, wenn der Code für die Funktion nicht zusammen steht, sondern durch anderen Code ”unterbrochen” wird. Und bei grösseren Programmen entstehen auf diese Weise oft Variablen die irgendwo definiert werden, aber nach Codeänderungen dann nicht mehr verwendet werden. Ganz einfach weil man leichter vergisst die Definition auch zu entfernen wenn man den Code weiter unten so ändert, das die Variable nicht mehr verwendet wird.

`speak` wäre ein guter Name für eine Funktion, weil es eine Tätigkeit beschreibt, aber es ist kein guter Name für ein Objekt das einen *Sprecher* oder eine *Stimme* repräsentiert. Ich würde mich da einfach an der Namensgebung der API orientieren und die Python-Namenskonventionen anwenden. Da käme dann `sp_voice` als Name bei heraus.

Bei `piges` gibt es eine kryptische Abkürzung und die beiden Worte sind nicht durch einen Unterstrich getrennt. Das erschwert das Lesen. `pi_gesamt` ist viel leichter zu lesen (falls ich die Abkürzung richtig geraten habe). Ausserdem würde ich behaupten π ist eine Konstante. Wenn die also literal im Quelltext steht, sollte sie auf Modulebene und komplett in Grossbuchstaben definiert werden. Bei `piok` fehlt auch der Unterstrich zwischen den beiden Worten. Wobei man auch nicht jeden Zwischenwert an einen Namen binden muss.

Ich wäre in 100 Jahren nicht darauf gekommen, das der Name `komma` für die Anzahl der Nachkommastellen stehen soll.

Indexzugriffe in Schleifen sind in Python in der Regel ein „code smell“. Man kann direkt über die Elemente von Sequenztypen wie Listen iterieren, ohne einen Umweg über einen Index. Falls man *zusätzlich* noch eine laufende Zahl benötigt, gibt es die `enumerate()`-Funktion. In jedem Fall ist die ``while``-Schleife hier das falsche Mittel, weil man das einfacher mit einer ``for``-Schleife ausdrücken kann.

Den vorliegenden Code kann man deutlich vereinfachen, wenn man nicht anhand der Durchlaufnummer entscheidet das der Dezimalpunkt gesprochen werden soll, sondern gleich eine Datenstruktur erstellt, wo der Dezimalpunkt an passender Stelle enthalten ist.

Ich komme dann ungefähr bei so etwas heraus (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
import win32com.client

PI_GESAMT = '453456 3563'


def main():
    #
    # TODO Ensure user input is a) an integer value and b) in 0…5000.
    # 
    nachkommastellenanzahl = int(
        input(
            'Auf wieviele Nachkommastellen soll π ausgegeben werden?'
            ' (max. 5000) '
        )
    )
    pi_stellen = list(PI_GESAMT.replace(' ', ''))
    pi_stellen.insert(1, 'point')
    sp_voice = win32com.client.Dispatch('SAPI.SpVoice')
    #
    # +2 for the integer place and the decimal point.
    # 
    for stelle in pi_stellen[:nachkommastellenanzahl + 2]:
        sp_voice.Speak(stelle)


if __name__ == '__main__':
    main()
Ich würde noch die Namen in dem Programm auf Englisch übersetzen. Das liest sich besser, weil Programmiersprache, Standardbibliothek, und so ziemlich alle externen Module ebenfalls Englisch verwenden. Ausserdem funktioniert die Mehrzahlbildung von Namen im Englischen deutlich besser als im Deutschen, wo man oft für Einzahl und Mehrzahl ein identisches Wort hat. Das ist wichtig, weil Sequenztypen üblicherweise in der Mehrzahl eines einzelnen Elements benannt werden. Also beispielweise `pi_stellen` für eine Sequenz von einzelnen Stellen von π.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
toper3902

Danke für die Hinweise aber eine Antwort auf meine Frage wäre auch nett gewesen
Benutzeravatar
__blackjack__
User
Beiträge: 14036
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@toper3902: Sorry, ich habe hier kein Windows. Kurzer Blick in die SAPI-Dokumentation lässt vermuten, dass Du die vorhandenen Stimmen auflisten kannst und zum Beispiel nach dem 'Language'-Attribut entscheiden kannst ob die Stimme etwas für Dich ist oder nicht. Es scheint auch Hilfsfunktionen zu geben bei denen man einen Filter angeben kann, wo man auch die Attribute verwenden kann.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Antworten