Commit 6b072fa5 authored by Marius Kriegerowski's avatar Marius Kriegerowski
Browse files

refactor

parent 838b17b1
...@@ -29,6 +29,9 @@ logger = logging.getLogger() ...@@ -29,6 +29,9 @@ logger = logging.getLogger()
class TagResult(Exception): class TagResult(Exception):
"""Raise this exception with the identified occupancy"""
def __init__(self, tag: GEMTag): def __init__(self, tag: GEMTag):
self.tag = tag self.tag = tag
...@@ -44,13 +47,12 @@ class OverridingOccupancy: ...@@ -44,13 +47,12 @@ class OverridingOccupancy:
def __init__(self, mapping): def __init__(self, mapping):
self.mapping = mapping self.mapping = mapping
def apply(self, occupancies: list[str]) -> Optional[str]: def apply(self, occupancies: TagStatistics) -> None:
"""Apply the loaded mapping to a list of `occupancies`.""" """Apply the loaded mapping to a list of `occupancies`."""
occupancies = set(occupancies)
for candidate in self.mapping.keys(): for candidate in self.mapping.keys():
if candidate in occupancies: if candidate in occupancies.tags:
return candidate raise TagResult(GEMTag(candidate))
@classmethod @classmethod
def from_csv(cls, fn: str) -> OverridingOccupancy: def from_csv(cls, fn: str) -> OverridingOccupancy:
...@@ -64,7 +66,7 @@ class OverridingOccupancy: ...@@ -64,7 +66,7 @@ class OverridingOccupancy:
def check_exactly_one_unique_tag(occupancies: TagStatistics): def check_exactly_one_unique_tag(occupancies: TagStatistics):
"""raises `TagResult` if there is exactly one unique type""" """raises `TagResult` if there is exactly one unique type"""
if occupancies.exactly_one_unique_tag: if occupancies.exactly_one_unique_tag():
raise TagResult(occupancies.tags[0]) raise TagResult(occupancies.tags[0])
......
...@@ -23,9 +23,10 @@ from dataclasses import dataclass ...@@ -23,9 +23,10 @@ from dataclasses import dataclass
from typing import Optional from typing import Optional
# Regular expression to extract group (0-N characters at beginning) # Regular expression to extract group (0-N characters at beginning),
# and sub_group (0-N digits at end) of GEM tags # sub_group (0-N digits) and sub_sub_group (0-N characters and end) of GEM tags
REGEX_GEM_GROUP = r"(?P<group>^[A-Z]*)(?P<sub_group>[0-9]*$)" # Can be letters-number-letters(-numbers)
REGEX_GEM_GROUP = r"(?P<group>^[A-Z]*)(?P<sub_group>[0-9]*)(?P<sub_sub_group>[A-Z]*$)"
@dataclass @dataclass
...@@ -35,10 +36,12 @@ class GEMTag: ...@@ -35,10 +36,12 @@ class GEMTag:
Args: Args:
group (str): multi-character GEM classifier group (str): multi-character GEM classifier
sub_group (int): multi-digit GEM classifier sub-group sub_group (int): multi-digit GEM classifier sub-group
sub_sub_group (str): multi-char GEM classifier sub-sub-group
""" """
group: str group: str
sub_group: Optional[int] sub_group: Optional[int]
sub_sub_group: Optional[str]
@classmethod @classmethod
def from_string(cls, tag_as_string: str) -> GEMTag: def from_string(cls, tag_as_string: str) -> GEMTag:
...@@ -51,10 +54,13 @@ class GEMTag: ...@@ -51,10 +54,13 @@ class GEMTag:
sub_group = matched.group("sub_group") sub_group = matched.group("sub_group")
sub_group = int(sub_group) if sub_group != "" else None sub_group = int(sub_group) if sub_group != "" else None
return cls(group, sub_group) sub_sub_group = matched.group("sub_sub_group")
sub_sub_group = sub_sub_group if sub_sub_group != "" else None
return cls(group, sub_group, sub_sub_group)
def __hash__(self): def __hash__(self):
return hash((self.group, self.sub_group)) return hash((self.group, self.sub_group, self.sub_sub_group))
class TagStatistics( class TagStatistics(
...@@ -84,9 +90,12 @@ class TagStatistics( ...@@ -84,9 +90,12 @@ class TagStatistics(
return len(self.subtypes_counter) return len(self.subtypes_counter)
@classmethod @classmethod
def from_tags_string(cls, tags: str): def from_strings(cls, tags: list[str]) -> TagStatistics:
"""Analyse a string containing tags separated by `|` and do statistics.""" tags = [GEMTag.from_string(tag_as_string) for tag_as_string in tags]
tags = [GEMTag.from_string(tag) for tag in tags.split("|")] return cls.from_tags(tags)
@classmethod
def from_tags(cls, tags: list[GEMTag]) -> TagStatistics:
tags_counter = Counter(tags) tags_counter = Counter(tags)
types = [tag.group for tag in tags] types = [tag.group for tag in tags]
......
...@@ -24,6 +24,7 @@ from rabotnikobm.rules.gem_occupancy.get_building_occupancy import ( ...@@ -24,6 +24,7 @@ from rabotnikobm.rules.gem_occupancy.get_building_occupancy import (
TagStatistics, TagStatistics,
TagResult, TagResult,
) )
from rabotnikobm.rules.gem_occupancy.mapping import GEMTag
@pytest.fixture() @pytest.fixture()
...@@ -46,22 +47,22 @@ async def test_rule_get_building_occupancy(storage_consumer, building_poi_mapper ...@@ -46,22 +47,22 @@ async def test_rule_get_building_occupancy(storage_consumer, building_poi_mapper
def test_overriding_occupancy(overriding_occupancies): def test_overriding_occupancy(overriding_occupancies):
"""Rule #1""" """Rule #1"""
demo_tags = ["ASS1", "COM10"] demo_tags = TagStatistics.from_strings(["ASS1", "COM10"])
occupancy = overriding_occupancies.apply(demo_tags) occupancy = overriding_occupancies.apply(demo_tags)
assert occupancy == "COM10" assert occupancy == "COM10"
def test_overriding_occupancy_unknown(overriding_occupancies): def test_overriding_occupancy_unknown(overriding_occupancies):
"""Rule #1""" """Rule #1"""
demo_tags = ["unknown tag"] demo_tags = TagStatistics.from_strings(["unknown tag"])
occupancy = overriding_occupancies.apply(demo_tags) occupancy = overriding_occupancies.apply(demo_tags)
assert occupancy is None assert occupancy is None
def test_unique_tags(): def test_unique_tags():
"""Rule #2""" """Rule #2"""
tags = TagStatistics.from_tags_string("COM|COM")
tags = TagStatistics.from_tags([GEMTag.from_string("COM"), GEMTag.from_string("COM")])
with pytest.raises(TagResult) as e: with pytest.raises(TagResult) as e:
check_exactly_one_unique_tag(tags) check_exactly_one_unique_tag(tags)
......
...@@ -21,10 +21,10 @@ import pytest ...@@ -21,10 +21,10 @@ import pytest
def test_tag_statistics(): def test_tag_statistics():
stats = TagStatistics.from_tags_string("COM|COM") stats = TagStatistics.from_tags([GEMTag.from_string("COM"), GEMTag.from_string("COM")])
assert stats.exactly_one_unique_tag() is True assert stats.exactly_one_unique_tag() is True
stats = TagStatistics.from_tags_string("COM|ASS") stats = TagStatistics.from_tags([GEMTag.from_string("COM"), GEMTag.from_string("COM1")])
assert stats.exactly_one_unique_tag() is False assert stats.exactly_one_unique_tag() is False
...@@ -41,6 +41,7 @@ def test_gem_classification_parser(): ...@@ -41,6 +41,7 @@ def test_gem_classification_parser():
assert GEMTag.from_string("COM1").sub_group == 1 assert GEMTag.from_string("COM1").sub_group == 1
assert GEMTag.from_string("COM11").sub_group == 11 assert GEMTag.from_string("COM11").sub_group == 11
assert GEMTag.from_string("COM11A").sub_sub_group == "A"
assert GEMTag.from_string("UNDECIDABLE").group == "UNDECIDABLE" assert GEMTag.from_string("UNDECIDABLE").group == "UNDECIDABLE"
assert GEMTag.from_string("UNDECIDABLE").sub_group is None assert GEMTag.from_string("UNDECIDABLE").sub_group is None
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment