From 0c2b4d77c643c220a56cb9bf8ec261818c90f6d3 Mon Sep 17 00:00:00 2001 From: Alexis Maya-Isabelle Shuping Date: Tue, 1 Oct 2024 18:02:06 -0500 Subject: [PATCH] Cleanup and refactor --- CONTRIBUTING.md | 6 +- environment.yml | 1 + {modules => exseos}/args/ArgumentProvider.py | 2 +- {modules => exseos}/data/Variable.py | 18 +++-- {modules => exseos}/report/ReportProvider.py | 2 +- {modules => exseos}/types/ComparableError.py | 2 +- {modules => exseos}/types/Either.py | 30 +++++---- {modules => exseos}/types/Option.py | 31 +++++---- {modules => exseos}/types/Result.py | 49 +++++++++----- {modules => exseos}/types/__init__.py | 62 +++++++++-------- {modules => exseos}/workflow/Workflow.py | 38 ++++++----- .../workflow/WorkflowModule.py | 8 +-- {modules => exseos}/workflow/__init__.py | 4 +- {modules => exseos}/workflow/stage/Stage.py | 39 ++++++----- .../workflow/stage/StageFromFunction.py | 14 ++-- modules/data/BasicDataStore.py | 42 ------------ modules/data/NoneDataStore.py | 17 ----- modules/experiment/Constraint.py | 67 ------------------- modules/experiment/Parameter.py | 17 ----- modules/experiment/Result.py | 17 ----- test.ipynb | 4 +- test/data/test_Variable.py | 6 +- test/types/test_ComparableError.py | 2 +- test/types/test_Either.py | 2 +- test/types/test_Option.py | 2 +- test/types/test_Result.py | 4 +- test/types/test_types.py | 6 +- test/workflow/stage/test_StageFromFunction.py | 8 +-- 28 files changed, 191 insertions(+), 309 deletions(-) rename {modules => exseos}/args/ArgumentProvider.py (94%) rename {modules => exseos}/data/Variable.py (94%) rename {modules => exseos}/report/ReportProvider.py (94%) rename {modules => exseos}/types/ComparableError.py (98%) rename {modules => exseos}/types/Either.py (85%) rename {modules => exseos}/types/Option.py (82%) rename {modules => exseos}/types/Result.py (88%) rename {modules => exseos}/types/__init__.py (73%) rename {modules => exseos}/workflow/Workflow.py (77%) rename {modules => exseos}/workflow/WorkflowModule.py (83%) rename {modules => exseos}/workflow/__init__.py (90%) rename {modules => exseos}/workflow/stage/Stage.py (79%) rename {modules => exseos}/workflow/stage/StageFromFunction.py (87%) delete mode 100644 modules/data/BasicDataStore.py delete mode 100644 modules/data/NoneDataStore.py delete mode 100644 modules/experiment/Constraint.py delete mode 100644 modules/experiment/Parameter.py delete mode 100644 modules/experiment/Result.py diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 14b57f4..d996483 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -90,6 +90,10 @@ with spaces on your end and have `git` automatically perform the conversion to tabs. You might want to use `ruff` instead of `expand` for a cross-platform solution that will also apply the rest of the project styling on commit! +Note also that, when writing docstrings, it is preferred to put the first line +of documentation on the line *below* the opening quotes, rather than on the same +line. + We use [Ruff](https://docs.astral.sh/ruff/) for code linting and formatting. To check your code, run `ruff check`. To automatically format your code, run `ruff format`. Note that certain rules are relaxed for test cases (for example, @@ -134,7 +138,7 @@ our test code can be found in the [`test`](blob/main/test) directory. We ask that you try to maximize test coverage of any code that you contribute. We use [Codecov](https://about.codecov.io/) to calculate coverage percentage for commits and pull requests. You can check the coverage locally using pytest: -`python -m pytest test --cov-report xml:cov.xml --cov modules` +`python -m pytest test --cov-report xml --cov exseos` This will generate an XML coverage report, which can be read by several IDE extensions (for example, [Coverage diff --git a/environment.yml b/environment.yml index f82f67f..e9dc3b5 100644 --- a/environment.yml +++ b/environment.yml @@ -1,6 +1,7 @@ name: exseos-h channels: - conda-forge + - nodefaults dependencies: - python=3.12 - patch diff --git a/modules/args/ArgumentProvider.py b/exseos/args/ArgumentProvider.py similarity index 94% rename from modules/args/ArgumentProvider.py rename to exseos/args/ArgumentProvider.py index 3df8abb..01f6963 100644 --- a/modules/args/ArgumentProvider.py +++ b/exseos/args/ArgumentProvider.py @@ -1,5 +1,5 @@ """ -Chicory ML Workflow Manager +ExSeOS-H Hardware ML Workflow Manager Copyright (C) 2024 Alexis Maya-Isabelle Shuping This program is free software: you can redistribute it and/or modify diff --git a/modules/data/Variable.py b/exseos/data/Variable.py similarity index 94% rename from modules/data/Variable.py rename to exseos/data/Variable.py index 505386a..330395d 100644 --- a/modules/data/Variable.py +++ b/exseos/data/Variable.py @@ -1,5 +1,5 @@ """ -Chicory ML Workflow Manager +ExSeOS-HLS Hardware ML Workflow Manager Copyright (C) 2024 Alexis Maya-Isabelle Shuping This program is free software: you can redistribute it and/or modify @@ -16,8 +16,8 @@ along with this program. If not, see . """ -from modules.types import common -from modules.types.Option import Option, Nothing, Some +from exseos.types import common +from exseos.types.Option import Option, Nothing, Some from abc import ABC, abstractmethod import logging @@ -29,7 +29,8 @@ class Variable[A](ABC): - """Stores a quantity whose value can vary from workflow to workflow, + """ + Stores a quantity whose value can vary from workflow to workflow, controlled either statically (manually set in configuration) or dynamically (controlled by an optimizer) """ @@ -37,7 +38,8 @@ class Variable[A](ABC): @property @abstractmethod def is_bound(self) -> bool: - """`True` iff this variable has been bound to a value. + """ + `True` iff this variable has been bound to a value. Note that `Variable.val` will only return a value if the variable is bound; otherwise, a `TypeError` will be raised. @@ -59,7 +61,8 @@ def desc(self) -> Option[str]: @property @abstractmethod def val(self) -> A: - """The bound value of this Variable. Only exists if `is_bound` is True; + """ + The bound value of this Variable. Only exists if `is_bound` is True; otherwise, a `TypeError` will be raised. """ ... # pragma: no cover @@ -73,7 +76,8 @@ def var_type(self) -> Option[type]: @property @abstractmethod def var_type_inferred(self) -> bool: - """True if `var_type` was automatically inferred (and thus potentially + """ + True if `var_type` was automatically inferred (and thus potentially inaccurate); False if it was explicitly provided. """ ... # pragma: no cover diff --git a/modules/report/ReportProvider.py b/exseos/report/ReportProvider.py similarity index 94% rename from modules/report/ReportProvider.py rename to exseos/report/ReportProvider.py index 6937301..4be45f1 100644 --- a/modules/report/ReportProvider.py +++ b/exseos/report/ReportProvider.py @@ -1,5 +1,5 @@ """ -Chicory ML Workflow Manager +ExSeOS-H Hardware ML Workflow Manager Copyright (C) 2024 Alexis Maya-Isabelle Shuping This program is free software: you can redistribute it and/or modify diff --git a/modules/types/ComparableError.py b/exseos/types/ComparableError.py similarity index 98% rename from modules/types/ComparableError.py rename to exseos/types/ComparableError.py index d7d35b7..c38a63b 100644 --- a/modules/types/ComparableError.py +++ b/exseos/types/ComparableError.py @@ -1,5 +1,5 @@ """ -Chicory ML Workflow Manager +ExSeOS-H Hardware ML Workflow Manager Copyright (C) 2024 Alexis Maya-Isabelle Shuping This program is free software: you can redistribute it and/or modify diff --git a/modules/types/Either.py b/exseos/types/Either.py similarity index 85% rename from modules/types/Either.py rename to exseos/types/Either.py index cf4af48..f4c34fa 100644 --- a/modules/types/Either.py +++ b/exseos/types/Either.py @@ -1,5 +1,5 @@ """ -Chicory ML Workflow Manager +ExSeOS-H Hardware ML Workflow Manager Copyright (C) 2024 Alexis Maya-Isabelle Shuping This program is free software: you can redistribute it and/or modify @@ -16,7 +16,7 @@ along with this program. If not, see . """ -from modules.types.ComparableError import ComparableError +from exseos.types.ComparableError import ComparableError from typing import TypeVar, Callable from abc import ABC, abstractmethod @@ -43,40 +43,44 @@ def is_right(self) -> bool: @property @abstractmethod def val(self) -> B: - """Return the inner value of a Right. + """ + Return the inner value of a Right. - @warning Raises a TypeError if called on a Left. + :raises TypeError: If called on a Left. """ ... # pragma: no cover @property @abstractmethod def lval(self) -> B: - """Return the inner value of a Left. + """ + Return the inner value of a Left. - @warning Raises a TypeError if called on a Right. + :raises TypeError: if called on a Right. """ ... # pragma: no cover @abstractmethod def map(self, f: Callable[[B], C]) -> "Either[A, C]": - """If this Either is a Right, call `f` on its rval and return a Right() - of the result. + """ + If this Either is a Right, call `f` on its rval and return a Right() of + the result. - If it is a Left, do not call `f` and just return a Left() of the - lval. + If it is a Left, do not call `f` and just return a Left() of the lval. """ ... # pragma: no cover @abstractmethod def flat_map(self, f: Callable[[B], "Either[A, C]"]) -> "Either[A, C]": - """Similar to Map, except that `f` should convert `B`'s directly into - an `Either`. + """ + Similar to Map, except that `f` should convert `B`'s directly into an + `Either`. """ ... # pragma: no cover def __eq__(self, other) -> bool: - """Returns True iff both Eithers being compared are the same type (i.e. + """ + Returns True iff both Eithers being compared are the same type (i.e. both Left or both Right) AND the relevant inner values are the same. """ if not issubclass(type(other), Either): diff --git a/modules/types/Option.py b/exseos/types/Option.py similarity index 82% rename from modules/types/Option.py rename to exseos/types/Option.py index d03e5fd..a25b30a 100644 --- a/modules/types/Option.py +++ b/exseos/types/Option.py @@ -1,5 +1,5 @@ """ -Chicory ML Workflow Manager +ExSeOS-H Hardware ML Workflow Manager Copyright (C) 2024 Alexis Maya-Isabelle Shuping This program is free software: you can redistribute it and/or modify @@ -16,7 +16,7 @@ along with this program. If not, see . """ -from modules.types.ComparableError import ComparableError +from exseos.types.ComparableError import ComparableError from typing import TypeVar, Callable from abc import ABC, abstractmethod @@ -41,16 +41,18 @@ def has_val(self) -> bool: @property @abstractmethod def val(self) -> A: - """Return the inner value of a `Some[A]`. + """ + Return the inner value of a `Some[A]`. - @warning Raises a TypeError if called on `Nothing`. + :raises TypeError: if called on `Nothing`. """ ... # pragma: no cover @abstractmethod def map(self, f: Callable[[A], B]) -> "Option[B]": - """If this is `Some[A]`, call `f` on its value and return a `Some[B]` - of the result. + """ + If this is `Some[A]`, call `f` on its value and return a `Some[B]` of + the result. If it is `Nothing`, do not call `f` and just return `Nothing`. @@ -61,24 +63,25 @@ def map(self, f: Callable[[A], B]) -> "Option[B]": @abstractmethod def flat_map(self, f: Callable[[A], "Option[B]"]) -> "Option[B]": - """Similar to Map, except that `f` should convert `A`'s directly into + """ + Similar to Map, except that `f` should convert `A`'s directly into `Option[B]`'s. - :param f: A function that takes an `A` and converts it to an - `Option[B]` + :param f: A function that takes an `A` and converts it to an `Option[B]` :returns: `f(a)` if this `Option` is `Some(a)`, else `Nothing()` """ ... # pragma: no cover @staticmethod def make_from(obj: any) -> "Option[A]": - """Convenience method to ensure an object is an Option. If `obj` is - already an Option, it is returned as-is. If `obj` is None, it is - converted to `Nothing()`. Otherwise, it is converted to `Some(obj)` + """ + Convenience method to ensure an object is an Option. If `obj` is already + an Option, it is returned as-is. If `obj` is None, it is converted to + `Nothing()`. Otherwise, it is converted to `Some(obj)` :param obj: The object to encapsulate - :returns: `obj` if `obj` is an Option; otherwise, `Some(obj)` if obj - is not None; otherwise, `Nothing()`. + :returns: `obj` if `obj` is an Option; otherwise, `Some(obj)` if obj is + not None; otherwise, `Nothing()`. """ ... # pragma: no cover diff --git a/modules/types/Result.py b/exseos/types/Result.py similarity index 88% rename from modules/types/Result.py rename to exseos/types/Result.py index 5bb457a..2988571 100644 --- a/modules/types/Result.py +++ b/exseos/types/Result.py @@ -1,5 +1,5 @@ """ -Chicory ML Workflow Manager +ExSeOS-H Hardware ML Workflow Manager Copyright (C) 2024 Alexis Maya-Isabelle Shuping This program is free software: you can redistribute it and/or modify @@ -16,7 +16,7 @@ along with this program. If not, see . """ -from modules.types.ComparableError import ComparableError +from exseos.types.ComparableError import ComparableError from typing import TypeVar, Callable, List from abc import ABC, abstractmethod @@ -28,15 +28,16 @@ class Result[A, B, C](ABC): - """Represents the result of a computation. + """ + Represents the result of a computation. Can either be `Okay[C]`, `Warning[B, C]`, or `Error[A, B]`. `val` of type `C` represents the return type of the computation. It is present in `Okay` and `Warning` types, but not `Error` types. - `warn` of type `B` represents non-fatal warnings. It is present in - `Warning` and `Error` types, but not `Okay` types. + `warn` of type `B` represents non-fatal warnings. It is present in `Warning` + and `Error` types, but not `Okay` types. `err` of type `A` represents fatal errors. It is only present in `Error` types. @@ -63,42 +64,53 @@ def is_error(self) -> bool: @property @abstractmethod def val(self) -> C: - """Return the result of the computation. + """ + Return the result of the computation. - This is present for `Okay` and `Warning` types. It is NOT present - for `Error` types. + This is present for `Okay` and `Warning` types. It is NOT present for + `Error` types. + + :raises TypeError: if called on an `Error` """ ... # pragma: no cover @property @abstractmethod def warnings(self) -> List[B]: - """Return the list of warnings generated during the computation. + """ + Return the list of warnings generated during the computation. - This is present for `Warning` and `Error` types. It is NOT present - for `Okay` types. + This is present for `Warning` and `Error` types. It is NOT present for + `Okay` types. + + :raises TypeError: if called on an `Okay` """ ... # pragma: no cover @property @abstractmethod def errors(self) -> List[A]: - """Return the list of fatal errors generated during the computation. + """ + Return the list of fatal errors generated during the computation. This is only present for `Error` types. + + :raises TypeError: if called on an `Okay` or `Warning` """ ... # pragma: no cover @abstractmethod def map(self, f: Callable[[C], D]) -> "Result[A, B, D]": - """If this `Result` is `Okay` or `Warning`, call `f` on its value and + """ + If this `Result` is `Okay` or `Warning`, call `f` on its value and return an `Okay` or `Warning` of the result. """ ... # pragma: no cover @abstractmethod def flat_map(self, f: Callable[[C], "Result[A, B, D]"]) -> "Result[A, B, D]": - """If this `Result` is `Okay` or `Warning`, call `f` on its value and + """ + If this `Result` is `Okay` or `Warning`, call `f` on its value and return the output, which must itself be a `Result`. """ ... # pragma: no cover @@ -154,7 +166,8 @@ def __eq__(self, other): class Okay[C](Result): - """Represents a computation that has succeeded without any errors or warnings. + """ + Represents a computation that has succeeded without any errors or warnings. Has a `val`, but no `warnings` or `errors` """ @@ -197,7 +210,8 @@ def __str__(self) -> str: class Warning[B, C](Result): - """Represents a computation that encountered non-fatal errors. + """ + Represents a computation that encountered non-fatal errors. Has a `val` and `warnings`, but no `errors` """ @@ -247,7 +261,8 @@ def __str__(self) -> str: class Error[A, B](Result): - """Represents a computation which failed with errors. + """ + Represents a computation which failed with errors. Has `warnings` and `errors`, but no `val`. """ diff --git a/modules/types/__init__.py b/exseos/types/__init__.py similarity index 73% rename from modules/types/__init__.py rename to exseos/types/__init__.py index 29f30d1..21a144d 100644 --- a/modules/types/__init__.py +++ b/exseos/types/__init__.py @@ -1,5 +1,5 @@ """ -Chicory ML Workflow Manager +ExSeOS-H Hardware ML Workflow Manager Copyright (C) 2024 Alexis Maya-Isabelle Shuping This program is free software: you can redistribute it and/or modify @@ -16,19 +16,21 @@ along with this program. If not, see . """ -from modules.types.Result import Result, Okay, Warning, Error +from exseos.types.Result import Result, Okay, Warning, Error from abc import ABC from typing import Generic class BroadCommonTypeWarning(Exception): - """Used when looking for common types. When the common type between two - values is extremely broad (e.g. `object`), this warning is given. + """ + Used when looking for common types. When the common type between two values + is extremely broad (e.g. `object`), this warning is given. """ def __init__(self, types: list[any], common: type, note: str = ""): - """Construct a BroadCommonTypeWarning. + """ + Construct a BroadCommonTypeWarning. :param types: List of types that triggered this warning. :param common: The common type that triggered this warning. @@ -55,7 +57,8 @@ def __init__(self, types: list[any], common: type, note: str = ""): class NoCommonTypeError(Exception): def __init__(self, types: list[any], note: str = ""): - """Construct a NoCommonTypeError + """ + Construct a NoCommonTypeError :param types: List of types that triggered this error :param note: Further information about this error @@ -79,30 +82,31 @@ def __init__(self, types: list[any], note: str = ""): def type_check(val: any, t: type) -> bool: - """Perform a basic, permissive type-check, ensuring that `val` can be + """ + Perform a basic, permissive type-check, ensuring that `val` can be reasonably considered to have type `t`. - This function is used internally for basic verification of, e.g., - `Variable` values. It considers subclasses, but it does not consider any - of the more complex, type-annotation style details. For example, `t` can - be a `list`, but not a `list[str]`. + This function is used internally for basic verification of, e.g., `Variable` + values. It considers subclasses, but it does not consider any of the more + complex, type-annotation style details. For example, `t` can be a `list`, + but not a `list[str]`. - :param val: The value to check - :param t: The type that `val` should have - :returns: Whether `val` has type `t` + :param val: The value to check + :param t: The type that `val` should have + :returns: Whether `val` has type `t` """ return issubclass(type(val), t) def common_t(a: type, b: type) -> Result[Exception, Exception, type]: - """As `common`, except that `a` and `b` are types rather than values. + """ + As `common`, except that `a` and `b` are types rather than values. :param a: The first type to compare :param b: The second type to compare :returns: `Okay(t)` where `t` is the most specific common type, or - `Warning(BroadCommonTypeWarning, t)` if the common type is too - broad, or `Error(NoCommonTypeError)` if there is no common type at - all. + `Warning(BroadCommonTypeWarning, t)` if the common type is too broad, or + `Error(NoCommonTypeError)` if there is no common type at all. """ if issubclass(b, a): return Okay(a) @@ -143,22 +147,22 @@ def _candidate_search(a, b, ignore_broad=True): def common(a: any, b: any) -> Result[Exception, Exception, type]: - """Return the most specifc type that `a` and `b` have in common. + """ + Return the most specifc type that `a` and `b` have in common. - If `a` and `b` have an extremely broad common type (e.g. `object`), then - the result will include a `BroadCommonTypeWarning`. If there is no - common type at all, the result will be a `NoCommonTypeError`. + If `a` and `b` have an extremely broad common type (e.g. `object`), then the + result will include a `BroadCommonTypeWarning`. If there is no common type + at all, the result will be a `NoCommonTypeError`. - Note that if `a` and `b` have the same type, or if one is a subclass of - the other, the result will always be `Okay()`, even if one or the - other's type is `object`. `BroadCommonTypeWarning` only applies when - this function has to look for 'common ancestors.' + Note that if `a` and `b` have the same type, or if one is a subclass of the + other, the result will always be `Okay()`, even if one or the other's type + is `object`. `BroadCommonTypeWarning` only applies when this function has to + look for 'common ancestors.' :param a: The first value to compare :param b: The second value to compare :returns: `Okay(t)` where `t` is the most specific common type, or - `Warning(BroadCommonTypeWarning, t)` if the common type is too - broad, or `Error(NoCommonTypeError)` if there is no common type at - all. + `Warning(BroadCommonTypeWarning, t)` if the common type is too broad, or + `Error(NoCommonTypeError)` if there is no common type at all. """ return common_t(type(a), type(b)) diff --git a/modules/workflow/Workflow.py b/exseos/workflow/Workflow.py similarity index 77% rename from modules/workflow/Workflow.py rename to exseos/workflow/Workflow.py index 4f65508..aaf5b82 100644 --- a/modules/workflow/Workflow.py +++ b/exseos/workflow/Workflow.py @@ -1,5 +1,5 @@ """ -Chicory ML Workflow Manager +ExSeOS-H Hardware ML Workflow Manager Copyright (C) 2024 Alexis Maya-Isabelle Shuping This program is free software: you can redistribute it and/or modify @@ -19,14 +19,15 @@ import logging import random -from modules.data.Variable import Variable, UnboundVariable -from modules.types.Option import Some +from exseos.data.Variable import Variable, UnboundVariable +from exseos.types.Option import Some log = logging.get_logger(__name__) class Workflow: - """Base class for Workflows. + """ + Base class for Workflows. Instead of instantiating this directly, use `MakeWorkflow`. """ @@ -36,8 +37,9 @@ def __init__(self, stages, inputs=[], outputs=[]): class MakeWorkflow: - """Workflow factory. Use this class to construct a Workflow that can then - be instantiated. + """ + Workflow factory. Use this class to construct a Workflow that can then be + instantiated. """ def __init__(self, name=None): @@ -50,14 +52,15 @@ def __init__(self, name=None): self.outputs = [] def given(self, *args, **kwargs): - """Add one or more inputs to the Workflow. + """ + Add one or more inputs to the Workflow. - Arguments should either be `Variable`s or strings. In the latter - case, appropriate variables are created for the strings. + Arguments should either be `Variable`s or strings. In the latter case, + appropriate variables are created for the strings. Keyword arguments may be provided - these are interpreted as default - values for the variable. For example, providing `my_var=1` creates a - new `UnboundVariable` called `my_var` with a default value of `1`. + values for the variable. For example, providing `my_var=1` creates a new + `UnboundVariable` called `my_var` with a default value of `1`. Keyword argument names must, of course, be strings. To provide a pre-existing `Variable` with a default value, the default must be @@ -75,11 +78,11 @@ def given(self, *args, **kwargs): self.inputs.append(UnboundVariable(kwarg, default=Some(kwdefault))) def output(self, *args): - """Add one or more outputs to the Workflow. + """ + Add one or more outputs to the Workflow. - Arguments should either be `Variable`s or strings. In the latter - case, wiring will search for the latest `Variable` with the provided - name. + Arguments should either be `Variable`s or strings. In the latter case, + wiring will search for the latest `Variable` with the provided name. """ for arg in args: if issubclass(type(arg), Variable): @@ -94,6 +97,7 @@ def from_stages(self, *args): self.stages = args def __call__(self, *args, **kwargs): - """Instantiate the Workflow and bind the provided arguments to its - inputs. """ + Instantiate the Workflow and bind the provided arguments to its inputs. + """ + raise NotImplementedError \ No newline at end of file diff --git a/modules/workflow/WorkflowModule.py b/exseos/workflow/WorkflowModule.py similarity index 83% rename from modules/workflow/WorkflowModule.py rename to exseos/workflow/WorkflowModule.py index d995b1b..81fcc94 100644 --- a/modules/workflow/WorkflowModule.py +++ b/exseos/workflow/WorkflowModule.py @@ -1,5 +1,5 @@ """ -Chicory ML Workflow Manager +ExSeOS-H Hardware ML Workflow Manager Copyright (C) 2024 Alexis Maya-Isabelle Shuping This program is free software: you can redistribute it and/or modify @@ -16,9 +16,9 @@ along with this program. If not, see . """ -from modules.data import DataStore -from modules.args.ArgumentProvider import ArgumentProvider -from modules.report.ReportProvider import ReportProvider +from exseos.data import DataStore +from exseos.args.ArgumentProvider import ArgumentProvider +from exseos.report.ReportProvider import ReportProvider import logging diff --git a/modules/workflow/__init__.py b/exseos/workflow/__init__.py similarity index 90% rename from modules/workflow/__init__.py rename to exseos/workflow/__init__.py index 4b9b952..7b015d5 100644 --- a/modules/workflow/__init__.py +++ b/exseos/workflow/__init__.py @@ -1,5 +1,5 @@ """ -Chicory ML Workflow Manager +ExSeOS-H Hardware ML Workflow Manager Copyright (C) 2024 Alexis Maya-Isabelle Shuping This program is free software: you can redistribute it and/or modify @@ -16,7 +16,7 @@ along with this program. If not, see . """ -from modules.report.ReportProvider import ReportProvider +from exseos.report.ReportProvider import ReportProvider import logging diff --git a/modules/workflow/stage/Stage.py b/exseos/workflow/stage/Stage.py similarity index 79% rename from modules/workflow/stage/Stage.py rename to exseos/workflow/stage/Stage.py index 4457944..bd116ec 100644 --- a/modules/workflow/stage/Stage.py +++ b/exseos/workflow/stage/Stage.py @@ -1,5 +1,5 @@ """ -Chicory ML Workflow Manager +ExSeOS-H Hardware ML Workflow Manager Copyright (C) 2024 Alexis Maya-Isabelle Shuping This program is free software: you can redistribute it and/or modify @@ -16,8 +16,8 @@ along with this program. If not, see . """ -from modules.data.Variable import Variable, UnboundVariable -from modules.types.Option import Option, Some, Nothing +from exseos.data.Variable import Variable, UnboundVariable +from exseos.types.Option import Option, Some, Nothing from dataclasses import dataclass from abc import ABC, abstractmethod @@ -26,7 +26,8 @@ def _process_stage_io( dex: int, i: Variable, args: list[Variable | str], kwargs: dict[str, Variable | str] ) -> Option[Variable]: - """Match a single input (or output) from our variable list to the provided + """ + Match a single input (or output) from our variable list to the provided parameters. :param dex: Offset in our input `Variable` list for `i` @@ -51,12 +52,12 @@ def __atov(a: Variable | str) -> Variable: class Stage(ABC): - """Represents a Stage - something that can be used as a step in a Workflow. + """ + Represents a Stage - something that can be used as a step in a Workflow. Stages are immutable - their inputs (and outputs, if applicable), do not - change once set. Functions modifying Stages will return a new Stage with - the desired modifications, rather than modifying the existing Stage - in-place. + change once set. Functions modifying Stages will return a new Stage with the + desired modifications, rather than modifying the existing Stage in-place. """ input_vars: tuple[UnboundVariable] = () @@ -68,7 +69,8 @@ def __init__( _to: tuple[list[str | Variable], dict[str, str | Variable]] = ([], {}), **kwargs: dict[str, str | Variable], ): - """Create a Stage and bind its input variables. + """ + Create a Stage and bind its input variables. All arguments should be either `Variable`s or strings. Strings are automatically converted to `UnboundVariable`s. Keyword arguments are @@ -97,13 +99,12 @@ def __init__( @abstractmethod def run(self, inputs: list[Variable]) -> "StageResult": - """Run this stage, returning a StageResult containing output - information. + """ + Run this stage, returning a StageResult containing output information. - :param inputs: A list of all `Variables` needed for this `Stage` to - run. - :returns: A `StageResult` containing output `Variable`s for this - `Stage`. + :param inputs: A list of all `Variables` needed for this `Stage` to run. + :returns: A `StageResult` containing output `Variable`s for this + `Stage`. """ ... # pragma: no cover @@ -114,13 +115,15 @@ def _input_bindings(self) -> list[Variable]: @property def _output_bindings(self) -> Option[list[Variable]]: - """An `Option`al list of Output bindings for this stage. Used for - internal wiring. + """ + An `Option`al list of Output bindings for this stage. Used for internal + wiring. """ return self.__outputs def to(self, *args, **kwargs) -> "Stage": - """Bind the outputs of the `Stage` to a `Variable` or name. + """ + Bind the outputs of the `Stage` to a `Variable` or name. :param args: Outputs to be bound by position :params kwargs: Outputs to be bound by name diff --git a/modules/workflow/stage/StageFromFunction.py b/exseos/workflow/stage/StageFromFunction.py similarity index 87% rename from modules/workflow/stage/StageFromFunction.py rename to exseos/workflow/stage/StageFromFunction.py index 8ac703a..b3ea5af 100644 --- a/modules/workflow/stage/StageFromFunction.py +++ b/exseos/workflow/stage/StageFromFunction.py @@ -1,5 +1,5 @@ """ -Chicory ML Workflow Manager +ExSeOS-H Hardware ML Workflow Manager Copyright (C) 2024 Alexis Maya-Isabelle Shuping This program is free software: you can redistribute it and/or modify @@ -16,9 +16,9 @@ along with this program. If not, see . """ -from modules.data.Variable import Variable, UnboundVariable -from modules.types.Option import Option, Some, Nothing -from modules.workflow.stage.Stage import Stage, StageResult +from exseos.data.Variable import Variable, UnboundVariable +from exseos.types.Option import Option, Some, Nothing +from exseos.workflow.stage.Stage import Stage, StageResult from abc import abstractmethod import inspect @@ -59,9 +59,9 @@ def _extract_func_args_and_ret(fn: Callable) -> tuple[list[Variable], Option[Var Extract the arguments and (if present) return-type annotation from a function. - :param fn: The function to extract data from. - :returns: A tuple whose first element is the list of input `Variable`s - and the second element is an `Option`al return-type `Variable` + :param fn: The function to extract data from. + :returns: A tuple whose first element is the list of input `Variable`s + and the second element is an `Option`al return-type `Variable` """ sig = inspect.signature(fn) diff --git a/modules/data/BasicDataStore.py b/modules/data/BasicDataStore.py deleted file mode 100644 index 3babe62..0000000 --- a/modules/data/BasicDataStore.py +++ /dev/null @@ -1,42 +0,0 @@ -""" -Chicory ML Workflow Manager -Copyright (C) 2024 Alexis Maya-Isabelle Shuping - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -""" - -from modules.data import DataStore - - -class BasicDataStore[T](DataStore): - """ - Basic data store that keeps all of its values in memory. - """ - - def __init__(self, label: str): - self.__label = label - self.__data = {} - - @property - def label(self) -> str: - return self.__label - - def insert(self, label: str, t: T) -> bool: - if label in self.__data.keys: - return False - else: - self.__data[label] = t - - def __iter__(self): - return self.__data.items() diff --git a/modules/data/NoneDataStore.py b/modules/data/NoneDataStore.py deleted file mode 100644 index 9113c70..0000000 --- a/modules/data/NoneDataStore.py +++ /dev/null @@ -1,17 +0,0 @@ -""" -Chicory ML Workflow Manager -Copyright (C) 2024 Alexis Maya-Isabelle Shuping - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -""" diff --git a/modules/experiment/Constraint.py b/modules/experiment/Constraint.py deleted file mode 100644 index 5590193..0000000 --- a/modules/experiment/Constraint.py +++ /dev/null @@ -1,67 +0,0 @@ -""" -Chicory ML Workflow Manager -Copyright (C) 2024 Alexis Maya-Isabelle Shuping - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -""" - -from enum import Enum - - -class Strategy(Enum): - """Enumeration containing strategies for handling constraint failures.""" - - # Fail immediately if the Constraint is not met - FAIL = 1 - - # If the Constraint is not met, clamp the failing value to the nearest - # acceptable one. - CLAMP = 2 - - # If the Constraint is not met, set the failing value to a constant. - SET = 3 - - -class Constraint: - """Defines a constraint on the experiment. - - Constraints ensure that a value at a specific stage of the experiment is - within acceptable parameters. They can also constrain pre-experiment - operations such as I/O wiring - see `WiringConstraint` - - """ - - pass - - -class RangeConstraint(Constraint): - """Constrains a value to be within a specified range.""" - - pass - - -class EqualsConstraint(Constraint): - """Constrains a value to be equal to a specified constant""" - - pass - - -class WiringConstraint(Constraint): - """Constrains the automatic wiring system. - - This can be used to override the default wiring for a specific Input or - Variable. - """ - - pass diff --git a/modules/experiment/Parameter.py b/modules/experiment/Parameter.py deleted file mode 100644 index 9113c70..0000000 --- a/modules/experiment/Parameter.py +++ /dev/null @@ -1,17 +0,0 @@ -""" -Chicory ML Workflow Manager -Copyright (C) 2024 Alexis Maya-Isabelle Shuping - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -""" diff --git a/modules/experiment/Result.py b/modules/experiment/Result.py deleted file mode 100644 index 9113c70..0000000 --- a/modules/experiment/Result.py +++ /dev/null @@ -1,17 +0,0 @@ -""" -Chicory ML Workflow Manager -Copyright (C) 2024 Alexis Maya-Isabelle Shuping - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -""" diff --git a/test.ipynb b/test.ipynb index a7753bb..5f3d08f 100644 --- a/test.ipynb +++ b/test.ipynb @@ -93,7 +93,7 @@ "metadata": {}, "outputs": [], "source": [ - "from modules.types.Either import Either, Left, Right" + "from exseos.types.Either import Either, Left, Right" ] }, { @@ -183,7 +183,7 @@ "metadata": {}, "outputs": [], "source": [ - "from modules.types.Result import Result, Okay, Warning, Error" + "from exseos.types.Result import Result, Okay, Warning, Error" ] }, { diff --git a/test/data/test_Variable.py b/test/data/test_Variable.py index cd0cbf3..4b8b5e6 100644 --- a/test/data/test_Variable.py +++ b/test/data/test_Variable.py @@ -1,5 +1,5 @@ """ -Chicory ML Workflow Manager +ExSeOS-H Hardware ML Workflow Manager Copyright (C) 2024 Alexis Maya-Isabelle Shuping This program is free software: you can redistribute it and/or modify @@ -16,8 +16,8 @@ along with this program. If not, see . """ -from modules.data.Variable import UnboundVariable, BoundVariable -from modules.types.Option import Nothing, Some +from exseos.data.Variable import UnboundVariable, BoundVariable +from exseos.types.Option import Nothing, Some def test_is_bound(): diff --git a/test/types/test_ComparableError.py b/test/types/test_ComparableError.py index 4e2beb4..17e66ee 100644 --- a/test/types/test_ComparableError.py +++ b/test/types/test_ComparableError.py @@ -1,4 +1,4 @@ -from modules.types.ComparableError import ComparableError +from exseos.types.ComparableError import ComparableError def test_get_exc(): diff --git a/test/types/test_Either.py b/test/types/test_Either.py index 7362788..10b377e 100644 --- a/test/types/test_Either.py +++ b/test/types/test_Either.py @@ -1,6 +1,6 @@ from pytest import raises -from modules.types.Either import Either, Left, Right +from exseos.types.Either import Either, Left, Right def test_is_right(): diff --git a/test/types/test_Option.py b/test/types/test_Option.py index 3c928b7..14a363e 100644 --- a/test/types/test_Option.py +++ b/test/types/test_Option.py @@ -1,6 +1,6 @@ from pytest import raises -from modules.types.Option import Option, Nothing, Some +from exseos.types.Option import Option, Nothing, Some def test_has_val(): diff --git a/test/types/test_Result.py b/test/types/test_Result.py index a4d5204..92de824 100644 --- a/test/types/test_Result.py +++ b/test/types/test_Result.py @@ -1,7 +1,7 @@ from pytest import raises -from modules.types.ComparableError import ComparableError -from modules.types.Result import Okay, Warning, Error +from exseos.types.ComparableError import ComparableError +from exseos.types.Result import Okay, Warning, Error def test_is_okay(): diff --git a/test/types/test_types.py b/test/types/test_types.py index d7fb6f3..fedd346 100644 --- a/test/types/test_types.py +++ b/test/types/test_types.py @@ -1,5 +1,5 @@ """ -Chicory ML Workflow Manager +ExSeOS-H Hardware ML Workflow Manager Copyright (C) 2024 Alexis Maya-Isabelle Shuping This program is free software: you can redistribute it and/or modify @@ -18,8 +18,8 @@ from abc import ABC -from modules.types.Result import Okay, Warning, Error -from modules.types import ( +from exseos.types.Result import Okay, Warning, Error +from exseos.types import ( type_check, common, common_t, diff --git a/test/workflow/stage/test_StageFromFunction.py b/test/workflow/stage/test_StageFromFunction.py index 0b6a598..b1c7a1c 100644 --- a/test/workflow/stage/test_StageFromFunction.py +++ b/test/workflow/stage/test_StageFromFunction.py @@ -1,5 +1,5 @@ """ -Chicory ML Workflow Manager +ExSeOS-H Hardware ML Workflow Manager Copyright (C) 2024 Alexis Maya-Isabelle Shuping This program is free software: you can redistribute it and/or modify @@ -16,9 +16,9 @@ along with this program. If not, see . """ -from modules.data.Variable import BoundVariable, UnboundVariable -from modules.workflow.stage.StageFromFunction import make_StageFromFunction -from modules.types.Option import Some +from exseos.data.Variable import BoundVariable, UnboundVariable +from exseos.workflow.stage.StageFromFunction import make_StageFromFunction +from exseos.types.Option import Some def test_basic_function():