Programming in Chemistry

Author and notebook information

Author: Arun K. Sharma
Department of Physical Sciences, Wagner College, 1 Campus Road, Staten Island, NY 10301.
Email: aksharma@wagner.edu

This notebook provides examples of chemistry oriented programming exercises that have been used in the author’s Introduction to Scientific Computing course at Wagner College. at Wagner College. The course provides students with an introduction to programming in the Wolfram language (Mathematica) and serves to fulfill the general education requirement of intensive technology in the newly established curriculum. Students develop competency in programming with examples that are drawn from the first-year Chemistry curriculum. They develop their problem-solving skills by writing small programs that reinforce and extend their understanding of chemical principles. These examples incorporate basic programming elements such as iteration, modular functions, arrays, and Boolean logic. Students also learn procedural and functional programming in the Wolfram language and engage in projects that utilize chemistry domain knowledge and programming elements learned in the course. This course has served as an efficient recruitment mechanism for the author’s research group and the Chemistry program.

Notebook Setup

Directory Setup

SetDirectory[NotebookDirectory[]]

Lists of chemicals:

This section creates lists of common chemicals that should be known to first-year Chemistry students. The chemicals from these lists are then used in various function calls and applications later in the notebook.

simpleAcids={"Perchloric acid","Hydroiodic acid","Hydrobromic acid","Hydrochloric acid","Sulfuric acid","Nitric acid","Hydronium","Oxalic acid","Sulfurous acid","Hydrogen sulfate","Phosphoric acid","Nitrous acid","Hydrofluoric acid","Methanoic acid","Benzoic acid","Hydrogen oxalate","Ethanoic acid","Carbonic acid","Dihydrogen phosphate","Hydrogen sulfite","Hydrocyanic acid","Ammonium","Boric Acid","Hydrogen carbonate","Hydrogen phosphate","Dihydrogen sulfide","Hydrogen borate"};

simpleBases={"Perchlorate","Iodide","Bromide","Chloride","Hydrogen sulfate","Nitrate","Water","Hydrogen oxalate","Hydrogen sulfite","Sulfate","Dihydrogen phosphate","Nitrite","Fluoride","Methanoate","Benzoate","Oxalate","Acetate","Hydrogen carbonate","Hydrogen sulfide","Hydrogen phosphate","Sulfite","Cyanide","Ammonia","Dihydrogenborate","Carbonate","Phosphate","Hydrogen borate","Borate","Hydroxide","Sodium hydroxide"};

simpleSalts={"Sodium chloride","Ammonium dichlorate","Magnesium sulfate","Sodium bicarbonate","Calcium carbonate","Sodium nitrate"};

simpleChemicals=Flatten[{simpleAcids,simpleBases,simpleSalts}];

molecularFormulas=MoleculeValue[Molecule[#],"MolecularFormulaString"]&/@simpleChemicals;

simpleAcidsv2={"Perchloric acid","Hydroiodic acid","Hydrobromic acid","Hydrochloric acid","Sulfuric acid","Nitric acid","Oxalic acid","Sulfurous acid","Phosphoric acid","Nitrous acid","Hydrofluoric acid","Methanoic acid","Hydrocyanic acid","Boric Acid","Dihydrogen sulfide"};

simpleBasesv2={"Water","Hydrogen sulfide","Ammonia"};

simpleSaltsv2={"Sodium chloride","Sodium bicarbonate","Sodium nitrate"};

simpleChemicalsv2=Flatten[{simpleAcidsv2,simpleBasesv2,simpleSaltsv2}];

simpleChemicalsv2Molality={"Perchloric acid","Hydroiodic acid","Hydrobromic acid","Hydrochloric acid","Sulfuric acid","Nitric acid","Oxalic acid","Sulfurous acid","Phosphoric acid","Hydrofluoric acid","Methanoic acid","Hydrosulfuric acid","Hydrocyanic acid","Dihydrogen sulfide","Water","Hydrogen sulfide","Ammonia","Sodium chloride","Sodium bicarbonate","Sodium nitrate"};

simpleChemicalsv3={"PerchloricAcid","HydroiodicAcid","HydrobromicAcid","HydrochloricAcid","SulfuricAcid","NitricAcid","OxalicAcid","SulfurousAcid","PhosphoricAcid","NitrousAcid","MethanoicAcid","BenzoicAcid","CarbonicAcid","HydrocyanicAcid","BoricAcid","Water","Nitrite","HydrogenSulfide","Ammonia"};

commonGases={"Hydrogen","Methane","Ammonia","Hydrogen Cyanide","Carbon Monoxide","Nitrogen","Nitrogen Oxide","Ethane","Oxygen","Phosphine","Hydrogen Sulfide","Hydrogen Chloride","Fluorine","Carbon Dioxide","Propane","Nitrogen Dioxide","Ozone","Butane","Sulfur Dioxide","Boron Trifluoride","Chlorine"};

inertGases={"Argon","Helium","Krypton","Xenon","Neon","Radon","Organesson"};

simpleGases=Flatten[{commonGases,inertGases}];

Examples

1. Nomenclature

Interactive chemical guessing game that asks for the molecular formula from the name of a random chemical chosen from the simpleChemicals list. User inputs the answer and if the answer is incorrect, the question is returned until the correct answer is supplied. All answers of chemicals that work are listed below.

formulaGuesser[chemical_String]:=Module[{moleculeAnswer=MoleculeValue[Molecule[chemical],"MolecularFormulaString"]},
While[InputString[StringJoin["What is the molecular formula for ",chemical,"?"]]≠ moleculeAnswer,Return]]

formulaGuesser[RandomChoice[simpleChemicals]]

MoleculeValue[Molecule["Oxalate"],"MolecularFormula"]

2. Molarity

Calculates molarity by supplying a chemical, mass,  and volume amount in mL. The volume is converted into L in the function. This function works with the chemical list simpleChemicalsv2.

calcMolarity[chem_String,mass_,vol_]:=
(((((Quantity[mass,"Grams"])/(Interpreter["Chemical"][chem]["MolarMass"]))))/(UnitConvert[Quantity[vol,"Milliliters"],"Liters"]))

Here, we calculate molarity for 18 g of each substance of all the chemicals present in the list simpleChemicalsv2

calcMolarity[#,18,1000]&/@simpleChemicalsv2

chem=RandomChoice[simpleChemicalsv2];
{chem,calcMolarity[chem,20.5,560.]}

3. Molality

Calculate the molality by supplying a chemical identified as solute, mass of the solute(g) and mass of solvent (g). Works with simpleChemicalsv2.

calcMolality[chem_String,massSolute_,massSolvent_]:=(((((Quantity[massSolute,"Grams"])/(Interpreter["Chemical"][chem]["MolarMass"]))))/(Quantity[massSolvent,"Kilograms"]))

calcMolality[#,50,2]&/@simpleChemicalsv2

chem=RandomChoice[simpleChemicalsv2];
{chem,calcMolality[chem,30.,1]}

4. Mole Fraction

Calculate mole fraction by supplying chemicals and mass amounts. Supply the name and amount in grams for each of the two chemical species.

calcMolFraction[chem1_String,mass1_,chem2_String,mass2_]:=Module[{mol1,mol2,molTotal,molFrac1,molFrac2},
mol1=((Quantity[mass1,"Grams"])/(Interpreter["Chemical"][chem1]["MolarMass"]));
mol2=((Quantity[mass2,"Grams"])/(Interpreter["Chemical"][chem2]["MolarMass"]));
molTotal=mol1+mol2;
{molFrac1=(mol1/molTotal),molFrac2=(mol2/molTotal)};
{molFrac1->chem1,molFrac2->chem2}]

calcMolFraction[RandomChoice[simpleChemicalsv2],20,RandomChoice[simpleChemicalsv2],40]

5. Partial Pressure

Calculate partial pressures for each gas in a mixture of two gases. The user supplies identity of each gas, amount of each gas, and the total pressure (mm Hg).

calcPartialPressure[chem1_String,mass1_,chem2_String,mass2_,totalPressure_]:=Module[{mol1,mol2,molTotal,pressureTotal,molFrac1,molFrac2,pressure1,pressure2},
mol1=(mass1/(Interpreter["Chemical"][chem1]["MolarMass"]));
mol2=(mass2/(Interpreter["Chemical"][chem2]["MolarMass"]));
molTotal=mol1+mol2;
pressureTotal=Quantity[totalPressure,"MillimetersOfMercury"];
{molFrac1=(mol1/molTotal),molFrac2=(mol2/molTotal)};
{molFrac1->chem1,molFrac2->chem2};
pressure1=molFrac1*pressureTotal;
pressure2=molFrac2*pressureTotal;
{pressure1->chem1,pressure2->chem2}]

calcPartialPressure[RandomChoice[simpleGases],20,RandomChoice[simpleGases],35,40]

6. Ideal Gas Law

Calculate the number of moles using the ideal gas law equation: PV = nRT. Input variables are (1) pressure of the system (Torr), volume (Milliliters), and the temperature (Kelvin).

calcIdealGasLawMoles[pressure_,vol_,temp_]:=
Module[{rGasAtm},
rGasAtm=Quantity[0.0820578,("Liters""Atmospheres")/("Kelvins""Moles")];
(((Quantity[pressure,"Torr"]*Quantity[vol,"Milliliters"]))/((rGasAtm*Quantity[temp,"Kelvins"])))]

calcIdealGasLawMoles[500,750,300]

7. Clausius-Clapeyron Equation

The Clausius-Clapeyron Equation and allows us to estimate the vapor pressure at another temperature, if the vapor pressure is known at some temperature, and if the enthalpy of vaporization is known. 

Compute ΔHvap from random pressures and temperatures. The user inputs pressures in Torr units (it doesn’t matter because it will cancel out) and temperatures in Kelvins. The gas constant is defined in the function. The function returns ΔH.

calcCCEquation[pressure1_,temp1_,pressure2_,temp2_]:=Module[{p1,p2,rGasConstant,t1,t2},
p1=Quantity[pressure1,"Torr"];
p2=Quantity[pressure2,"Torr"];
rGasConstant=Quantity[8.314,"Joules"/("Kelvins""Moles")];
t1=Quantity[temp1,"Kelvins"];
t2=Quantity[temp2,"Kelvins"];
UnitConvert[((rGasConstant * Log[(p1/p2)])/(((1/t2)-(1/t1)))),(("Kilojoules")/("Moles"))]]

The vapor pressures of ice at 268 K and 273 K are 2.965 and 4.560 torr respectively. Estimate the heat of sublimation of ice.

calcCCEquation[2.965,268,4.560,273]

Calculate  ΔHvap  for ethanol, given vapor pressure at 40 °C is 150 torr. The normal boiling point for ethanol is 78 °C.

calcCCEquation[150,313,760,351]

8. Lewis Dot Structures

A question and the answer are automatically generated asking for the Lewis dot structure from simpleChemicalsv3 list.

lewisStructureQuestion[]:=Module[{chem1,chemAns},
chem1=RandomChoice[simpleChemicalsv3];
chemAns=Entity["Chemical",chem1]["LewisDotStructureDiagram"];
Print[StringJoin["Draw the Lewis dot structure for ",ToString[chem1],"."]];
Print[chemAns]
]

lewisStructureQuestion[]

9. Periodic Trends

For loops to get the periodic trends of x number of elements. Atomic mass, Electronegativity, and atomic radius are shown here.

Atomic masses and radii of the first ten elements in the periodic table:

For[i=1,i≤ 10,i++,
Print[ElementData[i,"Abbreviation"]," ", ElementData[i,"AtomicMass"]," ",ElementData[i,"AtomicRadius"]]]

Electronegativity of elements in the second period:

For[i=11,i≤ 18,i++,
Print[ElementData[i,"Abbreviation"]," ", ElementData[i,"Electronegativity"]]]

10. While loop to select elements based on specified criterion.

Display atomic mass of elements that have an atomic mass less than 30 atomic mass units.

i=1;
While[ElementData[i,"AtomicMass"]≤  Quantity[30,"AtomicMassUnit"],
Print[i," ",ElementData[i,"Abbreviation"]," ", ElementData[i, "AtomicMass"]];
i++]

11. Mass to Moles Problems

A web deployable problem set for conversion of mass to moles for common chemicals. The form allows the user to input the number of problems to be generated and provides the answer for each of the generated problem.

chemicalsGenChem={Entity["Chemical","Water"],Entity["Chemical","CarbonDioxide"],Entity["Chemical","CarbonMonoxide"],Entity["Chemical","Methane"],Entity["Chemical","CopperIISulfate"],Entity["Chemical","SodiumChloride"],Entity["Chemical","PotassiumChloride"],Entity["Chemical","AceticAcid"],Entity["Chemical","NitricAcid"],Entity["Chemical","IronIIOxide"],Entity["Chemical","IronIIIOxide"],Entity["Chemical","PotassiumSulfate"],Entity["Chemical","MagnesiumChloride"],Entity["Chemical","SodiumBicarbonate"],Entity["Chemical","SulfuricAcid"],Entity["Chemical","SodiumHypochlorite"],Entity["Chemical","SodiumHydroxide"],Entity["Chemical","CalciumCarbonate"],Entity["Chemical","CalciumOxide"],Entity["Chemical","MagnesiumSulfate"],Entity["Chemical","HydrochloricAcid"],Entity["Chemical","NitricAcid"],Entity["Chemical","Ammonia"],Entity["Chemical","PhosphoricAcid"],Entity["Chemical","PotassiumDichromate"]};

masstoMolesProblems[numProblems_Integer]:=Module[{chemicalNames,chemicalAmounts,mmProblemStatements,mmSolutions,workingPrecision=2},
chemicalNames=RandomChoice[chemicalsGenChem,numProblems];
chemicalAmounts=Table[RandomReal[{1,5},WorkingPrecision->workingPrecision]*RandomChoice[{(Quantity[, "mg", milligrams, "Milligrams"]),(Quantity[, "µg", micrograms, "Micrograms"]),(Quantity[, "ng", nanograms, "Nanograms"]),(Quantity[, "g", grams, "Grams"])}],numProblems];
mmProblemStatements=Table[StringJoin["Convert ",ToString[chemicalAmounts[[i]]]," of ",ToString[EntityValue[chemicalNames[[i]],"Name"]]," to moles."],{i,1,numProblems}];
mmSolutions=(chemicalAmounts/(EntityValue[chemicalNames,"MolarMass"]));
TableForm[Transpose[{mmProblemStatements,mmSolutions}],TableHeadings->{Range[numProblems],{"Problem","Solution"}}]
]

CloudDeploy[FormFunction[{"problems"->Restricted["Integer",{1,10}]},masstoMolesProblems[#problems]&,"CloudCDF",AppearanceRules-><|"Title"-> "Mass to Moles Problems","Description"-> "Conversion problems" |>],
Permissions->"Public",IncludeDefinitions->True]

12. Interactive displays

Use Manipulate to present information that the user can control.

Manipulate[{Style[ElementData[atomicNumber,"Abbreviation"],FontFamily->"Latin Modern Math",FontSize->16],
Style[ElementData[atomicNumber,elementProperty],FontFamily->"Latin Modern Math",FontSize->16] },
{atomicNumber,1,54,1},{elementProperty,{"Name","Valence","Electronegativity","ElectronConfigurationString"}}]

Manipulate[ChemicalData[molecule,property],{molecule,simpleChemicalsv2},{property,{"BlackStructureDiagram","MoleculePlot","CompoundFormulaString"}}]