Skip to content

Commit

Permalink
Repository initialization (#1)
Browse files Browse the repository at this point in the history
Signed-off-by: Sylvain Leclerc <[email protected]>
  • Loading branch information
sylvlecl authored Feb 12, 2024
1 parent 5c851a2 commit 2cead04
Show file tree
Hide file tree
Showing 62 changed files with 7,889 additions and 0 deletions.
53 changes: 53 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: CI
on:
push:
branches:
- "**"

jobs:
ci:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.11
cache: pip
cache-dependency-path: |
requirements.txt
requirements-dev.txt
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt -r requirements-dev.txt
- name: Check imports sort order
uses: isort/isort-action@v1
with:
sort-paths: src, tests
configuration: --profile black --check-only --diff
requirements-files: "requirements.txt requirements-dev.txt"

- name: Check formatting
uses: psf/black@stable
with:
# Version of Black should match the versions set in `requirements-dev.txt`
version: "~=23.7.0"
options: --check --diff

- name: Check typing
run: |
python -m mypy
- name: Test
run: |
pytest --cov antarest --cov-report xml
- name: Archive code coverage results
uses: actions/upload-artifact@v3
with:
name: python-code-coverage-report
path: coverage.xml
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.vscode
__pycache__
**.ipynb
prof

.idea
venv
.env
.coverage
coverage.xml
27 changes: 27 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
repos:
- repo: local
hooks:
- id: mypy
name: Run mypy
entry: mypy
language: system
files: ^src/
types: [python]

- repo: local
hooks:
- id: black
name: Run black
entry: black
args: ["--config", "pyproject.toml"]
language: system
types: [python]

- repo: local
hooks:
- id: isort
name: Run isort
entry: isort
args: ["--profile", "black", "--filter-files"]
language: system
types: [python]
10 changes: 10 additions & 0 deletions AUTHORS.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Github identifiers of authors, in alphabetical order:

flomnes
ianmnz
klorel
MartinBelthle
pet-mit
sylvlecl
tbittar
vargastat
8 changes: 8 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[mypy]
mypy_path = src
packages = andromede
disallow_untyped_defs = true
disallow_untyped_calls = true

[mypy-ortools.*]
ignore_missing_imports = true
19 changes: 19 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[project]
name = "andromede_modeling_prototype"
version = "0.0.1"
license = {text="MPL-2.0"}
dependencies = [
"ortools"
]

[tool.setuptools.packages.find]
# All the following settings are optional:
where = ["src"]

[tool.black]
line-length = 88
include = '\.pyi?$'
4 changes: 4 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[pytest]
pythonpath = src
testpaths = tests
log_cli = true
6 changes: 6 additions & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pytest~=7.0.0
mypy~=1.7.1
black~=23.7.0
isort~=5.12.0
pytest-cov
pre-commit~=3.5.0
6 changes: 6 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
absl-py==1.4.0
numpy==1.24.4
ortools==9.6.2534
protobuf==4.23.3
scipy==1.10.1

11 changes: 11 additions & 0 deletions src/andromede/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright (c) 2024, RTE (https://www.rte-france.com)
#
# See AUTHORS.txt
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# SPDX-License-Identifier: MPL-2.0
#
# This file is part of the Antares project.
39 changes: 39 additions & 0 deletions src/andromede/expression/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright (c) 2024, RTE (https://www.rte-france.com)
#
# See AUTHORS.txt
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# SPDX-License-Identifier: MPL-2.0
#
# This file is part of the Antares project.

from .copy import CopyVisitor, copy_expression
from .degree import ExpressionDegreeVisitor, compute_degree
from .evaluate import EvaluationContext, EvaluationVisitor, ValueProvider, evaluate
from .evaluate_parameters import (
ParameterResolver,
ParameterValueProvider,
resolve_parameters,
)
from .expression import (
AdditionNode,
Comparator,
ComparisonNode,
DivisionNode,
ExpressionNode,
LiteralNode,
MultiplicationNode,
NegationNode,
ParameterNode,
SubstractionNode,
VariableNode,
literal,
param,
sum_expressions,
var,
)
from .print import PrinterVisitor, print_expr
from .visitor import ExpressionVisitor, visit
53 changes: 53 additions & 0 deletions src/andromede/expression/context_adder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Copyright (c) 2024, RTE (https://www.rte-france.com)
#
# See AUTHORS.txt
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# SPDX-License-Identifier: MPL-2.0
#
# This file is part of the Antares project.

from dataclasses import dataclass

from . import CopyVisitor
from .expression import (
ComponentParameterNode,
ComponentVariableNode,
ExpressionNode,
ParameterNode,
VariableNode,
)
from .visitor import visit


@dataclass(frozen=True)
class ContextAdder(CopyVisitor):
"""
Simply copies the whole AST but associates all variables and parameters
to the provided component ID.
"""

component_id: str

def variable(self, node: VariableNode) -> ExpressionNode:
return ComponentVariableNode(self.component_id, node.name)

def parameter(self, node: ParameterNode) -> ExpressionNode:
return ComponentParameterNode(self.component_id, node.name)

def comp_parameter(self, node: ComponentParameterNode) -> ExpressionNode:
raise ValueError(
"This expression has already been associated to another component."
)

def comp_variable(self, node: ComponentVariableNode) -> ExpressionNode:
raise ValueError(
"This expression has already been associated to another component."
)


def add_component_context(id: str, expression: ExpressionNode) -> ExpressionNode:
return visit(expression, ContextAdder(id))
110 changes: 110 additions & 0 deletions src/andromede/expression/copy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Copyright (c) 2024, RTE (https://www.rte-france.com)
#
# See AUTHORS.txt
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# SPDX-License-Identifier: MPL-2.0
#
# This file is part of the Antares project.

from dataclasses import dataclass
from typing import List, Union, cast

from .expression import (
AdditionNode,
ComparisonNode,
ComponentParameterNode,
ComponentVariableNode,
DivisionNode,
ExpressionNode,
ExpressionRange,
InstancesTimeIndex,
LiteralNode,
MultiplicationNode,
NegationNode,
ParameterNode,
PortFieldAggregatorNode,
PortFieldNode,
ScenarioOperatorNode,
SubstractionNode,
TimeAggregatorNode,
TimeOperatorNode,
VariableNode,
)
from .visitor import ExpressionVisitor, ExpressionVisitorOperations, T, visit


@dataclass(frozen=True)
class CopyVisitor(ExpressionVisitorOperations[ExpressionNode]):
"""
Simply copies the whole AST.
"""

def comp_parameter(self, node: ComponentParameterNode) -> ExpressionNode:
return ComponentParameterNode(node.component_id, node.name)

def comp_variable(self, node: ComponentVariableNode) -> ExpressionNode:
return ComponentVariableNode(node.component_id, node.name)

def literal(self, node: LiteralNode) -> ExpressionNode:
return LiteralNode(node.value)

def comparison(self, node: ComparisonNode) -> ExpressionNode:
return ComparisonNode(
visit(node.left, self), visit(node.right, self), node.comparator
)

def variable(self, node: VariableNode) -> ExpressionNode:
return VariableNode(node.name)

def parameter(self, node: ParameterNode) -> ExpressionNode:
return ParameterNode(node.name)

def copy_expression_range(
self, expression_range: ExpressionRange
) -> ExpressionRange:
return ExpressionRange(
start=visit(expression_range.start, self),
stop=visit(expression_range.stop, self),
step=visit(expression_range.step, self)
if expression_range.step is not None
else None,
)

def copy_instances_index(
self, instances_index: InstancesTimeIndex
) -> InstancesTimeIndex:
expressions = instances_index.expressions
if isinstance(expressions, ExpressionRange):
return InstancesTimeIndex(self.copy_expression_range(expressions))
if isinstance(expressions, list):
expressions_list = cast(List[ExpressionNode], expressions)
copy = [visit(e, self) for e in expressions_list]
return InstancesTimeIndex(copy)
raise ValueError("Unexpected type in instances index")

def time_operator(self, node: TimeOperatorNode) -> ExpressionNode:
return TimeOperatorNode(
visit(node.operand, self),
node.name,
self.copy_instances_index(node.instances_index),
)

def time_aggregator(self, node: TimeAggregatorNode) -> ExpressionNode:
return TimeAggregatorNode(visit(node.operand, self), node.name, node.stay_roll)

def scenario_operator(self, node: ScenarioOperatorNode) -> ExpressionNode:
return ScenarioOperatorNode(visit(node.operand, self), node.name)

def port_field(self, node: PortFieldNode) -> ExpressionNode:
return PortFieldNode(node.port_name, node.field_name)

def port_field_aggregator(self, node: PortFieldAggregatorNode) -> ExpressionNode:
return PortFieldAggregatorNode(visit(node.operand, self), node.aggregator)


def copy_expression(expression: ExpressionNode) -> ExpressionNode:
return visit(expression, CopyVisitor())
Loading

0 comments on commit 2cead04

Please sign in to comment.