seokin4862
(Seokin Yeh)
September 16, 2014, 3:21pm
1
I’ve been taking AP Chemistry in my high school this year.
And I’ve noticed that I’m having to find molar mass of a compound too many times.
So, as I’m wont to do, I coded a line to calculate molar masses for me:
Amu[Com_] :=
Total[
Table[
Com[[i*2]]*ElementData[Com[[i*2 - 1]], "AtomicMass"],
{i, Length[Com]/2}]
]
This code will tell me the molar mass of any compound or element I ask for. For example:
Amu[{"Carbon", 4, "Hydrogen", 10}]
Gives me 58.1222 u.
However, the beauty of mathematica is that a code can almost always be shortened and improved.
So, can anyone think up an improvement to this code?
I’m personally interested in turning my list input to something like C4H10.
Thank you.
dreiss
(David Reiss)
September 16, 2014, 6:32pm
2
I know that this may feel like it is cheating in some way but how about making use of WolframAlpha as in
waAMU[compound_String] :=
WolframAlpha["molar mass of " <> compound, "PodPlaintext"][[2]]
or even shorter, leveraging ChemicalData,
waAMU[compound_String] := ChemicalData[compound, "MolarMass"]
1 Like
iamorozov1
(Ivan Morozov)
September 16, 2014, 6:34pm
3
Hi, Seokin,
Not sure that this can be considered as an improvement of your code, but here is my solution:
A = Inner[Times, ElementData[#, "AtomicMass"] & /@ #1, #2, Plus] & ;
A[{"Carbon", "Hydrogen"}, {4, 10}]
As for fancy user input, you can try something similar to the following:
c = "Carbon" ;
h = "Hydrogen" ;
arg = Transpose@Partition[#, 2] & @ (ToExpression[#] & /@ StringSplit["c 4 h 10"]) ;
A @@ arg
and the final version:
A = Inner[Times, ElementData[#, "AtomicMass"] & /@ #1, #2, Plus] & @@ (
Transpose@Partition[#, 2] & @ (ToExpression[#] & /@
StringSplit[#])
) & ;
A["c 4 h 10"]
Also Characters[] function can be used to form input arg without blanks, but it will split 10 into 1 and 0 :
Characters["c4h10"]
I.M.
1 Like
seokin4862
(Seokin Yeh)
September 16, 2014, 8:23pm
4
Thank you for replying. I liked the ChemicalData approach, but I would have to know the names of all the chemical compounds I encounter (and I am quite awful at compound names). However, I did not know that ChemicalData was a function, and I am glad to know it. Thank you.
The wolfram alpha approach. That is sort of cheating.
And regardless of that fact, it requires internet connection and takes 10 times longer to evaluate.
Ivan, I loved your solution. I can never get the hang of pure functions, but when I see them, they look so elegant. Thank you very much.
iamorozov1
(Ivan Morozov)
September 16, 2014, 9:51pm
5
Just noticed that ElementData[] can be called with element’s number, hence
you can consider input of the form X_n^m Y_k^l \dots
Clear[A] ;
A[arg_] := Inner[Times, ElementData[#, "AtomicMass"] & /@ #1, #2, Plus] & @@
Transpose@(List @@ (arg) /. {\!\(\*SubsuperscriptBox[\(x_\), \(z_\), \(y_\)] -> \({y, z}\)\), Subscript[x_, z_] -> {1, z}, x_^y_ -> {y, 1}});
A[\!\(\*SubsuperscriptBox[\(C\), \(4\), \(6\)]\ \*SubsuperscriptBox[\(H\), \(10\), \(1\)]\)]
I.M.
1 Like