From 6c75d9979202bf683c41c4f6dd0a4a6ce7625d3c Mon Sep 17 00:00:00 2001 From: zdroid Date: Mon, 10 Aug 2020 14:12:51 +0200 Subject: [PATCH] Strip (s), (l), (g), (aq) --- Project.toml | 2 +- docs/src/examples.md | 6 +++++- src/balance.jl | 7 +++++-- src/chemequation.jl | 28 +++++++++++----------------- src/compound.jl | 8 +++++--- test/balance.jl | 1 + test/compound.jl | 4 ++++ 7 files changed, 32 insertions(+), 24 deletions(-) diff --git a/Project.toml b/Project.toml index 93bc95b..14dc98a 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "ChemEquations" uuid = "75e6b969-eb85-49eb-b654-b2cb515e226f" authors = ["zdroid and contributors"] -version = "0.2.0" +version = "0.2.1" [deps] DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" diff --git a/docs/src/examples.md b/docs/src/examples.md index edaa224..36b1866 100644 --- a/docs/src/examples.md +++ b/docs/src/examples.md @@ -14,11 +14,15 @@ julia> balance(equation) 2 Fe + 3 Cl2 = 2 FeCl3 ``` -Parsing the input is insensitive to whitespace, so you don't have to be pedantic if you don't want to. +Parsing the input is insensitive to whitespace and to state symbols (`(s)`, `(l)`, `(g)`, `(aq)`), +so you don't have to be pedantic if you don't want to. ```julia-repl julia> balance(ce"KMnO4+ HCl = KCl+MnCl2 +H2O + Cl2") 2 KMnO4 + 16 HCl = 2 KCl + 2 MnCl2 + 8 H2O + 5 Cl2 + +julia> balance(ce"Zn(s) + O2(g) = ZnO(s)") +2 Zn + O2 = 2 ZnO ``` Parentheses (`()`), compounds written with `*` and electrical charges are all supported. diff --git a/src/balance.jl b/src/balance.jl index 2c4737d..d9913e5 100644 --- a/src/balance.jl +++ b/src/balance.jl @@ -47,7 +47,9 @@ Returns an array in which each column represents a solution. balancematrix(equation::ChemEquation) = _balancematrix(equation) """ -Same as [`balancematrix(::ChemEquation)`](@ref), but with special format options. +Same as [`balancematrix(::ChemEquation)`](@ref), +but for a chemical equation with integer coefficients. + By default, the solutions of integer matrices are displayed as integers. If `fractions` is true, they will be displayed as rational fractions instead. """ @@ -62,7 +64,6 @@ end """ Balances the coefficients of a chemical equation. - If the equation cannot be balanced, an error is thrown. !!! info @@ -75,11 +76,13 @@ julia> balance(ce"Fe + Cl2 = FeCl3") julia> balance(ChemEquation{Rational}("H2 + Cl2 = HCl")) 1//2 H2 + 1//2 Cl2 = HCl +``` """ balance(equation::ChemEquation) = _balance(equation) """ Balances the coefficients of a chemical equation with integer coefficients. + The minimal integer solution is displayed by default. If `fractions` is true, they solution will be displayed as rational fractions instead. diff --git a/src/chemequation.jl b/src/chemequation.jl index ecffe41..131d880 100644 --- a/src/chemequation.jl +++ b/src/chemequation.jl @@ -20,23 +20,9 @@ struct ChemEquation{T<:Real} tuples::Vector{CompoundTuple{T}} end -""" -Constructs a chemical equation of specified type from `str`. -Follows the same rules as [`ChemEquation(::AbstractString)`](@ref). - -# Examples -```jldoctest -julia> ChemEquation{Rational}("1//2 H2 → H") -1//2 H2 = H - -julia> ChemEquation{Float64}("0.5 H2 + 0.5 Cl2 = HCl") -0.5 H2 + 0.5 Cl2 = HCl -``` -""" -ChemEquation{T}(str::AbstractString) where T<:Real = ChemEquation(_compoundtuples(str, T)) - """ Constructs a chemical equation from the given string. +If no `{Type}` is provided, it defaults to `Int`. Parsing is insensitive to whitespace. Any character in [`EQUALCHARS`](@ref) separates the equation into two sides, @@ -52,13 +38,21 @@ C2H4O2 + Na = H2 + C2H3O2Na julia> ChemEquation("⏣H + Cl2 = ⏣Cl + HCl") ⏣H + Cl2 = ⏣Cl + HCl + +julia> ChemEquation{Rational}("1//2 H2 → H") +1//2 H2 = H + +julia> ChemEquation{Float64}("0.5 H2 + 0.5 Cl2 = HCl") +0.5 H2 + 0.5 Cl2 = HCl +``` ``` """ +ChemEquation{T}(str::AbstractString) where T<:Real = ChemEquation(_compoundtuples(str, T)) ChemEquation(str::AbstractString) = ChemEquation{Int}(str) "Extracts compound tuples from equation's string." function _compoundtuples(str::AbstractString, T::Type) - strs = replace(str, ' ' => "") |> + strs = replace(str, [' ', '_'] => "") |> x -> split(x, EQUALCHARS) |> x -> split.(x, PLUSREGEX) splitindex = length(strs[1]) @@ -112,7 +106,7 @@ Creates a string to represent the chemical equation. All compounds are displayed with [`Base.string(::Compound)`](@ref), in the order in which they were originally given, with coefficients equal to 1 not displayed. -'=' and '+' are used as separators, with spaces inserted for easier reading. +`'='` and `'+'` are used as separators, with spaces inserted for easier reading. # Examples ```jldoctest diff --git a/src/compound.jl b/src/compound.jl index 4d66300..2337dc6 100644 --- a/src/compound.jl +++ b/src/compound.jl @@ -25,7 +25,8 @@ ends with a lowercase unicode letter or a unicode symbol. An element can also begin with a symbol if the symbol is the first character (e.g. `"⬡H"`). -Parsing is insensitive to whitespace and underscores (`_`). +Parsing is insensitive to whitespace and underscores (`_`), +but also to state symbols (`(s)`, `(l)`, `(g)`, `(aq)`). Special parsing is implemented for: - parens (e.g. `"(CH3COO)2Mg"`) - compounds with `"*"` (e.g. `"CuSO4 * 5H2O"`) @@ -35,7 +36,7 @@ It is automatically deduced for electron (`"e"`). # Examples ```jldoctest -julia> Compound("H2O") +julia> Compound("H2O(s)") H2O julia> Compound("H3O{+}") @@ -53,6 +54,7 @@ julia> Compound("⬡Cl") """ function Compound(str::AbstractString) str = replace(str, [' ', '_'] => "") + str = replace(str, r"\((s|l|g|aq)\)$" => "") # remove state symbols Compound(_elementtuples(str), _charge(str)) end @@ -153,7 +155,7 @@ Creates a string to represent the compound. All elements are displayed only once (e.g. `"H2O"` and not `"HOH"`), in the order in which they were originally given (e.g. `"MgO2H2"` from `cc"Mg(OH)2"`), -with coefficients equal to 1 not displayed (e.g. `"O"` and not `"O1"`). +with coefficients equal to 1 not displayed (e.g. `"H"` and not `"H1"`). # Examples ```jldoctest diff --git a/test/balance.jl b/test/balance.jl index 18d35ec..fde80c9 100644 --- a/test/balance.jl +++ b/test/balance.jl @@ -62,6 +62,7 @@ end "5 PhCH3 + 6 KMnO4 + 9 H2SO4 = 5 PhCO2H + 3 K2SO4 + 6 MnSO4 + 14 H2O", "CuSO4*5H2O = CuSO4 + H2O" => "CuSO4*5H2O = CuSO4 + 5 H2O", + "Zn(s) + O2(g) = ZnO(s)" => "2 Zn + O2 = 2 ZnO" ] for equation ∈ equations @test balance(ChemEquation(equation[1])) == ChemEquation(equation[2]) diff --git a/test/compound.jl b/test/compound.jl index 1b6717c..8ca8774 100644 --- a/test/compound.jl +++ b/test/compound.jl @@ -22,6 +22,10 @@ end @test cc"H2" == cc"H2" @test cc"{-}" == cc"{-1}" @test cc"CH2(OH)2(CH)" == cc"O2H5C2" + + @test cc"H H" == cc"H2" + @test cc"H_1C_1O_1" == cc"HCO" + @test cc"Mg(OH)2(s)" == cc"Mg(OH)2(aq)" end @testset "string" begin