Ich schreibe einen Facebook-Bot, der irgendwann ein paar zufällig generierte Status pro Tag produzieren wird. Gerade jetzt bin ich auf der Stufe, wo ich die Logik habe, Phrasen aus Wörterbucheinträgen auszuwählen, und ich habe es geschrieben, so dass es vorerst nur in der Python-Shell funktionieren wird - die Facebook-Authentifizierung wird kommen später.Wie kann ich ein zufälliges Element in ein Wörterbuch einfügen und es randomisieren lassen, wann immer ich es nenne?
Gerade jetzt aber, ich dachte, es wäre cool bestimmte Substantive innerhalb der Sätze in den Wörterbüchern enthalten sind, randomisieren, und ich tat dies mit random.choice()
und eine Funktion ausgeführt wird, dass jedes Mal, wenn ich ein erzeugen ein neues Zufallselement zurückgeben soll Status. Aber das Problem ist, dass, wann immer ich die Phrase rufe, ich sehe, dass es ein zufälliges Substantiv erzeugt, aber dieses Substantiv wird aus irgendeinem Grund "fixiert", so dass jedes Mal das gleiche Substantiv reproduziert wird. Wenn ich die Funktion als Teil des Erstellens eines Status ausführe, scheint es gut zu funktionieren, aber aus irgendeinem Grund kann ich nicht verstehen, dass neue zufällige Substantive nicht an das Wörterbuch übergeben werden. Natürlich funktioniert es, wenn ich das Programm neu starte, aber wenn ich das als Bot machen möchte, möchte ich das Programm idealerweise nicht jedes Mal neu starten müssen, wenn ich einen neuen Status möchte.
Ich habe einige Nachforschungen gemacht und ich denke, das Problem ist nicht mit meinen tatsächlichen random.choice()
Sachen oder die Funktionen, die sie sind, aber das Wörterbuch wird "behoben", bevor meine zufällige Substantiv-Funktion kann es berühren (ZB die Zufallsauswahlfunktion erzeugt eine zufällige Auswahl aus der Fruchtliste, aber das Wörterbuch wird immer nur das selbe Obst haben, das ausgewählt wird, wenn ich die StatusBuilder-Funktion ausführe). Ich habe einige mögliche Lösungen mit globalen Variablen und so weiter ausprobiert, aber nichts hat funktioniert. Der Auszug, der im folgenden Code gezeigt wird, ist meiner Meinung nach der nächste, dem ich gekommen bin.
from random import randint
from random import choice
from textwrap import fill
def RandomFruit():
return choice(["mango", "pomelo", "guava", "grapefruit", "watermelon"])
class DoTable():
def __init__(self, text):
self.text = text
DoDict = {
"do0": DoTable("sitting on the roof, completely naked, throwing Herb Alpert records at a dog like they were frisbees"),
"do1": DoTable("eating a " + RandomFruit() + " like it's a handfruit"),
"do2": DoTable("lurching around a supermarket"),
}
class BeTable():
def __init__(self, start_text, end_text):
self.start_text = start_text
self.end_text = end_text
BeDict = {
"be0": BeTable("I guess ", " is what my life has come to."),
"be1": BeTable("", ", just waiting for the police to arrive."),
"be2": BeTable("If ", " is wrong, then I don't ever want to be right!"),
}
def StatusBuilder():
#DoDict and BeDict will always have one entry selected from each, though
#BeDict will always have two attributes selected as part of the one entry.
DoRNG = randint(0,len(DoDict)-1)
BeRNG = randint(0,len(BeDict)-1)
#Logic to display concatenated strings
status = BeDict["be" + str(BeRNG)].start_text + DoDict["do" + str(DoRNG)].text + BeDict["be" + str(BeRNG)].end_text
#print the status with textwrapping and with the first letter always capitalised.
print fill((status[0].capitalize() + status[1:]), 80)
print
Controls()
def Controls():
command = raw_input("([RETURN] FOR ANOTHER ROUND OF BULLSHIT, [Q] TO QUIT): ")
if command.lower() == "q":
quit()
elif command.lower() == "":
print
RandomFruit()
StatusBuilder()
else:
print
print fill("Some kind of wise guy are you? Try again, this time with a PROPER command please.", 80)
print
Controls()
#Start the program
print "PHILBOT V1.0"
print "A social media status generator."
print
command = raw_input("(PRESS [RETURN] TO GET STARTED): ")
print
RandomFruit()
StatusBuilder()
Die Probe Wörterbücher sind in dem obigen Code enthalten (das ist ein massiv verglichen ist abgespeckte Version des Programms, das, wenn Sie laufen mit ihm spielen wollen). Die Ausgabe, mit der ich Probleme habe, wäre das Element in DoDict mit dem Schlüssel "do1". Nehmen wir zum Beispiel an, dass die StatusBuilder-Funktion nacheinander die gleichen Phrasen ("do1" und "be2") auswählt, was jedes Mal, wenn sie mit der StatusBuilder-Funktion aufgerufen wird, ein anderes Obst erzeugt:
"Wenn ich eine Mango esse wie eine Handfrucht ist falsch, dann will ich niemals richtig sein!"
"Wenn ich eine Grapefruit wie eine Handfruit falsch mag, dann will ich nie richtig sein!"
Momentan "klebt" immer, welches Obst ausgewählt wird, immer wenn ich es durch StatusBuilder() führe, obwohl die RandomFruit() Funktion normal zu funktionieren scheint.
EDIT: Ich habe jetzt ein paar vorgeschlagene Alternativen (mit Lambdas und mit Generatoren) versucht und habe versucht, mit einem einfacheren Datenformat (Listen ohne Klassen) zu arbeiten, aber das Problem wird noch reproduziert. SO, ich fange an zu denken, dass es mehr mit meiner Reihenfolge der Operationen zu tun hat, wie im Wörterbucheintrag geschrieben wird, nachdem die RandomFruit-Funktion anfänglich ausgeführt wird (yay!), Aber es wird nicht "neu geschrieben" wenn ich es nochmal starte (boo!) ... das gibt mir ein Problem, da ich entweder die Funktion dann das Dictionary deklarieren kann (wo die Funktion nach dem ersten Gebrauch nicht mit dem Dictionary zu sprechen scheint), oder deklariere das Dictionary und dann die Funktion (was nicht funktioniert, da das Dictionary versucht, sich auf eine noch nicht deklarierte Funktion zu verlassen). Also, ich denke, das ist die Wurzel des Problems - jede Hilfe?
können Sie eine MCVE bieten. zeigt uns ein Beispielwörterbuch und die erwarteten Ausgaben oder Ausgaben, die Sie wünschen. Mein Verständnis ist jetzt, dass Sie die Werte des Wörterbuchs randomisieren möchten, wenn Sie versuchen, mit einem Schlüssel darauf zuzugreifen, ist das richtig? – danidee
OK, gutes Denken, danke - wird den Beitrag bearbeiten. – phillipbrooker
Und ich sollte auch sagen, das Programm randomisiert bereits die Werte des Wörterbuchs als Teil der StatusBuilder() - Funktion, aber ich frage mich, ob ich auch den Inhalt von Wörterbucheinträgen randomisieren kann, bevor sie von StatusBuilder() aufgerufen werden Helfen Sie jedem Status neu/anders. Ich könnte nur in ähnlichen Wörterbuch Einträge mit verschiedenen Obstnamen hinzufügen, aber das fühlt sich nicht Pythonic ... – phillipbrooker