| Conditions | 10 | 
| Total Lines | 105 | 
| Code Lines | 53 | 
| Lines | 0 | 
| Ratio | 0 % | 
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like data.datasets.storages.home_batteries.allocate_home_batteries_to_buildings() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
| 1 | from loguru import logger  | 
            ||
| 36 | def allocate_home_batteries_to_buildings():  | 
            ||
| 37 | """  | 
            ||
| 38 | Allocate home battery storage systems to buildings with pv rooftop systems  | 
            ||
| 39 | """  | 
            ||
| 40 | # get constants  | 
            ||
| 41 | constants = config.datasets()["home_batteries"]["constants"]  | 
            ||
| 42 | scenarios = constants["scenarios"]  | 
            ||
| 43 | cbat_ppv_ratio = constants["cbat_ppv_ratio"]  | 
            ||
| 44 | rtol = constants["rtol"]  | 
            ||
| 45 | max_it = constants["max_it"]  | 
            ||
| 46 | cbat_pbat_ratio = get_cbat_pbat_ratio()  | 
            ||
| 47 | |||
| 48 | sources = config.datasets()["home_batteries"]["sources"]  | 
            ||
| 49 | |||
| 50 | df_list = []  | 
            ||
| 51 | |||
| 52 | for scenario in scenarios:  | 
            ||
| 53 | # get home battery capacity per mv grid id  | 
            ||
| 54 | sql = f"""  | 
            ||
| 55 | SELECT el_capacity as p_nom_min, bus_id as bus FROM  | 
            ||
| 56 |         {sources["storage"]["schema"]} | 
            ||
| 57 |         .{sources["storage"]["table"]} | 
            ||
| 58 | WHERE carrier = 'home_battery'  | 
            ||
| 59 |         AND scenario = '{scenario}'; | 
            ||
| 60 | """  | 
            ||
| 61 | |||
| 62 | home_batteries_df = db.select_dataframe(sql)  | 
            ||
| 63 | |||
| 64 | home_batteries_df = home_batteries_df.assign(  | 
            ||
| 65 | bat_cap=home_batteries_df.p_nom_min * cbat_pbat_ratio  | 
            ||
| 66 | )  | 
            ||
| 67 | |||
| 68 | sql = """  | 
            ||
| 69 | SELECT building_id, capacity  | 
            ||
| 70 | FROM supply.egon_power_plants_pv_roof_building  | 
            ||
| 71 |         WHERE scenario = '{}' | 
            ||
| 72 |         AND bus_id = {} | 
            ||
| 73 | """  | 
            ||
| 74 | |||
| 75 | for bus_id, bat_cap in home_batteries_df[  | 
            ||
| 76 | ["bus", "bat_cap"]  | 
            ||
| 77 | ].itertuples(index=False):  | 
            ||
| 78 | pv_df = db.select_dataframe(sql.format(scenario, bus_id))  | 
            ||
| 79 | |||
| 80 | grid_ratio = bat_cap / pv_df.capacity.sum()  | 
            ||
| 81 | |||
| 82 | if grid_ratio > cbat_ppv_ratio:  | 
            ||
| 83 | logger.warning(  | 
            ||
| 84 |                     f"In Grid {bus_id} and scenario {scenario}, the ratio of " | 
            ||
| 85 | f"home storage capacity to pv rooftop capacity is above 1"  | 
            ||
| 86 |                     f" ({grid_ratio: g}). The storage capacity of pv rooftop " | 
            ||
| 87 | f"systems will be high."  | 
            ||
| 88 | )  | 
            ||
| 89 | |||
| 90 | if grid_ratio < cbat_ppv_ratio:  | 
            ||
| 91 | random_state = RandomState(seed=bus_id)  | 
            ||
| 92 | |||
| 93 | n = max(int(len(pv_df) * grid_ratio), 1)  | 
            ||
| 94 | |||
| 95 | best_df = pv_df.sample(n=n, random_state=random_state)  | 
            ||
| 96 | |||
| 97 | i = 0  | 
            ||
| 98 | |||
| 99 | while (  | 
            ||
| 100 | not np.isclose(best_df.capacity.sum(), bat_cap, rtol=rtol)  | 
            ||
| 101 | and i < max_it  | 
            ||
| 102 | ):  | 
            ||
| 103 | sample_df = pv_df.sample(n=n, random_state=random_state)  | 
            ||
| 104 | |||
| 105 | if abs(best_df.capacity.sum() - bat_cap) > abs(  | 
            ||
| 106 | sample_df.capacity.sum() - bat_cap  | 
            ||
| 107 | ):  | 
            ||
| 108 | best_df = sample_df.copy()  | 
            ||
| 109 | |||
| 110 | i += 1  | 
            ||
| 111 | |||
| 112 | if sample_df.capacity.sum() < bat_cap:  | 
            ||
| 113 | n = min(n + 1, len(pv_df))  | 
            ||
| 114 | else:  | 
            ||
| 115 | n = max(n - 1, 1)  | 
            ||
| 116 | |||
| 117 | if not np.isclose(best_df.capacity.sum(), bat_cap, rtol=rtol):  | 
            ||
| 118 | logger.warning(  | 
            ||
| 119 | f"No suitable generators could be found in Grid "  | 
            ||
| 120 |                         f"{bus_id} and scenario {scenario} to achieve the " | 
            ||
| 121 | f"desired ratio between battery capacity and pv "  | 
            ||
| 122 | f"rooftop capacity. The ratio will be "  | 
            ||
| 123 |                         f"{bat_cap / best_df.capacity.sum()}." | 
            ||
| 124 | )  | 
            ||
| 125 | |||
| 126 | pv_df = best_df.copy()  | 
            ||
| 127 | |||
| 128 | bat_df = pv_df.drop(columns=["capacity"]).assign(  | 
            ||
| 129 | capacity=pv_df.capacity / pv_df.capacity.sum() * bat_cap,  | 
            ||
| 130 | p_nom=pv_df.capacity  | 
            ||
| 131 | / pv_df.capacity.sum()  | 
            ||
| 132 | * bat_cap  | 
            ||
| 133 | / cbat_pbat_ratio,  | 
            ||
| 134 | scenario=scenario,  | 
            ||
| 135 | bus_id=bus_id,  | 
            ||
| 136 | )  | 
            ||
| 137 | |||
| 138 | df_list.append(bat_df)  | 
            ||
| 139 | |||
| 140 | create_table(pd.concat(df_list, ignore_index=True))  | 
            ||
| 141 | |||
| 171 |