Programming · Python

Satzgenerator in Python

Für mein Twitch Horoskop Projekt brauche ich ein Stück Software das mir einen grammatikalisch korrekten Satz auf Englisch erzeugen kann. Dieses soll in Python laufen, da das weitere Projekt darauf aufbaut.

Folgende Punkte waren mir wichtig: Es sollte die Möglichkeit geben einen Seed in Form eines Parameters als String mitzugeben. Dieser Seed soll sicherstellen, dass mir die Funktion den selben Satz bei mehrmaliger Ausführung zurück liefert solange sich der Seed nicht geändert hat. Darüber hinaus möchte ich die Horoskope etwas Persönlicher erscheinen lassen indem ich die Namen von Streamern die dieser Streamer folgt gelegentlich in das Horoskop einbaue. Dies geschieht mit einem zweiten Parameter. Da ich zukünftig vielleicht unterschiedlich lange Horoskope erstellen möchte, soll ein letzter Parameter die Anzahl der der zurückgegebenen Horoskope einstellbar machen.

Zunächst schaue ich mir ein paar Horoskope aus dem Internet an. Dabei fällt auf, dass sie oft sehr ähnliche Wörter und Satzstrukturen verwenden. Ich schrieb mir ein paar davon raus und hier sind meine Ergebnisse:

„bla you will bla bla, and it will bla.“
„If bla, then bla.“
„If bla, bla.“
„bla bla is bla, which means that you should bla bla bla blabla.“
„bla bla and bla.“

Weil ich nicht so statisch wirkende Horoskope generieren will und ich es in diesem Fall nicht schlimm finde wenn ein Horoskop aus mehreren Sätzen besteht erweitere ich diese Strukturen etwas und schreibe sie in eine Liste von Objekten:

[
    {
        "structure": "%s you will %s %s, and it will %s. %s.",
        "parts": [
            [
                "Today",
                "This week",
                "Soon",
            ],
            [
                "stumble across",
                "find",
                "discover",
                "uncover",
            ],
            [
                "a long forgotten meme",
                "a game from your childhood",
                "a fact about {{streamername}}",
            ],
            [
                "become important to you",
                "take on a new meaning to you",
                "take on new meaning in your life",
            ],
            [
                "Sieze this day as your own",
                "Don't let this opportunity pass you by",
            ],
        ],
    },
    {
        "structure": "If %s, then %s. %s.",
        "parts": [
            [
                "you plan to look for cat videos on Youtube",
                "you plan to spam random emotes in the chat",
                "you consider becoming a fulltime chess player",
                "you plan to go to the next Twitchcon",
                "you consider founding an eSports team",
            ],
            [
                "this may be a big year for you",
                "don't put it off",
                "you might just be right",
                "you need to think about it more",
                "you might be right",
                "you arleady might know what to do",
                "{{streamername}} would agree",
            ],
            [
                
                "If that doesn't make sense for you, then the time is obviously wrong",
                "But it's never too late to reconsider your options",
                "When in doubt, consult someone wiser than you",
                "There's no reason to rush into anything rash",
            ],
        ],
    },
    {
        "structure": "If %s, %s. %s that %s. %s",
        "parts": [
            ...
        ]
    },
    {
        "structure": "%s %s is %s, which means that you should %s %s %s %s%s.%s%s",
        "parts": [
            ...
        ]
    },
    {
        "structure": "%s. %s %s and %s.%s%s",
        "parts": [
            ...
        ]
    },
}

Um Platz in deinem Browser zu speichern habe ich diese Liste oben im Beispiel verkürzt. Bei mir ist sie natürlich komplett ausgefüllt… Nun da die Satzliste mit Memes gefüllt ist kann ich endlich eine Funktion schreiben die die Sätze generiert:

from random import choice, seed, shuffle
from jinja2 import Template

def get_sentences(seedstring, yourstreamers, amount):
    """
    Generates your horoscope !

    Args:
        seedstring (str): just any random str. Same string = same result
        yourstreamers (list): A list of str. Will be used within sentences
        amount (int): Amount of horoscopes, any positive number

    Returns
        list: A list of (str). each one representing an individual horoscope
    """
    seed(a=seedstring, version=2)
    shuffle(SENTENCEOBJECTS)
    sentences = []
    for sentenceobj in SENTENCEOBJECTS:
        parts = map(choice, sentenceobj["parts"])
        sentence = sentenceobj["structure"] % (tuple(parts))
        sentence = Template(sentence).render(
            streamername=choice(yourstreamers)
        )
        sentences.append(sentence)
        amount -= 1
        if amount <= 0:
            break
    return sentences

Die Funktion funktioniert wie folgt:
Erst wird der Seed gesetzt. Der Seed beeinflusst die wahl der choice Funktion. In der nächsten Zeile wird die Satzliste durchmischt damit nicht immer die selbe Satzstruktur zuerst verwendet wird. Innerhalb der Schleife werden mit map + choice die Satzbausteine zufällig ausgewählt und anschließend mithilfe des Prozentoperators in den Satz eingesetzt. Der Prozentoperator nimmt unsere Liste nur in Tupleform. Der Template().render Befehl ersetzt die {{streamername}} Substrings meiner Sätze mit einem zufälligen Namen aus der Streamerliste. Das fertige Horoskop wird in die sentences variable gespeichert und das ganze wird amount mal wiederholt. Am Ende geben wir die sentences variable zurück.

Um das ganze jetzt auszutesten müssen wir einfach die ganze Python Datei importieren und als Funktion aufrufen:

from horoscopesentences import get_sentences
get_sentences(„test“,[„test“],2)
[‚Next Twitchcon you will uncover a very old meme, and it will take on a new meaning to you. Why not get started with the rest of your life today.‘, „If you are having a bad feeling abour your eSports careeryou don’t think you know exactly what you might want, then come to a decision and see it through. Understand that sometimes you can’t appreciate standing up unless you have first fallen down. „]

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden /  Ändern )

Google Foto

Du kommentierst mit Deinem Google-Konto. Abmelden /  Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s