-
Notifications
You must be signed in to change notification settings - Fork 24
Block design #24
Block design #24
Changes from 24 commits
72a2bd9
6d6f4d9
7b2d811
4ee38bb
aea2444
d859057
b84e7de
3e1fbc0
aec74ff
8a215de
52d26f6
94ffa99
a19116f
e48ec42
0ebe2a0
1d654dd
6d51079
0d17bb6
fba82b6
e7db4dd
af01c4e
a94c7eb
d06a26d
b7fcb59
8b03d98
cb29984
b49ffa1
c7a49a6
80b426f
e2bc1dc
79278fd
fed9702
030caad
ed9e13b
f78b81d
13701af
0953d9b
e1a5c23
fb48faf
b4088ce
64f971a
41c9144
6f5631a
41009e9
7fb7f67
63d4ea6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,136 @@ | ||||||||||||||||||||||||||||
| # Standard | ||||||||||||||||||||||||||||
| from abc import ABC | ||||||||||||||||||||||||||||
| from typing import Any, Dict, Iterable, List, Optional, Union | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| # Third Party | ||||||||||||||||||||||||||||
| from datasets import Dataset | ||||||||||||||||||||||||||||
| import pandas as pd | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| BLOCK_ROW_TYPE = Union[Dict, pd.Series] | ||||||||||||||||||||||||||||
| BLOCK_INPUT_TYPE = Union[Iterable[BLOCK_ROW_TYPE], pd.DataFrame, Dataset] | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| class BaseBlock(ABC): | ||||||||||||||||||||||||||||
| """Base Class for all Blocks""" | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| def __init__( | ||||||||||||||||||||||||||||
| self, | ||||||||||||||||||||||||||||
| name: str = None, | ||||||||||||||||||||||||||||
| arg_fields: List[str] = None, | ||||||||||||||||||||||||||||
| kwarg_fields: List[str] = None, | ||||||||||||||||||||||||||||
| result_field: str = None, | ||||||||||||||||||||||||||||
| ) -> None: | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| self._name = name | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| # minor type checking | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
| if type(arg_fields) == str: | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
| arg_fields = [arg_fields] | ||||||||||||||||||||||||||||
| if type(kwarg_fields) == str: | ||||||||||||||||||||||||||||
| kwarg_fields = [kwarg_fields] | ||||||||||||||||||||||||||||
| if type(result_field) == list: | ||||||||||||||||||||||||||||
| assert ( | ||||||||||||||||||||||||||||
| len(result_field) == 1 | ||||||||||||||||||||||||||||
| ), "Cannot have multiple 'result' fields for {name}" | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
| result_field = result_field[0] | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| self._arg_fields = arg_fields | ||||||||||||||||||||||||||||
| self._kwarg_fields = kwarg_fields | ||||||||||||||||||||||||||||
| self._result_field = result_field | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||||||
| def name(self): | ||||||||||||||||||||||||||||
| return self._name | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||||||
| def arg_fields(self): | ||||||||||||||||||||||||||||
| return self._arg_fields | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||||||
| def kwarg_fields(self): | ||||||||||||||||||||||||||||
| return self._kwarg_fields | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||||||
| def result_field(self): | ||||||||||||||||||||||||||||
| return self._result_field | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| def generate( | ||||||||||||||||||||||||||||
| self, | ||||||||||||||||||||||||||||
| inputs: BLOCK_INPUT_TYPE, | ||||||||||||||||||||||||||||
| arg_fields: Optional[List[str]] = None, | ||||||||||||||||||||||||||||
| kwarg_fields: Optional[List[str]] = None, | ||||||||||||||||||||||||||||
| result_field: Optional[str] = None, | ||||||||||||||||||||||||||||
gabe-l-hart marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||
| ): | ||||||||||||||||||||||||||||
| raise NotImplementedError | ||||||||||||||||||||||||||||
mvcrouse marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| class BaseUtilityBlock(BaseBlock): | ||||||||||||||||||||||||||||
| pass | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| class BaseGeneratorBlock(BaseBlock): | ||||||||||||||||||||||||||||
| pass | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| class BaseValidatorBlock(BaseBlock): | ||||||||||||||||||||||||||||
| def __init__(self, filter: bool = False, **kwargs: Any) -> None: | ||||||||||||||||||||||||||||
| super().__init__(**kwargs) | ||||||||||||||||||||||||||||
| self._filter_invalids = filter | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| def generate( | ||||||||||||||||||||||||||||
| self, | ||||||||||||||||||||||||||||
| inputs: BLOCK_INPUT_TYPE, | ||||||||||||||||||||||||||||
| arg_fields: Optional[List[str]] = None, | ||||||||||||||||||||||||||||
mvcrouse marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||
| kwarg_fields: Optional[List[str]] = None, | ||||||||||||||||||||||||||||
| result_field: Optional[List[str]] = None, | ||||||||||||||||||||||||||||
| ): | ||||||||||||||||||||||||||||
| outputs = [] | ||||||||||||||||||||||||||||
| for x in inputs: | ||||||||||||||||||||||||||||
| inp_args, inp_kwargs = get_args_kwargs( | ||||||||||||||||||||||||||||
| x, arg_fields or self.arg_fields, kwarg_fields or self.kwarg_fields | ||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
| res = self._validate(*inp_args, **inp_kwargs) | ||||||||||||||||||||||||||||
| if res or not self._filter_invalids: | ||||||||||||||||||||||||||||
| write_result(x, res, result_field or self.result_field) | ||||||||||||||||||||||||||||
| outputs.append(x) | ||||||||||||||||||||||||||||
| return outputs | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| def _validate(self, *args: Any, **kwargs: Any) -> bool: | ||||||||||||||||||||||||||||
| raise NotImplementedError | ||||||||||||||||||||||||||||
mvcrouse marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| def get_args_kwargs( | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
| inp: BLOCK_ROW_TYPE, | ||||||||||||||||||||||||||||
| arg_fields: Optional[List[str]] = None, | ||||||||||||||||||||||||||||
| kwarg_fields: Optional[List[str]] = None, | ||||||||||||||||||||||||||||
| ): | ||||||||||||||||||||||||||||
| if arg_fields is None: | ||||||||||||||||||||||||||||
| arg_fields = [] | ||||||||||||||||||||||||||||
| if kwarg_fields is None: | ||||||||||||||||||||||||||||
| kwarg_fields = [] | ||||||||||||||||||||||||||||
mvcrouse marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| if type(inp) == dict: | ||||||||||||||||||||||||||||
| args = [inp.get(arg) for arg in arg_fields] | ||||||||||||||||||||||||||||
| kwargs = {kwarg: inp.get(kwarg) for kwarg in kwarg_fields} | ||||||||||||||||||||||||||||
| elif type(inp) in [pd.DataFrame, Dataset]: | ||||||||||||||||||||||||||||
| args = [inp.get(arg) for arg in arg_fields] | ||||||||||||||||||||||||||||
| kwargs = {kwarg: inp.get(kwarg) for kwarg in kwarg_fields} | ||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||
| raise ValueError(f"Unexpected input type: {type(inp)}") | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
| if type(inp) == dict: | |
| args = [inp.get(arg) for arg in arg_fields] | |
| kwargs = {kwarg: inp.get(kwarg) for kwarg in kwarg_fields} | |
| elif type(inp) in [pd.DataFrame, Dataset]: | |
| args = [inp.get(arg) for arg in arg_fields] | |
| kwargs = {kwarg: inp.get(kwarg) for kwarg in kwarg_fields} | |
| else: | |
| raise ValueError(f"Unexpected input type: {type(inp)}") | |
| if isinstance(inp, (dict, pd.DataFrame, Dataset): | |
| args = [inp.get(arg) for arg in arg_fields] | |
| kwargs = {kwarg: inp.get(kwarg) for kwarg in kwarg_fields} | |
| else: | |
| raise ValueError(f"Unexpected input type: {type(inp)}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, yes good catch, I had initially put that second elif statement in there as a placeholder. But now revisiting it, I suspect we'll just handle it in the same way as the if statement, so collapsing the two is good
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment here about making this a @staticmethod on BlockBase. It may also be worth making it an instance method and making result_field Optional to fall back to self.result_field
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, yes that was actually my original design, however I was trying to go the free-function route you had mentioned earlier. It was a bit simpler when it was an instance method, as we didn't have to pass the odd result_field or self._result_field as input, perhaps I'll put it back to that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the free-function suggestion was certainly just a thought exercise. I think for these things member/static-member functions are probably good since the type in question is explicitly bound to the base class
mvcrouse marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.