Einwortzahlen (Plus/Minus)

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
SoSal
User
Beiträge: 4
Registriert: Mittwoch 15. Mai 2019, 12:54

Hallo, ich wollte fragen ob mir jemand bei folgender Aufgabenstellung bitte weiterhelfen kann:

Die Zahlen 1, 2, 3, ... können als ein Wort geschrieben werden, also eins, zwei, drei, ... und werden als "Einwortzahlen" bezeichnet (dieses Wort ist frei erfunden).
Nicht-Einwortzahlen sind Zahlen, die nur Wortbestandteile haben, die eine Einwortzahl sind oder das Wort "und" enthalten, z.B. 13 = dreizehn = "drei" + "zehn" oder 21 = einundzwanzig = "ein" + "und" + "zwanzig".
Erstellen Sie folgende Funktionen:
"def codieren" übernimmt als Parameter eine (1) Einwortzahl (=String) und liefert als Ergbnis die Zahl als Integerwert zurück.
"def decodieren" übernimmt als Parameter eine (1) Integerzahl und liefert als Ergbnis die Zahl als Einwortzahl (=String) zurück.
"def PlusMinus" übernimmer als Parameter einen (1) String und liefter als Ergbnis einen String mit einem Einwortzahl zurück. Folgendes gilt es zu berücksichtigen:
Der Eingabestring besteht aus mindestens einem Einwortzahl.
Wenn der Eingabestring aus mehr als einem Einwortzahl besteht, sind diese durch die Wörter "plus" oder "minus" getrennt. Diese repräsentieren Addition und Subtraktion.
Der Ausgabestring besteht aus exakt einer Einwortzahl, welche den Eingabestring oder das Ergbnis der Berechnung des Eingabestrings widerspiegelt.
Es müssen nur Berechnungen berücksichtig werden, welche ausschließlich aus Einwortzahlen in der Eingabe und Ausgabe bestehen.
Umlaute müssen in Ein- und Ausgabe vermieden werden, also immer fuenf, etc. schreiben und erwarten.
Verwenden Sie die beiden Eingangs definierten Funktionen in dieser Funktion, damit der Code übersichtlich bleibt.
Mit "run tests" (auf das Pfeil runter neben "run" klicken) wird die Funktion PlusMinus getestet. Verbessern Sie die Funktion jedesmal, wenn sie eine Fehlermeldung bekommen, die anzeigt, dass ein Testfall gefunden wurde, den Ihre Funktion noch nicht berücksichtig.
Bei jeder Fehlermeldung kann bei "Show details", dann auf den "PlusMinus", dann auf "More Info" geklickt werden. In der Fehlermeldung steht z.B. #7 - das heisst, dass bereits 6 Testfälle korrekt sind und beim 7. eine Fehlermeldung erzeugt wurde.

Vielen Dank für euere Hilfe!
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wir lösen hier keine Hausaufgaben auf Bestellung. Zeug uns was du versucht hast. Wo konkret hast du Probleme mit dem Verständnis? Gibt es Fehlermeldungen, wenn ja, wie genau sehen die aus? Beim Posten von code & trackbacks Code Tags benutzen. Sonst ist der Code unlesbar.
SoSal
User
Beiträge: 4
Registriert: Mittwoch 15. Mai 2019, 12:54

Mein Anfang:
def codieren(zahl):
listezahl = [1,2,3,4,5,6,7,8,9,10]
listebuch = ["eins","zwei", "drei", "vier", "fünf", "sechs", "sieben", "acht", "neun", "zehn"]

if zahl in listezahl:
pos = listzahl.index(zahl)
print(listebuch[pos])

Und bei "run test" kommt folgende Meldung bei mir:

Traceback (most recent call last):
File "/home/runner/unit_tests.py", line 24, in test_PlusMinus
self.assertEquals(PlusMinus('eins'),'eins') #1
NameError: name 'PlusMinus' is not defined
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Code. Tags. Benutzen.

Und was genau an der Fehlermeldung ist dir unklar? Diese Funktion wird doch in deiner Aufgabe gefordert.
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

1. Bitte schreibe deinen Code in Code-Tags. Die werden automatisch eingefügt, wenn du im "vollständigen Editor" den Button mit </> anklickst. Nur so bleiben die Einrückungen erhalten, die bei Python substanziell sind.

2. Offensichtlich fehlt eine Funktion, die laut Aufgabenstellung da sein muss und beim Test natürlich angesprochen wird.
SoSal
User
Beiträge: 4
Registriert: Mittwoch 15. Mai 2019, 12:54

Code: Alles auswählen

def codieren(zahl):
    listezahl = [1,2,3,4,5,6,7,8,9,10]
    listebuch = ["eins","zwei", "drei", "vier", "fünf", "sechs", "sieben", "acht", "neun", "zehn"]
    if zahl in listezahl:
        pos = listezahl.index(zahl)
        print(listebuch[pos])
Hoffe jetzt hat es geklappt. :)
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@SoSal: Grunddatentypen wie `liste` haben in Namen nichts zu suchen. Wenn man den Typ dann ändert, und das kommt öfter vor wenn man ein Programm entwickelt, dann hat man entweder falsche, irreführende Namen im Programm, oder man muss die überall anpassen.

Die Liste mit den ganzen Zahlen brauchst Du auch gar nicht, denn die Position des Wortes kannst Du aus der gegebenen Zahl ganz trivial berechnen, statt in einer anderen Liste danach suchen zu müssen. Überleg doch mal an welchem Index das Wort für 1 steht. Und an welchem Index das Wort für 2. Und so weiter. Da sollte Dir ein ganz einfaches Muster auffallen.

Zudem soll das Wort dann nicht *aus*gegeben, sondern an den Aufrufer *zurück*gegeben werden. Damit der dann etwas damit machen kann.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
SoSal
User
Beiträge: 4
Registriert: Mittwoch 15. Mai 2019, 12:54

Bei mir als absoluten Neuling scheitert es leider schon an dieser Aufgabenstellung, kann mir bitte jemand diesen Satz erklären?

-> "def codieren" übernimmt als Parameter eine (1) Einwortzahl (=String) und liefert als Ergbnis die Zahl als Integerwert zurück.
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

du schreibst eine Funktion, die als Parameter z.B. "vier" übergeben bekommt und als Rückgabewert 4 hat. Also:

Code: Alles auswählen

>>> def codieren(einwortzahl):
>>>     #hier steht dein Code für das Kodieren
>>>     return zahl
>>> codieren("vier")
4
>>>
Gruß, noisefloor
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Das Python-Tutorial in der offiziellen Dokumentation ist ein guter Einstieg um Python zu lernen.
Da steht auch etwas über Funktionen.
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Falls man davon ausgehen darf, dass die Funktionen nur mit gültigen Werten aufgerufen werden, hier ein Vorschlag für die `PlusMinus()`:

Code: Alles auswählen

#!/usr/bin/env python3
from collections import namedtuple
from functools import partial, reduce
from itertools import islice
from operator import add, getitem, sub

Pair = namedtuple('Pair', 'operation value')

convert_word_to_function = partial(getitem, {'plus': add, 'minus': sub})

def PlusMinus(expression):
    parts = expression.split()
    values = map(codieren, islice(parts, 0, None, 2))
    operations = map(convert_word_to_function, islice(parts, 1, None, 2))
    return decodieren(
        reduce(
            lambda accu, pair: pair.operation(accu, pair.value),
            map(Pair, operations, values),
            next(values)
        )
    )
😃
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das ganze mal spasseshalber in einer primitiveren Programmiersprache (QBasic) ohne so schicke Iteratoren und passende Funktionen dazu:

Code: Alles auswählen

DECLARE FUNCTION GetWord$ (start AS INTEGER, s AS STRING)
DECLARE FUNCTION PlusMinus$ (expression AS STRING)
DECLARE FUNCTION Codieren% (word AS STRING)

DIM SHARED Decodieren(1 TO 10) AS STRING

FOR i% = LBOUND(Decodieren) TO UBOUND(Decodieren): READ Decodieren(i%): NEXT
DATA "eins","zwei","drei","vier","fuenf"
DATA "sechs","sieben","acht","neun","zehn"

PRINT
PRINT Codieren("eins")
PRINT Decodieren(2)
PRINT PlusMinus("drei")
PRINT PlusMinus("eins plus zwei")
PRINT PlusMinus("drei plus vier minus fuenf")

FUNCTION Codieren% (word AS STRING)
  result% = LBOUND(Decodieren) - 1
  FOR i% = LBOUND(Decodieren) TO UBOUND(Decodieren)
    IF Decodieren(i%) = word THEN
      result% = i%
      EXIT FOR
    END IF
  NEXT
  Codieren% = result%
END FUNCTION

FUNCTION GetWord$ (start AS INTEGER, s AS STRING)
  DIM i AS INTEGER

  IF start = 0 THEN
    GetWord = ""
  ELSE
    i = INSTR(start, s, " ")
    IF i <> 0 THEN
      GetWord = MID$(s, start, i - start)
      start = i + 1
    ELSE
      GetWord = MID$(s, start)
      start = 0
    END IF
  END IF
END FUNCTION

FUNCTION PlusMinus$ (expression AS STRING)
  DIM i AS INTEGER, n AS INTEGER, result AS INTEGER
 
  i = 1: result = 0: op$ = "plus"
  DO
    n = Codieren(GetWord(i, expression))
    IF op$ = "minus" THEN n = -n
    result = result + n
    op$ = GetWord(i, expression)
  LOOP UNTIL op$ = ""

  PlusMinus = Decodieren(result)
END FUNCTION
Auch wieder mit der Voraussetzung das die Eingabedaten korrekt sind, also ohne irgendwelche Fehlerbehandlung.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten