Skip to content

Commit

Permalink
Merge pull request #37 from jsconan/feature/value-aggregator
Browse files Browse the repository at this point in the history
Feature/Value aggregator
  • Loading branch information
jsconan authored Oct 20, 2023
2 parents fce1c34 + f8de36d commit 5a81d90
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 3 deletions.
8 changes: 8 additions & 0 deletions docs/toolbox.data.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ print([extractor.extract(row) for row in data]) # ["2023-10-06", "2023-02-20", "
extractor = ValueExtractor(["value", "val", "number"], int)
data = [{"val": "42"}, {"value": 12, {"number": 100}]
print([extractor.extract(row) for row in data]) # [42, 12, 100]

# Build full names from multiple entries
extractor = ValueExtractor(["firstname", "lastname"], " ".join)
data = [
{"firstname": "John", "lastname": "Smith"},
{"firstname": "Jane", "lastname": "Doe"},
]
print([extractor.aggregate(row) for row in data]) # ["John Smith", "Jane Doe"]
```

**Global Variables**
Expand Down
62 changes: 59 additions & 3 deletions docs/toolbox.data.value_extractor.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,25 @@ A tool for extracting values from a set of possible entries.
```python
from toolbox.data import ValueExtractor

# Extracts a date from various possible entries
extractor = ValueExtractor(["date", "time", "day"])
data = [{"date": "2023-10-06"}, {"day": "2023-02-20"}, {"time": "2023-06-12"}]
print([extractor.extract(row) for row in data]) # ["2023-10-06", "2023-02-20", "2023-06-12"]

# Build full names from multiple entries
extractor = ValueExtractor(["firstname", "lastname"], " ".join)
data = [
{"firstname": "John", "lastname": "Smith"},
{"firstname": "Jane", "lastname": "Doe"},
]
print([extractor.aggregate(row) for row in data]) # ["John Smith", "Jane Doe"]
```



---

<a href="../src/toolbox/data/value_extractor.py#L17"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/toolbox/data/value_extractor.py#L26"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

## <kbd>class</kbd> `ValueExtractor`
Extracts a value from a set of possible entries.
Expand All @@ -43,7 +52,7 @@ data = [{"date": "2023-10-06"}, {"day": "2023-02-20"}, {"time": "2023-06-12"}]
print([extractor.extract(row) for row in data]) # ["2023-10-06", "2023-02-20", "2023-06-12"]
```

<a href="../src/toolbox/data/value_extractor.py#L35"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/toolbox/data/value_extractor.py#L44"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>method</kbd> `__init__`

Expand Down Expand Up @@ -106,7 +115,54 @@ The mapper applied to cast and format the extracted value.

---

<a href="../src/toolbox/data/value_extractor.py#L88"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/toolbox/data/value_extractor.py#L131"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>method</kbd> `aggregate`

```python
aggregate(structure: dict) → Any
```

Aggregates a value from the specified structure.



**Args:**

- <b>`structure`</b> (dict): The structure from which aggregate the value.



**Returns:**

- <b>`Any`</b>: The value aggregated from the structure.



**Examples:**
```python
from toolbox.data import ValueExtractor

# Build full names from multiple entries
extractor = ValueExtractor(["firstname", "lastname"], " ".join)
data = [
{"firstname": "John", "lastname": "Smith"},
{"firstname": "Jane", "lastname": "Doe"},
]
print([extractor.aggregate(row) for row in data]) # ["John Smith", "Jane Doe"]

# Build a list from multiple entries
extractor = ValueExtractor(["value_1", "value_2", "value_3"])
data = [
{"value_1": 42, "value_2": 12, "value_3": 100},
{"value_1": 10, "value_2": 20, "value_3": 30},
]
print([extractor.aggregate(row) for row in data]) # [[42, 12, 100], [10, 20, 30]]
```

---

<a href="../src/toolbox/data/value_extractor.py#L97"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>method</kbd> `extract`

Expand Down
8 changes: 8 additions & 0 deletions src/toolbox/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@
extractor = ValueExtractor(["value", "val", "number"], int)
data = [{"val": "42"}, {"value": 12, {"number": 100}]
print([extractor.extract(row) for row in data]) # [42, 12, 100]
# Build full names from multiple entries
extractor = ValueExtractor(["firstname", "lastname"], " ".join)
data = [
{"firstname": "John", "lastname": "Smith"},
{"firstname": "Jane", "lastname": "Doe"},
]
print([extractor.aggregate(row) for row in data]) # ["John Smith", "Jane Doe"]
```
"""
from toolbox.data.mappers import ValueMapper, boolean, decimal, passthrough
Expand Down
41 changes: 41 additions & 0 deletions src/toolbox/data/value_extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,18 @@
```python
from toolbox.data import ValueExtractor
# Extracts a date from various possible entries
extractor = ValueExtractor(["date", "time", "day"])
data = [{"date": "2023-10-06"}, {"day": "2023-02-20"}, {"time": "2023-06-12"}]
print([extractor.extract(row) for row in data]) # ["2023-10-06", "2023-02-20", "2023-06-12"]
# Build full names from multiple entries
extractor = ValueExtractor(["firstname", "lastname"], " ".join)
data = [
{"firstname": "John", "lastname": "Smith"},
{"firstname": "Jane", "lastname": "Doe"},
]
print([extractor.aggregate(row) for row in data]) # ["John Smith", "Jane Doe"]
```
"""
from typing import Any, Iterable
Expand Down Expand Up @@ -118,3 +127,35 @@ def extract(self, structure: dict) -> Any:
return self._mapper(structure[name])

return None

def aggregate(self, structure: dict) -> Any:
"""Aggregates a value from the specified structure.
Args:
structure (dict): The structure from which aggregate the value.
Returns:
Any: The value aggregated from the structure.
Examples:
```python
from toolbox.data import ValueExtractor
# Build full names from multiple entries
extractor = ValueExtractor(["firstname", "lastname"], " ".join)
data = [
{"firstname": "John", "lastname": "Smith"},
{"firstname": "Jane", "lastname": "Doe"},
]
print([extractor.aggregate(row) for row in data]) # ["John Smith", "Jane Doe"]
# Build a list from multiple entries
extractor = ValueExtractor(["value_1", "value_2", "value_3"])
data = [
{"value_1": 42, "value_2": 12, "value_3": 100},
{"value_1": 10, "value_2": 20, "value_3": 30},
]
print([extractor.aggregate(row) for row in data]) # [[42, 12, 100], [10, 20, 30]]
```
"""
return self._mapper([structure[name] for name in self._entries if name in structure])
29 changes: 29 additions & 0 deletions tests/data/test_value_extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,32 @@ def test_extract(self, entries, mapper, data):
extractor = ValueExtractor(entries, mapper)
for row, value in data:
self.assertEqual(extractor.extract(row), value)

@test_cases(
[
[
["firstname", "lastname"],
" ".join,
[
({"firstname": "John", "lastname": "Smith"}, "John Smith"),
({"firstname": "Jane", "lastname": "Doe"}, "Jane Doe"),
({"firstname": "John"}, "John"),
({"lastname": "Doe"}, "Doe"),
],
],
[
["value_1", "value_2", "value_3"],
None,
[
({"value_1": 42, "value_2": 12, "value_3": 100}, [42, 12, 100]),
({"value_1": 10, "value_2": 20, "value_3": 30}, [10, 20, 30]),
({"value_1": 42}, [42]),
],
],
]
)
def test_aggregate(self, entries, mapper, data):
"""Tests a value can be aggregated."""
extractor = ValueExtractor(entries, mapper)
for row, value in data:
self.assertEqual(extractor.aggregate(row), value)

0 comments on commit 5a81d90

Please sign in to comment.