Extra

Deze pagina bevat uitvoerbare code.

Potjeslatijn

In deze opgave schrijf je functies die een Nederlands woord vertalen naar potjeslatijn: een geheimtaal waarin je de beginklanken van een woord achteraan zet. Daarna vertaal je terug. Dit probleem is gebaseerd op Google Pig Latin[1]:

Google Pig Latin

De regels

De klinkers zijn a, e, i, o en u. Een woord bestaat uit kleine letters.

Het woord

Vertaling

Voorbeeld

is leeg

de lege string

"" wordt ""

begint met een klinker

het woord, met "hee" erachter

"aap" wordt "aaphee"

begint met een of meer medeklinkers

het woord zonder die medeklinkers, dan de medeklinkers, dan "ee"

"straat" wordt "aatstree"

De y is een geval apart. Staat er aan het begin een y gevolgd door een klinker, dan telt de y als medeklinker: "yoghurt" wordt "oghurtyee". Staat er aan het begin een y gevolgd door een medeklinker, dan telt de y als klinker: "ypsilon" wordt "ypsilonhee".

Wat je gaat maken

Stap

Functie

Doet

1

piglet_latin

opwarmen: de regels, met hoogstens één beginmedeklinker

2

initial_consonants

de medeklinkers waarmee een woord begint, recursief

3

pig_latin

alle regels, ook die voor de y

4

back_to_front

terug: steeds de laatste letter vooraan, recursief

5

originals

alle woorden waar een vertaling van kan komen

Geef elke functie een docstring.

Stap 1: piglet_latin(s)

Geeft de vertaling van s in potjeslatijn, maar verplaatst alleen de éérste letter als het woord met een medeklinker begint. De y telt hier altijd als medeklinker.

Aanroep

Resultaat

piglet_latin("aap")

"aaphee"

piglet_latin("noot")

"ootnee"

piglet_latin("straat")

"traatsee"

Dat laatste is nog niet goed: bij straat horen alle drie de beginmedeklinkers achteraan. Dat komt in stap 3.

# jouw oplossing
assert piglet_latin("") == ""
assert piglet_latin("aap") == "aaphee"
assert piglet_latin("noot") == "ootnee"
assert piglet_latin("straat") == "traatsee"

Stap 2: initial_consonants(s)

Geeft een string met de medeklinkers waarmee s begint. Begint s met een klinker, of is s leeg, dan geeft de functie de lege string terug. Gebruik recursie.

Aanroep

Resultaat

initial_consonants("straat")

"str"

initial_consonants("aap")

""

Hint

Is het eerste teken een medeklinker, dan hoort het erbij, samen met de medeklinkers waarmee de rest begint. Is het een klinker, dan ben je klaar.

# jouw oplossing
assert initial_consonants("straat") == "str"
assert initial_consonants("noot") == "n"
assert initial_consonants("aap") == ""
assert initial_consonants("") == ""

Stap 3: pig_latin(s)

Geeft de vertaling van s in potjeslatijn, volgens alle regels, ook die voor de y.

Aanroep

Resultaat

pig_latin("straat")

"aatstree"

pig_latin("ypsilon")

"ypsilonhee"

pig_latin("yoghurt")

"oghurtyee"

Hint

Gebruik initial_consonants uit stap 2. Weet je de beginmedeklinkers, dan zegt hun lengte waar de rest van het woord begint. Behandel de y gevolgd door een medeklinker vóórdat je initial_consonants aanroept.

# jouw oplossing
assert pig_latin("") == ""
assert pig_latin("aap") == "aaphee"
assert pig_latin("noot") == "ootnee"
assert pig_latin("straat") == "aatstree"
assert pig_latin("ypsilon") == "ypsilonhee"
assert pig_latin("yoghurt") == "oghurtyee"

Stap 4: back_to_front(s)

Nu vertaal je terug. Haal je bij "ootnee" de "ee" weg, dan blijft "ootn" over: de beginmedeklinker staat nog achteraan. Geeft een lijst met de woorden die je krijgt door de medeklinkers aan het eind van s vooraan te zetten: eerst alleen de laatste, dan de laatste twee, enzovoort, tot ze er alle vooraan staan. Er staat minstens één klinker in s. Gebruik recursie.

Aanroep

Resultaat

back_to_front("ootn")

["noot", "tnoo"]

back_to_front("aatstr")

["raatst", "traats", "straat", "tstraa"]

back_to_front("zee")

[]

Dat er meer uitkomt dan noot en straat, is geen fout. In stap 5 zie je waarom.

Hint

Eindigt s op een klinker, dan ben je klaar; dat is het basisgeval. Anders zet je eerst de laatste letter vooraan. Het kleinere probleem is deze keer geen kortere string: roep de functie aan op het nieuwe woord. Waarom stopt dit? En wat gebeurt er met "str"?

# jouw oplossing
assert back_to_front("ootn") == ["noot", "tnoo"]
assert back_to_front("aatstr") == ["raatst", "traats", "straat", "tstraa"]
assert back_to_front("zee") == []
assert back_to_front("a") == []

Stap 5: originals(p)

p is de vertaling van een woord met minstens één klinker en zonder y. Geeft een lijst met alle woorden die p als vertaling hebben. Eindigt p op "hee", dan staat p zonder "hee" vooraan in de lijst.

De y blijft buiten deze stap, omdat er dan woorden uitkomen die niet terugvertalen: uit "ypsilonhee" zou ook "hypsilon" komen, en pig_latin("hypsilon") geeft "ilonhypsee".

Aanroep

Resultaat

originals("ootnee")

["noot", "tnoo"]

originals("aaphee")

["aap", "haap", "phaa"]

originals("aatstree")

["raatst", "traats", "straat", "tstraa"]

Reken het na met pig_latin: ook pig_latin("tnoo") geeft "ootnee".

Hint

Een vertaling kan op twee manieren zijn ontstaan. Begon het woord met een klinker, dan staat er "hee" achter. Begon het met medeklinkers, dan staan die vlak vóór "ee", en geeft back_to_front uit stap 4 alle mogelijkheden. Een vertaling op "hee" kan op beide manieren zijn ontstaan: aaphee is de vertaling van aap en van haap.

# jouw oplossing
assert originals("ootnee") == ["noot", "tnoo"]
assert originals("aaphee") == ["aap", "haap", "phaa"]
assert originals("aatstree") == ["raatst", "traats", "straat", "tstraa"]
assert "straat" in originals(pig_latin("straat"))
assert "eend" in originals(pig_latin("eend"))

Tot slot

Potjeslatijn is niet eenduidig terug te vertalen: aatstree kan van vier woorden komen. Om het Nederlandse woord eruit te kiezen, heb je een woordenlijst nodig.

In stap 4 was het kleinere probleem geen kortere string. Het nieuwe woord was even lang, maar eindigde op één medeklinker minder. Zolang zo’n aantal bij elke recursieve aanroep kleiner wordt, tot het basisgeval, stopt de recursie. Zonder klinker in s wordt het aantal niet kleiner, en stopt de recursie niet.

Er blijven ook randgevallen over. Wat moet pig_latin("gym") teruggeven? Je mag zelf bepalen hoe je zulke woorden vertaalt.

Eelvee uccessee!