mirror of
https://github.com/google/blockly.git
synced 2026-01-09 01:50:11 +01:00
chore: Use ES6 template strings in CSS and code generators (#5902)
* Unindent CSS, save 3 kb of code. * Convert generator functions to template strings. This resolves #5761.
This commit is contained in:
@@ -29,13 +29,13 @@ Python['colour_random'] = function(block) {
|
||||
|
||||
Python['colour_rgb'] = function(block) {
|
||||
// Compose a colour from RGB components expressed as percentages.
|
||||
const functionName = Python.provideFunction_('colour_rgb', [
|
||||
'def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(r, g, b):',
|
||||
' r = round(min(100, max(0, r)) * 2.55)',
|
||||
' g = round(min(100, max(0, g)) * 2.55)',
|
||||
' b = round(min(100, max(0, b)) * 2.55)',
|
||||
' return \'#%02x%02x%02x\' % (r, g, b)'
|
||||
]);
|
||||
const functionName = Python.provideFunction_('colour_rgb', `
|
||||
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(r, g, b):
|
||||
r = round(min(100, max(0, r)) * 2.55)
|
||||
g = round(min(100, max(0, g)) * 2.55)
|
||||
b = round(min(100, max(0, b)) * 2.55)
|
||||
return \'#%02x%02x%02x\' % (r, g, b)
|
||||
`);
|
||||
const r = Python.valueToCode(block, 'RED', Python.ORDER_NONE) || 0;
|
||||
const g = Python.valueToCode(block, 'GREEN', Python.ORDER_NONE) || 0;
|
||||
const b = Python.valueToCode(block, 'BLUE', Python.ORDER_NONE) || 0;
|
||||
@@ -45,17 +45,17 @@ Python['colour_rgb'] = function(block) {
|
||||
|
||||
Python['colour_blend'] = function(block) {
|
||||
// Blend two colours together.
|
||||
const functionName = Python.provideFunction_('colour_blend', [
|
||||
'def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(colour1, colour2, ratio):',
|
||||
' r1, r2 = int(colour1[1:3], 16), int(colour2[1:3], 16)',
|
||||
' g1, g2 = int(colour1[3:5], 16), int(colour2[3:5], 16)',
|
||||
' b1, b2 = int(colour1[5:7], 16), int(colour2[5:7], 16)',
|
||||
' ratio = min(1, max(0, ratio))',
|
||||
' r = round(r1 * (1 - ratio) + r2 * ratio)',
|
||||
' g = round(g1 * (1 - ratio) + g2 * ratio)',
|
||||
' b = round(b1 * (1 - ratio) + b2 * ratio)',
|
||||
' return \'#%02x%02x%02x\' % (r, g, b)'
|
||||
]);
|
||||
const functionName = Python.provideFunction_('colour_blend', `
|
||||
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(colour1, colour2, ratio):
|
||||
r1, r2 = int(colour1[1:3], 16), int(colour2[1:3], 16)
|
||||
g1, g2 = int(colour1[3:5], 16), int(colour2[3:5], 16)
|
||||
b1, b2 = int(colour1[5:7], 16), int(colour2[5:7], 16)
|
||||
ratio = min(1, max(0, ratio))
|
||||
r = round(r1 * (1 - ratio) + r2 * ratio)
|
||||
g = round(g1 * (1 - ratio) + g2 * ratio)
|
||||
b = round(b1 * (1 - ratio) + b2 * ratio)
|
||||
return \'#%02x%02x%02x\' % (r, g, b)
|
||||
`);
|
||||
const colour1 =
|
||||
Python.valueToCode(block, 'COLOUR1', Python.ORDER_NONE) || '\'#000000\'';
|
||||
const colour2 =
|
||||
|
||||
@@ -57,7 +57,7 @@ Python['lists_isEmpty'] = function(block) {
|
||||
Python['lists_indexOf'] = function(block) {
|
||||
// Find an item in the list.
|
||||
const item = Python.valueToCode(block, 'FIND', Python.ORDER_NONE) || '[]';
|
||||
const list = Python.valueToCode(block, 'VALUE', Python.ORDER_NONE) || '\'\'';
|
||||
const list = Python.valueToCode(block, 'VALUE', Python.ORDER_NONE) || "''";
|
||||
let errorIndex = ' -1';
|
||||
let firstIndexAdjustment = '';
|
||||
let lastIndexAdjustment = ' - 1';
|
||||
@@ -68,21 +68,22 @@ Python['lists_indexOf'] = function(block) {
|
||||
lastIndexAdjustment = '';
|
||||
}
|
||||
|
||||
let functionName;
|
||||
if (block.getFieldValue('END') === 'FIRST') {
|
||||
const functionName = Python.provideFunction_('first_index', [
|
||||
'def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(my_list, elem):',
|
||||
' try: index = my_list.index(elem)' + firstIndexAdjustment,
|
||||
' except: index =' + errorIndex, ' return index'
|
||||
]);
|
||||
const code = functionName + '(' + list + ', ' + item + ')';
|
||||
return [code, Python.ORDER_FUNCTION_CALL];
|
||||
functionName = Python.provideFunction_('first_index', `
|
||||
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(my_list, elem):
|
||||
try: index = my_list.index(elem)${firstIndexAdjustment}
|
||||
except: index =${errorIndex}
|
||||
return index
|
||||
`);
|
||||
} else {
|
||||
functionName = Python.provideFunction_('last_index', `
|
||||
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(my_list, elem):
|
||||
try: index = len(my_list) - my_list[::-1].index(elem)${lastIndexAdjustment}
|
||||
except: index =${errorIndex}
|
||||
return index
|
||||
`);
|
||||
}
|
||||
const functionName = Python.provideFunction_('last_index', [
|
||||
'def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(my_list, elem):',
|
||||
' try: index = len(my_list) - my_list[::-1].index(elem)' +
|
||||
lastIndexAdjustment,
|
||||
' except: index =' + errorIndex, ' return index'
|
||||
]);
|
||||
const code = functionName + '(' + list + ', ' + item + ')';
|
||||
return [code, Python.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
@@ -152,11 +153,11 @@ Python['lists_getIndex'] = function(block) {
|
||||
return [code, Python.ORDER_FUNCTION_CALL];
|
||||
} else {
|
||||
const functionName =
|
||||
Python.provideFunction_('lists_remove_random_item', [
|
||||
'def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(myList):',
|
||||
' x = int(random.random() * len(myList))',
|
||||
' return myList.pop(x)'
|
||||
]);
|
||||
Python.provideFunction_('lists_remove_random_item', `
|
||||
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(myList):
|
||||
x = int(random.random() * len(myList))
|
||||
return myList.pop(x)
|
||||
`);
|
||||
const code = functionName + '(' + list + ')';
|
||||
if (mode === 'GET_REMOVE') {
|
||||
return [code, Python.ORDER_FUNCTION_CALL];
|
||||
@@ -294,15 +295,22 @@ Python['lists_sort'] = function(block) {
|
||||
const list = (Python.valueToCode(block, 'LIST', Python.ORDER_NONE) || '[]');
|
||||
const type = block.getFieldValue('TYPE');
|
||||
const reverse = block.getFieldValue('DIRECTION') === '1' ? 'False' : 'True';
|
||||
const sortFunctionName = Python.provideFunction_('lists_sort', [
|
||||
'def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(my_list, type, reverse):',
|
||||
' def try_float(s):', ' try:', ' return float(s)', ' except:',
|
||||
' return 0', ' key_funcs = {', ' "NUMERIC": try_float,',
|
||||
' "TEXT": str,', ' "IGNORE_CASE": lambda s: str(s).lower()', ' }',
|
||||
' key_func = key_funcs[type]',
|
||||
' list_cpy = list(my_list)', // Clone the list.
|
||||
' return sorted(list_cpy, key=key_func, reverse=reverse)'
|
||||
]);
|
||||
const sortFunctionName = Python.provideFunction_('lists_sort', `
|
||||
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(my_list, type, reverse):
|
||||
def try_float(s):
|
||||
try:
|
||||
return float(s)
|
||||
except:
|
||||
return 0
|
||||
key_funcs = {
|
||||
"NUMERIC": try_float,
|
||||
"TEXT": str,
|
||||
"IGNORE_CASE": lambda s: str(s).lower()
|
||||
}
|
||||
key_func = key_funcs[type]
|
||||
list_cpy = list(my_list)
|
||||
return sorted(list_cpy, key=key_func, reverse=reverse)
|
||||
`);
|
||||
|
||||
const code =
|
||||
sortFunctionName + '(' + list + ', "' + type + '", ' + reverse + ')';
|
||||
@@ -315,14 +323,14 @@ Python['lists_split'] = function(block) {
|
||||
let code;
|
||||
if (mode === 'SPLIT') {
|
||||
const value_input =
|
||||
Python.valueToCode(block, 'INPUT', Python.ORDER_MEMBER) || '\'\'';
|
||||
Python.valueToCode(block, 'INPUT', Python.ORDER_MEMBER) || "''";
|
||||
const value_delim = Python.valueToCode(block, 'DELIM', Python.ORDER_NONE);
|
||||
code = value_input + '.split(' + value_delim + ')';
|
||||
} else if (mode === 'JOIN') {
|
||||
const value_input =
|
||||
Python.valueToCode(block, 'INPUT', Python.ORDER_NONE) || '[]';
|
||||
const value_delim =
|
||||
Python.valueToCode(block, 'DELIM', Python.ORDER_MEMBER) || '\'\'';
|
||||
Python.valueToCode(block, 'DELIM', Python.ORDER_MEMBER) || "''";
|
||||
code = value_delim + '.join(' + value_input + ')';
|
||||
} else {
|
||||
throw Error('Unknown mode: ' + mode);
|
||||
|
||||
@@ -70,16 +70,20 @@ Python['controls_for'] = function(block) {
|
||||
|
||||
// Helper functions.
|
||||
const defineUpRange = function() {
|
||||
return Python.provideFunction_('upRange', [
|
||||
'def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(start, stop, step):',
|
||||
' while start <= stop:', ' yield start', ' start += abs(step)'
|
||||
]);
|
||||
return Python.provideFunction_('upRange', `
|
||||
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(start, stop, step):
|
||||
while start <= stop:
|
||||
yield start
|
||||
start += abs(step)
|
||||
`);
|
||||
};
|
||||
const defineDownRange = function() {
|
||||
return Python.provideFunction_('downRange', [
|
||||
'def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(start, stop, step):',
|
||||
' while start >= stop:', ' yield start', ' start -= abs(step)'
|
||||
]);
|
||||
return Python.provideFunction_('downRange', `
|
||||
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(start, stop, step):
|
||||
while start >= stop:
|
||||
yield start
|
||||
start -= abs(step)
|
||||
`);
|
||||
};
|
||||
// Arguments are legal Python code (numbers or strings returned by scrub()).
|
||||
const generateUpDownRange = function(start, end, inc) {
|
||||
|
||||
@@ -41,7 +41,7 @@ Python['math_arithmetic'] = function(block) {
|
||||
'MINUS': [' - ', Python.ORDER_ADDITIVE],
|
||||
'MULTIPLY': [' * ', Python.ORDER_MULTIPLICATIVE],
|
||||
'DIVIDE': [' / ', Python.ORDER_MULTIPLICATIVE],
|
||||
'POWER': [' ** ', Python.ORDER_EXPONENTIATION]
|
||||
'POWER': [' ** ', Python.ORDER_EXPONENTIATION],
|
||||
};
|
||||
const tuple = OPERATORS[block.getFieldValue('OP')];
|
||||
const operator = tuple[0];
|
||||
@@ -142,7 +142,7 @@ Python['math_constant'] = function(block) {
|
||||
'GOLDEN_RATIO': ['(1 + math.sqrt(5)) / 2', Python.ORDER_MULTIPLICATIVE],
|
||||
'SQRT2': ['math.sqrt(2)', Python.ORDER_MEMBER],
|
||||
'SQRT1_2': ['math.sqrt(1.0 / 2)', Python.ORDER_MEMBER],
|
||||
'INFINITY': ['float(\'inf\')', Python.ORDER_ATOMIC]
|
||||
'INFINITY': ['float(\'inf\')', Python.ORDER_ATOMIC],
|
||||
};
|
||||
const constant = block.getFieldValue('CONSTANT');
|
||||
if (constant !== 'INFINITY') {
|
||||
@@ -155,20 +155,15 @@ Python['math_number_property'] = function(block) {
|
||||
// Check if a number is even, odd, prime, whole, positive, or negative
|
||||
// or if it is divisible by certain number. Returns true or false.
|
||||
const PROPERTIES = {
|
||||
'EVEN': [' % 2 == 0', Python.ORDER_MULTIPLICATIVE,
|
||||
Python.ORDER_RELATIONAL],
|
||||
'ODD': [' % 2 == 1', Python.ORDER_MULTIPLICATIVE,
|
||||
Python.ORDER_RELATIONAL],
|
||||
'EVEN': [' % 2 == 0', Python.ORDER_MULTIPLICATIVE, Python.ORDER_RELATIONAL],
|
||||
'ODD': [' % 2 == 1', Python.ORDER_MULTIPLICATIVE, Python.ORDER_RELATIONAL],
|
||||
'WHOLE': [' % 1 == 0', Python.ORDER_MULTIPLICATIVE,
|
||||
Python.ORDER_RELATIONAL],
|
||||
'POSITIVE': [' > 0', Python.ORDER_RELATIONAL,
|
||||
Python.ORDER_RELATIONAL],
|
||||
'NEGATIVE': [' < 0', Python.ORDER_RELATIONAL,
|
||||
Python.ORDER_RELATIONAL],
|
||||
'POSITIVE': [' > 0', Python.ORDER_RELATIONAL, Python.ORDER_RELATIONAL],
|
||||
'NEGATIVE': [' < 0', Python.ORDER_RELATIONAL, Python.ORDER_RELATIONAL],
|
||||
'DIVISIBLE_BY': [null, Python.ORDER_MULTIPLICATIVE,
|
||||
Python.ORDER_RELATIONAL],
|
||||
'PRIME': [null, Python.ORDER_NONE,
|
||||
Python.ORDER_FUNCTION_CALL]
|
||||
'PRIME': [null, Python.ORDER_NONE, Python.ORDER_FUNCTION_CALL],
|
||||
}
|
||||
const dropdownProperty = block.getFieldValue('PROPERTY');
|
||||
const [suffix, inputOrder, outputOrder] = PROPERTIES[dropdownProperty];
|
||||
@@ -180,27 +175,26 @@ Python['math_number_property'] = function(block) {
|
||||
Python.definitions_['import_math'] = 'import math';
|
||||
Python.definitions_['from_numbers_import_Number'] =
|
||||
'from numbers import Number';
|
||||
const functionName = Python.provideFunction_(
|
||||
'math_isPrime',
|
||||
['def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(n):',
|
||||
' # https://en.wikipedia.org/wiki/Primality_test#Naive_methods',
|
||||
' # If n is not a number but a string, try parsing it.',
|
||||
' if not isinstance(n, Number):',
|
||||
' try:',
|
||||
' n = float(n)',
|
||||
' except:',
|
||||
' return False',
|
||||
' if n == 2 or n == 3:',
|
||||
' return True',
|
||||
' # False if n is negative, is 1, or not whole,' +
|
||||
' or if n is divisible by 2 or 3.',
|
||||
' if n <= 1 or n % 1 != 0 or n % 2 == 0 or n % 3 == 0:',
|
||||
' return False',
|
||||
' # Check all the numbers of form 6k +/- 1, up to sqrt(n).',
|
||||
' for x in range(6, int(math.sqrt(n)) + 2, 6):',
|
||||
' if n % (x - 1) == 0 or n % (x + 1) == 0:',
|
||||
' return False',
|
||||
' return True']);
|
||||
const functionName = Python.provideFunction_('math_isPrime', `
|
||||
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(n):
|
||||
# https://en.wikipedia.org/wiki/Primality_test#Naive_methods
|
||||
# If n is not a number but a string, try parsing it.
|
||||
if not isinstance(n, Number):
|
||||
try:
|
||||
n = float(n)
|
||||
except:
|
||||
return False
|
||||
if n == 2 or n == 3:
|
||||
return True
|
||||
# False if n is negative, is 1, or not whole, or if n is divisible by 2 or 3.
|
||||
if n <= 1 or n % 1 != 0 or n % 2 == 0 or n % 3 == 0:
|
||||
return False
|
||||
# Check all the numbers of form 6k +/- 1, up to sqrt(n).
|
||||
for x in range(6, int(math.sqrt(n)) + 2, 6):
|
||||
if n % (x - 1) == 0 or n % (x + 1) == 0:
|
||||
return False
|
||||
return True
|
||||
`);
|
||||
code = functionName + '(' + numberToCheck + ')';
|
||||
} else if (dropdownProperty === 'DIVISIBLE_BY') {
|
||||
const divisor = Python.valueToCode(block, 'DIVISOR',
|
||||
@@ -251,71 +245,72 @@ Python['math_on_list'] = function(block) {
|
||||
case 'AVERAGE': {
|
||||
Python.definitions_['from_numbers_import_Number'] =
|
||||
'from numbers import Number';
|
||||
const functionName = 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 ' + 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)'
|
||||
]);
|
||||
// This operation excludes null and values that aren't int or float:
|
||||
// math_mean([null, null, "aString", 1, 9]) -> 5.0
|
||||
const functionName = Python.provideFunction_('math_mean', `
|
||||
def ${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': {
|
||||
Python.definitions_['from_numbers_import_Number'] =
|
||||
'from numbers import Number';
|
||||
const functionName = Python.provideFunction_(
|
||||
'math_median',
|
||||
// This operation excludes null values:
|
||||
// math_median([null, null, 1, 3]) -> 2.0
|
||||
[
|
||||
'def ' + 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]'
|
||||
]);
|
||||
// This operation excludes null values:
|
||||
// math_median([null, null, 1, 3]) -> 2.0
|
||||
const functionName = Python.provideFunction_( 'math_median', `
|
||||
def ${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': {
|
||||
const functionName = 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 ' + 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'
|
||||
]);
|
||||
// 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]
|
||||
const functionName = Python.provideFunction_('math_modes', `
|
||||
def ${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': {
|
||||
Python.definitions_['import_math'] = 'import math';
|
||||
const functionName = Python.provideFunction_('math_standard_deviation', [
|
||||
'def ' + 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)'
|
||||
]);
|
||||
const functionName = Python.provideFunction_('math_standard_deviation', `
|
||||
def ${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;
|
||||
}
|
||||
|
||||
@@ -55,18 +55,18 @@ Python['text_join'] = function(block) {
|
||||
// Should we allow joining by '-' or ',' or any other characters?
|
||||
switch (block.itemCount_) {
|
||||
case 0:
|
||||
return ['\'\'', Python.ORDER_ATOMIC];
|
||||
return ["''", Python.ORDER_ATOMIC];
|
||||
case 1: {
|
||||
const element =
|
||||
Python.valueToCode(block, 'ADD0', Python.ORDER_NONE) || '\'\'';
|
||||
Python.valueToCode(block, 'ADD0', Python.ORDER_NONE) || "''";
|
||||
const codeAndOrder = forceString(element);
|
||||
return codeAndOrder;
|
||||
}
|
||||
case 2: {
|
||||
const element0 =
|
||||
Python.valueToCode(block, 'ADD0', Python.ORDER_NONE) || '\'\'';
|
||||
Python.valueToCode(block, 'ADD0', Python.ORDER_NONE) || "''";
|
||||
const element1 =
|
||||
Python.valueToCode(block, 'ADD1', Python.ORDER_NONE) || '\'\'';
|
||||
Python.valueToCode(block, 'ADD1', Python.ORDER_NONE) || "''";
|
||||
const code = forceString(element0)[0] + ' + ' + forceString(element1)[0];
|
||||
return [code, Python.ORDER_ADDITIVE];
|
||||
}
|
||||
@@ -74,7 +74,7 @@ Python['text_join'] = function(block) {
|
||||
const elements = [];
|
||||
for (let i = 0; i < block.itemCount_; i++) {
|
||||
elements[i] =
|
||||
Python.valueToCode(block, 'ADD' + i, Python.ORDER_NONE) || '\'\'';
|
||||
Python.valueToCode(block, 'ADD' + i, Python.ORDER_NONE) || "''";
|
||||
}
|
||||
const tempVar = Python.nameDB_.getDistinctName('x', NameType.VARIABLE);
|
||||
const code = '\'\'.join([str(' + tempVar + ') for ' + tempVar + ' in [' +
|
||||
@@ -88,19 +88,19 @@ Python['text_append'] = function(block) {
|
||||
// Append to a variable in place.
|
||||
const varName =
|
||||
Python.nameDB_.getName(block.getFieldValue('VAR'), NameType.VARIABLE);
|
||||
const value = Python.valueToCode(block, 'TEXT', Python.ORDER_NONE) || '\'\'';
|
||||
const value = Python.valueToCode(block, 'TEXT', Python.ORDER_NONE) || "''";
|
||||
return varName + ' = str(' + varName + ') + ' + forceString(value)[0] + '\n';
|
||||
};
|
||||
|
||||
Python['text_length'] = function(block) {
|
||||
// Is the string null or array empty?
|
||||
const text = Python.valueToCode(block, 'VALUE', Python.ORDER_NONE) || '\'\'';
|
||||
const text = Python.valueToCode(block, 'VALUE', Python.ORDER_NONE) || "''";
|
||||
return ['len(' + text + ')', Python.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Python['text_isEmpty'] = function(block) {
|
||||
// Is the string null or array empty?
|
||||
const text = Python.valueToCode(block, 'VALUE', Python.ORDER_NONE) || '\'\'';
|
||||
const text = Python.valueToCode(block, 'VALUE', Python.ORDER_NONE) || "''";
|
||||
const code = 'not len(' + text + ')';
|
||||
return [code, Python.ORDER_LOGICAL_NOT];
|
||||
};
|
||||
@@ -110,9 +110,9 @@ Python['text_indexOf'] = function(block) {
|
||||
// Should we allow for non-case sensitive???
|
||||
const operator = block.getFieldValue('END') === 'FIRST' ? 'find' : 'rfind';
|
||||
const substring =
|
||||
Python.valueToCode(block, 'FIND', Python.ORDER_NONE) || '\'\'';
|
||||
Python.valueToCode(block, 'FIND', Python.ORDER_NONE) || "''";
|
||||
const text =
|
||||
Python.valueToCode(block, 'VALUE', Python.ORDER_MEMBER) || '\'\'';
|
||||
Python.valueToCode(block, 'VALUE', Python.ORDER_MEMBER) || "''";
|
||||
const code = text + '.' + operator + '(' + substring + ')';
|
||||
if (block.workspace.options.oneBasedIndex) {
|
||||
return [code + ' + 1', Python.ORDER_ADDITIVE];
|
||||
@@ -126,7 +126,7 @@ Python['text_charAt'] = function(block) {
|
||||
const where = block.getFieldValue('WHERE') || 'FROM_START';
|
||||
const textOrder =
|
||||
(where === 'RANDOM') ? Python.ORDER_NONE : Python.ORDER_MEMBER;
|
||||
const text = Python.valueToCode(block, 'VALUE', textOrder) || '\'\'';
|
||||
const text = Python.valueToCode(block, 'VALUE', textOrder) || "''";
|
||||
switch (where) {
|
||||
case 'FIRST': {
|
||||
const code = text + '[0]';
|
||||
@@ -148,10 +148,11 @@ Python['text_charAt'] = function(block) {
|
||||
}
|
||||
case 'RANDOM': {
|
||||
Python.definitions_['import_random'] = 'import random';
|
||||
const functionName = Python.provideFunction_('text_random_letter', [
|
||||
'def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(text):',
|
||||
' x = int(random.random() * len(text))', ' return text[x];'
|
||||
]);
|
||||
const functionName = Python.provideFunction_('text_random_letter', `
|
||||
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(text):
|
||||
x = int(random.random() * len(text))
|
||||
return text[x]
|
||||
`);
|
||||
const code = functionName + '(' + text + ')';
|
||||
return [code, Python.ORDER_FUNCTION_CALL];
|
||||
}
|
||||
@@ -164,7 +165,7 @@ Python['text_getSubstring'] = function(block) {
|
||||
const where1 = block.getFieldValue('WHERE1');
|
||||
const where2 = block.getFieldValue('WHERE2');
|
||||
const text =
|
||||
Python.valueToCode(block, 'STRING', Python.ORDER_MEMBER) || '\'\'';
|
||||
Python.valueToCode(block, 'STRING', Python.ORDER_MEMBER) || "''";
|
||||
let at1;
|
||||
switch (where1) {
|
||||
case 'FROM_START':
|
||||
@@ -217,7 +218,7 @@ Python['text_changeCase'] = function(block) {
|
||||
'TITLECASE': '.title()'
|
||||
};
|
||||
const operator = OPERATORS[block.getFieldValue('CASE')];
|
||||
const text = Python.valueToCode(block, 'TEXT', Python.ORDER_MEMBER) || '\'\'';
|
||||
const text = Python.valueToCode(block, 'TEXT', Python.ORDER_MEMBER) || "''";
|
||||
const code = text + operator;
|
||||
return [code, Python.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
@@ -230,30 +231,33 @@ Python['text_trim'] = function(block) {
|
||||
'BOTH': '.strip()'
|
||||
};
|
||||
const operator = OPERATORS[block.getFieldValue('MODE')];
|
||||
const text = Python.valueToCode(block, 'TEXT', Python.ORDER_MEMBER) || '\'\'';
|
||||
const text = Python.valueToCode(block, 'TEXT', Python.ORDER_MEMBER) || "''";
|
||||
const code = text + operator;
|
||||
return [code, Python.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Python['text_print'] = function(block) {
|
||||
// Print statement.
|
||||
const msg = Python.valueToCode(block, 'TEXT', Python.ORDER_NONE) || '\'\'';
|
||||
const msg = Python.valueToCode(block, 'TEXT', Python.ORDER_NONE) || "''";
|
||||
return 'print(' + msg + ')\n';
|
||||
};
|
||||
|
||||
Python['text_prompt_ext'] = function(block) {
|
||||
// Prompt function.
|
||||
const functionName = Python.provideFunction_('text_prompt', [
|
||||
'def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(msg):', ' try:',
|
||||
' return raw_input(msg)', ' except NameError:', ' return input(msg)'
|
||||
]);
|
||||
const functionName = Python.provideFunction_('text_prompt', `
|
||||
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(msg):
|
||||
try:
|
||||
return raw_input(msg)
|
||||
except NameError:
|
||||
return input(msg)
|
||||
`);
|
||||
let msg;
|
||||
if (block.getField('TEXT')) {
|
||||
// Internal message.
|
||||
msg = Python.quote_(block.getFieldValue('TEXT'));
|
||||
} else {
|
||||
// External message.
|
||||
msg = Python.valueToCode(block, 'TEXT', Python.ORDER_NONE) || '\'\'';
|
||||
msg = Python.valueToCode(block, 'TEXT', Python.ORDER_NONE) || "''";
|
||||
}
|
||||
let code = functionName + '(' + msg + ')';
|
||||
const toNumber = block.getFieldValue('TYPE') === 'NUMBER';
|
||||
@@ -266,22 +270,22 @@ Python['text_prompt_ext'] = function(block) {
|
||||
Python['text_prompt'] = Python['text_prompt_ext'];
|
||||
|
||||
Python['text_count'] = function(block) {
|
||||
const text = Python.valueToCode(block, 'TEXT', Python.ORDER_MEMBER) || '\'\'';
|
||||
const sub = Python.valueToCode(block, 'SUB', Python.ORDER_NONE) || '\'\'';
|
||||
const text = Python.valueToCode(block, 'TEXT', Python.ORDER_MEMBER) || "''";
|
||||
const sub = Python.valueToCode(block, 'SUB', Python.ORDER_NONE) || "''";
|
||||
const code = text + '.count(' + sub + ')';
|
||||
return [code, Python.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Python['text_replace'] = function(block) {
|
||||
const text = Python.valueToCode(block, 'TEXT', Python.ORDER_MEMBER) || '\'\'';
|
||||
const from = Python.valueToCode(block, 'FROM', Python.ORDER_NONE) || '\'\'';
|
||||
const to = Python.valueToCode(block, 'TO', Python.ORDER_NONE) || '\'\'';
|
||||
const text = Python.valueToCode(block, 'TEXT', Python.ORDER_MEMBER) || "''";
|
||||
const from = Python.valueToCode(block, 'FROM', Python.ORDER_NONE) || "''";
|
||||
const to = Python.valueToCode(block, 'TO', Python.ORDER_NONE) || "''";
|
||||
const code = text + '.replace(' + from + ', ' + to + ')';
|
||||
return [code, Python.ORDER_MEMBER];
|
||||
};
|
||||
|
||||
Python['text_reverse'] = function(block) {
|
||||
const text = Python.valueToCode(block, 'TEXT', Python.ORDER_MEMBER) || '\'\'';
|
||||
const text = Python.valueToCode(block, 'TEXT', Python.ORDER_MEMBER) || "''";
|
||||
const code = text + '[::-1]';
|
||||
return [code, Python.ORDER_MEMBER];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user