Im letzten Artikel habe ich den selectOne Parameter von Perchance erklärt. Er mag am Anfang etwas verwirrend erscheinen, doch mit einigen Beispielen und Tests die man selbst durchführen kann, sollte es bald begreifbar werden. Doch mit Perchance kann man nicht nur ein Element aus einer Liste wählen, man kann auch mehrere wählen:
character = {{a-z}|{A-Z}|{0-9}}
tenCharacters = [character.selectMany(10)]
Was passiert hier genau? Fangen wir am besten mit der ersten Zeile an.
character = {{a-z}|{A-Z}|{0-9}}
Diese Zeile drückt aus, dass wenn „character“ angesprochen wird, ein zufälliges Zeichen zwischen a-z sowie A-Z und 0-9 als Ausgabe erfolgen kann. Also jeder Kleinbuchstabe, jeder Großbuchstabe und jede Zahl zwischen 0 und 9. Allerdings immer nur als 1 Zeichen. Die Ausgabe kann also beispielsweise lauten:
- 2
- D
- T
- H
- I
- 9
Inhaltsverzeichnis
Die selectMany Option
Die nächste Zeile erweitert diese Ausgabe:
tenCharacters = [character.selectMany(10)]
Diese Zeile hat zur Folge, dass das Element „tenCharacters“ das Element „character“ aufruft und zwar genau 10x (= selectMany(10)). Man könnte die Anzahl der Aufrufe auch auf 5 begrenzen, dann würde das Element selectMany(5) lauten.
output
[tenCharacters]
character = {{a-z}|{A-Z}|{0-9}}
tenCharacters = [character.selectMany(10)]
Durch diesen Code erfolgt also folgende zufällige Augaben wie:
- IGoj01Pp18
- SS3m5MEx99
- Bwf40K7TH3
- und so weiter
Ohne die selectMany Option müsstest du den Code so schreiben:
tenCharacters = {{a-z}|{A-Z}|{0-9}}{{a-z}|{A-Z}|{0-9}}{{a-z}|{A-Z}|{0-9}}.........
Und das wäre weder lustig noch effizient. Selbstvertändlich kann man auch die Ausgabe von selectMany noch steuern. Möchtest du beispielsweise nicht 10 Zeichen haben, sondern zufällig zwischen 3 und 10, dann ändere den Code auf:
output
[tenCharacters]
character = {{a-z}|{A-Z}|{0-9}}
tenCharacters = [character.selectMany(3, 10)]
Dadurch werden nun zufällige Zeichen von a-z, A-Z und 0-9 in der Länge von 3 bis 10 ausgegeben. Cool, oder?
Ein kurzer Hinweis: Wenn du im obigen Beispiel möchtest, dass jedes alphanumerische Zeichen die gleiche Wahrscheinlichkeit hat, ausgewählt zu werden, solltest du jeden Unterblock nach der möglichen Anzahl der Elemente gewichten, die er enthält:
{{a-z}^26|{A-Z}^26|{0-9}^10}
Wenn das für dich gerade keinen Sinn ergibt, dann macht das nichts. Manchmal werden manche Dinge erst später klarer, wenn wir öfters damit arbeiten. Zur Erklärung: Es gibt 26 Buchstaben und 10 Ziffern. Durch die Gewichtung und Angabe, welche Priorität diese haben, wird die Wahrscheinlichkeit so definiert, dass alle Zeichen die gleichgroße Chance haben ausgewählt zu werden.
Die joinItems Eigenschaft
Können wir nun die Ausgabe auch so anpassen, dass wir ausgewählte Elemente mit z.B. einem Komma verbinden können? Man könnte beispielsweise eine Obst-Liste erstellen und dann einen Satz erstellen wie „Meine Lieblingsfrüchte sind: Orangen, Mangos, Bananen, Birnen, Äpfel, Blaubeeren und Trauben“. Hier kommt die joinItems-Eigenschaft ins Spiel:
sentence
My favourite fruits are: [fruit.selectMany(5).joinItems(", ")] and [fruit].
Im ganzen Code-Beispiel würde das so aussehen:
output
[sentence]
fruit
bananas
apples
mangos
oranges
pears
berries
melon
currant
raspberry
sentence
My favourite fruits are: [fruit.selectMany(5).joinItems(", ")] and [fruit].
Was genau passiert hier?
Mit „fruit.selectMany(5)“ werden 5 Elemente aus der fruit-Liste ausgewählt. Das ist ja bereits bekannt. Mit „joinItems(„, „)“ wird das gewählte Element mit einem Komma und einem Leerzeichen ergänzt. Aus z.B. pearsmelonmangos wird pears, melon, mangos
joinItems zur einfachen Ausgabe
Falls du deine Listen-Elemente einfach nur Ausgaben möchtest, in der Reihenfolge in der sie eingetragen sind, dann kannst du einfach nur [fruit.joinItems(“, “)] verwenden. Dieser Befehl bewirkt, dass alle Elemente der Liste einfach mit einem Komma und Leerzeichen getrennt ausgegeben werden.
Dies kann manchmal nützlich sein, um „mehrzeilige Elemente“ zu definieren.
output
[sentence]
fruit
bananas
apples
mangos
oranges
pears
berries
melon
currant
raspberry
sentence
My favourite fruits are: [fruit.joinItems(“, “)] and [fruit].
Verwenden von Anführungszeichen
In den bisherigen Beispielen haben wir keine Sonderzeichen wie Anführungszeichen bei der Ausgabe verwendet. Anführungszeichen sind speziell zu behandeln, da nämlich die Befehle und Codes mit Anführungszeichen arbeiten. Nutzt man Anführungszeichen ohne „Maskierung“ also eine bestimmte Formatierung, dann wird der Code beendet und ist fehlerhaft.
Man kann sich auf zwei Wegen behelfen. Entweder man verwendet das‘ dass du auf der Tastatur neben dem Ä findest und mit Shift+# erzeugt wird oder du maskierst die Anführungszeichen korrekt. Was du in deinem Code machst, obliegt letztendlich dir. Wenn du Anführungszeichen maskierst, dann sieht das so aus:
\"
Diese zwei Zeichen haben zur Folge, dass ein Anfürhungszeichen als Ausgabe angezeigt wird. Der Schrägstrich vor dem Anführungszeichen gibt dem Code-Interpreter bekannt, dass das Zeichen nicht zum Code, sondern zur Ausgabe gehört. Klingt verwirrend? Der korrekte Code lautet dann:
sentence = My favourite fruits are: "[fruit.selectMany(2).joinItems("\", \"")]" and "[fruit]".
Versuche es am besten aus, damit du verstehst, was damit bezweckt wird.
num selectMany
Um das obige Beispiel zu optimieren – was du übrigens permanent machen solltest, damit der Code schnell und flüssig bleibt, kannst du auch folgendes hinterlegen:
output
[sentence]
fruit
bananas
apples
mangos
oranges
pears
berries
melon
currant
raspberry
num = {3-6}
sentence
My favourite fruits are: [fruit.selectMany(num).joinItems(", ")] and [fruit].
Dadurch werden nun zufällig zwischen 3 und 6 Früchte im ersten Abschnitt des Satzes ausgegeben. Einfach, oder?
Falls du dich nicht mehr an die vorherigen Kapitel so richtig erinnern kannst, wir haben nun mit dem Objekt [num] definiert, dass eine Zufallszahl zwischen 3 und 6 bei Abruf erfolgen soll. Dieses Objekt [num] haben wir mit der selectMany-Eigenschaft gekoppelt. Beachte, dass wir um die num-Eigenschaft innerhalb des Aufrufs keine eckigen Klammern verwenden, weil wir uns bereits in so einem Aufruf befinden. Dadurch können wir auf Listen einfach durch die Angabe von deren Namen verweisen.
Hinweis: Du solltest deine Listen übrigens nur mit Buchstaben, Zahlen und Unterstrichen benennen. Listennamen dürfen keine Leerzeichen enthalten und nicht mit einer Zahl beginnen. Zudem wird bei Listennamen Groß- und Kleinschreibung berücksichtigt.
Die selectUnique Option
In dem obigen Beispiel mit den Lieblingsfrüchten sehen wir aber auch ein Problem. Es kann nämlich passieren, dass manche Früchte öfters ausgegeben werden, wie z.B. „My favourite fruits are: grapes, grapes, pears, …“. Das ist natürlich nicht optimal und macht die Ausgabe überflüssig.
Mit der Option selectUnique können wir das allerdings verhindern. Es sagt ja bereits das Element „selektiere ein Einzigartiges“ und genau das ist das, was dieses Zusatzelement macht.
output
[sentence]
fruit
bananas
apples
mangos
oranges
pears
berries
melon
currant
raspberry
sentence
My favourite fruits are [fruit.selectUnique(3).joinItems(", ")].
Ziemlich einfach oder? Leider ist nun das Ergebnis grammatikalisch nicht mehr ganz korrekt, weil der Satz holprig klingt wie z.B. „My favourite fruits are pears, currant, melon.“ Also benötigen wir hier einen anderen und leistungsfähigeren Ansatz.
Die selectUnique Option mit Zufallsauswahl
Im letzten Abschnitt haben wir nun gelernt, dass wir einzigartige Elemente aus einer Liste mit selectUnique wählen können. Die Funktion selectUnique ist ähnlich wie selectMany, nur mit dem entscheidenden Unterschied, dass sie nicht zweimal das gleiche Element auswählt.
[animal.selectUnique(5)]
Diese Zeile bewirkt, dass 5 einzigartige Tiere aus der animal-Liste genommen werden.
[animal.selectUnique(3,20)]
Diese Zeile bewirkt, dass zufällig zwischen 3 und 20 einzigartigen Tieren aus der animal-Liste genommen werden.
hier ist der gesamte Code zum Testen mit zwei verschiedenen Sätzen in der Ausgabe:
output
[sentence]
animal
lion
elephant
tiger
giraffe
zebra
kangaroo
penguin
dolphin
shark
whale
panda
fox
wolf
eagle
owl
rabbit
deer
crocodile
hippopotamus
rhinoceros
sentence1
You can see different animals in zoo like [animal.selectUnique(5).joinItems(", ")]
sentence2
There are a lot of animals in this country like [animal.selectUnique(3,8).joinItems(", ")]
sentence
[sentence1].<br>[sentence2].
Die consumableList Option
Manchmal ist die selectUnique Option jedoch zu wenig und zu einfach um bestimmte Szenarien abzudecken. Denn was ist, wenn wir über einen ganzen Textabschnitt die Listen-Elemente einsetzen und verteilen wollen, anstatt sie einfach nacheinander auszugeben?
An dieser Stelle ist die consumableList Option sehr hilfreich. Dies ermöglicht es, eine Liste als eine verbrauchbare Liste zu definieren. Wenn eine Liste als Verbrauchsliste (consumableList) definiert wird, dann wird das selektierte Element aus der Liste entfernt. Die Liste schrumpft also mit jeder Verwendung. Man kann eine definierte Liste zu einer verbrauchbaren Liste definieren, in dem wir eine Liste mit dieser Option erstellen:
[cl = animal.consumableList]
Im gesamten Kontext würde das nun so aussehen:
output
[sentence]
animal
lion
elephant
tiger
giraffe
zebra
kangaroo
penguin
dolphin
shark
whale
panda
fox
wolf
eagle
owl
rabbit
deer
crocodile
hippopotamus
rhinoceros
cl = [animal.consumableList]
sentence1
You can see different animals in zoo like [cl.selectUnique(5).joinItems(", ")]
sentence2
There are a lot of animals in this country like [cl.selectUnique(3,8).joinItems(", ")]
sentence
[sentence1].<br>[sentence2].
Die beiden Sätze geben nun jeweils Tiere aus, die nur 1x genannt werden. Es kommen keine doppelten Tiernamen in diesem Beispiel pro Satz vor.
Hier ist ein weiteres Beispiel um consumableList zu verwenden. Dabei sollen zwei zufällig, nicht doppelte Elemente ausgewählt werden. Während das erste Element relativ egal ist, wollen wir das zweite in einem Folgesatz nochmals wiederholen:
output
[sentence]
animal
lion
elephant
tiger
giraffe
zebra
kangaroo
penguin
dolphin
shark
animal2
lion
elephant
tiger
giraffe
zebra
kangaroo
penguin
dolphin
shark
cl = [animal.consumableList]
sentence1
You can see different animals in zoo like [cl.selectUnique(5).joinItems(", ")]
sentence2
There are a lot of animals in this country like [cl.selectUnique(3,8).joinItems(", ")]
sentence3
She mostly writes about [t = animal.consumableList] and [a = t.selectOne]. Her last post was about [a].
sentence
[sentence1].<br><br>[sentence2].<br><br>[sentence3].
Kannst du erkennen, wie das realisiert wurde? Wir erstellen eine verbrauchbare Liste mit den animals und weisen ihnen die Variable t zu. Danach erhält die a-Variable ebenfalls ein Element aus der definierten t-Variable. Die a-variable wird dann im Folgesatz nochmals ausgegeben:
sentence3
She mostly writes about [t = animal.consumableList] and [a = t.selectOne]. Her last post was about [a].
Das war nun eine ganze Menge Lernmaterial, mach dir aber keine Sorgen, wenn du noch nicht alles ganz verstehst. Spiele einfach weiter mit den Beispielen und Generatoren und schau dir den Quellcode der Textgeneratoren anderer Leute an, und du wirst schon bald anfangen, diese fortgeschritteneren Techniken zu verstehen und einzusetzen.