Skip to content

Commit 965b8d3

Browse files
committed
Add final tests
1 parent 00522c3 commit 965b8d3

5 files changed

Lines changed: 132 additions & 29 deletions

File tree

packages/dtocean-economics/src/dtocean_economics/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ def get_phase_breakdown(bom: pd.DataFrame):
7070
phase_groups = bom.groupby("phase")
7171

7272
phase_breakdown = phase_groups.sum()
73-
if "unitary_costs" in phase_breakdown:
74-
phase_breakdown.drop("unitary_costs", axis=1, inplace=True)
73+
if "unitary_cost" in phase_breakdown:
74+
phase_breakdown.drop("unitary_cost", axis=1, inplace=True)
7575

7676
return phase_breakdown
7777

packages/dtocean-economics/src/dtocean_economics/preprocessing.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,14 @@
2727
def estimate_cost_per_power(total_rated_power, unit_cost, phase=None):
2828
cost = total_rated_power * unit_cost
2929
cost_bom = make_phase_bom([1], [cost], [0], phase)
30-
3130
return cost_bom
3231

3332

34-
def estimate_energy(lifetime, year_energy, network_efficiency=None):
35-
if network_efficiency is not None:
36-
net_coeff = network_efficiency
37-
else:
38-
net_coeff = 1.0
39-
40-
energy = [0] + [year_energy * net_coeff] * lifetime
33+
def estimate_energy(lifetime, year_energy, network_efficiency=1.0):
34+
energy = [0] + [year_energy * network_efficiency] * lifetime
4135
energy_year = range(lifetime + 1)
4236

4337
raw_energy = {"energy": energy, "project_year": energy_year}
44-
4538
energy_record = pd.DataFrame(raw_energy)
4639

4740
return energy_record

packages/dtocean-economics/src/dtocean_plugins/themes/economics.py

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ def _get_outputs(
517517
externalities_opex: Optional[float],
518518
) -> dict[str, Any]:
519519
series = [opex_bom, energy_record]
520-
series_lengths = [len(x) for x in series if not x.empty]
520+
series_lengths = [len(x.columns) for x in series if not x.empty]
521521
if len(series_lengths) == 2 and len(set(series_lengths)) != 1:
522522
msg = "opex bom and energy record must be the same length if not empty"
523523
raise ValueError(msg)
@@ -900,23 +900,7 @@ def _get_outputs_stats(
900900
except np.linalg.LinAlgError:
901901
_get_discounted_opex_stats(outputs, discounted_opex)
902902
_get_discounted_energy_stats(outputs, discounted_energy)
903-
904-
assert lcoe_total is not None
905-
906-
# Euro/Wh to Euro/kWh
907-
try:
908-
distribution = UniVariateKDE(lcoe_total)
909-
outputs["lcoe_mean"] = distribution.mean() * 1000
910-
outputs["lcoe_mode"] = distribution.mode() * 1000
911-
912-
intervals = distribution.confidence_interval(95)
913-
914-
if intervals is not None:
915-
outputs["lcoe_lower"] = intervals[0] * 1000
916-
outputs["lcoe_upper"] = intervals[1] * 1000
917-
918-
except np.linalg.LinAlgError:
919-
outputs["lcoe_mean"] = lcoe_total.mean() * 1000
903+
_get_lcoe_stats(outputs, lcoe_total)
920904

921905
return outputs
922906

@@ -926,6 +910,9 @@ def _get_outputs_stats(
926910
if discounted_energy is not None:
927911
_get_discounted_energy_stats(outputs, discounted_energy)
928912

913+
if lcoe_total is not None:
914+
_get_lcoe_stats(outputs, lcoe_total)
915+
929916
return outputs
930917

931918

@@ -962,6 +949,23 @@ def _get_discounted_energy_stats(outputs: dict[str, Any], discounted_energy):
962949
outputs["discounted_energy_mean"] = discounted_energy.mean() / 1e6
963950

964951

952+
def _get_lcoe_stats(outputs: dict[str, Any], lcoe_total):
953+
# Euro/Wh to Euro/kWh
954+
try:
955+
distribution = UniVariateKDE(lcoe_total)
956+
outputs["lcoe_mean"] = distribution.mean() * 1000
957+
outputs["lcoe_mode"] = distribution.mode() * 1000
958+
959+
intervals = distribution.confidence_interval(95)
960+
961+
if intervals is not None:
962+
outputs["lcoe_lower"] = intervals[0] * 1000
963+
outputs["lcoe_upper"] = intervals[1] * 1000
964+
965+
except np.linalg.LinAlgError:
966+
outputs["lcoe_mean"] = lcoe_total.mean() * 1000
967+
968+
965969
def _get_opex_breakdown(
966970
opex_bom,
967971
externalities_opex,

packages/dtocean-economics/tests/dtocean_economics/test_functions.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ def test_get_phase_breakdown(bom):
8585
assert isinstance(other, pd.Series)
8686
assert other["costs"] == 364
8787

88+
assert "unitary_cost" not in result
89+
8890

8991
def test_get_phase_breakdown_none(bom):
9092
none_bom = bom[pd.isnull(bom["phase"])]
@@ -93,6 +95,11 @@ def test_get_phase_breakdown_none(bom):
9395
assert result is None
9496

9597

98+
def test_get_phase_breakdown_no_costs():
99+
result = get_phase_breakdown(pd.DataFrame())
100+
assert result is None
101+
102+
96103
def test_get_present_values():
97104
value = np.array([1, 6 / 5, 36 / 25, 216 / 125])
98105
year = np.array([0, 1, 2, 3])

packages/dtocean-economics/tests/dtocean_plugins/themes/test_themes_economics.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,3 +1533,102 @@ def test_get_outputs_8_UniVariateKDE_error(
15331533
abs(outputs["lcoe_mean"] - lcoe_expected) / lcoe_expected * 100
15341534
)
15351535
assert lcoe_mean_error < 20
1536+
1537+
1538+
def test_get_outputs_8_no_opex(
1539+
bom,
1540+
energy_record_8,
1541+
):
1542+
discount_rate = 1 / 5
1543+
outputs = _get_outputs(
1544+
bom,
1545+
pd.DataFrame(),
1546+
energy_record_8,
1547+
discount_rate,
1548+
1e6,
1549+
None,
1550+
)
1551+
1552+
none_outputs = [
1553+
"discounted_opex_lower",
1554+
"discounted_opex_mean",
1555+
"discounted_opex_mode",
1556+
"discounted_opex_upper",
1557+
"lifetime_cost_mode",
1558+
"discounted_lifetime_cost_mode",
1559+
"lifetime_opex_mean",
1560+
"lifetime_opex_mode",
1561+
"lifetime_opex_lower",
1562+
"lifetime_opex_upper",
1563+
"confidence_density",
1564+
"lcoe_pdf",
1565+
"opex_breakdown",
1566+
"opex_lcoe_breakdown",
1567+
]
1568+
for key in none_outputs:
1569+
if outputs[key] is not None:
1570+
print(key)
1571+
assert outputs[key] is None
1572+
1573+
non_none_outputs = set(outputs.keys()) - set(none_outputs)
1574+
for key in non_none_outputs:
1575+
if outputs[key] is None:
1576+
print(key)
1577+
assert outputs[key] is not None
1578+
1579+
1580+
def test_get_outputs_8_no_energy(
1581+
bom,
1582+
opex_costs_8,
1583+
):
1584+
discount_rate = 1 / 5
1585+
outputs = _get_outputs(
1586+
bom,
1587+
opex_costs_8,
1588+
pd.DataFrame(),
1589+
discount_rate,
1590+
1e6,
1591+
None,
1592+
)
1593+
1594+
none_outputs = [
1595+
"opex_breakdown",
1596+
"discounted_energy_lower",
1597+
"discounted_energy_mean",
1598+
"discounted_energy_mode",
1599+
"discounted_energy_upper",
1600+
"lcoe_mean",
1601+
"lcoe_mode",
1602+
"lcoe_lower",
1603+
"lcoe_upper",
1604+
"confidence_density",
1605+
"lcoe_pdf",
1606+
"lcoe_breakdown",
1607+
"opex_lcoe_breakdown",
1608+
"capex_lcoe_breakdown",
1609+
]
1610+
for key in none_outputs:
1611+
if outputs[key] is not None:
1612+
print(key)
1613+
assert outputs[key] is None
1614+
1615+
non_none_outputs = set(outputs.keys()) - set(none_outputs)
1616+
for key in non_none_outputs:
1617+
if outputs[key] is None:
1618+
print(key)
1619+
assert outputs[key] is not None
1620+
1621+
1622+
def test_get_outputs_non_matching(bom, opex_costs_8, energy_record_0):
1623+
with pytest.raises(ValueError) as exc:
1624+
discount_rate = 1 / 5
1625+
_get_outputs(
1626+
bom,
1627+
opex_costs_8,
1628+
energy_record_0,
1629+
discount_rate,
1630+
1e6,
1631+
None,
1632+
)
1633+
1634+
assert "must be the same length" in str(exc)

0 commit comments

Comments
 (0)