robertlugg / easygui

easygui for Python
http://easygui.readthedocs.org/en/master/
BSD 3-Clause "New" or "Revised" License
455 stars 114 forks source link

Choices added to choicebox when less than 2 choices given #149

Open spyoungtech opened 6 years ago

spyoungtech commented 6 years ago

If less than 2 choices are given, the function to_list_of_str in choice_box.py will add the additional choices 'Add more choices'....

        while len(choices) < 2:
            choices.append("Add more choices")

Currently, the problem I have is that this erroneous choice is inserted when 1 or 0 choices are given to the user, which is OK in the context of my application. When I remove those lines, the application works as expected.

This is potentially disruptive to application logic. It's not clear why it is useful for easygui to do this. My suggestion is that this logic should be removed. Perhaps replaced with a UserWarning if needed.

zadacka commented 6 years ago

@spyoungtech - I'm intrigued: what is the application for a choice box with 0 or 1 choices?

I'd naively consider having a choice-box with less than 2 choices to be misconfigured (I could be wrong) and would think that raising an error would also be a valid response to this. Some context of the use-case would be useful to understand why the current default behaviour (or something even more strict) would be undesirable...

spyoungtech commented 5 years ago

It makes sense to me that, if there are no choices, raising an error would be a valid response. The main issue I take with the default behavior is when there is just 1 choice.

Consider the following example of a simple CRUD application for users in a company. Here, suppose we have a dictionary, user_dict whose keys are usernames and the values are dictionaries of properties for that user.

users = list(self.user_dict)
if not users:
    raise ValueError('There are no users. You must add some users first.')
selected_username = eg.choice_box('Select a thing', choices=users)
if not selected_username:
    # dialog was closed without selecting a choice
    return
user_properties = self.user_dict[selected_username]
# do something with user properties

Here, the idea is that the possible choices must be keys in the dictionary. However, if the dictionary has just one key, easygui will end up inserting 'Add more choices' as a choice in the GUI that is not in the dictionary. The user would see the choices like

  • SomeUser
  • Add more choices

Besides confusion for the user, this could lead to things like an unexpected KeyError in this case, or perhaps even more insidious bugs in more complex cases. Ultimately, I think it's undesirable for easygui to insert choices like this.

At first glance, it perhaps seems silly to provide a choice box that only has one choice. However, I think it's useful because the dialog infers to an end-user that there could be more than one choice, say, if more users existed.

Hope that provides some appropriate context.

My suggestion would be that the the lines

        while len(choices) < 2:
            choices.append("Add more choices")

could be replaced with something like

        if not choices:
            raise ValueError('Choice box choices require at least one choice')
zadacka commented 5 years ago

That is a clear use-case, and I'd agree that it shows a scenario where having a choice box with a single choice could be desired. Nice example, kudos!