Stepping Towards Chemistry Mastery

Jason Sonnenberg, Wolfram Alpha

Chemistry Step-by-Step Offerings

WordCloud[<|"Chemical Conversions"->3, "Mass Composition" ->4, "Chemical Structures" -> 2, "Oxidation States" -> 2, "Chemical Reactions" -> 4, "Orbital Hybridization" -> 2, "Aromaticity" -> 3, "Gases" -> 3, "Acids & Bases" -> 1, "Chemical Solutions" -> 5, "Quantum Chemistry" -> 1, "Colligative Properties" -> 2, "Thermodynamics" -> 1, "Concentration" -> 4|>]

Chemical Problem Solving

Mass Composition

Hyperlink["Antihemophilic factor elemental composition","https://www.wolframalpha.com/input/?i=antihemophilic+factor+elemental+composition&lk=3"]

WolframAlpha@"antihemophilic factor elemental composition"

Significant Figures

ClearAll@SignificantDigits;
Options[SignificantDigits]={"DigitDecompose"->False,"ExactNumber"->False,"TrimLeadingZeros"->False,"UseTrailingZeros"->False};
SignificantDigits[x___]:=$Failed;
SignificantDigits[x_Around,opts:OptionsPattern[]]:=SignificantDigits[x["Number"],opts];
SignificantDigits[x_VectorAround,opts:OptionsPattern[]]:=SignificantDigits[Around[x],opts];SignificantDigits[x_Complex,opts:OptionsPattern[]]:=SignificantDigits[ReIm[x],opts];
SignificantDigits[x_Integer,opts:OptionsPattern[]]:=SignificantDigits[ToString[x,InputForm,NumberMarks->Automatic],opts];
SignificantDigits[x_List,opts:OptionsPattern[]]:= SignificantDigits[#,opts]&/@x;
SignificantDigits[x_MixedMagnitude,opts:OptionsPattern[]]:=SignificantDigits[x[[1]],opts];
SignificantDigits[x_Quantity|x_StructuredArray,opts:OptionsPattern[]]:=SignificantDigits[QuantityMagnitude[x],opts];
SignificantDigits[Rational[n_Integer,d_Integer],opts:OptionsPattern[]]:=If[OptionValue["DigitDecompose"],{0,Infinity,0,0,Infinity,0},Infinity];
SignificantDigits[x_Real,opts:OptionsPattern[]]:=SignificantDigits[ToString[x,InputForm,NumberMarks->Automatic],opts];SignificantDigits[x_String,opts:OptionsPattern[]]:=Module[
{bAccuracy,bPrecision,decompose,digits,exact,fAccuracy,fPrecision,lLeadZero,lSigFig,lTrailZero,leftright,rLeadZero,rSigFig,rTrailZero,replace,string,total,trail,trim,truncated,
assigned=0,
found=0,
iFlag=False,
(* Regular Expressions *)
reBack="([0-9\\.]+)",
reDot="\\.",
reDigits="(\\d*)(\\.*)(\\d*)",
reEnd="[\\)%]*$",
reOptDot="\\.*",
reOptNum="([1-9]*\\d*?)",
reSciNot="(?:[eEdDxX*](?:(?:10)*\\^)*[\\+-]*\\d+)*",
reStart="^[\\(\\+-]*",
reOptZero="(0*)"},

(* Options *)
decompose=TrueQ @ OptionValue["DigitDecompose"];
exact=TrueQ @ OptionValue["ExactNumber"];
trail=TrueQ @ OptionValue["UseTrailingZeros"];
trim=TrueQ @ OptionValue["TrimLeadingZeros"];
If[exact, trail=True];

(* String cleanup *)
replace={","->"",Whitespace->"",RegularExpression["(?<!^)\\(\\d+\\)"]->""};
If[trim,AppendTo[replace,RegularExpression["^0+(\\d.*)"]->"$1"]];
string= StringReplace[StringTrim[x],replace];
If[string==="",
ResourceFunction["ResourceFunctionMessage"][SignificantDigits::EmptyString];
Return[$Failed,Module]
];

(* Specified Accuracy *)
fAccuracy=StringContainsQ[string,"``"];
If[fAccuracy,
{string,bAccuracy}=StringCases[string,RegularExpression[reStart<>reBack<>"``"<>reBack]:> {"$1","$2"}][[1]];
bAccuracy=Floor[ToExpression@bAccuracy]
];

(* Specified Precision *)
fPrecision=StringContainsQ[string,"`"];
If[fPrecision,
{string,bPrecision}=StringCases[string,RegularExpression[reStart<>reBack<>"`"<>reBack]:> {"$1","$2"}][[1]];
bPrecision=Ceiling[ToExpression@bPrecision]
];
If[fAccuracy&&fPrecision,Return[$Failed,Module]];

(* Extract digits *)
(* leftLeadZero, leftSigFig, leftTrailZero, rightLeadZero, rightSigFig, rightTrailZero *)
digits=Flatten@StringCases[string,
{(* integer *)
RegularExpression[reStart<>reOptZero<>"([1-9]\\d*?)"<>reOptZero<>reEnd]:>
(
iFlag=True;
lLeadZero=StringLength@"$1";
lSigFig=StringLength@"$2";
lTrailZero=StringLength@"$3";
If[trail,
{lLeadZero,lSigFig+lTrailZero,-lTrailZero,0,0,0},
{lLeadZero,lSigFig,lTrailZero,0,0,0}
]
),
(* zero *)
RegularExpression[reStart<>reOptZero<>reOptDot<>reOptZero<>reSciNot<>reEnd]:> 
(
lLeadZero=StringLength@"$1";
rLeadZero=StringLength@"$2";
Which[
lLeadZero≥1&&rLeadZero≥1,
{lLeadZero-1,1,0,0,rLeadZero,-rLeadZero},
lLeadZero≥1,
{lLeadZero-1,1,0,0,0,0},
rLeadZero≥1,{0,0,0,0,rLeadZero,-rLeadZero},
True,
ResourceFunction["ResourceFunctionMessage"][SignificantDigits::ZeroFail];
Return[$Failed,Module]
]
),
(* real *)
RegularExpression[reStart<>reOptZero<>reOptNum<>reDot<>reOptZero<>reOptNum<>reOptZero<>reSciNot<>reEnd]:>
 (
lLeadZero=StringLength@"$1";
lSigFig=StringLength@"$2";
rLeadZero=StringLength@"$3";
rSigFig=StringLength@"$4";
rTrailZero=StringLength@"$5";
Which[
lSigFig>0&&rSigFig==0&&rTrailZero==0,
{lLeadZero,lSigFig,0,0,rLeadZero,-rLeadZero},
lSigFig>0,
{lLeadZero,lSigFig,0,0,rLeadZero+rSigFig+rTrailZero,-rTrailZero},
lLeadZero>0&&lSigFig==0,
{lLeadZero,0,0,rLeadZero,rSigFig+rTrailZero,-rTrailZero},
lLeadZero==0&&lSigFig==0,
{0,0,0,rLeadZero,rSigFig+rTrailZero,-rTrailZero},
True,
ResourceFunction["ResourceFunctionMessage"][SignificantDigits::RealFail];
Return[$Failed,Module]
]
)
}];

(* Ensure digit presence and complete assignment *)
If[Length@digits==0,Return[$Failed,Module]];
assigned=Total[Cases[digits,_?NonNegative]];
found=StringCases[string,RegularExpression[reStart<>reDigits<>reSciNot<>reEnd]:> StringLength@"$1"+StringLength@"$3"][[1]];
If[found≠assigned ,
If[assigned >1,
ResourceFunction["ResourceFunctionMessage"][SignificantDigits::UnassignedDigits,found,assigned],
ResourceFunction["ResourceFunctionMessage"][SignificantDigits::UnassignedDigit,found,assigned]
];
Return[$Failed,Module]
];

(* Apply precision *)
total=Total@digits[[2;;5;;3]];
If[fPrecision&&(total≠bPrecision||total+If[digits[[3]]>0,digits[[3]],0]≠bPrecision),
leftright=bPrecision -If[digits[[3]]<0,digits[[2]],Total@digits[[2;;3]]];
Which[
(* adjust right of decimal *)
leftright≥ 0 && digits[[5]]>0,
fAccuracy=True;
bAccuracy=leftright,
(* adjust left of decimal *)
(* truncate sig fig *)
leftright<= 0 ,
truncated=StringCases[string,RegularExpression[reStart<>reDigits<>reSciNot<>reEnd]:> StringDrop["$1",leftright]][[1]];
digits=SignificantDigits[truncated,"DigitDecompose"->True,"UseTrailingZeros"->trail],
(* extend sig fig by adding trailing zeros *)
leftright> 0 && digits[[5]] ==0,
digits=ReplacePart[digits,{2-> bPrecision,3-> Total@digits[[2;;3]]-bPrecision}],
True,
Message[SignificantDigits::PrecisionFail];
Return[$Failed,Module]
];
total=Total@digits[[2;;5;;3]];
];

(* Apply accuracy *)
If[fAccuracy&&digits[[5]]≠ bAccuracy,
Which[
(* truncate sig fig *)
digits[[5]] > bAccuracy,
truncated=StringCases[string,RegularExpression[reStart<>reDigits<>reSciNot<>reEnd]:> "$1"<>"$2"<>StringDrop["$3",bAccuracy-digits[[5]]]][[1]];
digits=SignificantDigits[truncated,"DigitDecompose"->True,"UseTrailingZeros"->trail],
(* extend sig fig by adding trailing zeros *)
digits[[5]]<bAccuracy,
digits = ReplacePart[digits,{5->bAccuracy,6->Total[digits[[5;;6]]]-bAccuracy}],
True,
ResourceFunction["ResourceFunctionMessage"][SignificantDigits::AccuracyFail];
Return[$Failed,Module]
];
total=Total@digits[[2;;5;;3]];
];

(* Exact number *)
If[exact &&iFlag,
digits=ReplacePart[digits,2->Infinity];
total=Total@digits[[2;;5;;3]]
];

(* Return results *)
If[fPrecision &&total≠Infinity&&total≠ bPrecision,
If[Total@digits[[2;;3]]==bPrecision,
ResourceFunction["ResourceFunctionMessage"][SignificantDigits::ImpossiblePrecision ],
ResourceFunction["ResourceFunctionMessage"][SignificantDigits::PrecisionError ]
];
Return[$Failed,Module]
];
If[fAccuracy && digits[[5]]≠ bAccuracy,
ResourceFunction["ResourceFunctionMessage"][SignificantDigits::AccuracyError];
Return[$Failed,Module]
];
If[decompose,digits,total]
]
SignificantDigits::AccuracyError = "An error was detected in the final Accuracy.";
SignificantDigits::AccuracyFail="Accuracy adjustment failure";
SignificantDigits::EmptyString = "An empty string was found.";
SignificantDigits::ImpossiblePrecision="The requested Precision is impossible.";
SignificantDigits::PrecisionError = "An error was detected in the final Precison.";
SignificantDigits::PrecisionFail="Precision adjustment failure";
SignificantDigits::RealFail ="Real number parse failure";
SignificantDigits::UnassignedDigit="The total number of digits is `1` but `2` was assigned.";
SignificantDigits::UnassignedDigits="The total number of digits is `1` but `2` were assigned.";
SignificantDigits::ZeroFail ="Zero parse failure";

Wolfram Function Repository:

SignificantDigits[x] gives the number of significant digits in x.

SignificantDigits[{x, y, z, ...}] gives the list of results for each value.

SignificantDigits[{"1.2000", -6, 3.148,"-1.1e5","45.6(1)"}]

Details & Options:

Significant digits are a simple way to account for precision in measured quantities without utilizing uncertainty or absolute error.

All non-zero digits and zeros between non-zero digits are significant digits.

Zeros employed to position the decimal are not significant.

Zeros to the right of the decimal that are also right of the last non-zero digit are significant digits.

Trailing zeros in Integer numbers are not significant by default.

Significant Figure Compliance

Hyperlink["technetium fluoride molar mass","https://www.wolframalpha.com/input/?i=technetium+fluoride+molar+mass&lk=3"]

WolframAlpha@"technetium fluoride molar mass"

Unit Conversions

Hyperlink["Convert 2.355 g sulfuric acid to moles","https://www.wolframalpha.com/input/?i=convert+2.355+g+sulfuric+acid+to+moles"]

Result:

Result with more details:

Concentrations

Hyperlink["Molarity of 2.355 g sulfuric acid in 50.0 mL of water","https://www.wolframalpha.com/input/?i=Molarity+of+2.355+g+sulfuric+acid+in+50.0+mL+of+water"]

Result:

Result with more details:

Solution Preparation

Hyperlink["Prepare 480 mM sulfuric acid from 2.355 g H2SO4","https://www.wolframalpha.com/input/?i=prepare+480+mM+sulfuric+acid+from+2.355+g+H2SO4"]

Result:

Result with more details:

Tutorial Videos

Video team: Mads Bahrami,  Veronica Mullen, Bob Owens, Abby Gailey, Clayton Voyles & Chapin Langenheim

Future Directions

Import["/Users/jasons/Sync/Documents/Meetings/2019 WTC/SBS future directions.png"]

Resources

How to Use Wolfram|Alpha

Wolfram|Alpha Chemistry Step-by-Step

Wolfram Function Repository: Chemistry

Molecular Structure & Computation

Chemistry Entities