Finding the molar mass of a compound.

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.

I know that this may feel like it is cheating in some way :wink: 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

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

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. :slight_smile:
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.

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