From 7129013d52ce89599bd64559e2358d93f35f3f78 Mon Sep 17 00:00:00 2001 From: DhruvDuseja Date: Thu, 19 Oct 2023 09:35:25 +0400 Subject: [PATCH 1/5] add method to format solute dictionary --- src/pyEQL/utils.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/pyEQL/utils.py b/src/pyEQL/utils.py index 48bebb87..289eb661 100644 --- a/src/pyEQL/utils.py +++ b/src/pyEQL/utils.py @@ -32,6 +32,28 @@ def standardize_formula(formula: str): return Ion.from_formula(formula).reduced_formula +def format_solute(solute_dict: dict, units: str): + """ + Format a solute dictionary with the given units. + + Args: + solute_dict: The dictionary to format. + + Returns: + A formatted solute dictionary. + + Raises: + TypeError if `solute_dict` is invalid. + """ + if not isinstance(solute_dict, dict): + raise TypeError("solute_dict must be a dictionary of the format ...") + + for key, value in solute_dict.items(): + solute_dict[key] = f"{str(value)} {units}" + + return solute_dict + + class FormulaDict(UserDict): """ Automatically converts keys on get/set using pymatgen.core.Ion.from_formula(key).reduced_formula. From 2ecc908ab08849ac44c9a362aec2e08875921bec Mon Sep 17 00:00:00 2001 From: DhruvDuseja Date: Thu, 19 Oct 2023 09:43:47 +0400 Subject: [PATCH 2/5] doc fix & format with ruff --- src/pyEQL/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pyEQL/utils.py b/src/pyEQL/utils.py index 289eb661..33254b32 100644 --- a/src/pyEQL/utils.py +++ b/src/pyEQL/utils.py @@ -38,6 +38,7 @@ def format_solute(solute_dict: dict, units: str): Args: solute_dict: The dictionary to format. + units: The units to use for the solute. Returns: A formatted solute dictionary. @@ -49,7 +50,7 @@ def format_solute(solute_dict: dict, units: str): raise TypeError("solute_dict must be a dictionary of the format ...") for key, value in solute_dict.items(): - solute_dict[key] = f"{str(value)} {units}" + solute_dict[key] = f"{value!s} {units}" return solute_dict From 72377c408bf79d53bc2a55f8e9a91867556ae04f Mon Sep 17 00:00:00 2001 From: DhruvDuseja Date: Thu, 19 Oct 2023 18:55:32 +0400 Subject: [PATCH 3/5] add test for format_solute method --- tests/test_utils.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index 0722baca..50e3edd1 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -3,7 +3,7 @@ """ -from pyEQL.utils import FormulaDict, standardize_formula +from pyEQL.utils import FormulaDict, format_solute, standardize_formula def test_standardize_formula(): @@ -35,3 +35,12 @@ def test_formula_dict(): assert d.get("Na+") == 0.5 d.update({"Br-": 2}) assert d["Br[-]"] == 2 + + +def test_format_solute(): + """ + Test formatting solute dictionaries + """ + test = {"Na+": 0.5, "Cl-": 0.5} + base = {"Na+": "0.5 mol/kg", "Cl-": "0.5 mol/kg"} + assert format_solute(test, units="mol/kg") == base From 1087cc3f547c2050d4958d6fdf79dc54a968fee3 Mon Sep 17 00:00:00 2001 From: DhruvDuseja Date: Thu, 19 Oct 2023 20:57:04 +0400 Subject: [PATCH 4/5] update doc & add test for exception --- src/pyEQL/utils.py | 10 ++++++---- tests/test_utils.py | 10 ++++++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/pyEQL/utils.py b/src/pyEQL/utils.py index 33254b32..e162368a 100644 --- a/src/pyEQL/utils.py +++ b/src/pyEQL/utils.py @@ -32,12 +32,14 @@ def standardize_formula(formula: str): return Ion.from_formula(formula).reduced_formula -def format_solute(solute_dict: dict, units: str): +def format_solutes_dict(solute_dict: dict, units: str): """ - Format a solute dictionary with the given units. + Formats a dictionary of solutes by converting the amount to a string with the provided units suitable for passing to + use with the Solution class. Note that all solutes must be given in the same units. Args: - solute_dict: The dictionary to format. + solute_dict: The dictionary to format. This must be of the form dict{str: Number} + e.g. {"Na+": 0.5, "Cl-": 0.9} units: The units to use for the solute. Returns: @@ -47,7 +49,7 @@ def format_solute(solute_dict: dict, units: str): TypeError if `solute_dict` is invalid. """ if not isinstance(solute_dict, dict): - raise TypeError("solute_dict must be a dictionary of the format ...") + raise TypeError("solute_dict must be a dictionary. Refer to the doc for proper formatting.") for key, value in solute_dict.items(): solute_dict[key] = f"{value!s} {units}" diff --git a/tests/test_utils.py b/tests/test_utils.py index 50e3edd1..d2cfad37 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -2,8 +2,9 @@ Tests of pyEQL.utils module """ +from pytest import raises -from pyEQL.utils import FormulaDict, format_solute, standardize_formula +from pyEQL.utils import FormulaDict, format_solutes_dict, standardize_formula def test_standardize_formula(): @@ -43,4 +44,9 @@ def test_format_solute(): """ test = {"Na+": 0.5, "Cl-": 0.5} base = {"Na+": "0.5 mol/kg", "Cl-": "0.5 mol/kg"} - assert format_solute(test, units="mol/kg") == base + assert format_solutes_dict(test, units="mol/kg") == base + + bad_test = [["Na+", 0.5], ["Cl-", 0.5]] + error_msg = "solute_dict must be a dictionary. Refer to the doc for proper formatting." + with raises(TypeError, match=error_msg): + format_solutes_dict(bad_test, units="mol/kg") From 7f6fff34e577fecfa85fcea19a420ca1e59f7687 Mon Sep 17 00:00:00 2001 From: DhruvDuseja Date: Fri, 20 Oct 2023 09:06:39 +0400 Subject: [PATCH 5/5] use dict comprehension; doc update; changelog update --- CHANGELOG.md | 6 ++++++ src/pyEQL/utils.py | 9 +++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 016310d7..7ee082e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Added + +- `format_solutes_dict()` method added into the utils module to help format solutes dictionaries with a unit. + ## [0.9.0] - 2023-10-17 ### Added diff --git a/src/pyEQL/utils.py b/src/pyEQL/utils.py index e162368a..13da2884 100644 --- a/src/pyEQL/utils.py +++ b/src/pyEQL/utils.py @@ -40,21 +40,18 @@ def format_solutes_dict(solute_dict: dict, units: str): Args: solute_dict: The dictionary to format. This must be of the form dict{str: Number} e.g. {"Na+": 0.5, "Cl-": 0.9} - units: The units to use for the solute. + units: The units to use for the solute. e.g. "mol/kg" Returns: A formatted solute dictionary. Raises: - TypeError if `solute_dict` is invalid. + TypeError if `solute_dict` is not a dictionary. """ if not isinstance(solute_dict, dict): raise TypeError("solute_dict must be a dictionary. Refer to the doc for proper formatting.") - for key, value in solute_dict.items(): - solute_dict[key] = f"{value!s} {units}" - - return solute_dict + return {key: f"{value!s} {units}" for key, value in solute_dict.items()} class FormulaDict(UserDict):