Skip to content

Commit 823df20

Browse files
committed
charging station: add tests to distinguish valid value in enumeration
1 parent b5ff33c commit 823df20

File tree

2 files changed

+193
-35
lines changed

2 files changed

+193
-35
lines changed

analysers/analyser_merge_charging_station_FR.py

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

3535

3636
class Analyser_Merge_Charging_station_FR(Analyser_Merge_Point):
37+
# Constante pour limiter les valeurs aberrantes (en kW)
38+
MAX_POWER_KW = 401
3739
WIKIDATA_MAP = {
3840
"ionity": "Q42717773",
3941
"bouygues": "Q3046208",
@@ -45,43 +47,109 @@ class Analyser_Merge_Charging_station_FR(Analyser_Merge_Point):
4547
"Izivia": "Q86671322",
4648
}
4749

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

70-
if puissance_nominale is None:
114+
s = str(raw).strip()
115+
if s == "":
116+
return None
117+
118+
max_kw = getattr(self, "MAX_POWER_KW", 500)
119+
120+
# Cas énumération: on délègue à keepMaxValueIfEnum puis on formate.
121+
if ";" in s:
122+
max_str = self.keepMaxValueIfEnum(s)
123+
if not max_str:
124+
return None
125+
try:
126+
v = float(
127+
str(max_str).replace(",", ".").lower().replace("kw", "").strip()
128+
)
129+
except Exception:
130+
return None
131+
return f"{self._normalize_number(v)} kW"
132+
133+
# Cas valeur unique
134+
s_norm = s.lower().replace(",", ".")
135+
try:
136+
if s_norm.endswith("kw"):
137+
v = float(s_norm[:-2].strip())
138+
return f"{self._normalize_number(v)} kW"
139+
140+
if s_norm.endswith("w"):
141+
v_w = float(s_norm[:-1].strip())
142+
v = v_w / 1000.0
143+
return f"{self._normalize_number(v)} kW"
144+
145+
# Sans unité
146+
v = float(s_norm)
147+
if v > max_kw:
148+
# On suppose des watts => conversion en kW
149+
v = v / 1000.0
150+
return f"{self._normalize_number(v)} kW"
151+
except Exception:
71152
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"
85153

86154
def __init__(self, config, logger=None):
87155
Analyser_Merge_Point.__init__(self, config, logger)
@@ -109,23 +177,23 @@ def __init__(self, config, logger=None):
109177
level=3,
110178
tags=["merge", "fix:imagery", "fix:survey", "fix:picture"],
111179
title=T_("Car charging station not integrated"),
112-
**doc
180+
**doc,
113181
)
114182
self.def_class_possible_merge(
115183
item=8411,
116184
id=3,
117185
level=3,
118186
tags=["merge", "fix:imagery", "fix:survey", "fix:picture"],
119187
title=T_("Car charging station, integration suggestion"),
120-
**doc
188+
**doc,
121189
)
122190
self.def_class_update_official(
123191
item=8412,
124192
id=4,
125193
level=3,
126194
tags=["merge", "fix:imagery", "fix:survey", "fix:picture"],
127195
title=T_("Car charging station update"),
128-
**doc
196+
**doc,
129197
)
130198

131199
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)