<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def ip(addr, version=None):
 """ Converts a raw string to a valid IP address. Optional version argument will detect that \ object matches specified version. Motivation: the groups of the IP addreses may contain leading zeros. IPv6 addresses can \ contain sometimes uppercase characters. E.g.: 2001:0dB8:85a3:0000:0000:8A2e:0370:7334 has \ the same logical value as 2001:db8:85a3::8a2e:370:7334. However, their values as strings are \ not the same. :param raw: the raw string containing the value of the IP Address :param version: (optional) insist on a specific IP address version. :type version: int. :return: a string containing the IP Address in a standard format (no leading zeros, \ zeros-grouping, lowercase) Example: .. code-block:: python u'2001:db8:85a3::8a2e:370:7334' """

    addr_obj = IPAddress(addr)
    if version and addr_obj.version != version:
        raise ValueError("{} is not an ipv{} address".format(addr, version))
    return py23_compat.text_type(addr_obj)