Forum: PC-Programmierung Zahl für Sprachausgabe als String umwandeln


von H. C. (sunshine)


Lesenswert?

Ich benötige eine C-Funktion, der ich einen Double Wert übergebe und die 
mir als String die Zahl zurückgibt, wie sie gelesen werden sollte z.B. 
bei 125 Rückgabewert "Einhundertfünfundzwanzig".
Ich habe gesucht, ob ich was entsprechendes finde, aber die Funktion 
DoubleToStr wandelt sie ja nicht wörtlich in einen String um.

von Εrnst B. (ernst)


Lesenswert?

Sorry.
1
curl -s 'https://math.tools/calculator/numbers/words/de' -X POST --data 'number=1125' | grep 'Result'

curl für c: https://curl.se/libcurl/c/

von H. C. (sunshine)


Lesenswert?

Danke für den Hinweis! Aber ich bräuchte den Code für die Funktion. Hier 
hab ich sie für englische Sprachausgabe gefunden, nur bräuchte ich sie 
für eine deutsche Ausgabe.
https://www.geeksforgeeks.org/convert-number-to-words/

Ich glaub, ich passe mir diese an, dachte nur sowas gibt es 
wahrscheinlich schon mehrfach frei im Netz verfügbar.

von Joachim S. (oyo)


Lesenswert?

H. C. schrieb:
> Danke für den Hinweis! Aber ich bräuchte den Code für die Funktion. Hier
> hab ich sie für englische Sprachausgabe gefunden, nur bräuchte ich sie
> für eine deutsche Ausgabe.
> https://www.geeksforgeeks.org/convert-number-to-words/
>
> Ich glaub, ich passe mir diese an, dachte nur sowas gibt es
> wahrscheinlich schon mehrfach frei im Netz verfügbar.

Für C kenne ich nichts, aber für Python gibt es diese Library hier, die 
viele Sprachen unterstützt:
https://github.com/savoirfairelinux/num2words

Hier ein Link zum Code für Deutsch:
https://github.com/savoirfairelinux/num2words/blob/master/num2words/lang_DE.py

Keine Ahnung, wie leicht sich das nach C portieren lässt, aber 
vielleicht hilft es Dir ja.

von Programmierer (Gast)


Lesenswert?

H. C. schrieb:
> Danke für den Hinweis! Aber ich bräuchte den Code für die Funktion.

In der Zeit, wo Du verzweifelst suchst, hättest Du das mit etwas 
Nachdenken auch selbst geschrieben.

Schließlich ist es doch Sinn einer Hausaufgabe, etwas selbst zu 
erarbeiten damit Du was lernst. Später wirst Du auch nicht einfach alles 
googeln können, vor allem in der Prüfung.

von Jemand (Gast)


Lesenswert?

Programmierer schrieb:
> vor allem in der Prüfung

Eigentlich nur in der Prüfung

Beitrag #7140367 wurde von einem Moderator gelöscht.
von von idioten für idioten (Gast)


Lesenswert?

H. C. schrieb:
> Double

Also mit Nachkommastellen?  Wohl kaum.

Beitrag #7140384 wurde von einem Moderator gelöscht.
Beitrag #7140388 wurde von einem Moderator gelöscht.
von mm (Gast)


Lesenswert?

So eine Funktion lässt sich doch in ein/zwei Stunden selbst umsetzen. 
Zahlen unterliegen ja recht eindeutigen Regeln.

H. C. schrieb:
> Zahl für Sprachausgabe

Wie machst Du denn die Sprachausgabe?
Ich würde eigentlich erwarten, dass ein entspechendes Tool/Bibliothek 
mit Zahlen umgehen können sollte.

Beitrag #7140398 wurde von einem Moderator gelöscht.
von W.S. (Gast)


Lesenswert?

Jemand schrieb:
> Programmierer schrieb:
>> vor allem in der Prüfung
>
> Eigentlich nur in der Prüfung

Hä?
Eigentlich macht mich das so zornig, daß ich hier weitaus gröbere 
Ausdrücke schreiben würde um dem Sachverhalt zu entsprechen.

Nein, man studiert/lernt eben NICHT, um eine Prüfung zu überstehen und 
zum Schluß irgend ein Papier mit einem Stempel drauf zu kriegen. Sondern 
man studiert/lernt zu dem Zweck, daß man später im eigenen Berufsleben 
selbst etwas kann. Selbständig denken und praktikable Lösungen für 
Probleme finden zum Beispiel. Oder zuverlässig löten oder Blinddärme 
operieren.

Und hier geht es um eine zumeist zweistufige Konvertierung: nämlich 
erstens zu der Konvertierung Zahl-->Ziffern/Buchstaben-Folge und 
zweitens um die Konvertierung dieser Ziffern bzw. Buchstabenfolge in 
Phoneme mit der Randschwierigkeit, daß wir manches umdrehen: wie sagen 
ja nicht zwanzig_drei sondern drei_und_zwanzig. Sowas geht elektronisch 
zu machen, die Navi-Programme machen es einem ja vor. Aber die 
entsprechenden Audio-Ausgabeprogramme nebst Daten dafür sind nicht grad 
klein, da reden wir über Zeugs von etwa 20 MB oder mehr - und da sind 
die auszugebenden Texte noch nicht mit dabei.

W.S.

von H. C. (sunshine)


Lesenswert?

Also wenn's beruhigt. Es ist keine Hausaufgabe oder Vorbereitung für 
eine Prüfung. Ich wollte die Sprachausgabe einfach nur für ein privates 
Projekt und falls es wenn interessiert, so habe ich diesen Quellcode 
hier entsprechend für C angepasst: 
https://wiki.freitagsrunde.org/C-Kurs/Zahlen_sagen/Musterl%C3%B6sung
Funktioniert einwandfrei!

von Heinz B. (Firma: Privat) (hbrill)


Angehängte Dateien:

Lesenswert?

Ich hab da noch eine DLL (in ASM - 32Bit) von Frank Abbing.
Die bereitet die SAPI 5 Schnittstelle entsprechend vor.
Die Speech.dll hat nur 4 Funktionen und ist mit beiliegender
Anleitung auch leicht zu nutzen.
Da braucht es auch kein Zahlenumwandeln in Worten. Ein einfaches
Str$(zahl) reicht da. Entsprechendes (Str$) gibt es ja auch in C.
Vielleicht hilft dir das ja auch schon.

: Bearbeitet durch User
von Ein T. (ein_typ)


Lesenswert?

von idioten für idioten schrieb im Beitrag #7140367:
> Es ist echt lächerlich welche Python-"Libs" für diese Sprache angeboten
> werden.

Trotzdem ist diese herausragende Infrastruktur einer der Gründe, warum 
Python mittlerweile eine der beliebtesten und verbreitetsten Sprachen 
geworden ist.

> Einfach nur absolut sinnlose und schwachsinnige Funktionen.

Ach, weißt Du, was dem Einen seine Eule, ist dem Anderen seine 
Nachtigall.

> Jeden zweiten Buchstaben in einem String groß darstellen?

Piece of cake:
1
''.join([s[i].upper() if i %2 else s[i] for i in range(len(s))])

> Jedes zweite Wort in einem Satz umdrehen?

Das hängt nicht ganz unwesentlich davon ab, was Du als "Wort" 
definierst, ob Du die Punctuation miteinbeziehen oder entfernen willst, 
und so weiter. Möglichkeiten zur Tokenisierung findest Du in den 
etablierten Paketen zum Natural Language Processing, die bekanntesten 
für Python dürften wohl das Natural Language Toolkit (NLTK) [1] und 
Spacy [2] sein.

Die einfache Lösung (für einfache Gemüter mit str.split()):
1
' '.join([
2
    word if i % 2 else ''.join(list(reversed(word))) 
3
    for i, word in enumerate(sentence.split())])

[1] https://www.nltk.org/
[2] https://spacy.io/

> Wer kommt überhaupt auf die Idee solche Libs(!) zu erstellen?
> "Von Idioten - für Idioten", so sehe ich das.

Ich ganz persönlich halte ja solche Leute für Idioten, die nicht über 
den eigenen Tellerrand hinausschauen können. Aber das kann ja jeder für 
sich definieren.

Beitrag #7140827 wurde von einem Moderator gelöscht.
von Michael S. (Gast)


Lesenswert?

Hallo,

für Zeitansagen und die Ausgabe von Texten incl. Messwerten auf einen 
DFPlayerMini habe ich kürzlich eine ähnliche Sache gebastelt.

Anstelle von Textbausteinen werden entsprechende mp3-Dateien abgespielt.
Die kann man sich z.B. auf ttsmp3.com erstellen.
Da sind fast 200 mp3-Dateien zusammengekommen.
War etwas mühsam, funktioniert aber ganz gut.

Die Pausen zwischen den einzelnen Dateien sind etwas länger als bei 
einem menschlichen Sprecher.
Klingt ähnlich wie die Mailbox-Ansage bei Aldx-Talx.
Läuft auf einem Pi Pico unter Micropython.

Michael S.

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Der Aufwand zur korrekten Formulierung von deutschen Zahlworten ist 
nicht unerheblich. Man bedenke nur mal über die Unterschiede in der 
Aussprache von z.B.

elf, zwölf
drei-zehn
vier-zehn
...
zwan-zig (und nicht zwei-zig)
sieb-zehn (und nicht sieben-zehn)
sechs-zig (aber nicht sieben-zig)
elf (und nicht ein-zehn)
zwölf (und nicht zwei-zehn) ... usw.

Dazu kommt noch die Vertauschung von Einer und Zehner (deutsch: 
ein-und-zwan-zig, englisch: twenty-one). Ja, Sprache ist halt keine 
Mathematik.

Klar kann man das mit ausreichend Geduld alle Ausnahmen ausprogrammieren 
oder man hat Glück und findet eine passende Lib. Da aber Deutsch nicht 
gerade zu den bevorzugten Sprachen in Progger-Kreisen zählt, wird das 
wohl schwierig.

Ich habe das mal für ein Messgerät gemacht und bin dann kurzerhand auf 
die Idee gekommen, einfach nur die Ziffern und die Maßeinheit einzeln 
anzusagen, da gibt es quasi keine Ausnahme-Regeln. Ich finde im 
Verhältnis zum Aufwand, ein guter Kompromiss, z.B.:

drei-fünf-vier-komma-eins-acht-volt

: Bearbeitet durch User
von Jemand (Gast)


Lesenswert?

Ein T. schrieb:
> Piece of cake:

Und jetzt noch mal in korrekt für die Unicode sprechende Welt

von Ein T. (ein_typ)


Lesenswert?

Jemand schrieb:
> Ein T. schrieb:
>> Piece of cake:
>
> Und jetzt noch mal in korrekt für die Unicode sprechende Welt

Steht doch schon da. Guckstu 
Beitrag "Re: Zahl für Sprachausgabe als String umwandeln"

Beitrag #7141670 wurde von einem Moderator gelöscht.
von Oliver S. (oliverso)


Lesenswert?

Das konnte die Bundespost doch schon immer, sogar in Echtzeit. Und das 
schon, als es noch gar keine Computer gab ;)

"Beim nächsten Ton ist es 17 Uhr, .... - PIEP"

Oliver

von Schlaumaier (Gast)


Lesenswert?

25 Zeilen in Basic als Funktion und das wars.

So was mache ich im Schlaf mit geschlossenen Augen und einer süssen Lady 
im anderen Arm.

Aber ihr braucht ne Libs.  Au au au.

Jetzt weiß ich was die studierten Programmierer von modernen Sprachen am 
meisten machen. Libs suchen weil sie zu dumm sind das selbst zu machen.

Zugeben. Für die Phonetischen (Akustischen) Umsetzung des Textes und 
senden an die Audio-Ausgabe würde ich auch ne Lib nehmen. ;)

von Andreas B. (bitverdreher)


Lesenswert?

Oliver S. schrieb:
> Das konnte die Bundespost doch schon immer, sogar in Echtzeit. Und das
> schon, als es noch gar keine Computer gab ;)

Aber alles andere als trivial:
https://www.youtube.com/watch?v=zMwYxrmR--s

Schlaumaier schrieb:
> So was mache ich im Schlaf mit geschlossenen Augen und einer süssen Lady
> im anderen Arm.
Laß die Augen lieber zu. Sonst siehst Du noch den Dackel in Deinem Arm.

von Schlaumaier (Gast)


Lesenswert?

Andreas B. schrieb:
> Laß die Augen lieber zu. Sonst siehst Du noch den Dackel in Deinem Arm.

Kater nix Hund.

Und du hast recht. Der liegt fast jede Nacht bei mir im Bett.

von Εrnst B. (ernst)


Lesenswert?

Schlaumaier schrieb:
> Kater nix Hund.

Schlaumaier schrieb:
> süssen Lady im anderen Arm

und der Kater heißt "Lady"?

Aber sonst zeig doch mal eine 25 Zeilen Basic.
Wenn's im Schlaf schon so schnell geht, sollte es im Wachzustand ja kaum 
mehr als 10 Sekunden benötigen das runterzutippen.

Aber vermutlich ist's nur wieder eine der "typisch Schlaumeier" 
Angeber-Geschichten. Wissen wir genau, wenn von dir kein Quelltext 
kommmt.

von Christian M. (christian_m280)


Lesenswert?

Εrnst B. schrieb:
> Aber sonst zeig doch mal eine 25 Zeilen Basic

In Basic gibt's noch :

;-)

Gruss Chregu

von Schlaumaier (Gast)


Lesenswert?

Zahl in String umwandeln.
Dann in einer Schleife mit Mid-Funktion je nach Zahl den passenden Text 
zu einen Text dazu schreiben.

bei 9120 wären dann dann

function zahl_in_text (zahl)
txx$ = str(zahl)
all_text$ = ""
for i = 1 to len(txx$)
  tx$ = mid(txx$,i,1)
  if Tx$ = "9" then all_text$ = "neun"
  if Tx$ = "8" then all_text$ = "acht"
  if stelle = 4 then all_text$ = all_text + "tausend"
  if stelle = 3 then all_text$ = all_text + "hundert"
  if stelle = 2 then all_text$ = all_text + "zig"
next i

zahl_in_text = all_text$
end function

Dann noch die feinheiten bei 11 und 12 abgleichen und das wars. Dafür 
den Rest an Code-Zeilen.

Wie gesagt geschätzt 25 Zeilen Code. bei > 1 Millarde wird ein paar 
Zeilen mehr.

Aber irgendwo muss ja schluss sein.

von Εrnst B. (ernst)


Lesenswert?

Schlaumaier schrieb:
> Dann noch die feinheiten

Na dann, testen wir deinen Code.
Extra mit "implementierten" Zahlen: 8,9,89,98,888, damit die fehlenden 
"feinheiten" keine Rolle spielen.

(unter der Annahme dass du mit "stelle" deine Laufvariable "i" gemeint 
hast)
1
8 acht
2
9 neun
3
89 neunzig
4
98 achtzig
5
888 achthundert

Ups. Etwas an der Ideallinie vorbei.
Da muss dein Kater "Lady" nochmal auf die Tasten hüpfen.

Edit/Nachtrag:
Selbst wenn ich die offensichtlichen Dinge bereinige (variable "stelle" 
korrekt berechnen, Bei 8 und 9 String anhängen) kommt nicht viel 
besseres dabei raus:
1
8 acht
2
9 neun
3
89 achtzigneun
4
98 neunzigacht
5
888 achthundertachtzigacht

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Wenn man nach dem selben Schema noch die 7 dazu nimmt, wird aus 77 
"siebenzigsieben".
Es ist kein Hexenwerk, sowas selbst zu implementieren, aber ein paar 
mehr Sonderfälle als nur die 11 und 12 sind es dann doch.

von Schlaumaier (Gast)


Lesenswert?

Rolf M. schrieb:
> Es ist kein Hexenwerk, sowas selbst zu implementieren, aber ein paar
> mehr Sonderfälle als nur die 11 und 12 sind es dann doch.

Jo ;) Stimmt.

Aber ;)

Ich wollte absichtlich kein sauberen Text produzieren. Ich gebe Hinweise 
wie man es macht aber ich gebe kein Kiddys ein fertigen Code an die 
Hand.
Abschreiben im 21 Jahrhundert nicht mehr von Nachbarn sondern vom netten 
Typen aus den Internet ;) NE. Nicht mit mir. ;)

Εrnst B. schrieb:
> (unter der Annahme dass du mit "stelle" deine Laufvariable "i" gemeint
> hast)

Genau Stelle = i

I gibt die Stelle an, an der ich das Zeichen aus der Zeichenkette lese.

txx$ = "98567"

wenn i = 3 ist, dann ist tx$ 5 weil die 5 die 3 Stelle in der 
Zeichenkette ist.

Ich lese als du Zeichenkette Zeichen für Zeichen (erledigt die 
MID-Funktion) und ist die STELLE die 3 dann mit ich im Hunderter-Bereich 
der ZAHL.

Die Feinheiten der Zahlen-Sprache muss man noch berücksichtigen. Aber 
ich habe ja nur 11 Zeilen Code und else schreibe ich bei sowas sehr oft 
in die selbe Zeile wenn es nur eine Ausführung gibt.

Die Darstellung des Codes ist übrigens auf den Tablett Schrott. K.a. 
warum.)

von Εrnst B. (ernst)


Lesenswert?

Schlaumaier schrieb:
> Ich wollte absichtlich kein sauberen Text produzieren.

iaw: Du kannst es nicht.

Schlaumaier schrieb:
> Genau Stelle = i

Nö, sonst hängt er an die Einerstelle immer ein "zig" an, sh.
89 -> "neunzig"

So wie deine Schleife läuft macht: " Stelle = StringLänge - i "
mehr Sinn. So hab ich das im Zweiten Testlauf gesetzt, macht:

89 -> "achtzigneun"

was zumindest mit gutem Willen wieder in die Ausgangszahl 
zurückübersetzt werden kann.

Schlaumaier schrieb:
> gebe kein Kiddys ein fertigen Code an die
> Hand.

Weil du es nicht kannst. Du kommst ja schon mit der einfachen 
For-Schleife + ein paar "IFs" an deine Grenzen. Sowas haben Früher™ die 
Viertklass-Kiddies schon besser gebastelt gekriegt.

von Jemand (Gast)


Lesenswert?

Ein T. schrieb:
> Steht doch schon da. Guckstu
1
>>> s = "Fräs­maschine"
2
>>> print(''.join([s[i].upper() if i %2 else s[i] for i in range(len(s))]))
3
FRäs­mAsChIn

Erbärmlich.

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Jemand schrieb:
> 1>>> s = "Fräs­maschine"
> 2>>> print(''.join([s[i].upper() if i %2 else s[i] for i in
> range(len(s))]))
> 3FRäs­mAsChIn
>
> Erbärmlich.

Antike Python-Version oder falsch konfigurierte locale? String-Literale 
sind in 3.x vom Typ „unicode“, Iteration passiert zeichenweise und 
Transformationen wie upper() beherrschen Unicode.

pp schrieb im Beitrag #7140827:
> Niemand zwingt dich, solche Libs zu verwenden. Andere sind dankbar
> dafür. Nicht jeder ist "hardcore"- Programmierer - möchte aber schon was
> erstellen - wo ist das Problem?

Oder sie leben in einer Welt in der man mehr als eine einzige Sprache 
unterstützen muss.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Andreas S. schrieb:
> Antike Python-Version oder falsch konfigurierte locale?

Zwei Spezialzeichen (ein "Combining Diaeresis" zur Bildung des 'ä' und
ein "Soft Hyphen" nach 'Fräs') führen dazu, dass das erste 's' nicht
umgewandelt wird, der Rest aber wieder stimmt.

von LostInMusic (Gast)


Lesenswert?

Für einen Code, der...
(1) im Prinzip funktioniert: 5 Minuten
(2) schon ziemlich gut funktioniert: 30 Minuten
(3) bis auf "ein paar Kleinigkeiten" korrekt funktioniert: 3 Stunden
(4) korrekt funktioniert: 2 Tage

Ja, ich halte diese Zeiten für realistisch. Der Schwierigkeitslevel 
dieser Aufgabe wird von Amateuren gerne unterschätzt. Dafür eine gute 
Lösung im Sinne von (4) zu coden und ihre Korrektheit durch Modultesting 
zu beweisen, ist eine anspruchsvolle Angelegenheit, bei der man eine 
Menge lernen kann.

von Rolf M. (rmagnus)


Lesenswert?

LostInMusic schrieb:
> und ihre Korrektheit durch Modultesting zu beweisen

Korrektheit kann man durch Tests nicht beweisen. Ansonsten kommt das in 
etwa hin.

von LostInMusic (Gast)


Lesenswert?

>Korrektheit kann man durch Tests nicht beweisen.

Nach der reinen Lehre und in voller Allgemeinheit: Ja! Richtig ist aber 
auch, dass für "genügend gutartige" Probleme mit Modultesting etwas 
erreicht werden kann, was man als "Nachweis von Korrektheit" gelten 
lassen darf. Dieser Kategorie ordne ich die hiesige Aufgabe zu. Die für 
Zahlen-Dreiergruppen zuständige Unterfunktion könnte man sogar (gerade 
noch) vollständig testen; sie muss ja nur 1000 Inputs richtig handeln.

von tom (Gast)


Lesenswert?

Hallo,

im Buch "Taschenbuch der Algorithmen ", ISBN 978-3-540-76393-2 gibt es 
eine schöne Lösung mit Herleitung und Pseudocode. Preview hier: 
https://link.springer.com/chapter/10.1007/978-3-540-76394-9_23

Schöne Grüße
tomas

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.