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

refactor

parent 838b17b1
......@@ -29,6 +29,9 @@ logger = logging.getLogger()
class TagResult(Exception):
"""Raise this exception with the identified occupancy"""
def __init__(self, tag: GEMTag):
self.tag = tag
......@@ -44,13 +47,12 @@ class OverridingOccupancy:
def __init__(self, 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`."""
occupancies = set(occupancies)
for candidate in self.mapping.keys():
if candidate in occupancies:
return candidate
if candidate in occupancies.tags:
raise TagResult(GEMTag(candidate))
@classmethod
def from_csv(cls, fn: str) -> OverridingOccupancy:
......@@ -64,7 +66,7 @@ class OverridingOccupancy:
def check_exactly_one_unique_tag(occupancies: TagStatistics):
"""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])
......
......@@ -23,9 +23,10 @@ from dataclasses import dataclass
from typing import Optional
# Regular expression to extract group (0-N characters at beginning)
# and sub_group (0-N digits at end) of GEM tags
REGEX_GEM_GROUP = r"(?P<group>^[A-Z]*)(?P<sub_group>[0-9]*$)"
# Regular expression to extract group (0-N characters at beginning),
# sub_group (0-N digits) and sub_sub_group (0-N characters and end) of GEM tags
# 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
......@@ -35,10 +36,12 @@ class GEMTag:
Args:
group (str): multi-character GEM classifier
sub_group (int): multi-digit GEM classifier sub-group
sub_sub_group (str): multi-char GEM classifier sub-sub-group
"""
group: str
sub_group: Optional[int]
sub_sub_group: Optional[str]
@classmethod
def from_string(cls, tag_as_string: str) -> GEMTag:
......@@ -51,10 +54,13 @@ class GEMTag:
sub_group = matched.group("sub_group")
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):
return hash((self.group, self.sub_group))
return hash((self.group, self.sub_group, self.sub_sub_group))
class TagStatistics(
......@@ -84,9 +90,12 @@ class TagStatistics(
return len(self.subtypes_counter)
@classmethod
def from_tags_string(cls, tags: str):
"""Analyse a string containing tags separated by `|` and do statistics."""
tags = [GEMTag.from_string(tag) for tag in tags.split("|")]
def from_strings(cls, tags: list[str]) -> TagStatistics:
tags = [GEMTag.from_string(tag_as_string) for tag_as_string in tags]
return cls.from_tags(tags)
@classmethod
def from_tags(cls, tags: list[GEMTag]) -> TagStatistics:
tags_counter = Counter(tags)
types = [tag.group for tag in tags]
......
......@@ -24,6 +24,7 @@ from rabotnikobm.rules.gem_occupancy.get_building_occupancy import (
TagStatistics,
TagResult,
)
from rabotnikobm.rules.gem_occupancy.mapping import GEMTag
@pytest.fixture()
......@@ -46,22 +47,22 @@ async def test_rule_get_building_occupancy(storage_consumer, building_poi_mapper
def test_overriding_occupancy(overriding_occupancies):
"""Rule #1"""
demo_tags = ["ASS1", "COM10"]
demo_tags = TagStatistics.from_strings(["ASS1", "COM10"])
occupancy = overriding_occupancies.apply(demo_tags)
assert occupancy == "COM10"
def test_overriding_occupancy_unknown(overriding_occupancies):
"""Rule #1"""
demo_tags = ["unknown tag"]
demo_tags = TagStatistics.from_strings(["unknown tag"])
occupancy = overriding_occupancies.apply(demo_tags)
assert occupancy is None
def test_unique_tags():
"""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:
check_exactly_one_unique_tag(tags)
......
......@@ -21,10 +21,10 @@ import pytest
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
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
......@@ -41,6 +41,7 @@ def test_gem_classification_parser():
assert GEMTag.from_string("COM1").sub_group == 1
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").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