diff --git a/.cz.toml b/.cz.toml index 570b859b..a1215f5c 100644 --- a/.cz.toml +++ b/.cz.toml @@ -1,6 +1,6 @@ [tool.commitizen] name = "cz_conventional_commits" -version = "2.3.3" +version = "2.3.5" version_provider = "poetry" version_files = [ "pyproject.toml", diff --git a/.github/workflows/publish-to-dockerhub.yml b/.github/workflows/publish-to-dockerhub.yml index bc3bd6b4..3ae520bd 100644 --- a/.github/workflows/publish-to-dockerhub.yml +++ b/.github/workflows/publish-to-dockerhub.yml @@ -57,12 +57,6 @@ jobs: id: push uses: docker/build-push-action@v5 with: + platforms: linux/amd64,linux/arm64 tags: hypernetx/hypernetx:latest push: true - - - name: Generate artifact attestation - uses: actions/attest-build-provenance@v1 - with: - subject-name: hypernetx/hypernetx - subject-digest: ${{ steps.push.outputs.digest }} - push-to-registry: true diff --git a/LONG_DESCRIPTION.rst b/LONG_DESCRIPTION.rst index ee816721..e6c85f3c 100644 --- a/LONG_DESCRIPTION.rst +++ b/LONG_DESCRIPTION.rst @@ -1,7 +1,7 @@ .. _long_description: HyperNetX -================= +========= The HyperNetX library provides classes and methods for the analysis and visualization of complex network data modeled as hypergraphs. @@ -25,7 +25,7 @@ Documentation is available at: https://pnnl.github.io/HyperNetX For questions and comments contact the developers directly at: hypernetx@pnnl.gov HyperNetX 2.3 -============= +~~~~~~~~~~~~~ HyperNetX 2.3. is the latest, stable release. The core library has been refactored to take better advantage of Pandas Dataframes, improve readability and maintainability, address bugs, and make it easier to change. diff --git a/Makefile b/Makefile index b40349d4..bf36b44f 100644 --- a/Makefile +++ b/Makefile @@ -66,7 +66,7 @@ lint: pylint flake8 .PHONY: pylint pylint: - @$(PYTHON3) -m pylint --recursive=y --persistent=n --verbose hypernetx + @$(PYTHON3) -m pylint --recursive=y --persistent=n --exit-zero --verbose hypernetx # Todo: fix flake8 errors and remove --exit-zero .PHONY: flake8 diff --git a/README.md b/README.md index 0f0bd772..231b6ce6 100644 --- a/README.md +++ b/README.md @@ -235,41 +235,57 @@ After the container has started, access the HyperNetX Jupyter Notebooks by openi [http://localhost:8888/tree](http://localhost:8888/tree) -Development -=========== +# Development -Install an editable version -``` -pip install -e . -``` +As a developer, set up your environment using either the standard `pip` tool or [`Poetry`](https://python-poetry.org/). + +## Using Pip -Install additional dependencies to support testing and jupyter notebooks: +### Setup virtual environment and install HNX + +Create a virtual environement. Then install an editable version of HNX and also install additional dependencies to support testing and jupyter notebooks: ``` +python -m venv venv-hnx +source venv-hnx/bin/activate +pip install -e . pip install -r requirements.txt ``` -You can also install all these requirements in one Make target: +As an alternative, you can also install all these requirements in one Make target: ``` +make venv +source venv-hnx/bin/activate make install ``` -Poetry -====== +### Setup pre-commit + +Use the [pre-commit framework](https://pre-commit.com/) to automatically point out issues and resolve those issues before code review. +It is highly recommended to install pre-commit in your development environment so that issues with your code can be found before you submit a +pull request. More importantly, using pre-commit will automatically format your code changes so that they pass the CI build. For example, pre-commit will +automatically run the formatter Black on your code changes. + +```shell +# Once installed, pre-commit will be triggered every time you make a commit in your environment +pre-commit install +``` + + +## Using Poetry This library uses [Poetry](https://python-poetry.org/docs/) to manage dependencies and packaging. Poetry can also be used to manage your environment for development. -Prerequisites -------------- +### Prerequisites * [Install Poetry](https://python-poetry.org/docs/#installation) -Configure Poetry ----------------- +### Configure Poetry + +[Configure your Poetry](https://python-poetry.org/docs/configuration/) to ensure that the virtual environment gets created in your project directory (this is not necessary but recommended for convenience): -[Configure your Poetry](https://python-poetry.org/docs/configuration/) to create the virtual environment in your project directory: ``` poetry config virtualenvs.in-project true @@ -277,21 +293,38 @@ poetry config virtualenvs.in-project true poetry config --list ``` -Set up virtual environment ----------------------------- +### Setup virtual environment and install HNX Create and activate a virtual environment. + ``` poetry shell ``` -Install required dependencies and HyperNetX in editable mode. +Install HyperNetX in editable mode, the library's core/required dependencies, and the optional dependencies to support development. + ``` -poetry install +poetry install --with test,lint,docs,release,tutorials ``` -Install support for testing ------------------------------ +Details about these dependencies are defined in [pyproject.toml](pyproject.toml). + +### Setup Pre-commit + +Use the [pre-commit framework](https://pre-commit.com/) to automatically point out issues and resolve those issues before code review. +It is highly recommended to install pre-commit in your development environment so that issues with your code can be found before you submit a +pull request. More importantly, using pre-commit will automatically format your code changes so that they pass the CI build. For example, pre-commit will +automatically run the formatter Black on your code changes. + +```shell +# Once installed, pre-commit will be triggered every time you make a commit in your environment +pre-commit install +``` + +### Details about optional dependencies + +#### Install support for testing + > ℹ️ **NOTE:** This project has pytest configuration contained in pyproject.toml. By default, pytest will use those configuration settings to run tests. @@ -312,8 +345,7 @@ coverage html open htmlcov/index.html ``` -Install support for tutorials ------------------------------ +#### Install support for tutorials ```shell poetry install --with tutorials @@ -325,8 +357,8 @@ poetry shell make tutorials ``` -Code Quality ------------- +#### Code Quality: Pylint, Black + HyperNetX uses a number of tools to maintain code quality: * Pylint @@ -341,8 +373,6 @@ poetry install --with lint poetry shell ``` -Pylint ------- [Pylint](https://pylint.pycqa.org/en/latest/index.html) is a static code analyzer for Python-based projects. From the [Pylint docs](https://pylint.pycqa.org/en/latest/index.html#what-is-pylint): @@ -362,8 +392,6 @@ pylint hypernetx --output=pylint-results.txt For more information on configuration, see https://pylint.pycqa.org/en/latest/user_guide/configuration/index.html -Black ------ [Black](https://black.readthedocs.io/en/stable/) is a PEP 8 compliant formatter for Python-based project. This tool is highly opinionated about how Python should be formatted and will automagically reformat your code. @@ -371,21 +399,7 @@ Black black hypernetx ``` -Pre-commit ---------- - -Use the [pre-commit framework](https://pre-commit.com/) to automatically point out issues and resolve those issues before code review. -It is highly recommended to install pre-commit in your development environment so that issues with your code can be found before you submit a -pull request. More importantly, using pre-commit will automatically format your code changes so that they pass the CI build. For example, pre-commit will -automatically run the formatter Black on your code changes. - -```shell -# Once installed, pre-commit will be triggered every time you make a commit in your environment -pre-commit install -``` - -Documentation -------------- +### Documentation Build and view documentation locally: @@ -422,13 +436,14 @@ The HTML pages are in docs/html. Click on [http://127.0.0.1:8000/install.html](http://127.0.0.1:8000/install.html) to open the docs on your browser. Since this will auto-rebuild, every time you change a document file, it will automatically render on your browser, allowing you to verify your document changes. -Testing the Docker Image ------------------------- + +## Developing and Testing the Docker Image If you want to test the Docker image after making any source code changes, follow this workflow: 1. Make a change in the HNX codebase -2. Build image: `docker build --rm --tag hypernetx/hypernetx:latest` +2. Build image for multi-platforms (i.e.ARM64, x86): `docker build --platform linux/amd64,linux/arm64 --rm --tag hypernetx/hypernetx:latest .` + 3. If you're having issues building, see https://docs.docker.com/desktop/containerd/ 3. Test image: `docker run -it --rm -p 8888:8888 -v "${PWD}":/home/jovyan/work hypernetx/hypernetx:latest` 4. Open a browser to [http://localhost:8888/tree](http://localhost:8888/tree). Check that tutorials still work and/or open a notebook and test the changes that you made. 5. Once finished testing, kill the container using Ctrl-C diff --git a/docs/source/conf.py b/docs/source/conf.py index c72b4246..fc65e2c6 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -19,7 +19,7 @@ import os -__version__ = "2.3.3" +__version__ = "2.3.5" # If extensions (or modules to document with autodoc) are in another directory, diff --git a/hypernetx/__init__.py b/hypernetx/__init__.py index 3ea7c6f7..6a19503d 100644 --- a/hypernetx/__init__.py +++ b/hypernetx/__init__.py @@ -11,4 +11,4 @@ from hypernetx.utils import * from hypernetx.utils.toys import * -__version__ = "2.3.3" +__version__ = "2.3.5" diff --git a/hypernetx/algorithms/hypergraph_modularity.py b/hypernetx/algorithms/hypergraph_modularity.py index e91f2db3..f29efe3b 100644 --- a/hypernetx/algorithms/hypergraph_modularity.py +++ b/hypernetx/algorithms/hypergraph_modularity.py @@ -183,7 +183,7 @@ def modularity(HG, A, wdc=linear): _df = pd.DataFrame(zip(_keys, _vals), columns=["key", "val"]) _df = _df.groupby(by="key").sum() EC = sum( - [wdc(k[1], k[0]) * v[0] for (k, v) in _df.iterrows() if k[0] > k[1] / 2] + [wdc(k[1], k[0]) * v.iloc[0] for (k, v) in _df.iterrows() if k[0] > k[1] / 2] ) ## Degree Tax @@ -292,6 +292,12 @@ def two_section(HG): w = 1 / (len(E) - 1) s.extend([(k[0], k[1], w) for k in itertools.combinations(E, 2)]) G = ig.Graph.TupleList(s, weights=True).simplify(combine_edges="sum") + + ## add isolates if any + isolates = list(set([v for v in HG.nodes]) - set(G.vs['name'])) + if len(isolates)>0: + G.add_vertices(isolates) + return G @@ -392,17 +398,17 @@ def _last_step_weighted(H, A, wdc, delta=0.01, verbose=False): n_moves = 0 for v in list(np.random.permutation(list(H.nodes))): dct_A_v = dct_A[v] - H_id = [H.incidence_dict[x] for x in H.nodes[v].memberships] + H_id = [H.incidence_dict[x] for x in H.nodes[v]] L = [[dct_A[i] for i in x] for x in H_id] ## ec portion before move _keys = [(Counter(l).most_common(1)[0][1], len(l)) for l in L] - _vals = [H.edges[x].weight for x in H.nodes[v].memberships] + _vals = [H.edges[x].weight for x in H.nodes[v]] _df = pd.DataFrame(zip(_keys, _vals), columns=["key", "val"]) _df = _df.groupby(by="key").sum() ec = sum( [ - wdc(k[1], k[0]) * val[0] + wdc(k[1], k[0]) * val.iloc[0] for (k, val) in _df.iterrows() if k[0] > k[1] / 2 ] @@ -425,12 +431,12 @@ def _last_step_weighted(H, A, wdc, delta=0.01, verbose=False): L = [[dct_A[i] for i in x] for x in H_id] ## EC _keys = [(Counter(l).most_common(1)[0][1], len(l)) for l in L] - _vals = [H.edges[x].weight for x in H.nodes[v].memberships] + _vals = [H.edges[x].weight for x in H.nodes[v]] _df = pd.DataFrame(zip(_keys, _vals), columns=["key", "val"]) _df = _df.groupby(by="key").sum() ecp = sum( [ - wdc(k[1], k[0]) * val[0] + wdc(k[1], k[0]) * val.iloc[0] for (k, val) in _df.iterrows() if k[0] > k[1] / 2 ] @@ -491,7 +497,7 @@ def _last_step_unweighted(H, A, wdc, delta=0.01, verbose=False): n_moves = 0 for v in list(np.random.permutation(list(H.nodes))): dct_A_v = dct_A[v] - H_id = [H.incidence_dict[x] for x in H.nodes[v].memberships] + H_id = [H.incidence_dict[x] for x in H.nodes[v]] L = [[dct_A[i] for i in x] for x in H_id] deg_v = H.degree(v) diff --git a/hypernetx/algorithms/s_centrality_measures.py b/hypernetx/algorithms/s_centrality_measures.py index e56f55cd..4915ca3d 100644 --- a/hypernetx/algorithms/s_centrality_measures.py +++ b/hypernetx/algorithms/s_centrality_measures.py @@ -77,7 +77,7 @@ def _s_centrality(func, H, s=1, edges=True, f=None, return_singletons=True, **kw vertices = h.nodes if h.shape[edges * 1] == 1: - stats = {v: 0 for v in vertices} + stats.update({v: 0 for v in vertices}) else: g = h.get_linegraph(s=s, edges=edges) stats.update({k: v for k, v in func(g, **kwargs).items()}) diff --git a/pylintrc b/pylintrc index 5ceacf76..c6615209 100644 --- a/pylintrc +++ b/pylintrc @@ -1,7 +1,7 @@ [MAIN] # Specify a score threshold to be exceeded before program exits with error. -fail-under=7.00 +# fail-under= # A comma-separated list of package or module names from where C extensions may # be loaded. Extensions are loading into the active Python interpreter and may diff --git a/pyproject.toml b/pyproject.toml index c60467a7..a81215b6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "hypernetx" -version = "2.3.3" +version = "2.3.5" description = "HyperNetX is a Python library for the creation and study of hypergraphs." authors = ["Brenda Praggastis ", "Dustin Arendt ", "Sinan Aksoy ", "Emilie Purvine ", diff --git a/tox.ini b/tox.ini index d753703a..04e29757 100644 --- a/tox.ini +++ b/tox.ini @@ -44,7 +44,7 @@ basepython = python3.11 commands_pre = poetry install --with lint commands = - poetry run pylint --recursive=y --persistent=n hypernetx + poetry run pylint --recursive=y --exit-zero --persistent=n hypernetx poetry run flake8 hypernetx --exit-zero poetry run pre-commit install poetry run pre-commit run --all-files