| 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 | """ |
||
| 70 | def allocate_home_batteries_to_buildings(): |
||
| 71 | """ |
||
| 72 | Allocate home battery storage systems to buildings with pv rooftop systems |
||
| 73 | """ |
||
| 74 | # get constants |
||
| 75 | constants = config.datasets()["home_batteries"]["constants"] |
||
| 76 | scenarios = constants["scenarios"] |
||
| 77 | cbat_ppv_ratio = constants["cbat_ppv_ratio"] |
||
| 78 | rtol = constants["rtol"] |
||
| 79 | max_it = constants["max_it"] |
||
| 80 | cbat_pbat_ratio = get_cbat_pbat_ratio() |
||
| 81 | |||
| 82 | sources = config.datasets()["home_batteries"]["sources"] |
||
| 83 | |||
| 84 | df_list = [] |
||
| 85 | |||
| 86 | for scenario in scenarios: |
||
| 87 | # get home battery capacity per mv grid id |
||
| 88 | sql = f""" |
||
| 89 | SELECT el_capacity as p_nom_min, bus_id as bus FROM |
||
| 90 | {sources["storage"]["schema"]} |
||
| 91 | .{sources["storage"]["table"]} |
||
| 92 | WHERE carrier = 'home_battery' |
||
| 93 | AND scenario = '{scenario}'; |
||
| 94 | """ |
||
| 95 | |||
| 96 | home_batteries_df = db.select_dataframe(sql) |
||
| 97 | |||
| 98 | home_batteries_df = home_batteries_df.assign( |
||
| 99 | bat_cap=home_batteries_df.p_nom_min * cbat_pbat_ratio |
||
| 100 | ) |
||
| 101 | |||
| 102 | sql = """ |
||
| 103 | SELECT building_id, capacity |
||
| 104 | FROM supply.egon_power_plants_pv_roof_building |
||
| 105 | WHERE scenario = '{}' |
||
| 106 | AND bus_id = {} |
||
| 107 | """ |
||
| 108 | |||
| 109 | for bus_id, bat_cap in home_batteries_df[ |
||
| 110 | ["bus", "bat_cap"] |
||
| 111 | ].itertuples(index=False): |
||
| 112 | pv_df = db.select_dataframe(sql.format(scenario, bus_id)) |
||
| 113 | |||
| 114 | grid_ratio = bat_cap / pv_df.capacity.sum() |
||
| 115 | |||
| 116 | if grid_ratio > cbat_ppv_ratio: |
||
| 117 | logger.warning( |
||
| 118 | f"In Grid {bus_id} and scenario {scenario}, the ratio of " |
||
| 119 | f"home storage capacity to pv rooftop capacity is above 1" |
||
| 120 | f" ({grid_ratio: g}). The storage capacity of pv rooftop " |
||
| 121 | f"systems will be high." |
||
| 122 | ) |
||
| 123 | |||
| 124 | if grid_ratio < cbat_ppv_ratio: |
||
| 125 | random_state = RandomState(seed=bus_id) |
||
| 126 | |||
| 127 | n = max(int(len(pv_df) * grid_ratio), 1) |
||
| 128 | |||
| 129 | best_df = pv_df.sample(n=n, random_state=random_state) |
||
| 130 | |||
| 131 | i = 0 |
||
| 132 | |||
| 133 | while ( |
||
| 134 | not np.isclose(best_df.capacity.sum(), bat_cap, rtol=rtol) |
||
| 135 | and i < max_it |
||
| 136 | ): |
||
| 137 | sample_df = pv_df.sample(n=n, random_state=random_state) |
||
| 138 | |||
| 139 | if abs(best_df.capacity.sum() - bat_cap) > abs( |
||
| 140 | sample_df.capacity.sum() - bat_cap |
||
| 141 | ): |
||
| 142 | best_df = sample_df.copy() |
||
| 143 | |||
| 144 | i += 1 |
||
| 145 | |||
| 146 | if sample_df.capacity.sum() < bat_cap: |
||
| 147 | n = min(n + 1, len(pv_df)) |
||
| 148 | else: |
||
| 149 | n = max(n - 1, 1) |
||
| 150 | |||
| 151 | if not np.isclose(best_df.capacity.sum(), bat_cap, rtol=rtol): |
||
| 152 | logger.warning( |
||
| 153 | f"No suitable generators could be found in Grid " |
||
| 154 | f"{bus_id} and scenario {scenario} to achieve the " |
||
| 155 | f"desired ratio between battery capacity and pv " |
||
| 156 | f"rooftop capacity. The ratio will be " |
||
| 157 | f"{bat_cap / best_df.capacity.sum()}." |
||
| 158 | ) |
||
| 159 | |||
| 160 | pv_df = best_df.copy() |
||
| 161 | |||
| 162 | bat_df = pv_df.drop(columns=["capacity"]).assign( |
||
| 163 | capacity=pv_df.capacity / pv_df.capacity.sum() * bat_cap, |
||
| 164 | p_nom=pv_df.capacity |
||
| 165 | / pv_df.capacity.sum() |
||
| 166 | * bat_cap |
||
| 167 | / cbat_pbat_ratio, |
||
| 168 | scenario=scenario, |
||
| 169 | bus_id=bus_id, |
||
| 170 | ) |
||
| 171 | |||
| 172 | df_list.append(bat_df) |
||
| 173 | |||
| 174 | create_table(pd.concat(df_list, ignore_index=True)) |
||
| 175 | |||
| 205 |