Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add body to unit tests #338

Merged
merged 18 commits into from
Apr 20, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 52 additions & 1 deletion src/fundus/parser/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from dataclasses import dataclass, fields
from typing import (
Any,
Callable,
ClassVar,
Collection,
Dict,
Iterable,
Expand Down Expand Up @@ -188,9 +190,33 @@ def __repr__(self) -> str:
def __str__(self) -> str:
return "\n".join(self)

def __eq__(self, other: object) -> bool:
if not isinstance(other, TextSequence):
return NotImplemented
return self._data == other._data


@dataclass
class TextSequenceTree(ABC):
"""Base class to traverse and build trees of TextSequence.

The ClassVar __transformation__ is needed to serialize the tree. There must be an entry with type
Tuple[Callable, Callable] for each field with the first callable beeing the serialization and
the second the deserialization of that specific field.

Examples:
>>> import datetime
>>> class Tree(TextSequenceTree):
>>> head: TextSequence
>>> tail: TextSequence
>>>
>>> __transformation__ = {"head": (list, TextSequence), "tail": (list, TextSequence)}


"""

__transformation__: ClassVar[Dict[str, Tuple[Callable[[Any], Any], Callable[[Any], Any]]]]

def as_text_sequence(self) -> TextSequence:
texts = [text for tl in self.df_traversal() for text in tl]
return TextSequence(texts)
Expand All @@ -215,7 +241,22 @@ def recursion(o: object):
for value in self:
yield from recursion(value)

def __iter__(self):
def serialize(self) -> Dict[str, Any]:
serialized = {}
for field in fields(self):
name = field.name
serialized[name] = self.__transformation__[name][0](getattr(self, name))
return serialized

@classmethod
def deserialize(cls, obj: Dict[str, Any]) -> "TextSequenceTree":
kwargs = {}
for name, value in obj.items():
kwargs[name] = cls.__transformation__[name][1](value)
# noinspection PyArgumentList
return cls(**kwargs)

def __iter__(self) -> Iterator[Any]:
field_values = [getattr(self, f.name) for f in fields(self)]
yield from field_values

Expand All @@ -231,8 +272,18 @@ class ArticleSection(TextSequenceTree):
headline: TextSequence
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a quick question: Why is the headline a TextSequence again? It would be intuitive to me if it was just a single string without any sequential structure like a section with multiple paragraphs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Headline was originally intended to be a TextSequence to catch any errors resulting from consequent headlines.

paragraphs: TextSequence

__transformation__ = {"headline": (list, TextSequence), "paragraphs": (list, TextSequence)}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also make the TextSequence it self serializable as well and call the serialize function here. Would this also be a desired feature?



@dataclass
class ArticleBody(TextSequenceTree):
summary: TextSequence
sections: List[ArticleSection]

__transformation__ = {
"summary": (list, TextSequence),
"sections": (
lambda sections: [section.serialize() for section in sections],
lambda sections: [ArticleSection.deserialize(section) for section in sections],
),
}
14 changes: 13 additions & 1 deletion tests/resources/parser/test_data/at/ORF.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@
"ORF.at"
],
"publishing_date": "2023-04-28 18:03:46.463000+00:00",
"title": "Mädchen bei Straßenbahnunfall in Wien verletzt"
"title": "Mädchen bei Straßenbahnunfall in Wien verletzt",
"body": {
"summary": [],
"sections": [
{
"headline": [],
"paragraphs": [
"Ein zwölfjähriges Mädchen ist heute bei einem Straßenbahnunfall in Wien-Favoriten schwer verletzt worden. Das Mädchen versuchte offenbar die Straße zu überqueren und wurde dabei von der Straßenbahn erfasst.",
"Mehr dazu in wien.ORF.at"
]
}
]
}
}
}
53 changes: 52 additions & 1 deletion tests/resources/parser/test_data/de/BerlinerZeitung.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,57 @@
"topics": [
"News",
"Niederlande"
]
],
"body": {
"summary": [
"Nach der Zeugung von mindestens 550 Kindern hat ein niederländisches Gericht einen übereifrigen Samenspender gestoppt. Das Gericht untersagte dem Mann am Freitag jede weitere Samenspende. Bei einem Verstoß muss er 100.000 Euro Strafe zahlen. Eine Frau, die durch eine Samenspende des Mannes ein Kind bekam, und die Stiftung Donorkind hatten den 41-Jährigen verklagt. Weil er in Online-Netzwerken weiter seine Dienste anbot, wurde er nun im Eilverfahren verurteilt."
],
"sections": [
{
"headline": [],
"paragraphs": [
"Nach der Zeugung von mindestens 550 Kindern hat ein niederländisches Gericht einen übereifrigen Samenspender gestoppt. Das Gericht untersagte dem Mann am Freitag jede weitere Samenspende. Bei einem Verstoß muss er 100.000 Euro Strafe zahlen. Eine Frau, die durch eine Samenspende des Mannes ein Kind bekam, und die Stiftung Donorkind hatten den 41-Jährigen verklagt. Weil er in Online-Netzwerken weiter seine Dienste anbot, wurde er nun im Eilverfahren verurteilt."
]
},
{
"headline": [
"Der Mann hatte sein Sperma an mindestens zwölf Kliniken und über Internet-Plattformen auch privat an hunderte Paare gespendet. Die Klägerin, die ihn nach Angaben von Donorkind im Internet kennengelernt hatte, wirft ihm vor, sie über die Zahl der von ihm gezeugten Kinder getäuscht zu haben. Er gab demnach an, Vater von maximal 25 Kindern in zwölf Familien zu sein. Mehr ist in den Niederlanden zur Vermeidung von Inzest durch zu viele Halbgeschwister nicht erlaubt."
],
"paragraphs": [
"Der Mann hatte sein Sperma an mindestens zwölf Kliniken und über Internet-Plattformen auch privat an hunderte Paare gespendet. Die Klägerin, die ihn nach Angaben von Donorkind im Internet kennengelernt hatte, wirft ihm vor, sie über die Zahl der von ihm gezeugten Kinder getäuscht zu haben. Er gab demnach an, Vater von maximal 25 Kindern in zwölf Familien zu sein. Mehr ist in den Niederlanden zur Vermeidung von Inzest durch zu viele Halbgeschwister nicht erlaubt."
]
},
{
"headline": [
"Samenbetrug: Kinder wachsen jetzt mit Hunderten Halbgeschwistern auf"
],
"paragraphs": [
"Dem Urteil zufolge ist der Mann Vater von allein hundert Kindern, die in niederländischen Kliniken gezeugt wurden. Hinzu kommt demnach eine nicht genau bezifferbare Zahl von Kindern, die über privat organisierte Samenspenden und eine dänische Klinik gezeugt wurden, die sein Sperma an Paare in verschiedenen Ländern weitergeleitet hatte. Insgesamt hat der Mann nach Auffassung der Gerichts seit 2007 mindestens 550 bis 600 Kinder gezeugt."
]
},
{
"headline": [
"Dem Urteil zufolge ist der Mann Vater von allein hundert Kindern, die in niederländischen Kliniken gezeugt wurden. Hinzu kommt demnach eine nicht genau bezifferbare Zahl von Kindern, die über privat organisierte Samenspenden und eine dänische Klinik gezeugt wurden, die sein Sperma an Paare in verschiedenen Ländern weitergeleitet hatte. Insgesamt hat der Mann nach Auffassung der Gerichts seit 2007 mindestens 550 bis 600 Kinder gezeugt."
],
"paragraphs": [
"Der Mann habe die Paare „bewusst“ über die Zahl der von ihm gezeugten Kinder getäuscht, urteilte das Gericht in Den Haag. „All diese Eltern sind nun mit der Tatsache konfrontiert, dass ihre Kinder Teil eines riesigen Verwandtschaftsnetzwerkes mit Hunderten von Halbgeschwistern sind“, erklärte das Gericht. Negative Folgen für die Kinder, etwa psychische Probleme aufgrund von Identitätsfragen und Angst vor Inzest, hält das Gericht für „hinreichend plausibel“."
]
},
{
"headline": [
"Der Mann habe die Paare „bewusst“ über die Zahl der von ihm gezeugten Kinder getäuscht, urteilte das Gericht in Den Haag. „All diese Eltern sind nun mit der Tatsache konfrontiert, dass ihre Kinder Teil eines riesigen Verwandtschaftsnetzwerkes mit Hunderten von Halbgeschwistern sind“, erklärte das Gericht. Negative Folgen für die Kinder, etwa psychische Probleme aufgrund von Identitätsfragen und Angst vor Inzest, hält das Gericht für „hinreichend plausibel“."
],
"paragraphs": [
"Der Fall ist nicht der erste Samenspende-Skandal in den Niederlanden. Im Jahr 2020 kam heraus, dass ein inzwischen gestorbener Gynäkologe bei der künstlichen Befruchtung von Patientinnen mindestens 17 Kinder gezeugt hatte. Er hatte sein eigenes Sperma benutzt, die Frauen aber in dem Glauben gelassen, es stamme von anonymen Spendern."
]
},
{
"headline": [
"Der Fall ist nicht der erste Samenspende-Skandal in den Niederlanden. Im Jahr 2020 kam heraus, dass ein inzwischen gestorbener Gynäkologe bei der künstlichen Befruchtung von Patientinnen mindestens 17 Kinder gezeugt hatte. Er hatte sein eigenes Sperma benutzt, die Frauen aber in dem Glauben gelassen, es stamme von anonymen Spendern."
],
"paragraphs": []
}
]
}
}
}
18 changes: 17 additions & 1 deletion tests/resources/parser/test_data/de/Bild.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,22 @@
"Saison 2022-2023",
"Sport – Leuchtturm Essen",
"Niemiec Jona"
]
],
"body": {
"summary": [
"Es war bereits der zwölfte Einsatz in der 2. Bundesliga von Fortuna Düsseldorfs Bubi Jona Niemiec (21). Kaum nach 67 Minuten eingewechselt, scheiterte der Stürmer nur an der Latte. Doch war er beim 0:0 auf Pauli eine Bereicherung."
],
"sections": [
{
"headline": [],
"paragraphs": [
"Endlich wieder – denn nach starken ersten Spielen mit seinem Tordebüt beim 3:1 über Braunschweig lief es nicht mehr ganz so rund.",
"Daniel Thioune (48) wundert es nicht: „Jeder Spieler hat seine Qualitäten, die letzten Partien haben ihm nicht so den Raum gegeben. Jetzt durch das hohe Pressing haben sich riesen Räume ergeben und er konnte sich zeigen.”",
"Der Trainer freut sich: „Ich bin froh, dass es wieder etwas mehr war. Wie müssen einfach deutlich geduldiger mit dem Jungen sein. Er muss sich anpassen, man sieht oft, dass er am durchschnaufen ist.”",
"Obwohl Niemiec mit seiner Schnelligkeit Fortuna guttun kann, muss er vor allem konditionell noch zulegen, um beständig so aufzutrumpfen wie die letzten 23 Minuten am Millerntor."
]
}
]
}
}
}
Loading