<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def version(serial=None):
 """ Returns version information for MicroPython running on the connected device. If such information is not available or the device is not running MicroPython, raise a ValueError. If any other exception is thrown, the device was running MicroPython but there was a problem parsing the output. """

    try:
        out, err = execute([
            'import os',
            'print(os.uname())',
        ], serial)
        if err:
            raise ValueError(clean_error(err))
    except ValueError:
        # Re-raise any errors from stderr raised in the try block.
        raise
    except Exception:
        # Raise a value error to indicate unable to find something on the
        # microbit that will return parseable information about the version.
        # It doesn't matter what the error is, we just need to indicate a
        # failure with the expected ValueError exception.
        raise ValueError()
    raw = out.decode('utf-8').strip()
    raw = raw[1:-1]
    items = raw.split(', ')
    result = {}
    for item in items:
        key, value = item.split('=')
        result[key] = value[1:-1]
    return result