Skip to content

Commit 34152c8

Browse files
Implement COM Tagesvektor (#263)
* tagesvektor draft * list length check Co-authored-by: Annika <73470827+hf-aschloegl@users.noreply.github.com>
1 parent a1c622c commit 34152c8

2 files changed

Lines changed: 118 additions & 0 deletions

File tree

src/bo4e/com/tagesvektor.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
"""
2+
Contains Tagesvektor class and corresponding marshmallow schema for de-/serialization
3+
"""
4+
import datetime
5+
from typing import List
6+
7+
import attr
8+
from marshmallow import fields, post_load
9+
10+
from bo4e.com.com import COM, COMSchema
11+
from bo4e.com.zeitreihenwertkompakt import Zeitreihenwertkompakt, ZeitreihenwertkompaktSchema
12+
13+
14+
# pylint: disable=too-few-public-methods
15+
from bo4e.validators import check_list_length_at_least_one
16+
17+
18+
@attr.s(auto_attribs=True, kw_only=True)
19+
class Tagesvektor(COM):
20+
"""
21+
Abbildung eines Tagesvektors eines beliebigen äquidistanten Zeitrasters
22+
"""
23+
24+
# required attributes
25+
# for the validator see https://github.com/Hochfrequenz/BO4E-python/issues/261
26+
tag: datetime.datetime = attr.ib(validator=attr.validators.instance_of(datetime.datetime))
27+
"""
28+
Der Zeitpunkt ab dem die Werte ermittelt wurden.
29+
Es kann entweder der Beginn des Strom- oder Gastages verwendet werden.
30+
Der Zeitpunkt sollte eindeutig sein, d.h. sowohl Datum+Uhrzeit als auch den UTC-Offset spezifizieren.
31+
"""
32+
# for the validator see also https://github.com/Hochfrequenz/BO4E-python/issues/262
33+
# https://www.attrs.org/en/stable/api.html#attr.validators.deep_iterable
34+
werte: List[Zeitreihenwertkompakt] = attr.ib(
35+
validator=[
36+
attr.validators.deep_iterable(
37+
member_validator=attr.validators.instance_of(Zeitreihenwertkompakt),
38+
iterable_validator=attr.validators.instance_of(list),
39+
),
40+
check_list_length_at_least_one,
41+
]
42+
)
43+
"""
44+
Die Werte am angegebenen Tag;
45+
In Kombination aus Zeitintervall und Tag lassen sich die Zeiten der Werte eindeutig konstruieren.
46+
"""
47+
48+
49+
class TagesvektorSchema(COMSchema):
50+
"""
51+
Schema for de-/serialization of Tagesvektor
52+
"""
53+
54+
# required attributes
55+
tag = fields.DateTime()
56+
werte = fields.List(fields.Nested(ZeitreihenwertkompaktSchema))
57+
58+
# pylint: disable=no-self-use, unused-argument
59+
@post_load
60+
def deserialize(self, data, **kwargs) -> Tagesvektor:
61+
"""Deserialize JSON to Preisstaffel object"""
62+
return Tagesvektor(**data)

tests/test_tagesvektor.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from datetime import datetime, timezone
2+
from decimal import Decimal
3+
4+
import pytest # type:ignore[import]
5+
6+
from bo4e.com.tagesvektor import Tagesvektor, TagesvektorSchema
7+
from bo4e.com.zeitreihenwertkompakt import Zeitreihenwertkompakt
8+
from tests.serialization_helper import assert_serialization_roundtrip # type:ignore[import]
9+
from tests.test_sigmoidparameter import example_sigmoidparameter # type:ignore[import]
10+
11+
12+
class TestTagesvektor:
13+
@pytest.mark.parametrize(
14+
"tagesvektor, expected_json_dict",
15+
[
16+
pytest.param(
17+
Tagesvektor(
18+
tag=datetime(2021, 12, 15, 5, 0, tzinfo=timezone.utc),
19+
werte=[
20+
Zeitreihenwertkompakt(
21+
wert=Decimal(40),
22+
),
23+
Zeitreihenwertkompakt(
24+
wert=Decimal(50),
25+
),
26+
],
27+
),
28+
{
29+
"tag": "2021-12-15T05:00:00+00:00",
30+
"werte": [
31+
{"wert": "40", "statuszusatz": None, "status": None},
32+
{"wert": "50", "statuszusatz": None, "status": None},
33+
],
34+
},
35+
),
36+
],
37+
)
38+
def test_serialization_roundtrip(self, tagesvektor: Tagesvektor, expected_json_dict: dict):
39+
"""
40+
Test de-/serialisation of Preisstaffel.
41+
"""
42+
assert_serialization_roundtrip(tagesvektor, TagesvektorSchema(), expected_json_dict)
43+
44+
def test_missing_required_attribute(self):
45+
with pytest.raises(TypeError) as excinfo:
46+
_ = Tagesvektor()
47+
48+
assert "missing 2 required" in str(excinfo.value)
49+
50+
def test_list_not_long_enough_attribute(self):
51+
with pytest.raises(ValueError) as excinfo:
52+
_ = Tagesvektor(tag=datetime(2021, 12, 15, 5, 0, tzinfo=timezone.utc), werte=[])
53+
54+
assert "List werte must not be empty" in str(excinfo.value)
55+
56+
# add tests for issues 261 and 262 here

0 commit comments

Comments
 (0)