<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def directional_irradiance(self, altitude=90, azimuth=180, ground_reflectance=0.2, isotrophic=True):
 """Returns the irradiance components facing a given altitude and azimuth. This method computes unobstructed solar flux facing a given altitude and azimuth. The default is set to return the golbal horizontal irradiance, assuming an altitude facing straight up (90 degrees). Args: altitude: A number between -90 and 90 that represents the altitude at which irradiance is being evaluated in degrees. azimuth: A number between 0 and 360 that represents the azimuth at wich irradiance is being evaluated in degrees. ground_reflectance: A number between 0 and 1 that represents the reflectance of the ground. Default is set to 0.2. Some common ground reflectances are: urban: 0.18 grass: 0.20 fresh grass: 0.26 soil: 0.17 sand: 0.40 snow: 0.65 fresh_snow: 0.75 asphalt: 0.12 concrete: 0.30 sea: 0.06 isotrophic: A boolean value that sets whether an istotrophic sky is used (as opposed to an anisotrophic sky). An isotrophic sky assummes an even distribution of diffuse irradiance across the sky while an anisotrophic sky places more diffuse irradiance near the solar disc. Default is set to True for isotrophic Returns: total_irradiance: A data collection of total solar irradiance. direct_irradiance: A data collection of direct solar irradiance. diffuse_irradiance: A data collection of diffuse sky solar irradiance. reflected_irradiance: A data collection of ground reflected solar irradiance. """

        # function to convert polar coordinates to xyz.
        def pol2cart(phi, theta):
            mult = math.cos(theta)
            x = math.sin(phi) * mult
            y = math.cos(phi) * mult
            z = math.sin(theta)
            return Vector3(x, y, z)

        # convert the altitude and azimuth to a normal vector
        normal = pol2cart(math.radians(azimuth), math.radians(altitude))

        # create sunpath and get altitude at every timestep of the year
        direct_irr, diffuse_irr, reflected_irr, total_irr = [], [], [], []
        sp = Sunpath.from_location(self.location)
        sp.is_leap_year = self.is_leap_year
        for dt, dnr, dhr in zip(self.datetimes, self.direct_normal_irradiance,
                                self.diffuse_horizontal_irradiance):
            sun = sp.calculate_sun_from_date_time(dt)
            sun_vec = pol2cart(math.radians(sun.azimuth),
                               math.radians(sun.altitude))
            vec_angle = sun_vec.angle(normal)

            # direct irradiance on surface
            srf_dir = 0
            if sun.altitude > 0 and vec_angle < math.pi / 2:
                srf_dir = dnr * math.cos(vec_angle)

            # diffuse irradiance on surface
            if isotrophic is True:
                srf_dif = dhr * ((math.sin(math.radians(altitude)) / 2) + 0.5)
            else:
                y = max(0.45, 0.55 + (0.437 * math.cos(vec_angle)) + 0.313 *
                        math.cos(vec_angle) * 0.313 * math.cos(vec_angle))
                srf_dif = self.dhr * (y * (
                    math.sin(math.radians(abs(90 - altitude)))) +
                    math.cos(math.radians(abs(90 - altitude))))

            # reflected irradiance on surface.
            e_glob = dhr + dnr * math.cos(math.radians(90 - sun.altitude))
            srf_ref = e_glob * ground_reflectance * (0.5 - (math.sin(
                math.radians(altitude)) / 2))

            # add it all together
            direct_irr.append(srf_dir)
            diffuse_irr.append(srf_dif)
            reflected_irr.append(srf_ref)
            total_irr.append(srf_dir + srf_dif + srf_ref)

        # create the headers
        a_per = AnalysisPeriod(timestep=self.timestep, is_leap_year=self.is_leap_year)
        direct_hea = diffuse_hea = reflected_hea = total_hea = \
            Header(Irradiance(), 'W/m2', a_per, self.metadata)

        # create the data collections
        direct_irradiance = HourlyContinuousCollection(direct_hea, direct_irr)
        diffuse_irradiance = HourlyContinuousCollection(diffuse_hea, diffuse_irr)
        reflected_irradiance = HourlyContinuousCollection(reflected_hea, reflected_irr)
        total_irradiance = HourlyContinuousCollection(total_hea, total_irr)

        return total_irradiance, direct_irradiance, \
            diffuse_irradiance, reflected_irradiance