def parse_number(val):
    """
    Tries to parse number from any value

    Valid values are:

    - any float / integer
    - 123.45
    - 123 456.899
    - 123,456.899
    - 123 456,899
    - 123.456,82

    Args:
        val: value to parse
    Returns:
        val as-is if val is integer, float or None, otherwise parsed value
    Raises:
        ValueError: if input val can not be parsed
    """
    if isinstance(val, int) or isinstance(val, float) or val is None:
        return val
    if not isinstance(val, str):
        raise ValueError(val)
    else:
        val = val.strip()
    try:
        return float(val)
    except:
        pass
    spaces = val.count(' ')
    commas = val.count(',')
    dots = val.count('.')
    if spaces > 0:
        return float(val.replace(' ', '').replace(',', '.'))
    elif commas > 1:
        return float(val.replace(',', ''))
    elif commas == 1 and commas <= dots:
        if val.find(',') < val.find('.'):
            return float(val.replace(',', ''))
        else:
            return float(val.replace('.', '').replace(',', '.'))
    else:
        return float(val.replace(',', '.'))