Variablenname durch Wert ausfindig machen

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.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Frostie hat geschrieben:Vielen Dank an euch! @Alfons Mittelmeyer, der Code funktioniert, vielen vielen Dank! :D
Für die Umwandlung von Zahlen in Worte war mein Code nicht gedacht, denn wie würdest Du damit das machen?

einhundertdreiundzwanzigmilliardenvierhundertsechsundfünfzigmillionensiebenhundertneunundachtzigtausendeinhundertdreiundzwanzig

Damit aber geht es:

Code: Alles auswählen

# -*- coding: utf-8 -*-

EINER = ('null','ein','zwei','drei','vier','fünf','sechs','sieben','acht','neun','zehn','elf','zwölf','dreizehn','vierzehn','fünfzehn','sechzehn','siebzehn','achtzehn','neunzehn')
ZEHNER = ('','zehn','zwanzig','dreißig','vierzig','fünfzig','sechzig','siebzig','achtzig','neunzig')

def convert_small_number_to_word(value):
    wort = ''
    hunderter = value // 100
    if hunderter:
        wort = EINER[hunderter] + 'hundert'
        value %= 100
        if value == 0:
            return wort

    zehner = value // 10
    if zehner < 2:
        if value == 1:
            wort += "eins"
        else:
            wort += EINER[value]
    else:
        einer = value % 10
        if einer != 0:
            wort += EINER[einer]+'und'+ZEHNER[zehner]
        else:
            wort += ZEHNER[zehner]
    return wort


def convert_number_to_word(value):
    if value >= 1000000000000:
        print("Wert zu hoch")
        return False

    begin_value = value
    wort = ''
    if value >= 1000000000:
        milliarden = value // 1000000000
        if milliarden == 1:
            wort = 'einemilliarde'
        else:
            wort = convert_small_number_to_word(milliarden) + 'milliarden'
        value %= 1000000000
            
    if value >= 1000000:
        millionen = value // 1000000
        if millionen == 1:
            wort += 'einemillion'
        else:
            wort += convert_small_number_to_word(millionen) + 'millionen'
        value %= 1000000

    if value >= 1000:
        tausend = value // 1000
        wort += convert_small_number_to_word(tausend) + 'tausend'
        value %= 1000

    if value == 0 and begin_value != 0:
        return wort

    wort += convert_small_number_to_word(value)
    return wort


while True:
    a = input("Zahl: ")
    print(convert_number_to_word(a))
Billionen und Billiarden usw. könnte man noch anfügen
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Frostie hat geschrieben:Vielen Dank an euch! @Alfons Mittelmeyer, der Code funktioniert, vielen vielen Dank! :D
Man kann auch mit dem Hammer Schrauben in Dübel klopfen und behaupten, dass es ja funktioniert.

Anders ausgedrückt: In dem angegebenen Minimalbeispiel funktioniert es, trotzdem ist die Lösung grundsätzlich Mist.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

/me hat geschrieben:
Frostie hat geschrieben:Anders ausgedrückt: In dem angegebenen Minimalbeispiel funktioniert es, trotzdem ist die Lösung grundsätzlich Mist.
Die eine Lösung bezog sich auf "Variablenname durch Wert ausfindig machen". Dafür ist sie kein Mist, sondern genau richtig. Allerdings damit Zahlen in Worte verwandeln wollen, das ist Mist!
BlackJack

@Alfons Mittelmeyer: Eine Lösung für etwas was man nicht machen sollte ist Mist. Das scheint ein Muster bei Dir zu sein…
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

BlackJack hat geschrieben:@Alfons Mittelmeyer: Eine Lösung für etwas was man nicht machen sollte ist Mist.
Wieso sollte man das nicht machen? Für den beabsichtigeten Zweck sollte man das nicht machen, das wäre Mist. Ein sinnvoller Zweck fällt mir allerdings nicht ein. Wenn mir kein sinnvoller Zweck einfällt, heißt das noch nicht, dass es keinen gibt, höchstens dass ich noch keinen gefunden habe und evtl. ein anderer auch noch nicht. Aber vielleicht findet noch jemand einen.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Doch mir fällt etwas ein. Für die Fehlersuche könnte es sinnvol sein. Irgendwo wird ein bestimmer Wert ausgegeben, der nicht ausgegeben werden sollte. Wo kommt der her? Da könnte man so evtl. nach der Variablen suchen.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

@Frostie: ich habe dir ja ein Codebeispiel geschrieben, mit dem Du Zahlen in Text konvertieren kannst. Reicht das? Oder brauchst Du mehr?

Weil das hatte ich noch nicht implementiert:

billionen,billiarden
trillionen,trilliarden
quadrillionen,quadrilliarden
quintillionen,quintilliarden
sextillionen,sextilliarden
septillionen,septilliarden
oktillionen,oktilliarden
nonillionen,nonilliarden
dezillionen, dezilliarden

Und da könnte man weitermachen. Eine Zahl mit einer eins und 6 Millionen Nullen heißt etwa Millinillinillion.

Aber so weit gehen die Integerzahlen in Python eh nicht. Wenn man aber diese als String übergeben würde, könnte man es machen. Allerdings wären so große Zahlen schwer lesbar.
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@Alfons Mittelmeyer: wie kommst Du darauf, dass Integerzahlen nicht so weit gehen? Da gibt es keine feste Grenze:

Code: Alles auswählen

>>> print(convert_number_to_word(562308745608237652983566947306894705053490573495895734598553453363634245356786))
fünfhundertzweiundsechzigduodezillardendreihundertachtduodezillionensiebenhundertfünfundvierzigundezillardensechshundertachtundezillionenzweihundertsiebenunddreißigdezillardensechshundertzweiundfünfzigdezillionenneunhundertdreiundachtzignonillardenfünfhundertsechsundsechzignonillionenneunhundertsiebenundvierzigoktillardendreihundertsechsoktillionenachthundertvierundneunzigseptillardensiebenhundertfünfseptillionendreiundfünfzigsextillardenvierhundertneunzigsextillionenfünfhundertdreiundsiebzigquintillardenvierhundertfünfundneunzigquintillionenachthundertfünfundneunzigquadrillardensiebenhundertvierunddreißigquadrillionenfünfhundertachtundneunzigtrillardenfünfhundertdreiundfünfzigtrillionenvierhundertdreiundfünfzigbillardendreihundertdreiundsechzigbillionensechshundertvierunddreißigmillardenzweihundertfünfundvierzigmillionendreihundertsechsundfünfzigtausendsiebenhundertsechsundachtzig
Mit Deinem Copy-Paste-Code wird man da aber nicht weit kommen.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Sirius3 hat geschrieben:@Alfons Mittelmeyer: wie kommst Du darauf, dass Integerzahlen nicht so weit gehen? Da gibt es keine feste Grenze
Wie ich darauf kam, weil ich an andere Programmiersprachen dachte, die sich an der Bitbreite des Maschinenwortes orientieren, also so etwas wie 64 oder bei Long Interer vielleicht auch 128 Bits. Aber stimmt, für Python gibt es da keine Beschränkung.

Ach so. hast das Programm noch bis zur Dezilliarde aufgerüstet. Nicht schlecht, aber soweit braucht es apple wohl nicht.

@Frostie: Wenn man zum Programmieren anfängt und etwa an Zahlen von null bis sieben denkt, sollte man nicht an Finden von Variablennamen denken.

Normalerweise sollte man dann an so etwas, wie Lösung 1 denken und dann schauen, ob es auch so etwas wie Lösung 2 gibt:

Code: Alles auswählen

# -*- coding: utf-8 -*-

def number_to_string1(number):

    if number == 0:
        return 'null'

    if number == 1:
        return 'eins'

    if number == 2:
        return 'zwei'

    if number == 3:
        return 'drei'

    if number == 4:
        return 'vier'

    if number == 5:
        return 'fünf'

    if number == 6:
        return 'sechs'

    if number == 7:
        return 'sieben'


def number_to_string2(number):
    return ('null','eins','zwei','drei','vier','fünf','sechs','sieben')[number]


print('Lösung 1')
for i in range(8):
    print(number_to_string1(i))

print('\n\n\nLösung 2')
for i in range(8):
    print(number_to_string2(i))
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

so ist es eleganter, robuster und vor allem besser erweiterbar:
[codebox=pycon file=Unbenannt.txt]>>> NUMBER_TO_WORD = {
... 1: 'eins',
... 2: 'zwei',
... 3: 'drei',
... 4: 'vier',
... 5: 'fünf'}
>>> WORD_TO_NUMBER = {}
>>> for k, v in NUMBER_TO_WORD.items():
... WORD_TO_NUMBER[v] = k
...
>>> def get_word(number):
... return NUMBER_TO_WORD.get(number, 'no matching word found')
...
>>> def get_number(word):
... return WORD_TO_NUMBER.get(word, 'no matching number found')
...
>>> get_word(1)
'eins'
>>> get_word(6)
'no matching word found'
>>> get_number('drei')
3
>>> get_number('sieben')
'no matching number found'
>>>[/code]

Das ganze macht natürlich nur Sinn, wenn die Menge der Schlüssel-Werte Paare endlich und überschaubar ist. Ein gutes Beispiel wäre z.B. ein De-/Encoder für Morse-Code.

Gruß, noisefloor
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@noisefloor: ein String als Fehlerkennzeichnung ist weit entfernt von gut. Da wäre des defaultmäßige None schon besser, der KeyError der beim Indexzugriff geworfen wird am besten.
Antworten