mardi 26 avril 2016

How can I insert a random element into a dictionary and have it randomised whenever I call it?

I'm writing a Facebook bot which will eventually produce a couple of randomly-generated statuses a day. Right now, I'm at the stage where I've got the logic of selecting bits of phrases from dictionary entries and I've written it so it will just work in the Python shell for the time being - the Facebook authentication stuff will come later.

Right now though, I thought it'd be cool to randomise certain nouns within the phrases contained in the dictionaries, and I was doing this with random.choice() and running a function that should return a new random element every time I generate a status. But the problem is that whenever I call the phrase, I can see that it's generated one random noun, but that noun gets 'fixed' for some reason such that the same random noun is reproduced every time. When I run the function as part of building a status, it seems to be working fine, but for some reason I can't figure, any new random nouns are not passed to the dictionary. Naturally, it works when I restart the programme, but if I'm aiming to do this as a bot, I'd ideally like to not have to restart the programme every time I want a new status.

I've done some investigating and I think the problem is not to do with my actual random.choice() stuff or the functions that they're in, but that the dictionary gets 'fixed' before my random noun function can touch it (e.g. the random choice function produces a random selection from the fruit list, but the dictionary will only ever have the same fruit selected when I run the StatusBuilder function). I have tried out some potential solutions with global variables and so on, but nothing has worked. The excerpt demonstrated in the code below is, I think, the closest I've come.

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
        RandomElements()
        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
RandomElements()
StatusBuilder()




Aucun commentaire:

Enregistrer un commentaire