Ideas for Writer architecture #669
NicolasGensollen
started this conversation in
Ideas
Replies: 2 comments
-
A slightly modified implementation with more dynamicity using the factory pattern: import json
from pathlib import Path
from abc import ABC, abstractmethod
from typing import Type, Any
from enum import Enum
class WriterName(str, Enum):
CAPS_DATASET = "caps_dataset"
ADAM_OPTIMIER = "adam_optimizer"
class Writable(ABC):
"""All object that can be written in MAPS implement this interface."""
@abstractmethod
def get_writer_name(self) -> WriterName:
...
def write(self, folder: Path) -> None:
writer = writer_factory(self.get_writer_name()).from_instance(self)
writer.write(folder)
class Writer(ABC):
"""Base class for writers."""
@abstractmethod
def to_dict(self) -> dict:
...
@abstractmethod
def get_filename(self) -> str:
...
@classmethod
@abstractmethod
def from_instance(cls, instance: Any):
...
def write(self, folder: Path) -> None:
folder.mkdir(parents=True, exist_ok=True)
with open(folder / self.get_filename(), "w") as fp:
json.dump(self.to_dict(), fp)
def writer_factory(name: str | WriterName) -> Type[Writer]:
name = WriterName(name)
if name == WriterName.CAPS_DATASET:
return CAPSDatasetWriter
if name == WriterName.ADAM_OPTIMIER:
return AdamOptimizerWriter
class Dataset(ABC):
"All dataset implement this interface."""
@abstractmethod
def some_common_dataset_method(self) -> None:
...
class CAPSDataset(Dataset, Writable):
def __init__(self, size: int):
self.size = size
def some_common_dataset_method(self) -> None:
print("I'm a CAPS dataset.")
def get_writer_name(self) -> WriterName:
return WriterName.CAPS_DATASET
class CAPSDatasetWriter(Writer):
"""Writer for CAPSDataset."""
def __init__(self, dataset_size: int):
self.dataset_size = dataset_size
@classmethod
def from_instance(cls, dataset: CAPSDataset):
"""Alternative constructor."""
return cls(dataset.size)
def to_dict(self) -> dict:
return {"DatasetSize": self.dataset_size}
def get_filename(self) -> str:
return "dataset.json"
class Optimizer(ABC):
"""All optimizer implement this interface."""
@abstractmethod
def optimize(self, iteration: int) -> None:
...
class AdamOptimizer(Optimizer, Writable):
def __init__(self, max_iteration: int):
self.max_iteration = max_iteration
def optimize(self, iteration: int) -> None:
for i in range(min(iteration, self.max_iteration)):
print("Optimizing...")
def get_writer_name(self) -> WriterName:
return WriterName.ADAM_OPTIMIER
class AdamOptimizerWriter(Writer):
"""Writer for Adam optimizer."""
def __init__(self, max_iteration: int):
self.max_iteration = max_iteration
@classmethod
def from_instance(cls, optimizer: AdamOptimizer):
"""Alternative constructor."""
return cls(optimizer.max_iteration)
def to_dict(self) -> dict:
return {"MaxIteration": self.max_iteration}
def get_filename(self) -> str:
return "optimizer.json" |
Beta Was this translation helpful? Give feedback.
0 replies
-
Finally, a more straightforward design without the Writer classes which are strongly coupled to their counterparts and which might not be useful: import json
from pathlib import Path
from abc import ABC, abstractmethod
class Writable(ABC):
"""All object that can be written in MAPS implement this interface."""
@abstractmethod
def to_dict(self) -> dict:
...
@abstractmethod
def get_filename(self) -> str:
...
def write(self, folder: Path) -> None:
folder.mkdir(parents=True, exist_ok=True)
with open(folder / self.get_filename(), "w") as fp:
json.dump(self.to_dict(), fp)
class Dataset(ABC):
"All dataset implement this interface."""
@abstractmethod
def some_common_dataset_method(self) -> None:
...
class CAPSDataset(Dataset, Writable):
def __init__(self, size: int):
self.size = size
def some_common_dataset_method(self) -> None:
print("I'm a CAPS dataset.")
def to_dict(self) -> dict:
return {"DatasetSize": self.size}
def get_filename(self) -> str:
return "dataset.json"
class Optimizer(ABC):
"""All optimizer implement this interface."""
@abstractmethod
def optimize(self, iteration: int) -> None:
...
class AdamOptimizer(Optimizer, Writable):
def __init__(self, max_iteration: int):
self.max_iteration = max_iteration
def optimize(self, iteration: int) -> None:
for i in range(min(iteration, self.max_iteration)):
print("Optimizing...")
def to_dict(self) -> dict:
return {"MaxIteration": self.max_iteration}
def get_filename(self) -> str:
return "optimizer.json" |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Hi,
I've been doing some thinking after our discussion yesterday.
If you want to group the writing logic in the same module without having a huge class doing everything, you can have an architecture that would look more or less like that (classes and methods are only unrealistic toy examples to show the idea):
This would be used in the following way:
Beta Was this translation helpful? Give feedback.
All reactions