diff --git a/.gitignore b/.gitignore index 6f38c66..df6dbb2 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ src/lorenzpy.egg-info /coverage.xml + +dist diff --git a/CHANGELOG.md b/CHANGELOG.md index 36b728f..774876b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog: ---- + + +### v0.0.1 (16.03.2023) +- First release of `lorenzpy` + ### Pre-release status (13.03.2023): - Now using [pre-commit](https://pre-commit.com/) as an automatic CI tool. - pre-commit runs some standard hooks, black, ruff and mypy. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..a80ae42 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,63 @@ +# Contributing to LorenzPy + +... 🚧 More will come soon ... + +### 🛠️ Setting up the development environment: + +1. Fork and Clone the repository. +2. Install the package with dev-dependencies in an editable way +(from your local clone of the repository): + ```` + pip install -e .[dev,plot] + ```` + This will install: + - `pytest` and `pytest-cov` for testing with coverage. + - `black` and `ruff` for linting. + - `mypy` for type-hinting. + - `mkdocs`, `mkdocstrings[python]` and `mkdocs-material` for + documentation generation. + - `pre-commit` to add a pre-commit hook that includes: + - `trailing-whitespace` and `check-added-large-files` + - `black` + - `ruff` + - `mypy` +3. Install the pre-commit hooks with `pre-commit install` + +After making changes to the code you can: +- (optional) run `pre-commit run --all-files` to manually run the pre-commit hooks. + Otherwise, pre-commit is always run when committing a file. +- Test the code with coverage by running `pytest` +- To see the local docs in your browser, run `mkdocs serve`. +Changes in the code and docs files will be automatically implemented. + +### ✈️ Manual deployment: +⚠️Steps are not fixed yet. +1. Make changes ready for deployment (on seperate branch) + - Modify Documentation according to the code changes. + Observe changes with `mkdocs serve`. + - Run pre-commit (runs automatically when commiting) + - Bump version number in `pyproject.toml` and `lorenzpy/__init__` + - Test everything with `pytest` +2. Create merge request. See if all GitHub actions pass. Merge. +3. (Me) Pull code on `main` branch after MR. +4. (Me) Reinstall package in a fresh venv using `pip install -e .[dev,plot]` +5. (Me) Tag git? Create GH release? +6. (Me) Upload to TestPyPI and PyPI and GH docs: + - Run `python -m pip install --upgrade build twine` + - To build run `python -m build` + - To upload to Test PyPI: run `python -m twine upload --repository testpypi dist/*` + - Test the package installation from Test PyPI by running: + ``` + pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple lorenzpy + ``` + - To upload to PyPI run `twine upload dist/*` + - Upload new docs by running: ``mkdocs gh-deploy`` + +### 📚 Some resources: + +| Element | Resources | +|------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| General Python Packaging | [Python Packages E-book](https://py-pkgs.org/), [Creating an open source Python project from scratch](https://jacobtomlinson.dev/series/creating-an-open-source-python-project-from-scratch/), [PyPA Packaging Python Projects](https://packaging.python.org/en/latest/tutorials/packaging-projects/) | +| Documentation with MKdocs | [Real Python Tutorial](https://realpython.com/python-project-documentation-with-mkdocs/), [Latex in MKdocs](https://squidfunk.github.io/mkdocs-material/reference/mathjax/#docsjavascriptsmathjaxjs) | +| Other repos using `setuptools` with `pyproject.toml` | [modern-python-package](https://github.com/dkmiller/modern-python-package), [py-tiny-pkg](https://github.com/denkiwakame/py-tiny-pkg) | +| Markdown | [The Markdown Guide](https://www.markdownguide.org/), [GitHub Basic writing and formatting syntax](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax) | diff --git a/README.md b/README.md index f5df1c5..d756b2a 100644 --- a/README.md +++ b/README.md @@ -6,35 +6,61 @@ [![license: MIT](https://img.shields.io/badge/License-MIT-purple.svg)](LICENSE) [![Python versions](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/) -## 🚧 Under construction 🚧 -There is no release of the package yet and most of the functionalities are missing. -For now only the basic functionalities are implemented in order to build up the -developing workflow. +## ⚙️ Installation -## Documentation: -The documentation can be found here: https://duncdennis.github.io/lorenzpy/ +To install only the core functionality: +```bash +$ pip install lorenzpy +``` -## Installation: +To install with the additional plotting functionality. +This also installs `plotly`. +```bash +$ pip install lorenzpy[plot] +``` -#### User installation: -Only the core LorenzPy functionality: +## ▶️ Usage -`` -pip install . -`` +LorenzPy can be used to simulate and measure chaotic dynamical systems. +The following example shows how to simulate the famous +[Lorenz63 system](https://de.wikipedia.org/wiki/Lorenz-Attraktor), and measure its +largest [Lyapunov exponent](https://en.wikipedia.org/wiki/Lyapunov_exponent) from the +Lorenz63 iterator: -With plotting functionalities: +````python +import lorenzpy as lpy -`` -pip install .[plot] -`` +# Initialize the Lorenz63 simulation object with a RK4 time step of dt=0.05 +l63_obj = lpy.simulations.Lorenz63(dt=0.05) -#### Developer installation: -`` -pip install -e .[dev,plot] -`` +# Simulate 5000 steps of the Lorenz63 system: +data = l63_obj.simulate(5000) # -> data.shape = (5000,3) +# Calculate the largest Lyapunov exponent from the l63_obj iterator: +iterator = l63_obj.iterate +lle = lpy.measures.largest_lyapunov_exponent( + iterator_func=iterator, + starting_point=l63_obj.default_starting_point, + dt=l63_obj.dt +) +# -> lle = 0.905144329... +```` -## Resources: -#### Similar package: *pynamical* -https://github.com/gboeing/pynamical +The calculated largest Lyapunov exponent of *0.9051...* is very close to the literature +value of *0.9056*[^SprottChaos]. + +## 📗 Documentation + +- The main documentation can be found here: https://duncdennis.github.io/lorenzpy/ + - ⚠️: The documentation is not in a useful state. +## ⚠️ Further notes: +- So far the usefulness of this package is very limited. +The authors main purpose to creating this package was to learn the full workflow to +develop a Python package. +More information about the development process can be found in [CONTRIBUTING.md](CONTRIBUTING.md). +- The plotting functionality, which can be installed with ``pip install lorenzpy[plot]`` is not tested so far. +- See [Pynamical](https://github.com/gboeing/pynamical) for a similar package + +[^SprottChaos]: + Sprott, Julien Clinton, and Julien C. Sprott. Chaos and time-series analysis. Vol. 69. + Oxford: Oxford university press, 2003. diff --git a/docs/javascripts/mathjax.js b/docs/javascripts/mathjax.js new file mode 100644 index 0000000..06dbf38 --- /dev/null +++ b/docs/javascripts/mathjax.js @@ -0,0 +1,16 @@ +window.MathJax = { + tex: { + inlineMath: [["\\(", "\\)"]], + displayMath: [["\\[", "\\]"]], + processEscapes: true, + processEnvironments: true + }, + options: { + ignoreHtmlClass: ".*|", + processHtmlClass: "arithmatex" + } +}; + +document$.subscribe(() => { + MathJax.typesetPromise() +}) diff --git a/mkdocs.yml b/mkdocs.yml index d74c374..053ea0b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,7 +1,21 @@ site_name: LorenzPy Docs +repo_url: https://github.com/DuncDennis/lorenzpy + +watch: + - src + theme: name: "material" plugins: - mkdocstrings + +markdown_extensions: + - pymdownx.arithmatex: + generic: true + +extra_javascript: + - javascripts/mathjax.js + - https://polyfill.io/v3/polyfill.min.js?features=es6 + - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js diff --git a/pyproject.toml b/pyproject.toml index 15b0014..39b01ee 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,22 +4,28 @@ readme = "README.md" version = "0.0.1" description = "A Python package to simulate and measure chaotic dynamical systems." authors = [ - { name = "Dennis Duncan", email = "DuncDennis@gmail.com" } + {name = "Dennis Duncan", email = "DuncDennis@gmail.com"}, ] +maintainers = [ + {name = "Dennis Duncan", email = "DuncDennis@gmail.com"} +] +license = { file = "LICENSE" } requires-python = ">=3.8" -license = { file = "LICENSE.txt" } classifiers = [ "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ] dependencies = [ - "numpy==1.24.2", + "numpy>=1.22.0", ] [project.urls] -"Documentation" = "https://duncdennis.github.io/lorenzpy/" -"Homepage" = "https://github.com/DuncDennis/lorenzpy" +homepage = "https://github.com/DuncDennis/lorenzpy" +repository = "https://github.com/DuncDennis/lorenzpy" +documentation = "https://duncdennis.github.io/lorenzpy/" +changelog = "https://github.com/DuncDennis/lorenzpy/blob/main/CHANGELOG.md" + [project.optional-dependencies] dev = [ @@ -34,7 +40,7 @@ dev = [ "pre-commit==3.1.1", # add version? ] plot = [ - "plotly==5.13.1", + "plotly>=5.11", ] [tool.pytest.ini_options] diff --git a/src/lorenzpy/plot/__init__.py b/src/lorenzpy/plot/__init__.py index 876f6c3..d1626c9 100644 --- a/src/lorenzpy/plot/__init__.py +++ b/src/lorenzpy/plot/__init__.py @@ -1,3 +1 @@ """Submodule to plot chaotic dynamics systems.""" - -from .plot_3d import test_plotting diff --git a/src/lorenzpy/plot/plot_3d.py b/src/lorenzpy/plot/plot_3d.py index 52792c1..2da2f25 100644 --- a/src/lorenzpy/plot/plot_3d.py +++ b/src/lorenzpy/plot/plot_3d.py @@ -5,7 +5,7 @@ DEFAULT_FIGSIZE = (650, 500) -def test_plotting(time_series: np.ndarray) -> None: +def plot_3d(time_series: np.ndarray) -> None: """Plot simple three-dim time series.""" fig = go.Figure() fig.update_layout(height=DEFAULT_FIGSIZE[1], width=DEFAULT_FIGSIZE[0])