gui.DlgFromDict dictionary keys ordering difference in Py2 and Py3 version

The gui.DlgFromDict method (without sort_keys=False) in Psychopy2_Py2 renders the dialog box differently compared to Psychopy2_Py3.
Python2 renders the keys in arbitrary order while Python3 preserves the order.

This is due to the difference both Python versions deal with key order in the dictionary:
Quote from the Python2 docs:

CPython implementation detail: Keys and values are listed in an arbitrary order which is non-random, varies across Python implementations, and depends on the dictionary’s history of insertions and deletions.

This leads to 3 options in the Python2 version:

  • alphabetical ordering
  • random ordering
  • force ordering by setting sort_keys=True and add an alphabetical increment for each label (eg 1), 2), … )

This makes gui.DlgFromDict not very flexible. Therefor, a suggestion is to enable the user to fix the order by applying a key order in the dict (eventually with a flag to tell gui.dlgFromDict to use the user-supplied key order.

An example:

expInfo = {'participant': [99, 0]
           'type': [['healthy volunteer', 'patient'], 1],
           'step size': [0.05, 2]
           'factor': [10, 3]
           'white noise volume': [ 0.2 , 4]
           'log directory': ['logs', 5]
          }

The second value of each parameter encodes the order of the parameters.

Or we could just use an OrderedDict instead of a dict.

This is indeed a more elegant solution.

I don’t think dictionary ordering became a first-class language feature until Python 3.7 (for 3.5 – 3.6 it is still officially just an implementation detail for CPython). So using OrderedDict would ensure explicit ordering across both Python 2 and 3 as used by PsychoPy, and not break any existing user experiment code. I imagine that it would also effectively be a silent change within the PsychoPy code base itself.

Are you willing to test it out and submit a pull request?

I will do so when I return to the office

1 Like