in generators/lua/math.js [209:375]
Blockly.Lua['math_on_list'] = function(block) {
// Math functions for lists.
var func = block.getFieldValue('OP');
var list = Blockly.Lua.valueToCode(block, 'LIST',
Blockly.Lua.ORDER_NONE) || '{}';
var functionName;
// Functions needed in more than one case.
function provideSum() {
return Blockly.Lua.provideFunction_(
'math_sum',
['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)',
' local result = 0',
' for _, v in ipairs(t) do',
' result = result + v',
' end',
' return result',
'end']);
}
switch (func) {
case 'SUM':
functionName = provideSum();
break;
case 'MIN':
// Returns 0 for the empty list.
functionName = Blockly.Lua.provideFunction_(
'math_min',
['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)',
' if #t == 0 then',
' return 0',
' end',
' local result = math.huge',
' for _, v in ipairs(t) do',
' if v < result then',
' result = v',
' end',
' end',
' return result',
'end']);
break;
case 'AVERAGE':
// Returns 0 for the empty list.
functionName = Blockly.Lua.provideFunction_(
'math_average',
['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)',
' if #t == 0 then',
' return 0',
' end',
' return ' + provideSum() + '(t) / #t',
'end']);
break;
case 'MAX':
// Returns 0 for the empty list.
functionName = Blockly.Lua.provideFunction_(
'math_max',
['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)',
' if #t == 0 then',
' return 0',
' end',
' local result = -math.huge',
' for _, v in ipairs(t) do',
' if v > result then',
' result = v',
' end',
' end',
' return result',
'end']);
break;
case 'MEDIAN':
functionName = Blockly.Lua.provideFunction_(
'math_median',
// This operation excludes non-numbers.
['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)',
' -- Source: http://lua-users.org/wiki/SimpleStats',
' if #t == 0 then',
' return 0',
' end',
' local temp={}',
' for _, v in ipairs(t) do',
' if type(v) == "number" then',
' table.insert(temp, v)',
' end',
' end',
' table.sort(temp)',
' if #temp % 2 == 0 then',
' return (temp[#temp/2] + temp[(#temp/2)+1]) / 2',
' else',
' return temp[math.ceil(#temp/2)]',
' end',
'end']);
break;
case 'MODE':
functionName = Blockly.Lua.provideFunction_(
'math_modes',
// As a list of numbers can contain more than one mode,
// the returned result is provided as an array.
// The Lua version includes non-numbers.
['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)',
' -- Source: http://lua-users.org/wiki/SimpleStats',
' local counts={}',
' for _, v in ipairs(t) do',
' if counts[v] == nil then',
' counts[v] = 1',
' else',
' counts[v] = counts[v] + 1',
' end',
' end',
' local biggestCount = 0',
' for _, v in pairs(counts) do',
' if v > biggestCount then',
' biggestCount = v',
' end',
' end',
' local temp={}',
' for k, v in pairs(counts) do',
' if v == biggestCount then',
' table.insert(temp, k)',
' end',
' end',
' return temp',
'end']);
break;
case 'STD_DEV':
functionName = Blockly.Lua.provideFunction_(
'math_standard_deviation',
['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)',
' local m',
' local vm',
' local total = 0',
' local count = 0',
' local result',
' m = #t == 0 and 0 or ' + provideSum() + '(t) / #t',
' for _, v in ipairs(t) do',
" if type(v) == 'number' then",
' vm = v - m',
' total = total + (vm * vm)',
' count = count + 1',
' end',
' end',
' result = math.sqrt(total / (count-1))',
' return result',
'end']);
break;
case 'RANDOM':
functionName = Blockly.Lua.provideFunction_(
'math_random_list',
['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)',
' if #t == 0 then',
' return nil',
' end',
' return t[math.random(#t)]',
'end']);
break;
default:
throw Error('Unknown operator: ' + func);
}
return [functionName + '(' + list + ')', Blockly.Lua.ORDER_HIGH];
};