elements.frink

// Simple periodic table of the elements//// This allows you to access the properties of an element by referring it to// it as "Element.Hydrogen" or "Element.H" or "Element.Silicon" or// "Element.Si"//// (Hint: for less typing in a program, you can say "e=Element" and then// type e.H or e.Si. Note that only works in the current scope and will// not work across function calls.)//// Each element has the following properties:// symbol// name// number// atomicMass//// The individual properties of an element can be looked up as, say:// Element.Hydrogen.atomicMass//// This class also has methods to enumerate through all elements (e.g.// Element.listByName[], Element.listBySymbol[], Element.listByNumber[])//// The methods Element.getByName[str] and Element.getByNumber[num] allow// you to look up elements by name, symbol, or atomic number.//// NOTE: Because this uses the method array.shallowCopy[], this requires// a version of Frink dated 2006-09-25 or later!//// Thanks to "overgauss" for research and contributions.//
class Element
{
var symbol

var name

var number

var atomicMass

// A class-level container for all the elements.
class var elements = new array[]

// Defer this until it's used. This will be an array sorted by name.
class var elementsByName = undef

// Defer this until it's used. This will be an array sorted by symbol.
class var elementsBySymbol = undef

// Defer this until it's used. This will be an array sorted by number.
class var elementsByNumber = undef

// Constructor, creates a new element// This constructor should be private. It should only be called by// the add[] factory method.
new[eSymbol, eName, eProtons, eMass is mass] :=
{
symbol = eSymbol
name = eName
number = eProtons
atomicMass = eMass
}

// Fetches an element by searching for an exact match in the name// or symbol of the element. If that fails, returns undef. This is// a case-insensitive match.
class getByName[n] :=
{
lcName = lc[n]
for e = elements
if (lc[e.name] == lcName) or (lc[e.symbol] == lcName)
return e

return undef
}

// Returns the element with the specified number. If that fails, returns// undef. This could be made smarter by storing the elements in an array// at certain positions, but that approach is made somewhat non-elegant// because elements of arrays in Frink begin with index 0.
class getByNumber[n] :=
{
for e = elements
if (e.number == n)
return e