Get value from dictionary by selecting key in Commandline

Hi guys,

Slowly digging myself into python whenever I have some time, but got stuck on this one.

So I’m making a script where I would like to receive the value from a dictionary by selecting the key in the command menu.
This is my script and I’m struggling with 3 things (see below)

import Rhino

Dict = {
"Option1" : 111,
"Option2" : 214,
"Option3" : 356,
"Option4" : 482,
"Option5" : 514
}

def GetInputFromDict():
    
    gn = Rhino.Input.Custom.GetNumber()
    gn.SetCommandPrompt("Choose Number")
    
    listValues = []
    for key,val in Dict.items():
        listValues.append(key)
    listIndex = 0
    
    opList = gn.AddOptionList("Option", listValues, listIndex)
    
    gn.Get()
    
    Number = (""" *Here I would like to get the selected value from the Optionlist* """)
    FinalOption = (""" *Here I would like to get the selected key from the Optionlist* """)
    
    print "You chose option" + str(FinalOption) + " which contains the number" + str(Number) + "."
    
    
GetInputFromDict()
  1. Why do I not get the same order as I have in my dictionary in my menu? image

  2. How do I make sure that after selecting one of the options in the command line I go back to this first menu but with the new option the user selected. So that it’s possible to go back into the options and choose something else.
    image

  3. How do I retrieve the value of the selected key from the library to be able to print the correct output

  1. Dictionaries do not store keys in any particular order. For that you need a list or a set both of which can be sorted.
    3.Dict[key] gives you the value. Not sure if this what you are asking.

Regards,
Terry.

Hi Terry, thanks for your reply.

Right. So then I’ll need to solve it in a different way, by retrieving the index of the chosen item in the list and then using that index to get the item from another list.

Not really. I made a commandline option where one can select from the values of that dictionary by clicking on them. What I would like to do is retrieve the item that has been clicked on, but I don’t know how I can retrieve that, since it depends on the users’ input.

Hi Siemen,

I took a stab at it, (and made it a little more pythonic on the way)
Ley me know if you have any questions:

import Rhino

def GetInputFromDict(my_dict):
    
    gn = Rhino.Input.Custom.GetNumber()
    gn.SetCommandPrompt("Choose Number")
    
    list_keys = my_dict.keys()
    list_keys.sort()

    list_index = 0   
    opList = gn.AddOptionList("Option", list_keys, list_index)
    
    gn.Get()
    
    choice_index = gn.Option().CurrentListOptionIndex
    
    key = list_keys[choice_index]
    value = my_dict[key]
    
    #formatted the string with .format
    print 'You chose option {} which contains the number {}'.format(key,value)
    

my_dict = {
"Option1" : 111,
"Option2" : 214,
"Option3" : 356,
"Option4" : 482,
"Option5" : 514
}


GetInputFromDict(my_dict)

-Willem

1 Like

Looks very promising. I’m gonna have a proper look at this later after production.

1 Like

This looks perfect again Willem, genius. How do you find out about things like “currentlistoptionindex”? Do you do that using that debugging method with going inside the function? I tried doing that but got stuck somehow. I need to go over you explanation again.

One last question. How would I go about allowing users to enter custom values as well with this script? So instead of choosing one of the options which refers to a number, they enter their own number which overrides value before printing it.

The debugger indeed does not go beyond the top-level of .NET/RhinoCommon objects.
instead it did:

On the SDK-page I searched for AddOptionList from the resukts, the second link resulted in a page with examples (scroll down for python).
Somewhere in that example was the CurrentListOptionIndex

I suppose the more you search for this the more you know how to find what you are looking for.
Also the Rhino.Input stuff was a blax box for me and slowly it became greyish, still I don’t use it much as I mainly write scripts without user intercations.

I’d have to find that out myself as well. I believe you can create nested options, so you initially present the user with 2 options: from a list or ‘custom’.

Or you make 1 item in the optionslist 'Custom" and if they choose that, invoke a UI to enter the number.

I dug up a script I saved for later reference, maybe it is of use for you:

import Rhino

def GetRadius(radius):
    radius_mode = True
    
    gn = Rhino.Input.Custom.GetNumber()
    gn.SetLowerLimit(0.0, True)
    gn.AcceptNothing(True)
    
    while True:
        gn.ClearCommandOptions()

        if radius_mode:
            gn.SetCommandPrompt("Radius")
            gn.SetDefaultNumber(radius)
            gn.AddOption("Diameter")
        else:
            gn.SetCommandPrompt("Diameter")
            gn.SetDefaultNumber(radius * 2.0)
            gn.AddOption("Radius")
        
        res = gn.Get()

        if res == Rhino.Input.GetResult.Option:
            radius_mode = not radius_mode
            continue
        elif res == Rhino.Input.GetResult.Nothing:
            return radius
        elif res != Rhino.Input.GetResult.Number:
            return Rhino.RhinoMath.UnsetValue
        
        value = gn.Number()
        if radius_mode:
            return value
        return value * 0.5


radius = GetRadius(50.0)
if Rhino.RhinoMath.IsValidDouble(radius):
    print radius

-Willem

1 Like

Thanks Willem! I’ll look into this