Skip to content

Commit 8e60d67

Browse files
authored
3 re organize secondary corrections (#4)
* move secondary models to independent files, rename modules, add README * add missing refs to models * add venv + pip requirements and instructions to readme, update version of matplotlib * change workflow to use pip, update actions so release calls test directly
1 parent 95a89bf commit 8e60d67

25 files changed

Lines changed: 486 additions & 357 deletions

.github/workflows/python-release.yml

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,30 @@
11
name: Create and upload release
22

33
on:
4-
push:
5-
tags:
6-
- 'v*'
4+
workflow_run:
5+
workflows: ["Python Package using pip"]
6+
types:
7+
- completed
78

89
jobs:
9-
test-linux:
10+
release:
11+
# Only run if the triggering run was for a tag starting with v
12+
if: >
13+
github.event.workflow_run.conclusion == 'success' &&
14+
startsWith(github.event.workflow_run.head_branch, 'v')
1015
runs-on: ubuntu-latest
1116
strategy:
1217
max-parallel: 5
1318

1419
steps:
1520
- uses: actions/checkout@v4
1621

17-
- name: Set up Python 3.11.2
18-
uses: actions/setup-python@v3
22+
- name: Download pytest-results artifact from previous workflow
23+
uses: actions/download-artifact@v4
1924
with:
20-
python-version: '3.11.2'
21-
22-
- name: Add conda to system path
23-
run: |
24-
# $CONDA is an environment variable pointing to the root of the miniconda directory
25-
echo $CONDA/bin >> $GITHUB_PATH
26-
27-
- name: Install dependencies
28-
run: |
29-
conda env update --file environment.yaml
30-
31-
- name: Lint with flake8
32-
run: |
33-
conda install flake8
34-
# stop the build if there are Python syntax errors or undefined names
35-
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
36-
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
37-
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
38-
39-
- name: Test with pytest
40-
run: |
41-
source activate bemol
42-
pytest tests/ -vvs
43-
# store the latest run results as release artifact
44-
zip -r pytest-results.zip tests/results/
25+
name: pytest-results
26+
run-id: ${{ github.event.workflow_run.id }}
27+
path: .
4528

4629
- name: Create Release
4730
id: create_release
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1-
name: Python Package using Conda
1+
name: Python Package using pip
2+
3+
on:
4+
push:
5+
branches:
6+
- '*'
7+
tags:
8+
- '*'
29

3-
on: [push]
410

511
jobs:
612
test-linux:
@@ -16,15 +22,11 @@ jobs:
1622
with:
1723
python-version: '3.11.2'
1824

19-
- name: Add conda to system path
20-
run: |
21-
# $CONDA is an environment variable pointing to the root of the miniconda directory
22-
echo $CONDA/bin >> $GITHUB_PATH
23-
2425
- name: Install dependencies
2526
run: |
26-
conda env update --file environment.yaml
27-
conda install flake8
27+
python -m pip install --upgrade pip
28+
pip install -r requirements.txt
29+
pip install flake8
2830
2931
- name: Lint with flake8
3032
run: |
@@ -33,15 +35,27 @@ jobs:
3335
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
3436
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
3537
36-
# TODO: conside the latest release, not a hardcoded one!
38+
# considers the latest release, not a hardcoded one!
3739
- name: Get reference results
3840
run: |
39-
curl -L -o pytest-results.zip "https://github.com/ifpen/bemol/releases/download/v0.0.1/pytest-results.zip"
41+
URL=$(curl -s https://api.github.com/repos/ifpen/bemol/releases/latest \
42+
| jq -r '.assets[] | select(.name=="pytest-results.zip") | .browser_download_url')
43+
if [ -z "$URL" ] || [ "$URL" = "null" ]; then
44+
echo "pytest-results.zip not found in latest release assets"
45+
exit 1
46+
fi
47+
curl -L -o pytest-results.zip "$URL"
4048
unzip pytest-results.zip
4149
mv tests/results tests/ref/
4250
4351
- name: Test with pytest
4452
run: |
45-
source activate bemol
4653
pytest tests/ -vvs --reference tests/ref/
47-
54+
zip -r pytest-results.zip tests/results
55+
56+
- name: Upload pytest-results artifact
57+
uses: actions/upload-artifact@v4
58+
with:
59+
name: pytest-results
60+
path: pytest-results.zip
61+
retention-days: 0.020833 # 30 minutes

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
**/__pycache__/
2-
**/.pytest_cache/
2+
**/.pytest_cache/
3+
4+
/.bemol/

README.md

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,25 @@ The library is based on [Numpy](https://numpy.org/), [Scipy](https://scipy.org/)
8181
[pytest](https://pytest.org/) is as well optional, used for the evaluation
8282
of the tests inside the `tests` sub-folder.
8383

84-
The list of considered/tested versions are available in environment.yaml.
85-
For use with conda:
84+
The list of considered/tested versions are available in conda and pip formats.
8685

87-
```bash
88-
conda env create -f environment.yaml
89-
```
86+
- For use with conda:
87+
88+
```bash
89+
conda env create -f environment.yaml
90+
```
91+
92+
Use `conda activate bemol` to use the env.
93+
94+
- Using pip and venv:
95+
96+
```bash
97+
python3 -m venv .bemol
98+
source .bemol/bin/activate
99+
pip install -r requirements.txt
100+
```
90101

91-
Use `conda activate bemol` to use the env.
102+
Use `source .bemol/bin/activate` to use the env.
92103

93104
## Authors
94105

bemol/bem.py

Lines changed: 2 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -5,60 +5,11 @@
55
import numpy as np
66

77
from . import rotor
8-
from . import secondary
8+
from . import correction
99
from . import tools
1010

1111

1212

13-
14-
class Corrections(object):
15-
"""Class for storing corrections.
16-
17-
Consider all the corrections available in the secondary
18-
models module. If not given by the user considers the base (empty)
19-
correction with the default parameters.
20-
21-
Parameters
22-
----------
23-
corrections : optional
24-
dictionary or list with the secondary corrections, either classes of
25-
instances - in case of custom parameters. If dictionary is
26-
given, the key must be the name of the correction as defined in
27-
secondary.py with a lower first letter.
28-
29-
"""
30-
def __init__(self,corrections:dict={}):
31-
for name, obj in inspect.getmembers(secondary):
32-
if inspect.isclass(obj):
33-
_name = name[0].lower() + name[1:]
34-
if type(corrections) is dict:
35-
if _name in corrections:
36-
# instantiation of correction with default values
37-
corr = corrections[_name]
38-
corr = corr() if isinstance(corr,type) else corr
39-
setattr(self,_name,corr)
40-
else:
41-
setattr(self,_name,obj.Dummy())
42-
else:
43-
effect_name = obj.__qualname__
44-
setattr(self,_name,obj.Dummy())
45-
# loop for all effects to check if any of the input
46-
# corrections are inner of the available corrections
47-
for corr in corrections:
48-
# instantiation of correction with default values
49-
corr = corr() if isinstance(corr,type) else corr
50-
correction_name = type(corr).__qualname__
51-
if effect_name in correction_name:
52-
setattr(self,_name,corr)
53-
break
54-
55-
56-
def __iter__(self):
57-
"""Iterate corrections."""
58-
for value in self.__dict__.values():
59-
yield value
60-
61-
6213
class BaseBEM:
6314
"""Base BEM class.
6415
@@ -89,7 +40,7 @@ def __init__(self,rotor:rotor.Rotor,rho:float=1.225,corrections:dict=None):
8940
self.n = len(rotor.sections)
9041

9142
if corrections is None: corrections = {}
92-
self.corrections = Corrections(corrections)
43+
self.corrections = correction.Corrections(corrections)
9344

9445

9546

bemol/correction.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
2+
import inspect
3+
from types import ModuleType
4+
5+
from . import secondary
6+
7+
8+
class Corrections(object):
9+
"""Class for storing corrections.
10+
11+
Consider all the corrections available in the secondary
12+
models module. If not given by the user considers the base (empty)
13+
correction with the default parameters.
14+
15+
Parameters
16+
----------
17+
corrections : optional
18+
dictionary or list with the secondary corrections, either classes of
19+
instances - in case of custom parameters. If dictionary is
20+
given, the key must be the name of the correction as defined in
21+
secondary.py with a lower first letter.
22+
23+
"""
24+
def __init__(self,corrections:dict={}):
25+
26+
for name_mod, mod in inspect.getmembers(secondary):
27+
if not isinstance(mod,ModuleType): continue
28+
effect_name = name_mod[0].lower() + name_mod[1:]
29+
for name_obj, obj in inspect.getmembers(mod):
30+
if inspect.isclass(obj):
31+
if type(corrections) is dict:
32+
if effect_name in corrections:
33+
# instantiation of correction with default values
34+
corr = corrections[effect_name]
35+
corr = corr() if isinstance(corr,type) else corr
36+
setattr(self,effect_name,corr)
37+
else:
38+
setattr(self,effect_name,mod.Dummy())
39+
else:
40+
setattr(self,effect_name,mod.Dummy())
41+
# loop for all effects to check if any of the input
42+
# corrections are classes of the available corrections
43+
for corr in corrections:
44+
# instantiation of correction with default values
45+
# TODO: check name before instanciating!
46+
corr = corr() if isinstance(corr,type) else corr
47+
if effect_name in corr.__module__:
48+
setattr(self,effect_name,corr)
49+
break
50+
51+
52+
def __iter__(self):
53+
"""Iterate corrections."""
54+
for value in self.__dict__.values():
55+
yield value

0 commit comments

Comments
 (0)