Lua模块用于计算化合物的摩尔质量。

我在我的维基上使用(或者说尝试使用)基于 Lua 的模块及其调用模板(即使用 {{#invoke:}} 调用它们的模板)已经有一段时间了,并且我有一个用于化合物(即 _Chembox_)的信息框,其中包括化合物中每个化学元素的原子数目的输入(即化合物的分子式中使用的数字)以及化合物的摩尔质量。我在想,由于可以根据分子式计算化合物的摩尔质量,所以可能可以创建一个 Lua 模块,可以自动执行此操作,这样就不需要我自己将摩尔质量输入到这些信息框中。

所以我的问题基本上是,我该如何做到这一点?

研究

我的背景是数学,所以我觉得最直接的方法是设置两个向量 A 和 B,并在它们之间执行点积。A 包含用户定义的变量,即提供给调用模块的模板中的变量。例如,假设我们正在讨论乙醇(C2H6O),则模板可能如下所示:

{{Molar mass calculator
|C = 2
|H = 6
|O = 1
}}

B 包含每个元素的平均原子质量,单位为克/摩尔(g/mol)。这个向量将由我自己提供(即我有一个包含84个在自然界中含量足够多的元素的列表,可以得到它们的标准原子质量。因此,如果您只是向我展示在哪里将它们添加到代码中,我将在 Lua 代码中提供它们)。

我已经查找了在 Lua 中进行点积的方法以查看这是否可行以及如何执行它们,并找到了这个代码(http://rosettacode.org/wiki/Dot_product#Lua):

function dotprod(a, b)
  local ret = 0
  for i = 1, #a do
    ret = ret + a[i] * b[i]
  end
  return ret
end

print(dotprod({1, 3, -5}, {4, -2, 1}))
点赞
用户793615
用户793615

请使用自己的值填充“AtomicWeightLookup”表格。

程序末尾有一个“Calculate”函数的示例调用。

local AtomicWeightLookup = {
 C = 12.01,
 H = 1.001,
 O = 16
}

local function Calculate(Input)
 -- Input Example: {C = 2, H = 6, O = 1}
 local Result = 0
 -- Iterate through Input table
 for Element,Quantity in next,Input do
  -- If element is not found in table, assume 0 weight.
  local AtomicWeight = AtomicWeightLookup[Element] or 0
  -- Multiply
  Result = Result + Quantity * AtomicWeight
 end
 return Result
end

-- EXAMPLE
print(Calculate({C = 2, H = 6, O = 1}))
2015-03-31 21:44:54
用户1876983
用户1876983

通过向Wikitech-I邮件列表(wikitech-I@lists.sourceforge.net)发送电子邮件,我收到了答案。_模块:摩尔质量计算器_将具有以下代码(round函数设计为将最终结果四舍五入到最接近的三个小数位,因为我后来决定我也想要这种功能):

local p = {};

function p.calc(frame)
    local atomicWeights = mw.loadData(  'Module:Standard atomic weight'  )
    local total = 0

    for element, quantity in pairs( frame:getParent().args ) do
        if quantity ~= "" then
            local atomicWeight = atomicWeights[element] or error( 'Element "' .. element .. '" is not known. Please add it to [[Module:Standard atomic weight]] if it\'s not a typo.' )
            quantity = tonumber( quantity ) or error( 'Quantity for ' .. element .. ' is not a number.' )
            total = total + atomicWeight * quantity
        end
    end

    function round(num, idp)
        local mult = 10^(idp or 0)
        return math.floor(num * mult + 0.5) / mult
    end

    return round(total,3)
end

return p

_模块:标准原子质量_具有以下代码:

local  M =  {}

M['Ag']  =  107.8682      -- 银(Ag)
M['As']  =  74.921595     -- 砷(As)
M['Au']  =  196.966569    -- 金(Au)
M['B']   =  10.8135       -- 硼(B)
M['Ba']  =  137.327       -- 钡(Ba)
M['Bi']  =  208.9804      -- 铋(Bi)
M['Br']  =  79.904        -- 溴(Br)
M['C']   =  12.0106       -- 碳(C)
M['Ca']  =  40.078        -- 钙(Ca)
M['Cl']  =  35.4515       -- 氯(Cl)
M['Co']  =  58.933194     -- 钴(Co)
M['Cu']  =  63.546        -- 铜(Cu)
M['F']   =  18.998403163  -- 氟(F)
M['Fe']  =  55.845        -- 铁(Fe)
M['Ga']  =  69.723        -- 镓(Ga)
M['H']   =  1.007975      -- 氢(H)
M['Hg']  =  200.592       -- 汞(Hg)
M['I']   =  126.90447     -- 碘(I)
M['K']   =  39.0983       -- 钾(K)
M['Li']  =  6.9675        -- 锂(Li)
M['Mg']  =  24.3055       -- 镁(Mg)
M['Mn']  =  54.938044     -- 锰(Mn)
M['N']   =  14.006855     -- 氮(N)
M['Na']  =  22.98976928   -- 钠(Na)
M['Ni']  =  58.6934       -- 镍(Ni)
M['O']   =  15.9994       -- 氧(O)
M['P']   =  30.973761998  -- 磷(P)
M['Pb']  =  207.2         -- 铅(Pb)
M['Pt']  =  195.084       -- 铂(Pt)
M['S']   =  32.0675       -- 硫(S)
M['Se']  =  78.971        -- 硒(Se)
M['Sr']  =  87.62         -- 锶(Sr)
M['Tl']  =  204.3835      -- 铊(Tl)
M['Zn']  =  65.38         -- 锌(Zn)

return  M

和 _Template:Molar mass calculator_:

{{#invoke:Molar mass calculator|calc}} g/mol
2015-04-02 22:43:50