2016-04-26 2 views
1

私はFacebookボットを書いています。最終的には、ランダムに生成された2つのステータスが最終的に生成されます。今、私は辞書のエントリーからフレーズのビットを選ぶロジックを持っている段階にあります。私はそれを書いていますので、今度はPythonのシェルで動作します - Facebook認証のものが来ます後で。ランダムな要素を辞書に挿入して、それを呼び出すたびにランダム化する方法はありますか?

は今しかし、私は辞書に含まれる語句内の特定の名詞をランダム化するためにクールだろうと思った、と私はrandom.choice()でこれをやって、私は発生するたびに新しいランダムな要素を返すべき関数を実行していた 状態。しかし、問題は、私がそのフレーズを呼び出すたびに、私はそれが1つのランダム名詞が生成されているのを見ることができますが、その名詞はいつも同じランダム名詞が再現されるような理由で「固定」になります。状態を構築する際に関数を実行すると、うまくいっているように見えますが、何らかの理由で新しいランダム名詞が辞書に渡されません。当然、プログラムを再起動すると動作しますが、私がボットとしてこれを行うことを目指しているなら、私は理想的には、新しいステータスを望むたびにプログラムを再起動する必要がないようにしたいと思います。

私はいくつか調査しましたが、私の問題は自分の実際のrandom.choice()のものやそれらの機能とは関係ないと思いますが、ランダムな名詞関数がそれに触れる前に例えば、ランダム選択機能は果物リストから無作為に選択しますが、StatusBuilder機能を実行すると、同じ果物のみが選択されます)。私はグローバル変数などの潜在的な解決策を試しましたが、何も効果がありませんでした。以下のコードで説明されている抜粋は、私が一番近いものです。

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

サンプル辞書は(あなたがそれを再生したい場合に実行するプログラムの大規模なダウン切り詰めバージョンである)上記のコードに含まれています。だから私が問題を抱えている出力は、キー "do1"を持つDoDictの要素になります。たとえば、StatusBuilder関数が同じフレーズ( "do1"と "be2")を連続して選択すると、StatusBuilder関数で呼び出されるたびに、次のように異なるフルーツが生成されます。

「マンゴーを食べるのが手作りだと間違っているとすれば、正しいとは思っていません!」

「グレープフルーツを食べるのが手作りだと間違っていたら、私は正しいとは思っていません!」

現在のところ、RandomFruit()関数が正常に動作しているように見えるにしても、StatusBuilder()を通じて実行するたびに、最初に選択された果物が常に「スティック」されます。

EDIT:lambdaとジェネレータを使用していくつかの代替案を試してみましたが、より簡単なデータ形式(クラスなしのリスト)で作業しようとしましたが、問題はまだ再現されています。だから、私は、RandomFruit関数が最初に実行された後(yay!)辞書の項目が '書き込まれる'ように、私の操作の順序ともっと関係があると思っていますが、私はそれをもう一度実行すると(ブー!)...これは私に問題をもたらします。なぜなら、関数と辞書(関数が最初に使用された後に辞書に話しているように見えない)を宣言するか、辞書を次に関数に宣言します(これは辞書が未だ宣言されていない関数に頼っているので機能しません)。だから、私はこれが問題の根源だと思う - どんな助け?

+0

あなたはMCVEを提供することができます。サンプルの辞書と期待する出力を表示します。私の理解は、あなたがキーを使ってそれらにアクセスしようとするときに辞書の値を無作為化したいということです。 – danidee

+0

OK、良い考え、感謝 - 投稿を編集します。 – phillipbrooker

+0

また、プログラムはすでにStatusBuilder()関数の一部として辞書の値をランダム化していますが、StatusBuilder()によって呼び出される前に辞書エントリのCONTENTをランダム化できるかどうかは疑問です各ステータスを新規/異なるものにするのに役立ちます。私はちょうど別の果物の名前と同様の辞書のエントリを追加することができますが、それはPythonicを感じることはありません... – phillipbrooker

答えて

5

あなたは(私はかなりあなたの例を簡略化しました)あなたの辞書に値としてrandom.choice機能を使用できます。

import random 
fruits = ["mango", "pomelo", "guava", "grapefruit", "watermelon"] 
DoDict = {'do1': random.choice} 

あなたはランダムな果物あなたが辞書にアクセスするたびに取得するこの方法:

def random_fruit(): 
    while True: 
     yield random.choice(["mango", "pomelo", "guava", "grapefruit", "watermelon"]) 
DoDict = {'do1': random_fruit().next} 
012:また 発電を使用することができます
>>> for i in range(10): print DoDict['do1'](fruits) 
guava 
pomelo 
watermelon 
mango 
watermelon 
grapefruit 
pomelo 
watermelon 
watermelon 
watermelon 

あなたは、パラメータとして果物のリストを渡す必要はありません。この場合

>>> for i in range(10): print DoDict['do1']() 
grapefruit 
pomelo 
pomelo 
guava 
grapefruit 
pomelo 
pomelo 
pomelo 
mango 
guava 
+0

私はできるだけ早くこれらのソリューションの両方を試してみる、両方の本当に有望なので、私は彼らと一緒に行ったときに戻って報告! でも、ここではすばやい質問がまず必要です。私はnumpyが何をしているのか全く分かっていないので、これまで使っていないので、既存のrandom.choiceのやり方を超えて何が提供されているのだろうかと思っているだけです... – phillipbrooker

+0

はい、numpyは厳密には必要ではありません。代わりに(私はそれに応じて私の答えを編集しました)。 – Tonechas

+0

Hmmm、両方とも試してみましたが、両方とも問題を再現しているようです(つまり、エントリーが最初にランダムに選択されましたが、その後のすべてのインスタンスに対してその選択を保持します)...辞書をもっとシンプルなリストに入れて、クラスを削除して物事を試して単純化しました。私の操作の順序でそれがより問題だと思うようになる - 私の元の投稿を編集します。偉大なアイデアをありがとう、良いことをするための新しい方法を学ぶことができました! – phillipbrooker

関連する問題