pyEQL 1.0.1__tar.gz → 1.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyeql-1.0.1 → pyeql-1.0.2}/CHANGELOG.md +9 -0
- {pyeql-1.0.1/src/pyEQL.egg-info → pyeql-1.0.2}/PKG-INFO +1 -1
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/changelog.md +9 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/pyproject.toml +1 -1
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL/engines.py +3 -3
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL/salt_ion_match.py +1 -1
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL/solute.py +1 -1
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL/solution.py +6 -6
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL/utils.py +38 -5
- {pyeql-1.0.1 → pyeql-1.0.2/src/pyEQL.egg-info}/PKG-INFO +1 -1
- {pyeql-1.0.1 → pyeql-1.0.2}/tests/test_utils.py +13 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/.coveragerc +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/.gitattributes +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/.github/dependabot.yml +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/.github/pull_request_template.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/.github/release.yml +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/.github/workflows/post-process.yml +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/.github/workflows/release.yml +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/.github/workflows/testing.yaml +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/.github/workflows/upgrade_dependencies.yml +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/.gitignore +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/.pre-commit-config.yaml +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/.readthedocs.yml +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/.zenodo.json +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/AUTHORS.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/CITATION.cff +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/COPYING +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/LICENSE.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/MANIFEST.in +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/README.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/Makefile +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/_static/.gitignore +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/amounts.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/arithmetic.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/authors.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/chemistry.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/class_solution.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/conf.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/contributing.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/creating.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/database.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/engines.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/examples/.ipynb_checkpoints/pyEQL_demo_1-checkpoint.ipynb +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/examples/.ipynb_checkpoints/pyeql_demo-checkpoint.ipynb +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/examples/.ipynb_checkpoints/pyeql_tutorial_database-checkpoint.ipynb +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/examples/.ipynb_checkpoints/pyeql_tutorial_osmotic_pressure-checkpoint.ipynb +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/examples/.ipynb_checkpoints/speedup-checkpoint.ipynb +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/examples/pyEQL_demo_1.ipynb +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/examples/pyeql_demo.ipynb +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/examples/pyeql_tutorial_database.ipynb +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/examples/pyeql_tutorial_osmotic_pressure.ipynb +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/examples/speedup.ipynb +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/index.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/installation.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/internal.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/license.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/mixing.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/quickstart.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/readme.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/requirements.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/serialization.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/tutorials.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/docs/units.md +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/pyeql-logo.png +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/pyeql-logo.svg +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/macos-latest_py3.10.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/macos-latest_py3.10_extras.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/macos-latest_py3.11.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/macos-latest_py3.11_extras.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/macos-latest_py3.12.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/macos-latest_py3.12_extras.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/macos-latest_py3.9.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/macos-latest_py3.9_extras.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/ubuntu-latest_py3.10.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/ubuntu-latest_py3.10_extras.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/ubuntu-latest_py3.11.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/ubuntu-latest_py3.11_extras.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/ubuntu-latest_py3.12.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/ubuntu-latest_py3.12_extras.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/ubuntu-latest_py3.9.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/ubuntu-latest_py3.9_extras.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/windows-latest_py3.10.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/windows-latest_py3.10_extras.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/windows-latest_py3.11.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/windows-latest_py3.11_extras.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/windows-latest_py3.12.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/windows-latest_py3.12_extras.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/windows-latest_py3.9.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/requirements/windows-latest_py3.9_extras.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/setup.cfg +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/setup.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL/__init__.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL/activity_correction.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL/database/geothermal.dat +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL/database/llnl.dat +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL/database/phreeqc_license.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL/database/pyeql_db.json +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL/equilibrium.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL/functions.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL/pint_custom_units.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL/presets/Ringers lactate.yaml +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL/presets/normal saline.yaml +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL/presets/rainwater.yaml +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL/presets/seawater.yaml +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL/presets/urine.yaml +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL/presets/wastewater.yaml +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL.egg-info/SOURCES.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL.egg-info/dependency_links.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL.egg-info/not-zip-safe +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL.egg-info/requires.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/src/pyEQL.egg-info/top_level.txt +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/tests/conftest.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/tests/test_activity.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/tests/test_bulk_properties.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/tests/test_debye_length.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/tests/test_density.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/tests/test_dielectric.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/tests/test_effective_pitzer.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/tests/test_equilibrium.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/tests/test_functions.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/tests/test_logging.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/tests/test_mixed_electrolyte_activity.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/tests/test_osmotic_coeff.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/tests/test_phreeqc.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/tests/test_salt_matching.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/tests/test_solute.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/tests/test_solute_properties.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/tests/test_solution.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/tests/test_volume_concentration.py +0 -0
- {pyeql-1.0.1 → pyeql-1.0.2}/tox.ini +0 -0
|
@@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.0.2] - 2024-07-09
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- `standardize_formula`: Fix incorrect display of ammonium/ammonia. Previously, their formulas
|
|
13
|
+
were shown as "H4N[+1]" and "H3N(aq)", respectively. They now correctly display as NH4 and NH3.
|
|
14
|
+
Similar fixes were implemented for HPO4[-2] / H2PO4[-1] / H3PO4, formate (HCOO[-1]), oxalate (C2O4[-2]), thicyanate (SCN[-1]), and triiodide (I3[-1]).
|
|
15
|
+
Fixes #136 (@xiaoxiaozhu123)
|
|
16
|
+
|
|
8
17
|
## [1.0.1] - 2024-06-17
|
|
9
18
|
|
|
10
19
|
### Added
|
|
@@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.0.2] - 2024-07-09
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- `standardize_formula`: Fix incorrect display of ammonium/ammonia. Previously, their formulas
|
|
13
|
+
were shown as "H4N[+1]" and "H3N(aq)", respectively. They now correctly display as NH4 and NH3.
|
|
14
|
+
Similar fixes were implemented for HPO4[-2] / H2PO4[-1] / H3PO4, formate (HCOO[-1]), oxalate (C2O4[-2]), thicyanate (SCN[-1]), and triiodide (I3[-1]).
|
|
15
|
+
Fixes #136 (@xiaoxiaozhu123)
|
|
16
|
+
|
|
8
17
|
## [1.0.1] - 2024-06-17
|
|
9
18
|
|
|
10
19
|
### Added
|
|
@@ -139,7 +139,7 @@ class NativeEOS(EOS):
|
|
|
139
139
|
def __init__(
|
|
140
140
|
self,
|
|
141
141
|
phreeqc_db: Literal["vitens.dat", "wateq4f_PWN.dat", "pitzer.dat", "llnl.dat", "geothermal.dat"] = "llnl.dat",
|
|
142
|
-
):
|
|
142
|
+
) -> None:
|
|
143
143
|
"""
|
|
144
144
|
Args:
|
|
145
145
|
phreeqc_db: Name of the PHREEQC database file to use for solution thermodynamics
|
|
@@ -712,7 +712,7 @@ class NativeEOS(EOS):
|
|
|
712
712
|
# call to equilibrate can thus result in a slight change in the Solution mass.
|
|
713
713
|
solution.components[solution.solvent] = orig_solvent_moles
|
|
714
714
|
|
|
715
|
-
def __deepcopy__(self, memo):
|
|
715
|
+
def __deepcopy__(self, memo) -> "NativeEOS":
|
|
716
716
|
# custom deepcopy required because the PhreeqPython instance used by the Native and Phreeqc engines
|
|
717
717
|
# is not pickle-able.
|
|
718
718
|
import copy
|
|
@@ -736,7 +736,7 @@ class PhreeqcEOS(NativeEOS):
|
|
|
736
736
|
phreeqc_db: Literal[
|
|
737
737
|
"vitens.dat", "wateq4f_PWN.dat", "pitzer.dat", "llnl.dat", "geothermal.dat"
|
|
738
738
|
] = "phreeqc.dat",
|
|
739
|
-
):
|
|
739
|
+
) -> None:
|
|
740
740
|
"""
|
|
741
741
|
Args:
|
|
742
742
|
phreeqc_db: Name of the PHREEQC database file to use for solution thermodynamics
|
|
@@ -57,7 +57,7 @@ class Solution(MSONable):
|
|
|
57
57
|
database: str | Path | Store | None = None,
|
|
58
58
|
default_diffusion_coeff: float = 1.6106e-9,
|
|
59
59
|
log_level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] | None = "ERROR",
|
|
60
|
-
):
|
|
60
|
+
) -> None:
|
|
61
61
|
"""
|
|
62
62
|
Instantiate a Solution from a composition.
|
|
63
63
|
|
|
@@ -2512,7 +2512,7 @@ class Solution(MSONable):
|
|
|
2512
2512
|
return loadfn(filename)
|
|
2513
2513
|
|
|
2514
2514
|
# arithmetic operations
|
|
2515
|
-
def __add__(self, other: Solution):
|
|
2515
|
+
def __add__(self, other: Solution) -> Solution:
|
|
2516
2516
|
"""
|
|
2517
2517
|
Solution addition: mix two solutions together.
|
|
2518
2518
|
|
|
@@ -2600,10 +2600,10 @@ class Solution(MSONable):
|
|
|
2600
2600
|
pE=mix_pE,
|
|
2601
2601
|
)
|
|
2602
2602
|
|
|
2603
|
-
def __sub__(self, other: Solution):
|
|
2603
|
+
def __sub__(self, other: Solution) -> None:
|
|
2604
2604
|
raise NotImplementedError("Subtraction of solutions is not implemented.")
|
|
2605
2605
|
|
|
2606
|
-
def __mul__(self, factor: float):
|
|
2606
|
+
def __mul__(self, factor: float) -> None:
|
|
2607
2607
|
"""
|
|
2608
2608
|
Solution multiplication: scale all components by a factor. For example, Solution * 2 will double the moles of
|
|
2609
2609
|
every component (including solvent). No other properties will change.
|
|
@@ -2611,7 +2611,7 @@ class Solution(MSONable):
|
|
|
2611
2611
|
self.volume *= factor
|
|
2612
2612
|
return self
|
|
2613
2613
|
|
|
2614
|
-
def __truediv__(self, factor: float):
|
|
2614
|
+
def __truediv__(self, factor: float) -> None:
|
|
2615
2615
|
"""
|
|
2616
2616
|
Solution division: scale all components by a factor. For example, Solution / 2 will remove half of the moles
|
|
2617
2617
|
of every compoonents (including solvent). No other properties will change.
|
|
@@ -2657,7 +2657,7 @@ class Solution(MSONable):
|
|
|
2657
2657
|
|
|
2658
2658
|
print(f"{i}:\t {amt:0.{places}f}")
|
|
2659
2659
|
|
|
2660
|
-
def __str__(self):
|
|
2660
|
+
def __str__(self) -> str:
|
|
2661
2661
|
# set output of the print() statement for the solution
|
|
2662
2662
|
l1 = f"Volume: {self.volume:.3f~}"
|
|
2663
2663
|
l2 = f"Temperature: {self.temperature:.3f~}"
|
|
@@ -9,6 +9,7 @@ pyEQL utilities
|
|
|
9
9
|
import logging
|
|
10
10
|
from collections import UserDict
|
|
11
11
|
from functools import lru_cache
|
|
12
|
+
from typing import Any
|
|
12
13
|
|
|
13
14
|
from iapws import IAPWS95, IAPWS97
|
|
14
15
|
from pymatgen.core.ion import Ion
|
|
@@ -59,7 +60,39 @@ def standardize_formula(formula: str):
|
|
|
59
60
|
be enclosed in square brackets to remove any ambiguity in the meaning of the formula. For example, 'Na+',
|
|
60
61
|
'Na+1', and 'Na[+]' will all standardize to "Na[+1]"
|
|
61
62
|
"""
|
|
62
|
-
|
|
63
|
+
sform = Ion.from_formula(formula).reduced_formula
|
|
64
|
+
|
|
65
|
+
# TODO - manual formula adjustments. May be implemented upstream in pymatgen in the future
|
|
66
|
+
# thanks to @xiaoxiaozhu123 for pointing out these issues in
|
|
67
|
+
# https://github.com/KingsburyLab/pyEQL/issues/136
|
|
68
|
+
|
|
69
|
+
# ammonia
|
|
70
|
+
if sform == "H4N[+1]":
|
|
71
|
+
sform = "NH4[+1]"
|
|
72
|
+
elif sform == "H3N(aq)":
|
|
73
|
+
sform = "NH3(aq)"
|
|
74
|
+
# phosphoric acid system
|
|
75
|
+
elif sform == "PH3O4(aq)":
|
|
76
|
+
sform = "H3PO4(aq)"
|
|
77
|
+
elif sform == "PHO4[-2]":
|
|
78
|
+
sform = "HPO4[-2]"
|
|
79
|
+
elif sform == "P(HO2)2[-1]":
|
|
80
|
+
sform = "H2PO4[-1]"
|
|
81
|
+
# thiocyanate
|
|
82
|
+
elif sform == "CSN[-1]":
|
|
83
|
+
sform = "SCN[-1]"
|
|
84
|
+
# triiodide
|
|
85
|
+
elif sform == "I[-0.33333333]":
|
|
86
|
+
sform = "I3[-1]"
|
|
87
|
+
# formate
|
|
88
|
+
elif sform == "HCOO[-1]":
|
|
89
|
+
sform = "HCO2[-1]"
|
|
90
|
+
# oxalate
|
|
91
|
+
elif sform == "CO2[-1]":
|
|
92
|
+
sform = "C2O4[-2]"
|
|
93
|
+
|
|
94
|
+
# TODO - consider adding recognition of special formulas like MeOH for methanol or Cit for citrate
|
|
95
|
+
return sform
|
|
63
96
|
|
|
64
97
|
|
|
65
98
|
def format_solutes_dict(solute_dict: dict, units: str):
|
|
@@ -115,18 +148,18 @@ class FormulaDict(UserDict):
|
|
|
115
148
|
formula notation (e.g., "Na+", "Na+1", "Na[+]" all have the same effect)
|
|
116
149
|
"""
|
|
117
150
|
|
|
118
|
-
def __getitem__(self, key):
|
|
151
|
+
def __getitem__(self, key) -> Any:
|
|
119
152
|
return super().__getitem__(standardize_formula(key))
|
|
120
153
|
|
|
121
|
-
def __setitem__(self, key, value):
|
|
154
|
+
def __setitem__(self, key, value) -> None:
|
|
122
155
|
super().__setitem__(standardize_formula(key), value)
|
|
123
156
|
# sort contents anytime an item is set
|
|
124
157
|
self.data = dict(sorted(self.items(), key=lambda x: x[1], reverse=True))
|
|
125
158
|
|
|
126
159
|
# Necessary to define this so that .get() works properly in python 3.12+
|
|
127
160
|
# see https://github.com/python/cpython/issues/105524
|
|
128
|
-
def __contains__(self, key):
|
|
161
|
+
def __contains__(self, key) -> bool:
|
|
129
162
|
return standardize_formula(key) in self.data
|
|
130
163
|
|
|
131
|
-
def __delitem__(self, key):
|
|
164
|
+
def __delitem__(self, key) -> None:
|
|
132
165
|
super().__delitem__(standardize_formula(key))
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Tests of pyEQL.utils module
|
|
3
3
|
|
|
4
4
|
"""
|
|
5
|
+
|
|
5
6
|
from iapws import IAPWS95, IAPWS97
|
|
6
7
|
from pytest import raises
|
|
7
8
|
|
|
@@ -19,6 +20,18 @@ def test_standardize_formula():
|
|
|
19
20
|
assert standardize_formula("SO4--") == "SO4[-2]"
|
|
20
21
|
assert standardize_formula("Mg+2") == "Mg[+2]"
|
|
21
22
|
assert standardize_formula("O2") == "O2(aq)"
|
|
23
|
+
assert standardize_formula("NH4+") == "NH4[+1]"
|
|
24
|
+
assert standardize_formula("NH3") == "NH3(aq)"
|
|
25
|
+
assert standardize_formula("HPO4--") == "HPO4[-2]"
|
|
26
|
+
assert standardize_formula("H2PO4-") == "H2PO4[-1]"
|
|
27
|
+
assert standardize_formula("SCN-") == "SCN[-1]"
|
|
28
|
+
assert standardize_formula("I3-") == "I3[-1]"
|
|
29
|
+
assert standardize_formula("HCOO-") == "HCO2[-1]"
|
|
30
|
+
assert standardize_formula("CO2-1") == "C2O4[-2]"
|
|
31
|
+
assert standardize_formula("C2O4--") == "C2O4[-2]"
|
|
32
|
+
assert standardize_formula("H3PO4") == "H3PO4(aq)"
|
|
33
|
+
assert standardize_formula("H2SO4") == "H2SO4(aq)"
|
|
34
|
+
assert standardize_formula("HClO4") == "HClO4(aq)"
|
|
22
35
|
|
|
23
36
|
|
|
24
37
|
def test_formula_dict():
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|