Repository: psychopy/psychopy

Issue:
Cedrus buttonbox not working in Builder
I noticed today, playing with Cedrus component in the Builder (PsychoPy 2021.1.4), that it does not work, resulting in an error exit of the procedure.

After compiling the code, the problem seems to be a faulty generation of the buttonbox variable name:
```python
cedrusBox_0.0 = None
for n in range(10):  # doesn't always work first time!
    try:
        devices = pyxid.get_xid_devices()
        core.wait(0.1)
        cedrusBox_0.0 = devices[0.0]
        cedrusBox_0.0.clock = core.Clock()
        break  # found the device so can break the loop
    except Exception:
        pass
if not cedrusBox_0.0:
    logging.error('could not find a Cedrus device.')
    core.quit()
```

As You can see, the name has a float after underscore instead of an integer. Also index of the devices list is a float.

I narrowed the problem to [this line](https://github.com/psychopy/psychopy/blob/49cf52e7a420fae000f3b66b43ba9d7a33a804fb/psychopy/experiment/components/cedrusBox/__init__.py#L87) where function Params has attribute valType set to 'num', which changes it to a float.
The description of Params function recognizes this situation and it should preserve int type with the valType set to 'str'. 
However, as far as I can see, this is not implemented. After setting it to 'str' it just changes it to a string (also resulting in faulty code).

There is a placeholder for handling int variables, but currently it also changes the variable to a string.

I was not sure if this is a deliberate choice or a mistake, so either the Params function needs fixing or the generation of buttonbox variable name.
Hope this will help. I can also help with the fix, if needed.


Discussion:
Thanks @mkoculak 
That looks a bug introduced by a recent refactoring of parameter types to make them more flexible (e.g. allowing us to provide controls for each type of parameter). Yes, in this instance it needs to be either an int or pure code. We'll look into it
Ah yes that was something I missed when implementing the new param types - a simple fix, just needs to be `int` rather than `num`! Will reference this issue in the pull request.

The placeholder you found is actually just for the control drawn - `inputType = "spin"` will eventually make a control with up/down arrows for increasing/decreasing the value, but we couldn't get the spinner to work with our usual `$` notation in time for the release, so that's why it's currently just commented out and replaced with a string control. If `valType` is `"int"` then the value is converted to an integer regardless of what control is used, so `valType` is the important thing here.

Resolving patch:
diff --git a/psychopy/experiment/components/cedrusBox/__init__.py b/psychopy/experiment/components/cedrusBox/__init__.py
--- a/psychopy/experiment/components/cedrusBox/__init__.py
+++ b/psychopy/experiment/components/cedrusBox/__init__.py
@@ -82,7 +82,7 @@ def __init__(self, exp, parentName, name='buttonBox',
         msg = _translate('Device number, if you have multiple devices which'
                          ' one do you want (0, 1, 2...)')
         self.params['deviceNumber'] = Param(
-            deviceNumber, valType='num', inputType="spin", allowedTypes=[], categ='Hardware',
+            deviceNumber, valType='int', inputType="spin", allowedTypes=[], categ='Hardware',
             updates='constant', allowedUpdates=[],
             hint=msg,
             label=_localized['deviceNumber'])


Test patch: