forked from gem-spaas/powerplant-coding-challenge
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpowerplant_payload.py
126 lines (104 loc) · 5.99 KB
/
powerplant_payload.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import json
powerplant_types = ['gasfired', 'turbojet', 'windturbine']
fuel_associations = {"gasfired": "gas(euro/MWh)", "turbojet": 'kerosine(euro/MWh)'}
co2_production_rate = 0.3 # t/MWh
def calculate_powerplant_price(powerplants, prices):
for powerplant in powerplants:
if powerplant['type'] == 'windturbine':
powerplant['price(eur/MWh)'] = 0
powerplant['production_cost(euro)'] = 0
powerplant['production(MWh)'] = round(powerplant['pmax'] * prices['wind(%)'] / 100, 2)
else:
fuel_type = fuel_associations[powerplant['type']]
powerplant_fuel_prices = prices[fuel_type]
powerplant['price(eur/MWh)'] = powerplant_fuel_prices / powerplant['efficiency']
powerplant['production(MWh)'] = 0
def calculate_powerplant_price_with_co2(powerplants, prices):
for powerplant in powerplants:
if powerplant['type'] == 'windturbine':
powerplant['price(eur/MWh)'] = 0
powerplant['production(MWh)'] = round(powerplant['pmax'] * prices['wind(%)'] / 100, 2)
else:
fuel_type = fuel_associations[powerplant['type']]
powerplant_fuel_prices = prices[fuel_type]
powerplant['price(eur/MWh)'] = powerplant_fuel_prices / powerplant['efficiency'] + co2_production_rate * prices['co2(euro/ton)']
powerplant['production(MWh)'] = 0
def sort_sources(powerplants):
sorted_powerplants = sorted(powerplants, key=lambda powerplant: powerplant['price(eur/MWh)'])
return sorted_powerplants
def allocation_of_resources(powerplants, load):
remaining_load = load
for index, powerplant in enumerate(powerplants):
if remaining_load > powerplant['pmax']:
# there is more load to cover, maximal production is needed
if powerplant['type'] == 'windturbine':
remaining_load -= powerplant['production(MWh)']
else:
powerplant['production(MWh)'] = powerplant['pmax']
powerplant['production_cost(euro)'] = powerplant['production(MWh)'] * powerplant['price(eur/MWh)']
remaining_load -= powerplant['production(MWh)']
elif 0 < remaining_load < powerplant['pmin']:
# minimal production of the powerplant is more than requiered load, so lets borrow production from previous sources
production_to_borrow = powerplant['pmin'] - remaining_load
for index_to_borrow in range(index - 1, -1, -1):
if powerplants[index_to_borrow]['type'] != 'windturbine':
if powerplants[index_to_borrow]['production(MWh)'] - production_to_borrow >= powerplants[index_to_borrow]['pmin']:
powerplants[index_to_borrow]['production(MWh)'] -= production_to_borrow
production_to_borrow = 0
powerplants[index_to_borrow]['production_cost(euro)'] = powerplants[index_to_borrow]['production(MWh)'] * powerplants[index_to_borrow]['price(eur/MWh)']
break
else:
if powerplants[index_to_borrow]['production(MWh)'] != 0:
powerplants[index_to_borrow]['production(MWh)'] = powerplants[index_to_borrow]['pmin']
production_to_borrow -= powerplants[index_to_borrow]['production(MWh)'] - powerplants[index_to_borrow]['pmin']
powerplants[index_to_borrow]['production_cost(euro)'] = powerplants[index_to_borrow]['production(MWh)'] * powerplants[index_to_borrow]['price(eur/MWh)']
if production_to_borrow != 0:
# unable to borrow enough power from settled powerplats
powerplant['production(MWh)'] = 0
powerplant['production_cost(euro)'] = 0
else:
remaining_load = powerplant['pmin']
powerplant['production(MWh)'] = remaining_load
powerplant['production_cost(euro)'] = powerplant['production(MWh)'] * powerplant['price(eur/MWh)']
remaining_load -= powerplant['production(MWh)']
elif powerplant['pmin'] <= remaining_load <= powerplant['pmax']:
# the powerplant is final that is used to supply load
#if powerplant['type'] != 'windturbine':
powerplant['production(MWh)'] = remaining_load
powerplant['production_cost(euro)'] = powerplant['production(MWh)'] * powerplant['price(eur/MWh)']
remaining_load -= powerplant['production(MWh)']
else:
powerplant['production(MWh)'] = 0
powerplant['production_cost(euro)'] = 0
continue
if remaining_load != 0:
print(f"Unable to supply enough production to meet requirements")
def produce_output(powerplants, desired_load):
output_list = []
output_production = 0
cost_of_production = 0
for powerplant in powerplants:
output_dictionary = {'name': powerplant['name'], 'p': round(powerplant['production(MWh)'], 1)}
output_list.append(output_dictionary)
output_production += powerplant['production(MWh)']
cost_of_production += powerplant['production_cost(euro)']
if round(output_production, 1) != round(desired_load, 1):
print(f"Production does not match load {desired_load}, delivered load {output_production}")
print(f"{output_list}")
print(f"Output production {output_production}(MWh) at cost {cost_of_production} euro")
return output_list
def processing_output(input):
#print(f"{input}")
load = input["load"]
fuels = input["fuels"]
powerplants = input["powerplants"]
wind_effectivity = fuels['wind(%)']
gas_price = fuels['gas(euro/MWh)']
kerosine_price = fuels['kerosine(euro/MWh)']
co2 = fuels['co2(euro/ton)']
calculate_powerplant_price(powerplants, fuels)
sorted_powerplants = sort_sources(powerplants)
allocation_of_resources(sorted_powerplants, load)
output_list = produce_output(sorted_powerplants, load)
json_output = json.dumps(output_list)
return json_output