2016-06-23 9 views
3

nehme ich diese einfache Funktion in Python haben:Wie ein Argument mögliche Werte abhängig von einem anderen Argument mit IPython Widgets haben?

def f(gender, name): 
    if gender == 'male': 
     return ranking_male(name) 
    else: 
     return ranking_female(name) 

wo gender zu ['male', 'female'] gehört während name zu ['Adam', 'John', 'Max', 'Frodo'] gehört (wenn gender ist male) oder ['Mary', 'Sarah', 'Arwen'] (sonst).

Ich möchte interact von ipywidgets auf diese Funktion f anwenden. Normalerweise würde man tun

from ipywidgets import interact 
interact(f, gender = ('male', 'female'), name = ('Adam', 'John', 'Max', 'Frodo')) 

Das Problem ist, dass die zulässigen Werte für name hängen nun von dem Wert für gender gewählt.

Ich habe versucht, es in der Dokumentation zu finden, konnte es aber nicht finden. Die einzige Sache, die ich denke, kann wichtig sein, ist Dies wird verwendet, um dynamische Benachrichtigungen von Merkmalsänderungen einzurichten.

Parameters 
    ---------- 
    handler : callable 
     A callable that is called when a trait changes. Its 
     signature should be ``handler(change)``, where ``change```is a 
     dictionary. The change dictionary at least holds a 'type' key. 
     * ``type``: the type of notification. 
     Other keys may be passed depending on the value of 'type'. In the 
     case where type is 'change', we also have the following keys: 
     * ``owner`` : the HasTraits instance 
     * ``old`` : the old value of the modified trait attribute 
     * ``new`` : the new value of the modified trait attribute 
     * ``name`` : the name of the modified trait attribute. 
    names : list, str, All 
     If names is All, the handler will apply to all traits. If a list 
     of str, handler will apply to all names in the list. If a 
     str, the handler will apply just to that name. 
    type : str, All (default: 'change') 
     The type of notification to filter by. If equal to All, then all 
     notifications are passed to the observe handler. 

Aber ich habe keine Ahnung, wie es zu tun ist und nicht zu interpretieren, worüber der Doc-String spricht. Jede Hilfe wird sehr geschätzt!

Antwort

1

zum Beispiel Sie brand und model von Auto mit und model hängt von brand.

d = {'Volkswagen' : ['Tiguan', 'Passat', 'Polo', 'Touareg', 'Jetta'], 'Chevrolet' : ['TAHOE', 'CAMARO'] } 

brand_widget = Dropdown(options=list(d.keys()), 
         value='Volkswagen', 
         description='Brand:', 
         style=style 
         ) 
model_widget = Dropdown(options=d['Volkswagen'], 
         value=None, 
         description='Model:', 
         style=style 
         ) 

def on_update_brand_widget(*args): 
    model_widget.options = d[brand_widget.value] 

brand_widget.observe(on_update_brand_widget, 'value') 
+0

sehr interessant! Vielen Dank! Kannst du erklären, was diese Linie macht? 'brand_widget.observe (on_update_brand_widget, 'value')' – gota

+0

Callback-Registrierung: http://ipywidgets.readthedocs.io/en/latest/examples/Widget%20Events.html#Traitlet-events – mrgloom

0

Ich habe verschachtelte Widgets verwendet, um dieses Problem zu lösen. Es wird funktionieren, aber es ist hässlich, teilweise, weil es kein gängiger Anwendungsfall in ipywidgets (see discussion) zu sein scheint.

Angesichts Ihrer Funktion f(gender, name) Sie einen Zwischen Wrapper definieren:

def f_intermediate_wrapper(gender): 
    if gender=="male": 
     possible_names = ['Adam', 'John', 'Max', 'Frodo'] 
    else: 
     possible_names = ['Mary', 'Sarah', 'Arwen'] 

    try: 
     f_intermediate_wrapper.name_widget.widget.close() 
    except AttributeError: 
     pass 

    f_intermediate_wrapper.name_widget = interact(f, 
                gender=widgets.fixed(gender), 
                name = possible_names) 

Der erste Teil stellt die möglichen Namen Optionen, um das Geschlecht gegeben, wie gewünscht.

Der zweite Teil schließt die name_widget aus Ihrer vorherigen Auswertung, falls sie existiert. Andernfalls wird jedes Mal, wenn Sie das Geschlecht ändern, die alte Namensliste mit dem falschen Geschlecht verlassen (see example).

Der dritte Teil erstellt ein Namens-Widget der möglichen Namen für dieses Geschlecht und speichert es irgendwo ausreichend statisch. (Ansonsten, wenn Sie das Geschlecht der alte Name Widget ändern wird außerhalb des Bereichs sein, und Sie werden in der Nähe der Lage sein, es nicht.)

Jetzt können Sie Ihr Geschlecht und Name-Widget erstellen:

gender_and_name_widget = interact(f_intermediate_wrapper, 
            gender = ["male", "female"]) 

und Sie das Ergebnis Ihrer f(gender, name) zugreifen können

gender_and_name_widget.name_widget.widget.result