2016-12-01 8 views
1

私は、リストを提示し、ユーザにリスト内のアイテムのインデックスを選択するように求めて、Python 2.7で関数を呼び出そうとしています。私は2つの点で混乱しています:ユーザが入力したインデックスを使って関数を呼び出す

  1. ユーザが入力したインデックスは、初期リストに定義されている関数とどのように対応していますか?私はリスト内の項目を選択する方法を理解していますが、関数を呼び出す方法を理解していません。

  2. このコードブロックはどこに配置すればよいですか?主な機能は?ここで

は私のコードです:

''' neoPixel setups''' 
import time 
from neopixel import * 

# LED configuration. 
LED_COUNT = 16 # Number of LED pixels. 
LED_PIN = 12 # GPIO pin connected to the pixels (must support PWM!). 
LED_FREQ_HZ = 800000 # LED signal frequency in hertz (usually 800khz) 
LED_DMA = 5 # DMA channel to use for generating signal (try 5) 
LED_BRIGHTNESS = 255 # Set to 0 for darkest and 255 for brightest 
LED_INVERT = False # True to invert the signal (when using NPN transistor level shift) 


def colorWipe(strip, color, wait_ms=50): 
    """Wipe color across display a pixel at a time.""" 
    for i in range(strip.numPixels()): 
     strip.setPixelColor(i, color) 
     strip.show() 
     time.sleep(wait_ms/1000.0) 


def theaterChaseRainbow(strip, wait_ms=50): 
    """Rainbow movie theater light style chaser animation.""" 
    for j in range(256): 
     for q in range(3): 
      for i in range(0, strip.numPixels(), 3): 
       strip.setPixelColor(i + q, wheel((i + j) % 255)) 
      strip.show() 
      time.sleep(wait_ms/1000.0) 
      for i in range(0, strip.numPixels(), 3): 
       strip.setPixelColor(i + q, 0) 


if __name__ == '_main_': 
    # create neopixel object with appropriate configuration 
    strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS) 
    # initialize the library (must be called before other function) 
    strip.begin() 

    print 'Press Ctrl-C to quit' 

''' user input block ''' 
lighting_modes = 'rainbow', 'colorWipe' 

for i, item in enumerate(lighting_modes): 
    print i, item 

user_input = input("Please enter index of the lighting modes listed above") 

if user_input == 0: 
    colorWipe(strip, Color(255, 0, 0)) # red 
    colorWipe(strip, Color(0, 255, 0)) # blue 
    colorWipe(strip, Color(0, 0, 255)) # green 
elif user_input == 1: 
    theaterChase(strip, Color(127, 127, 127)) 
    theaterChase(strip, Color(127, 0, 0)) 
    theaterChase(strip, Color(0, 0, 127)) 
+0

'' '文字列を返しますinput'''、' ''してみてくださいもしUSER_INPUT == '0''''と '' '場合USER_INPUT ==' 1'''' – wwii

+0

右のおかげで、私はそれをキャストすることもできますが、これは関数呼び出しにどのように対応しますか? –

+0

私はあなたが何を求めているのか確認しています。リストから関数をインデックスで選択して呼び出すのですか? – wwii

答えて

4
>>> def f(): 
    print('foo') 

>>> def g(): 
    print('bar') 

ありがとう、ユーザーの入力と

>>> funcs = [f, g] 

インデックスリストをリスト内の関数を入れて、に結果を代入します名。

>>> which = int(input('which .. ')) 
which .. 1 
>>> func = funcs[which] 

は、ユーザーの選択に基づいて、所定の引数を持つさまざまな機能を複数回呼び出すに

>>> func() 
bar 

def fff(arg1, arg2): 
    print('f', arg1, arg2) 

def ggg(arg1, arg2): 
    print('g', arg1, arg2) 

それを呼び出します - あなたは、関数や機能でユーザーの選択を関連付ける必要があります彼らが呼び出される議論と一緒に。これは、その後、あなたは、あなたが選択すると、このような関数を呼び出します

options = '\n'.join('{} - {}'.format(k, v[0].__name__) for k,v in p.items()) 
which = input('Which?\n' + options + '\n') 

とオプションメニューを構築することができ辞書

{choice : [function, [(args), (args), (args)]], ...} 

func_f = [fff, [('strip', 'blue'), ('strip', 'green'), ('strip', 'red')]] 
func_g = [ggg, [('strip', 'grey'), ('strip', 'dk_red'), ('strip', 'dk_blue')]] 

p = {'0': func_f, '1': func_g} 

で行うことができます。 *argsに、アスタリスクは、リストまたはタプル内に複数の項目をアンパックします。

func, calls = p[which] 
for args in calls: 
    func(*args) 

>>> 
Which? 
1 - ggg 
0 - fff 
1 
g strip grey 
g strip dk_red 
g strip dk_blue 
>>> 

関数の引数が多すぎたり小さすぎたりすると、関数を呼び出すときにTypeError例外がスローされます。ユーザーが無効なオプションを送信すると、KeyError例外が発生します。 Handling Exceptions


これは、あなたの例で使用されていますが、多くの機能を持っている場合、これは良いかもしれないと、これはあなたが別の引数値で、実行時に辞書を修正/構築することができます簡単な条件文に比べて少し複雑なようです。

f_calls = operator.itemgetter(1) 
f_calls(func_f).append(('strip', 'hazel')) 
f_calls (func_g)[0] = ('strip', 'maroon') 

pprint(p) 

>>> 
{'0': [<function fff at 0x000000000312C048>, 
     [('strip', 'blue'), 
     ('strip', 'green'), 
     ('strip', 'red'), 
     ('strip', 'hazel')]], 
'1': [<function ggg at 0x0000000003165268>, 
     [('strip', 'maroon'), 
     ('strip', 'dk_red'), 
     ('strip', 'dk_blue')]]} 
>>> 

これはあまり一般的ではなく、クラスにカプセル化できるようです。私はこれはかなり一般的なことだと誰かの周りを検索する場合はもう少し洗練された何かを思い付いた。


可能改良は、それが少し読みやすくするためにcollections.namedtupleを使用することです。

Task = collections.namedtuple('Task', ['func', 'calls']) 
task_f = Task(fff, [('strip', 'blue'), ('strip', 'green'), ('strip', 'red')]) 
task_g = Task(ggg, [('strip', 'grey'), ('strip', 'dk_red'), ('strip', 'dk_blue')]) 

p = {'0': task_f, '1': task_g} 
options = '\n'.join('{} - {}'.format(item, task.func.__name__) for item,task in p.items()) 

which = input('Which?\n' + options + '\n') 

task = p[which] 
for args in task.calls: 
    task.func(*args) 


task_f.calls.append(('strip', 'candycane')) 
task_g.calls.remove(('strip', 'grey')) 
+0

ありがとうございます。これはうまくいくようです。しかし、関数が引数を持っていた場合や、同じ関数を別の引数で複数回呼びたい場合(上のコードのように)、どうすればうまくいくのだろうか。私の目標は、インデックスがユーザーによって入力されると、これは一連の機能を可能にする条件を満たすことです。 (また、コードのこのブロックは、メインステートメントに入る、または関数の宣言の前に?)ありがとう、私は非常に助けていただきありがとうございます。 –

+0

@ErikSvenBroberg、あなたの例のような条件文を使うのが最も簡単で簡単です。なぜあなたはそれを違ったものにしたいのですか? – wwii

+0

これは深遠な答えをありがとうございます。私は辞書を使うことを考えていましたが、これはうまくいきます。私は、「声明が最も簡単な解決策であれば」と同意する。しかし、あなたが提示したソリューションがどのように達成されたかを知りたいと思っていました。私があなたの貢献から多くを学んだように、ありがとうございました。 –

関連する問題