in generators/python/math.js [240:334]
Blockly.Python['math_on_list'] = function(block) {
// Math functions for lists.
var func = block.getFieldValue('OP');
var list = Blockly.Python.valueToCode(block, 'LIST',
Blockly.Python.ORDER_NONE) || '[]';
var code;
switch (func) {
case 'SUM':
code = 'sum(' + list + ')';
break;
case 'MIN':
code = 'min(' + list + ')';
break;
case 'MAX':
code = 'max(' + list + ')';
break;
case 'AVERAGE':
Blockly.Python.definitions_['from_numbers_import_Number'] =
'from numbers import Number';
var functionName = Blockly.Python.provideFunction_(
'math_mean',
// This operation excludes null and values that aren't int or float:',
// math_mean([null, null, "aString", 1, 9]) == 5.0.',
['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(myList):',
' localList = [e for e in myList if isinstance(e, Number)]',
' if not localList: return',
' return float(sum(localList)) / len(localList)']);
code = functionName + '(' + list + ')';
break;
case 'MEDIAN':
Blockly.Python.definitions_['from_numbers_import_Number'] =
'from numbers import Number';
var functionName = Blockly.Python.provideFunction_(
'math_median',
// This operation excludes null values:
// math_median([null, null, 1, 3]) == 2.0.
['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(myList):',
' localList = sorted([e for e in myList if isinstance(e, Number)])',
' if not localList: return',
' if len(localList) % 2 == 0:',
' return (localList[len(localList) // 2 - 1] + ' +
'localList[len(localList) // 2]) / 2.0',
' else:',
' return localList[(len(localList) - 1) // 2]']);
code = functionName + '(' + list + ')';
break;
case 'MODE':
var functionName = Blockly.Python.provideFunction_(
'math_modes',
// As a list of numbers can contain more than one mode,
// the returned result is provided as an array.
// Mode of [3, 'x', 'x', 1, 1, 2, '3'] -> ['x', 1].
['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(some_list):',
' modes = []',
' # Using a lists of [item, count] to keep count rather than dict',
' # to avoid "unhashable" errors when the counted item is ' +
'itself a list or dict.',
' counts = []',
' maxCount = 1',
' for item in some_list:',
' found = False',
' for count in counts:',
' if count[0] == item:',
' count[1] += 1',
' maxCount = max(maxCount, count[1])',
' found = True',
' if not found:',
' counts.append([item, 1])',
' for counted_item, item_count in counts:',
' if item_count == maxCount:',
' modes.append(counted_item)',
' return modes']);
code = functionName + '(' + list + ')';
break;
case 'STD_DEV':
Blockly.Python.definitions_['import_math'] = 'import math';
var functionName = Blockly.Python.provideFunction_(
'math_standard_deviation',
['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(numbers):',
' n = len(numbers)',
' if n == 0: return',
' mean = float(sum(numbers)) / n',
' variance = sum((x - mean) ** 2 for x in numbers) / n',
' return math.sqrt(variance)']);
code = functionName + '(' + list + ')';
break;
case 'RANDOM':
Blockly.Python.definitions_['import_random'] = 'import random';
code = 'random.choice(' + list + ')';
break;
default:
throw Error('Unknown operator: ' + func);
}
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
};