<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def get_critical_line_loading(grid):
 """ Assign line loading to each branch determined by peak load and peak generation of descendant branches The attribute `s_res` is a list of two elements 1. apparent power in load case 2. apparent power in feed-in case Parameters grid : ding0.core.network.grids.LVGridDing0 Ding0 LV grid object Returns ------- :any:`list` List of critical branches incl. its line loading :any:`list` List of critical stations incl. its transformer loading """

    cos_phi_load = cfg_ding0.get('assumptions', 'cos_phi_load')
    cos_phi_feedin = cfg_ding0.get('assumptions', 'cos_phi_gen')
    lf_trafo_load = cfg_ding0.get('assumptions',
                                  "load_factor_lv_trans_lc_normal")
    lf_trafo_gen = cfg_ding0.get('assumptions',
                                  "load_factor_lv_trans_fc_normal")

    critical_branches = []
    critical_stations = []

    # Convert grid to a tree (is a directed graph)
    # based on this tree, descendants of each node are accessible
    station = grid._station

    tree = nx.dfs_tree(grid._graph, station)

    for node in tree.nodes():

        # list of descendant nodes including the node itself
        descendants = list(nx.descendants(tree, node))
        descendants.append(node)

        if isinstance(node, LVStationDing0):
            # determine cumulative peak load at node and assign to branch
            peak_load, peak_gen = peak_load_generation_at_node(descendants)

            if grid.id_db == 61107:
                if isinstance(node, LVStationDing0):
                    print(node)
            # get trafos cumulative apparent power
            s_max_trafos = sum([_.s_max_a for _ in node._transformers])

            # compare with load and generation connected to
            if (((peak_load / cos_phi_load) > s_max_trafos * lf_trafo_load) or
                    ((peak_gen / cos_phi_feedin) > s_max_trafos * lf_trafo_gen)):
                critical_stations.append(
                    {'station': node,
                     's_max': [
                         peak_load / cos_phi_load,
                         peak_gen / cos_phi_feedin]})

        else:
            # preceeding node of node
            predecessors = list(tree.predecessors(node))

            # a non-meshed grid topology returns a list with only 1 item
            predecessor = predecessors[0]

            # get preceeding
            branches = grid.graph_branches_from_node(node)
            preceeding_branch = [branch for branch in branches
                                 if branch[0] is predecessor][0]

            # determine cumulative peak load at node and assign to branch
            peak_load, peak_gen = peak_load_generation_at_node(descendants)

            s_max_th = 3 ** 0.5 * preceeding_branch[1]['branch'].type['U_n'] * \
                       preceeding_branch[1]['branch'].type['I_max_th'] / 1e3

            if (((peak_load / cos_phi_load) > s_max_th) or
                    ((peak_gen / cos_phi_feedin) > s_max_th)):
                critical_branches.append(
                    {'branch': preceeding_branch[1]['branch'],
                     's_max': [
                         peak_load / cos_phi_load,
                         peak_gen / cos_phi_feedin]})

    return critical_branches, critical_stations