Changelogο
π History of the main changes in the code, in complement to the commit history.
From scripts to a proper packageο
Package structureο
Creation of the marge3D folder, containing a __init__.py file so it can be imported as a python package. Then :
Dtche_J_parameters_3D.py->marge3D/params.pyDtche_J_cls_3D.py->marge3D/numeric.pyAnaly_obj_3D.py->marge3D/analytic.pyVortex_Fld_3D.py->marge3D/fields.py
Consider using short names, to avoid km-long import statements β¦
π‘
VSCodecan be quite useful when moving and renaming files, as it can automatically update all related imports.
Class namingο
Most classes in marge3D have been renamed to follow the standard Python conventions (PEP8), that is :
mr_parameter->DaitcheParametersmaxey_riley_analytic_3d->AnalyticalSolvermaxey_riley_Daitche_3d->NumericalSolvervelocity_field_3d->VelocityField3D
π‘ The
F2renaming option inVSCodeis quite useful to update all dependencies when renaming functions, variables or classes.
Package setupο
Created the pyproject.toml file at the root of the repository, containing this :
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "marge3d"
version = "0.0.1"
description = "Solver for Maxey-Riley-Gatignol (MaRGE) in 3D"
dependencies = [
"numpy",
"scipy",
"matplotlib",
]
requires-python = ">=3.10"
maintainers = [
{name = "Vamika Rathi", email = "vamika.rathi@tuhh.de"},
{name = "Finn Sommer", email = "finn.sommer@tuhh.de"},
]
readme = "README.md"
license = {file = "LICENSE"}
classifiers = [
"Development Status :: 3 - Alpha",
"Topic :: Scientific/Engineering :: Mathematics",
"License :: OSI Approved :: BSD License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
[project.urls]
Homepage = "https://github.com/CompMath-TUHH/MaRGE_3D_solver"
Tracker = "https://github.com/CompMath-TUHH/MaRGE_3D_solver/issues"
This allows to install locally the package now using
pip install -e .
π‘ The
-eoption installs in editable mode, creating link to themarge3dpackage in the Python environment rather than copying the package into it. That way, any local modification on the package is automatically taken into account.
In addition, a base LICENSE file is added in the root folder.
Continuous testingο
added first tests in the tests folder (order convergence VS analytical solution)
added the
testsoptional dependencies inpyproject.toml
# previous content ...
[project.optional-dependencies]
tests = [
"flake8",
"pytest",
]
added the
ci_pipeline.ymlfile in a.github/workflowsfolder, containing :
name: CI pipeline βοΈ
on:
push:
branches: [ "main" ]
pull_request:
jobs:
test-code:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python: ['3.10', '3.11', '3.12', '3.13', '3.14']
defaults:
run:
shell: bash -l {0}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Set up Python ${{ matrix.python }}
uses: actions/setup-python@v4
with:
python-version: "${{ matrix.python }}"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install .[tests]
- name: Lint with flake8
run: |
# stop if there are Python syntax errors or undefined names
flake8 ./marge3d ./tests --count --select=E9,F63,F7,F82 --show-source --statistics
- name: Run pytest
run: |
pytest --continue-on-collection-errors -v --durations=0 ./tests
Now, all tests are run on every commit done to the main branch, but can also be run locally using
pip install -e .[tests]
pytest -v ./tests
Test coverageο
π Itβs nice to have test for your package, itβs better to have coverage analysis checking how much of your code is tested (and preferably 100%).
First, complete the pyproject.toml file with an additional tests dependency (pytest-cov),
and add the following coverage options :
[project.optional-dependencies]
tests = [
"flake8",
"pytest",
"pytest-cov",
"pytest-timeout",
"coverage[toml]",
]
[tool.coverage.run]
relative_files = true
concurrency = ['multiprocessing']
include = ['*/marge3d/*']
[tool.coverage.report]
skip_empty = true
# Regexes for lines to exclude from consideration
exclude_lines = [
# Enable the standard pragma
'pragma: no cover',
# Don't complain if tests don't hit defensive assertion code:
'raise',
'except',
# Ignore footer of scripts
'if __name__ == "__main__":',
]
Now, test can be run with a coverage report using :
pip install -e .[tests]
pytest --cov --cov-branch --cov-report=html -v ./tests
This will generate an HTML report with file-by-file test coverage in the htmlcov/index.html file,
that can open with you favorite browser.
π‘ Note that the
htmlcovfolder is added in the.gitignorefile
Finally, modify the last part of the ci_pipeline.yml file :
- name: Run pytest
run: |
pytest --cov --cov-report=xml -v --durations=0 ./tests
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v5
if: github.repository_owner == 'CompMath-TUHH' && matrix.python == '3.13'
with:
token: ${{ secrets.CODECOV_TOKEN }}
slug: CompMath-TUHH/MaRGE_3D_solver
This will upload a coverage report to codecov each time
a modification is made on the main branch, or when someone do a pull request.
π‘ In particular, it will follow at each code modification if the coverage improved (or not β¦)
Finally, some badges can now be added at the top of the README.md file :
[](https://github.com/CompMath-TUHH/MaRGE_3D_solver)
[](https://github.com/CompMath-TUHH/MaRGE_3D_solver/actions/workflows/ci_pipeline.yml)
[](https://codecov.io/github/CompMath-TUHH/MaRGE_3D_solver)
π‘ The
Coveragebadge must be retrieved directly from the codecov interface
Dedicated scripts folderο
All remaining scripts are moved in a scripts folder, and names are changed to be more explicit :
Analy_obj_3D.py->run_analytical_solution.pyDtche_obj_3D->run_Daitche_solution.pyConv_3D->run_convergence.py
Adding documentationο
In the docs folder is added a documentation template inspired from qmat. In particular, it contains :
the
docsdependencies inpyproject.tomla base
index.rstandconf.pyfile forsphinx(documentation builder)a
logo.pngquickly generated from a plot and some additional CSS and favicon files in_statica
Makefileto easily build the documentation in a_build/htmlfolder using
make html
Setup online documentationο
Use ReadTheDocs to host documentation online,
which requires the .readthedocs.yaml file,
and some configuration on GitHub and ReadTheDocs dashboard.
Once itβs done, a new badge can be added on the top of the main README.md file :
[](https://marge-3d-solver.readthedocs.io/)
π‘ Online documentation will be automatically regenerated and updated at each commit on the
mainbranch.
Setup PyPI packageο
This requires the publish.yml file and setting up of new publisher on PyPI.
Once the latter is set, the Publish to PyPI π¦ workflow has to be triggered manually on the
GitHub action panel
to publish the first package version 0.0.1.
In addition, a first release is done with the tag v0.0.1 on the GitHub releases page.
Also, some new badges can be added to the documentation and main README.md file :
[](https://pypi.org/project/marge3d)
[](https://pypistats.org/packages/marge3d)
Setup the Zenodo releaseο
Once Zenodo is connected to the CompMath-TUHH GitHub organization, then it will follow all releases published on GitHub and create a unique DOI for it.
In particular, one can keep now track of the latest DOI using this Badge :
[](https://doi.org/10.5281/zenodo.17601798)
In addition, the CITATION.cff file is added at the root of the repository.
Improving the packageο
π List of additional steps that help improving the quality of the package and itβs further developments.
β first notebook tutorial
β docs on testing and publishing pipeline
complete docstrings for modules, classes and function
test coverage at 100%
Also, donβt hesitate to check the GitHub issues for targeted potential improvements β¦