<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def cycles(cls, **kwargs):
 """ Classmethod for convienence in returning both the sunrise and sunset based on a location and date. Always calculates the sunrise and sunset on the given date, no matter the time passed into the function in the datetime object. Parameters: loc = Location4D (object) OR point = Shapely point (object) time = datetime in UTC (object) OR lat = latitude (float) lon = longitude (float) time = datetime in UTC (object) Returns: { 'sunrise': datetime in UTC, 'sunset': datetime in UTC } Sources: http://williams.best.vwh.net/sunrise_sunset_example.htm """

        if "loc" not in kwargs:
            if "point" not in kwargs:
                if "lat" not in kwargs or "lon" not in kwargs:
                    raise ValueError("You must supply some form of lat/lon coordinates")
                else:
                    lat = kwargs.get("lat")
                    lon = kwargs.get("lon")
            else:
                lat = kwargs.get("point").y
                lon = kwargs.get("point").x
            if "time" not in kwargs:
                raise ValueError("You must supply a datetime object")
            else:
                time = kwargs.get("time")
        else:
            lat = kwargs.get("loc").latitude
            lon = kwargs.get("loc").longitude
            time = kwargs.get("loc").time

        # Convert time to UTC.  Save passed in timezone to return later.
        if time.tzinfo is None:
            time = time.replace(tzinfo=pytz.utc)
            original_zone = pytz.utc
        else:
            original_zone = time.tzinfo

        local_jd = time.timetuple().tm_yday
        utc_jd = time.astimezone(pytz.utc).timetuple().tm_yday

        # We ALWAYS want to return the sunrise/sunset for the day that was passed
        # in (with timezone accounted for), regardless of what the UTC day is.  Modify
        # the UTC julian day here if need be.
        comp = cmp(utc_jd, local_jd)
        if comp == 1:
            utc_jd -= 1
        elif comp == -1:
            utc_jd += 1

        time = time.replace(hour=0, minute=0, second=0, microsecond=0)

        rising_h, rising_m = cls._calc(jd=utc_jd, lat=lat, lon=lon, stage=cls.RISING)
        setting_h, setting_m = cls._calc(jd=utc_jd, lat=lat, lon=lon, stage=cls.SETTING)

        # _calc returns UTC hours and minutes, so assume time is in UTC for a few lines...
        rising = time.replace(tzinfo=pytz.utc) + timedelta(hours=rising_h, minutes=rising_m)
        setting = time.replace(tzinfo=pytz.utc) + timedelta(hours=setting_h, minutes=setting_m)
        # LOOK: We may be adding 24 hours to the setting time.  Why?
        if setting < rising:
            setting = setting + timedelta(hours=24)

        rising = rising.astimezone(original_zone)
        setting = setting.astimezone(original_zone)

        return { cls.RISING : rising, cls.SETTING : setting}