Skip to content

Commit 50ea73e

Browse files
committed
charging station: add tests to distinguish valid value in enumeration
1 parent e60258e commit 50ea73e

File tree

2 files changed

+194
-35
lines changed

2 files changed

+194
-35
lines changed

analysers/analyser_merge_charging_station_FR.py

Lines changed: 104 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535

3636
class Analyser_Merge_Charging_station_FR(Analyser_Merge_Point):
37+
MAX_POWER_KW = 401
3738
WIKIDATA_MAP = {
3839
"ionity": "Q42717773",
3940
"bouygues": "Q3046208",
@@ -45,43 +46,111 @@ class Analyser_Merge_Charging_station_FR(Analyser_Merge_Point):
4546
"Izivia": "Q86671322",
4647
}
4748

48-
def keepMaxValueIfEnum(str):
49+
@staticmethod
50+
def keepMaxValueIfEnum(str_val):
51+
# Constante pour limiter les valeurs aberrantes (en kW)
52+
MAX_POWER_KW = 500
53+
4954
# si la valeur contient un ; on sépare et on prend la plus haute valeur
50-
if ";" in str:
51-
boom = str.split(";")
52-
max = 0
55+
if ";" in str_val:
56+
boom = str_val.split(";")
57+
max_val = 0
5358
for p in boom:
54-
p = int(p)
55-
if p > max:
56-
max = p
57-
58-
if max > 0:
59-
str = max
60-
return str
61-
62-
def getPuissanceNominaleInKw(self, puissance_nominale):
63-
# deviner un nombre en kw dans la puissance nominale,
64-
# les valeurs de plus de 401 sont à diviser par mille,
65-
# il faut aussi évacuer le leftpad de 0
66-
if puissance_nominale is None:
59+
# Supprimer les unités éventuelles (comme "kw")
60+
p_clean = p.lower().replace("kw", "").strip()
61+
try:
62+
p_val = int(float(p_clean))
63+
# Ignorer les valeurs supérieures à la limite maximale connue (MAX_POWER_KW)
64+
if (
65+
p_val <= Analyser_Merge_Charging_station_FR.MAX_POWER_KW
66+
and p_val > max_val
67+
):
68+
max_val = p_val
69+
except ValueError:
70+
# Ignorer les valeurs qui ne peuvent pas être converties en nombre
71+
pass
72+
73+
if max_val > 0:
74+
str_val = str(max_val)
75+
else:
76+
# Gérer les cas où il n'y a pas de délimiteur mais une unité est présente
77+
if "kw" in str_val.lower():
78+
p_clean = str_val.lower().replace("kw", "").strip()
79+
try:
80+
p_val = int(float(p_clean))
81+
if p_val <= Analyser_Merge_Charging_station_FR.MAX_POWER_KW:
82+
str_val = str(p_val)
83+
except ValueError:
84+
pass
85+
return str_val
86+
87+
def _normalize_number(self, v: float) -> str:
88+
"""Formate un float en supprimant les .0 inutiles et les zéros de fin."""
89+
try:
90+
iv = int(v)
91+
if abs(v - iv) < 1e-9:
92+
return str(iv)
93+
return f"{v:.6f}".rstrip("0").rstrip(".")
94+
except Exception:
95+
return str(v)
96+
97+
def getPuissanceNominaleInKw(self, raw):
98+
"""
99+
Calcule la puissance nominale en kW à partir d'une valeur brute.
100+
101+
Règles:
102+
- Si 'raw' est une énumération 'a;b;c', on garde la valeur max en kW <= MAX_POWER_KW.
103+
- Si 'raw' est une valeur unique:
104+
* suffixe 'kW' => valeur déjà en kW
105+
* suffixe 'W' => conversion W -> kW
106+
* sans unité:
107+
- si > MAX_POWER_KW => on suppose des watts, on divise par 1000
108+
- sinon => déjà en kW
109+
110+
Retour: 'X kW' ou None si indéterminable.
111+
"""
112+
if raw is None:
67113
return None
68-
puissance_nominale = str(puissance_nominale)
69114

70-
if puissance_nominale is None:
115+
s = str(raw).strip()
116+
if s == "":
117+
return None
118+
119+
max_kw = getattr(self, "MAX_POWER_KW", 500)
120+
121+
# Cas énumération: on délègue à keepMaxValueIfEnum puis on formate.
122+
if ";" in s:
123+
max_str = self.keepMaxValueIfEnum(s)
124+
if not max_str:
125+
return None
126+
try:
127+
v = float(
128+
str(max_str).replace(",", ".").lower().replace("kw", "").strip()
129+
)
130+
except Exception:
131+
return None
132+
return f"{self._normalize_number(v)} kW"
133+
134+
# Cas valeur unique
135+
s_norm = s.lower().replace(",", ".")
136+
try:
137+
if s_norm.endswith("kw"):
138+
v = float(s_norm[:-2].strip())
139+
return f"{self._normalize_number(v)} kW"
140+
141+
if s_norm.endswith("w"):
142+
v_w = float(s_norm[:-1].strip())
143+
v = v_w / 1000.0
144+
return f"{self._normalize_number(v)} kW"
145+
146+
# Sans unité
147+
v = float(s_norm)
148+
if v > max_kw:
149+
# On suppose des watts => conversion en kW
150+
v = v / 1000.0
151+
return f"{self._normalize_number(v)} kW"
152+
except Exception:
71153
return None
72-
# Convertir en chaîne et supprimer les zéros à gauche
73-
puissance_str = str(puissance_nominale).lstrip("0")
74-
if not puissance_str:
75-
return 0
76-
77-
puissance_str = self.keepMaxValueIfEnum(puissance_str)
78-
# Reconvertir en entier
79-
puissance_nominale = int(puissance_str)
80-
# puisssance max de borne en kW connue
81-
if puissance_nominale > 401:
82-
return str(puissance_nominale / 1000) + " kW"
83-
else:
84-
return str(puissance_nominale) + " kW"
85154

86155
def __init__(self, config, logger=None):
87156
Analyser_Merge_Point.__init__(self, config, logger)
@@ -109,23 +178,23 @@ def __init__(self, config, logger=None):
109178
level=3,
110179
tags=["merge", "fix:imagery", "fix:survey", "fix:picture"],
111180
title=T_("Car charging station not integrated"),
112-
**doc
181+
**doc,
113182
)
114183
self.def_class_possible_merge(
115184
item=8411,
116185
id=3,
117186
level=3,
118187
tags=["merge", "fix:imagery", "fix:survey", "fix:picture"],
119188
title=T_("Car charging station, integration suggestion"),
120-
**doc
189+
**doc,
121190
)
122191
self.def_class_update_official(
123192
item=8412,
124193
id=4,
125194
level=3,
126195
tags=["merge", "fix:imagery", "fix:survey", "fix:picture"],
127196
title=T_("Car charging station update"),
128-
**doc
197+
**doc,
129198
)
130199

131200
self.init(
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# !/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
4+
import unittest
5+
from analysers.analyser_merge_charging_station_FR import (
6+
Analyser_Merge_Charging_station_FR,
7+
)
8+
9+
10+
class TestAnalyserMergeChargingStationFR(unittest.TestCase):
11+
12+
def test_keepMaxValueIfEnum(self):
13+
# Test de base avec une liste de valeurs sans unité
14+
self.assertEqual(
15+
"20", Analyser_Merge_Charging_station_FR.keepMaxValueIfEnum("15;20;11.5")
16+
)
17+
18+
# Test avec valeurs dépassant la limite maximale connue (MAX_POWER_KW)
19+
self.assertEqual(
20+
"20",
21+
Analyser_Merge_Charging_station_FR.keepMaxValueIfEnum("15;20;1200;11.5"),
22+
)
23+
24+
# Test avec des unités mélangées
25+
self.assertEqual(
26+
"20", Analyser_Merge_Charging_station_FR.keepMaxValueIfEnum("15;20kw;11.5")
27+
)
28+
29+
# Test avec une seule valeur
30+
self.assertEqual(
31+
"30", Analyser_Merge_Charging_station_FR.keepMaxValueIfEnum("30")
32+
)
33+
34+
# Test avec des zéros au début
35+
self.assertEqual(
36+
"50", Analyser_Merge_Charging_station_FR.keepMaxValueIfEnum("050;30;40")
37+
)
38+
39+
def test_getPuissanceNominaleInKw(self):
40+
# Créer une instance sans l'initialiser complètement
41+
analyser = Analyser_Merge_Charging_station_FR.__new__(
42+
Analyser_Merge_Charging_station_FR
43+
)
44+
45+
# Définir seulement les attributs nécessaires pour la méthode testée
46+
analyser.MAX_POWER_KW = 401
47+
48+
# Définir la méthode _normalize_number manuellement
49+
def _normalize_number(v):
50+
try:
51+
iv = int(v)
52+
if abs(v - iv) < 1e-9:
53+
return str(iv)
54+
return f"{v:.6f}".rstrip("0").rstrip(".")
55+
except Exception:
56+
return str(v)
57+
58+
analyser._normalize_number = _normalize_number
59+
60+
# Attacher la méthode keepMaxValueIfEnum à l'instance
61+
analyser.keepMaxValueIfEnum = (
62+
Analyser_Merge_Charging_station_FR.keepMaxValueIfEnum
63+
)
64+
65+
# Test avec une énumération et un max dépassant MAX_POWER_KW (doit ignorer 1200)
66+
self.assertEqual(
67+
"20 kW", analyser.getPuissanceNominaleInKw("15;20kw;1200;11.5")
68+
)
69+
70+
# Test avec une énumération en dessous de MAX_POWER_KW
71+
self.assertEqual("50 kW", analyser.getPuissanceNominaleInKw("30;50;20"))
72+
73+
# Test avec une valeur unique valide
74+
self.assertEqual("30 kW", analyser.getPuissanceNominaleInKw("30"))
75+
76+
# Test avec None
77+
self.assertIsNone(analyser.getPuissanceNominaleInKw(None))
78+
79+
# Test avec une valeur à 0
80+
self.assertEqual("0 kW", analyser.getPuissanceNominaleInKw("0"))
81+
82+
# Test avec une valeur au-dessus de la limite avec conversion automatique
83+
self.assertEqual("350 kW", analyser.getPuissanceNominaleInKw("350000"))
84+
85+
# Test daube
86+
self.assertEqual(None, analyser.getPuissanceNominaleInKw("daube"))
87+
88+
89+
if __name__ == "__main__":
90+
unittest.main()

0 commit comments

Comments
 (0)