Документация для Модуль:Calculate Перейти к коду ↴ [ править | очистить ]

▶️ Planeshift.
Документацию для этого шаблона или модуля можно найти в Template:Calculate.
Вы можете быть перенаправлены на другой язык вики, если перевод недоступен.


Yes check.svg Д All tests passed.

Name Expected Actual
Yes check.svg Д test_non_substituted_expression
Yes check.svg Д test_non_substituted_expression_with_percentage
Yes check.svg Д test_non_substituted_expression_with_round
Yes check.svg Д test_non_substituted_expression_with_round_at_end
Yes check.svg Д test_percentage_in_main_expression
Yes check.svg Д test_percentage_in_v_value
Yes check.svg Д test_percentage_output_percentage_in_both
Yes check.svg Д test_percentage_output_percentage_in_expression
Yes check.svg Д test_percentage_output_percentage_in_v
Yes check.svg Д test_substituted_expression_1v
Yes check.svg Д test_substituted_expression_2v
Yes check.svg Д test_substituted_expression_3v
Yes check.svg Д test_substitution_1v
Yes check.svg Д test_substitution_2v
Yes check.svg Д test_substitution_3v


local p = {}
local expr = mw.ext.ParserFunctions.expr
local getArgs = require('Модуль:Arguments').getArgs
local split = require('Модуль:Split')
local yesno = require('Модуль:Yesno')

local i18n = {
  value_separator = '/',
  error_no_expression = 'Введите выражение',

function p.main(frame)
  local args = getArgs(frame, {
    wrappers = {
  return p._main(args)

function p._main(args)
  local calculate = function(ru_calc)
    -- Replaces , with .
    local en_calc = string.gsub( ru_calc, '(%d),(%d)', '%1.%2' )
    -- Replaces percentage signs with /100 since #expr can't handle them.
    en_calc = string.gsub( en_calc, '%%', '/100' )
    local success, result = pcall( expr, en_calc )
    if success then
      -- Replaces . with ,
      result = string.gsub( result, '(%d)%.(%d)', '%1,%2' )
      return result
      -- Remove the leading "Expression error: " and the trailing ".".
      local error_message = result:sub( 19, -2 )
      -- Add the faulty expression to make debugging easier.
      local error_message = string.format( '%s in expression "%s"', error_message, ru_calc )

      error( error_message )

  assert( args and args[1], i18n.error_no_expression )
  if args['v1'] then
    -- Create a table that holds a table for each v argument.
    local v_values = {}
    local n = 1
    while args['v'..n] do
      -- Escape percentage signs to prevent them from escaping the / during the split.
      v = string.gsub(args['v'..n], '%%', '%%%%')
      -- Split the v into the individual values and add them to the v_values table.
      table.insert(v_values, split(v, i18n.value_separator))
      n = n + 1

    local output = {}
    -- Run once for each value in the v1 argument.
    for level=1,#v_values[1] do
      local calc = args[1]
      -- Do a replacement for each v arg.
      for i,v in ipairs(v_values) do
        calc = calc:gsub('v'..i, v[level])

      -- Solve the calculation we just constructed and insert it into the output.
      -- args[2] is used to trigger special percentage handling.
      if yesno(args.percent) or args[2] then
        table.insert(output, calculate('('..calc..')*100') .. '%') 
        table.insert(output, calculate(calc)) 

    -- Return the values in the output table separated by a /.
    return table.concat(output, i18n.value_separator)
    -- Just do a normal #expr if no v values are given.
    -- Still has percentage handling which normal #expr doesn't.
    -- TODO: Remove the args[2] once all pages are transitioned.
    if yesno(args.percent) or args[2] then
      return calculate('('..args[1]..')*100') .. '%'
      return calculate(args[1])

return p