blockly 7.20211209.4 → 8.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/blockly.d.ts +18963 -18432
- package/blockly.min.js +5 -4
- package/blockly_compressed.js +4 -3
- package/blockly_compressed.js.map +1 -1
- package/blocks/blocks.js +47 -0
- package/blocks/colour.js +13 -3
- package/blocks/lists.js +22 -13
- package/blocks/logic.js +13 -3
- package/blocks/loops.js +24 -11
- package/blocks/math.js +12 -3
- package/blocks/procedures.js +45 -32
- package/blocks/text.js +22 -13
- package/blocks/variables.js +14 -3
- package/blocks/variables_dynamic.js +13 -3
- package/blocks_compressed.js +1 -1
- package/blocks_compressed.js.map +1 -1
- package/core/block.js +1869 -1814
- package/core/block_drag_surface.js +201 -200
- package/core/block_dragger.js +377 -373
- package/core/block_svg.js +1593 -1479
- package/core/blockly.js +8 -22
- package/core/blocks.js +9 -2
- package/core/browser_events.js +22 -5
- package/core/bubble.js +841 -797
- package/core/bubble_dragger.js +213 -206
- package/core/bump_objects.js +2 -2
- package/core/clipboard.js +9 -9
- package/core/comment.js +353 -332
- package/core/common.js +46 -17
- package/core/component_manager.js +181 -174
- package/core/config.js +87 -0
- package/core/connection.js +595 -584
- package/core/connection_checker.js +242 -244
- package/core/connection_db.js +235 -230
- package/core/contextmenu.js +9 -6
- package/core/contextmenu_items.js +1 -2
- package/core/contextmenu_registry.js +93 -89
- package/core/css.js +474 -474
- package/core/delete_area.js +45 -42
- package/core/drag_target.js +57 -56
- package/core/dropdowndiv.js +153 -163
- package/core/events/events.js +2 -2
- package/core/events/events_abstract.js +89 -77
- package/core/events/events_block_base.js +37 -36
- package/core/events/events_block_change.js +130 -124
- package/core/events/events_block_create.js +73 -71
- package/core/events/events_block_delete.js +84 -82
- package/core/events/events_block_drag.js +50 -49
- package/core/events/events_block_move.js +147 -140
- package/core/events/events_bubble_open.js +51 -50
- package/core/events/events_click.js +48 -44
- package/core/events/events_comment_base.js +72 -69
- package/core/events/events_comment_change.js +63 -61
- package/core/events/events_comment_create.js +44 -42
- package/core/events/events_comment_delete.js +42 -40
- package/core/events/events_comment_move.js +106 -104
- package/core/events/events_marker_move.js +65 -64
- package/core/events/events_selected.js +46 -45
- package/core/events/events_theme_change.js +36 -35
- package/core/events/events_toolbox_item_select.js +46 -45
- package/core/events/events_trashcan_open.js +37 -36
- package/core/events/events_ui.js +47 -46
- package/core/events/events_ui_base.js +30 -29
- package/core/events/events_var_base.js +37 -36
- package/core/events/events_var_create.js +50 -48
- package/core/events/events_var_delete.js +50 -48
- package/core/events/events_var_rename.js +51 -49
- package/core/events/events_viewport.js +66 -65
- package/core/events/utils.js +29 -14
- package/core/events/workspace_events.js +49 -55
- package/core/extensions.js +4 -3
- package/core/field.js +1061 -997
- package/core/field_angle.js +462 -442
- package/core/field_checkbox.js +194 -182
- package/core/field_colour.js +519 -505
- package/core/field_dropdown.js +617 -598
- package/core/field_image.js +229 -220
- package/core/field_label.js +102 -91
- package/core/field_label_serializable.js +42 -41
- package/core/field_multilineinput.js +372 -358
- package/core/field_number.js +272 -253
- package/core/field_textinput.js +499 -467
- package/core/field_variable.js +458 -420
- package/core/flyout_base.js +1005 -952
- package/core/flyout_button.js +277 -260
- package/core/flyout_horizontal.js +304 -302
- package/core/flyout_metrics_manager.js +64 -64
- package/core/flyout_vertical.js +306 -300
- package/core/generator.js +459 -446
- package/core/gesture.js +829 -813
- package/core/grid.js +166 -163
- package/core/icon.js +168 -159
- package/core/inject.js +7 -5
- package/core/input.js +257 -248
- package/core/insertion_marker_manager.js +655 -624
- package/core/internal_constants.js +0 -129
- package/core/keyboard_nav/ast_node.js +605 -596
- package/core/keyboard_nav/basic_cursor.js +166 -165
- package/core/keyboard_nav/cursor.js +99 -97
- package/core/keyboard_nav/marker.js +83 -79
- package/core/keyboard_nav/tab_navigate_cursor.js +18 -23
- package/core/marker_manager.js +153 -141
- package/core/menu.js +377 -372
- package/core/menuitem.js +223 -217
- package/core/metrics_manager.js +403 -390
- package/core/mutator.js +468 -437
- package/core/names.js +229 -188
- package/core/options.js +290 -284
- package/core/procedures.js +29 -17
- package/core/registry.js +19 -16
- package/core/rendered_connection.js +482 -463
- package/core/renderers/common/block_rendering.js +9 -3
- package/core/renderers/common/constants.js +1119 -1112
- package/core/renderers/common/debug.js +14 -0
- package/core/renderers/common/debugger.js +338 -316
- package/core/renderers/common/drawer.js +380 -370
- package/core/renderers/common/i_path_object.js +2 -2
- package/core/renderers/common/info.js +626 -618
- package/core/renderers/common/marker_svg.js +579 -541
- package/core/renderers/common/path_object.js +203 -200
- package/core/renderers/common/renderer.js +220 -218
- package/core/renderers/geras/constants.js +36 -36
- package/core/renderers/geras/drawer.js +155 -147
- package/core/renderers/geras/highlight_constants.js +244 -238
- package/core/renderers/geras/highlighter.js +231 -179
- package/core/renderers/geras/info.js +392 -369
- package/core/renderers/geras/measurables/inline_input.js +25 -19
- package/core/renderers/geras/measurables/statement_input.js +23 -17
- package/core/renderers/geras/path_object.js +106 -121
- package/core/renderers/geras/renderer.js +96 -98
- package/core/renderers/measurables/base.js +30 -18
- package/core/renderers/measurables/bottom_row.js +83 -80
- package/core/renderers/measurables/connection.js +22 -15
- package/core/renderers/measurables/external_value_input.js +35 -22
- package/core/renderers/measurables/field.js +35 -20
- package/core/renderers/measurables/hat.js +18 -13
- package/core/renderers/measurables/icon.js +24 -17
- package/core/renderers/measurables/in_row_spacer.js +15 -13
- package/core/renderers/measurables/inline_input.js +43 -33
- package/core/renderers/measurables/input_connection.js +41 -28
- package/core/renderers/measurables/input_row.js +50 -44
- package/core/renderers/measurables/jagged_edge.js +14 -12
- package/core/renderers/measurables/next_connection.js +16 -14
- package/core/renderers/measurables/output_connection.js +26 -20
- package/core/renderers/measurables/previous_connection.js +16 -15
- package/core/renderers/measurables/round_corner.js +20 -18
- package/core/renderers/measurables/row.js +184 -168
- package/core/renderers/measurables/spacer_row.js +38 -23
- package/core/renderers/measurables/square_corner.js +18 -16
- package/core/renderers/measurables/statement_input.js +23 -20
- package/core/renderers/measurables/top_row.js +88 -85
- package/core/renderers/minimalist/constants.js +8 -7
- package/core/renderers/minimalist/drawer.js +11 -10
- package/core/renderers/minimalist/info.js +18 -18
- package/core/renderers/minimalist/renderer.js +40 -39
- package/core/renderers/thrasos/info.js +258 -248
- package/core/renderers/thrasos/renderer.js +20 -20
- package/core/renderers/zelos/constants.js +898 -873
- package/core/renderers/zelos/drawer.js +186 -169
- package/core/renderers/zelos/info.js +502 -479
- package/core/renderers/zelos/marker_svg.js +129 -115
- package/core/renderers/zelos/measurables/bottom_row.js +31 -30
- package/core/renderers/zelos/measurables/inputs.js +22 -21
- package/core/renderers/zelos/measurables/row_elements.js +14 -13
- package/core/renderers/zelos/measurables/top_row.js +34 -33
- package/core/renderers/zelos/path_object.js +181 -180
- package/core/renderers/zelos/renderer.js +91 -92
- package/core/scrollbar.js +759 -713
- package/core/scrollbar_pair.js +250 -245
- package/core/serialization/blocks.js +26 -10
- package/core/serialization/workspaces.js +3 -2
- package/core/shortcut_registry.js +286 -277
- package/core/sprites.js +31 -0
- package/core/theme.js +135 -141
- package/core/theme_manager.js +147 -143
- package/core/toolbox/category.js +602 -576
- package/core/toolbox/collapsible_category.js +226 -227
- package/core/toolbox/separator.js +70 -61
- package/core/toolbox/toolbox.js +934 -927
- package/core/toolbox/toolbox_item.js +115 -99
- package/core/tooltip.js +108 -35
- package/core/touch.js +8 -3
- package/core/touch_gesture.js +254 -251
- package/core/trashcan.js +606 -595
- package/core/utils/coordinate.js +97 -95
- package/core/utils/dom.js +2 -2
- package/core/utils/global.js +2 -0
- package/core/utils/rect.js +41 -37
- package/core/utils/sentinel.js +25 -0
- package/core/utils/size.js +30 -27
- package/core/utils/svg.js +18 -16
- package/core/variable_map.js +325 -341
- package/core/variable_model.js +55 -54
- package/core/variables.js +9 -2
- package/core/variables_dynamic.js +3 -1
- package/core/warning.js +126 -120
- package/core/widgetdiv.js +4 -4
- package/core/workspace.js +685 -664
- package/core/workspace_audio.js +124 -118
- package/core/workspace_comment.js +308 -298
- package/core/workspace_comment_svg.js +1029 -951
- package/core/workspace_drag_surface_svg.js +147 -140
- package/core/workspace_dragger.js +70 -71
- package/core/workspace_svg.js +2322 -2297
- package/core/xml.js +30 -20
- package/core/zoom_controls.js +431 -439
- package/generators/dart/colour.js +56 -64
- package/generators/dart/lists.js +61 -50
- package/generators/dart/math.js +160 -148
- package/generators/dart/text.js +83 -61
- package/generators/javascript/colour.js +37 -34
- package/generators/javascript/lists.js +50 -43
- package/generators/javascript/math.js +123 -139
- package/generators/javascript/text.js +67 -81
- package/generators/lua/colour.js +25 -23
- package/generators/lua/lists.js +97 -69
- package/generators/lua/logic.js +1 -2
- package/generators/lua/math.js +182 -144
- package/generators/lua/text.js +116 -99
- package/generators/php/colour.js +38 -32
- package/generators/php/lists.js +109 -89
- package/generators/php/math.js +90 -81
- package/generators/php/text.js +63 -61
- package/generators/python/colour.js +18 -18
- package/generators/python/lists.js +38 -30
- package/generators/python/loops.js +12 -8
- package/generators/python/math.js +104 -106
- package/generators/python/text.js +34 -30
- package/msg/smn.js +436 -0
- package/package.json +7 -6
- package/blocks/all.js +0 -23
|
@@ -41,7 +41,7 @@ Python['math_arithmetic'] = function(block) {
|
|
|
41
41
|
'MINUS': [' - ', Python.ORDER_ADDITIVE],
|
|
42
42
|
'MULTIPLY': [' * ', Python.ORDER_MULTIPLICATIVE],
|
|
43
43
|
'DIVIDE': [' / ', Python.ORDER_MULTIPLICATIVE],
|
|
44
|
-
'POWER': [' ** ', Python.ORDER_EXPONENTIATION]
|
|
44
|
+
'POWER': [' ** ', Python.ORDER_EXPONENTIATION],
|
|
45
45
|
};
|
|
46
46
|
const tuple = OPERATORS[block.getFieldValue('OP')];
|
|
47
47
|
const operator = tuple[0];
|
|
@@ -142,7 +142,7 @@ Python['math_constant'] = function(block) {
|
|
|
142
142
|
'GOLDEN_RATIO': ['(1 + math.sqrt(5)) / 2', Python.ORDER_MULTIPLICATIVE],
|
|
143
143
|
'SQRT2': ['math.sqrt(2)', Python.ORDER_MEMBER],
|
|
144
144
|
'SQRT1_2': ['math.sqrt(1.0 / 2)', Python.ORDER_MEMBER],
|
|
145
|
-
'INFINITY': ['float(\'inf\')', Python.ORDER_ATOMIC]
|
|
145
|
+
'INFINITY': ['float(\'inf\')', Python.ORDER_ATOMIC],
|
|
146
146
|
};
|
|
147
147
|
const constant = block.getFieldValue('CONSTANT');
|
|
148
148
|
if (constant !== 'INFINITY') {
|
|
@@ -152,65 +152,62 @@ Python['math_constant'] = function(block) {
|
|
|
152
152
|
};
|
|
153
153
|
|
|
154
154
|
Python['math_number_property'] = function(block) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
155
|
+
// Check if a number is even, odd, prime, whole, positive, or negative
|
|
156
|
+
// or if it is divisible by certain number. Returns true or false.
|
|
157
|
+
const PROPERTIES = {
|
|
158
|
+
'EVEN': [' % 2 == 0', Python.ORDER_MULTIPLICATIVE, Python.ORDER_RELATIONAL],
|
|
159
|
+
'ODD': [' % 2 == 1', Python.ORDER_MULTIPLICATIVE, Python.ORDER_RELATIONAL],
|
|
160
|
+
'WHOLE': [' % 1 == 0', Python.ORDER_MULTIPLICATIVE,
|
|
161
|
+
Python.ORDER_RELATIONAL],
|
|
162
|
+
'POSITIVE': [' > 0', Python.ORDER_RELATIONAL, Python.ORDER_RELATIONAL],
|
|
163
|
+
'NEGATIVE': [' < 0', Python.ORDER_RELATIONAL, Python.ORDER_RELATIONAL],
|
|
164
|
+
'DIVISIBLE_BY': [null, Python.ORDER_MULTIPLICATIVE,
|
|
165
|
+
Python.ORDER_RELATIONAL],
|
|
166
|
+
'PRIME': [null, Python.ORDER_NONE, Python.ORDER_FUNCTION_CALL],
|
|
167
|
+
}
|
|
168
|
+
const dropdownProperty = block.getFieldValue('PROPERTY');
|
|
169
|
+
const [suffix, inputOrder, outputOrder] = PROPERTIES[dropdownProperty];
|
|
170
|
+
const numberToCheck = Python.valueToCode(block, 'NUMBER_TO_CHECK',
|
|
171
|
+
inputOrder) || '0';
|
|
162
172
|
let code;
|
|
163
|
-
if (
|
|
173
|
+
if (dropdownProperty === 'PRIME') {
|
|
174
|
+
// Prime is a special case as it is not a one-liner test.
|
|
164
175
|
Python.definitions_['import_math'] = 'import math';
|
|
165
176
|
Python.definitions_['from_numbers_import_Number'] =
|
|
166
177
|
'from numbers import Number';
|
|
167
|
-
const functionName = Python.provideFunction_('math_isPrime',
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
code = number_to_check + ' % 1 == 0';
|
|
195
|
-
break;
|
|
196
|
-
case 'POSITIVE':
|
|
197
|
-
code = number_to_check + ' > 0';
|
|
198
|
-
break;
|
|
199
|
-
case 'NEGATIVE':
|
|
200
|
-
code = number_to_check + ' < 0';
|
|
201
|
-
break;
|
|
202
|
-
case 'DIVISIBLE_BY': {
|
|
203
|
-
const divisor =
|
|
204
|
-
Python.valueToCode(block, 'DIVISOR', Python.ORDER_MULTIPLICATIVE);
|
|
205
|
-
// If 'divisor' is some code that evals to 0, Python will raise an error.
|
|
206
|
-
if (!divisor || divisor === '0') {
|
|
207
|
-
return ['False', Python.ORDER_ATOMIC];
|
|
208
|
-
}
|
|
209
|
-
code = number_to_check + ' % ' + divisor + ' == 0';
|
|
210
|
-
break;
|
|
178
|
+
const functionName = Python.provideFunction_('math_isPrime', `
|
|
179
|
+
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(n):
|
|
180
|
+
# https://en.wikipedia.org/wiki/Primality_test#Naive_methods
|
|
181
|
+
# If n is not a number but a string, try parsing it.
|
|
182
|
+
if not isinstance(n, Number):
|
|
183
|
+
try:
|
|
184
|
+
n = float(n)
|
|
185
|
+
except:
|
|
186
|
+
return False
|
|
187
|
+
if n == 2 or n == 3:
|
|
188
|
+
return True
|
|
189
|
+
# False if n is negative, is 1, or not whole, or if n is divisible by 2 or 3.
|
|
190
|
+
if n <= 1 or n % 1 != 0 or n % 2 == 0 or n % 3 == 0:
|
|
191
|
+
return False
|
|
192
|
+
# Check all the numbers of form 6k +/- 1, up to sqrt(n).
|
|
193
|
+
for x in range(6, int(math.sqrt(n)) + 2, 6):
|
|
194
|
+
if n % (x - 1) == 0 or n % (x + 1) == 0:
|
|
195
|
+
return False
|
|
196
|
+
return True
|
|
197
|
+
`);
|
|
198
|
+
code = functionName + '(' + numberToCheck + ')';
|
|
199
|
+
} else if (dropdownProperty === 'DIVISIBLE_BY') {
|
|
200
|
+
const divisor = Python.valueToCode(block, 'DIVISOR',
|
|
201
|
+
Python.ORDER_MULTIPLICATIVE) || '0';
|
|
202
|
+
// If 'divisor' is some code that evals to 0, Python will raise an error.
|
|
203
|
+
if (divisor === '0') {
|
|
204
|
+
return ['False', Python.ORDER_ATOMIC];
|
|
211
205
|
}
|
|
212
|
-
|
|
213
|
-
|
|
206
|
+
code = numberToCheck + ' % ' + divisor + ' == 0';
|
|
207
|
+
} else {
|
|
208
|
+
code = numberToCheck + suffix;
|
|
209
|
+
};
|
|
210
|
+
return [code, outputOrder];
|
|
214
211
|
};
|
|
215
212
|
|
|
216
213
|
Python['math_change'] = function(block) {
|
|
@@ -248,71 +245,72 @@ Python['math_on_list'] = function(block) {
|
|
|
248
245
|
case 'AVERAGE': {
|
|
249
246
|
Python.definitions_['from_numbers_import_Number'] =
|
|
250
247
|
'from numbers import Number';
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
' return float(sum(localList)) / len(localList)'
|
|
260
|
-
]);
|
|
248
|
+
// This operation excludes null and values that aren't int or float:
|
|
249
|
+
// math_mean([null, null, "aString", 1, 9]) -> 5.0
|
|
250
|
+
const functionName = Python.provideFunction_('math_mean', `
|
|
251
|
+
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(myList):
|
|
252
|
+
localList = [e for e in myList if isinstance(e, Number)]
|
|
253
|
+
if not localList: return
|
|
254
|
+
return float(sum(localList)) / len(localList)
|
|
255
|
+
`);
|
|
261
256
|
code = functionName + '(' + list + ')';
|
|
262
257
|
break;
|
|
263
258
|
}
|
|
264
259
|
case 'MEDIAN': {
|
|
265
260
|
Python.definitions_['from_numbers_import_Number'] =
|
|
266
261
|
'from numbers import Number';
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
]);
|
|
262
|
+
// This operation excludes null values:
|
|
263
|
+
// math_median([null, null, 1, 3]) -> 2.0
|
|
264
|
+
const functionName = Python.provideFunction_( 'math_median', `
|
|
265
|
+
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(myList):
|
|
266
|
+
localList = sorted([e for e in myList if isinstance(e, Number)])
|
|
267
|
+
if not localList: return
|
|
268
|
+
if len(localList) % 2 == 0:
|
|
269
|
+
return (localList[len(localList) // 2 - 1] + localList[len(localList) // 2]) / 2.0
|
|
270
|
+
else:
|
|
271
|
+
return localList[(len(localList) - 1) // 2]
|
|
272
|
+
`);
|
|
279
273
|
code = functionName + '(' + list + ')';
|
|
280
274
|
break;
|
|
281
275
|
}
|
|
282
276
|
case 'MODE': {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
277
|
+
// As a list of numbers can contain more than one mode,
|
|
278
|
+
// the returned result is provided as an array.
|
|
279
|
+
// Mode of [3, 'x', 'x', 1, 1, 2, '3'] -> ['x', 1]
|
|
280
|
+
const functionName = Python.provideFunction_('math_modes', `
|
|
281
|
+
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(some_list):
|
|
282
|
+
modes = []
|
|
283
|
+
# Using a lists of [item, count] to keep count rather than dict
|
|
284
|
+
# to avoid "unhashable" errors when the counted item is itself a list or dict.
|
|
285
|
+
counts = []
|
|
286
|
+
maxCount = 1
|
|
287
|
+
for item in some_list:
|
|
288
|
+
found = False
|
|
289
|
+
for count in counts:
|
|
290
|
+
if count[0] == item:
|
|
291
|
+
count[1] += 1
|
|
292
|
+
maxCount = max(maxCount, count[1])
|
|
293
|
+
found = True
|
|
294
|
+
if not found:
|
|
295
|
+
counts.append([item, 1])
|
|
296
|
+
for counted_item, item_count in counts:
|
|
297
|
+
if item_count == maxCount:
|
|
298
|
+
modes.append(counted_item)
|
|
299
|
+
return modes
|
|
300
|
+
`);
|
|
304
301
|
code = functionName + '(' + list + ')';
|
|
305
302
|
break;
|
|
306
303
|
}
|
|
307
304
|
case 'STD_DEV': {
|
|
308
305
|
Python.definitions_['import_math'] = 'import math';
|
|
309
|
-
const functionName = Python.provideFunction_('math_standard_deviation',
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
306
|
+
const functionName = Python.provideFunction_('math_standard_deviation', `
|
|
307
|
+
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(numbers):
|
|
308
|
+
n = len(numbers)
|
|
309
|
+
if n == 0: return
|
|
310
|
+
mean = float(sum(numbers)) / n
|
|
311
|
+
variance = sum((x - mean) ** 2 for x in numbers) / n
|
|
312
|
+
return math.sqrt(variance)
|
|
313
|
+
`);
|
|
316
314
|
code = functionName + '(' + list + ')';
|
|
317
315
|
break;
|
|
318
316
|
}
|
|
@@ -55,18 +55,18 @@ Python['text_join'] = function(block) {
|
|
|
55
55
|
// Should we allow joining by '-' or ',' or any other characters?
|
|
56
56
|
switch (block.itemCount_) {
|
|
57
57
|
case 0:
|
|
58
|
-
return ['
|
|
58
|
+
return ["''", Python.ORDER_ATOMIC];
|
|
59
59
|
case 1: {
|
|
60
60
|
const element =
|
|
61
|
-
Python.valueToCode(block, 'ADD0', Python.ORDER_NONE) || '
|
|
61
|
+
Python.valueToCode(block, 'ADD0', Python.ORDER_NONE) || "''";
|
|
62
62
|
const codeAndOrder = forceString(element);
|
|
63
63
|
return codeAndOrder;
|
|
64
64
|
}
|
|
65
65
|
case 2: {
|
|
66
66
|
const element0 =
|
|
67
|
-
Python.valueToCode(block, 'ADD0', Python.ORDER_NONE) || '
|
|
67
|
+
Python.valueToCode(block, 'ADD0', Python.ORDER_NONE) || "''";
|
|
68
68
|
const element1 =
|
|
69
|
-
Python.valueToCode(block, 'ADD1', Python.ORDER_NONE) || '
|
|
69
|
+
Python.valueToCode(block, 'ADD1', Python.ORDER_NONE) || "''";
|
|
70
70
|
const code = forceString(element0)[0] + ' + ' + forceString(element1)[0];
|
|
71
71
|
return [code, Python.ORDER_ADDITIVE];
|
|
72
72
|
}
|
|
@@ -74,7 +74,7 @@ Python['text_join'] = function(block) {
|
|
|
74
74
|
const elements = [];
|
|
75
75
|
for (let i = 0; i < block.itemCount_; i++) {
|
|
76
76
|
elements[i] =
|
|
77
|
-
Python.valueToCode(block, 'ADD' + i, Python.ORDER_NONE) || '
|
|
77
|
+
Python.valueToCode(block, 'ADD' + i, Python.ORDER_NONE) || "''";
|
|
78
78
|
}
|
|
79
79
|
const tempVar = Python.nameDB_.getDistinctName('x', NameType.VARIABLE);
|
|
80
80
|
const code = '\'\'.join([str(' + tempVar + ') for ' + tempVar + ' in [' +
|
|
@@ -88,19 +88,19 @@ Python['text_append'] = function(block) {
|
|
|
88
88
|
// Append to a variable in place.
|
|
89
89
|
const varName =
|
|
90
90
|
Python.nameDB_.getName(block.getFieldValue('VAR'), NameType.VARIABLE);
|
|
91
|
-
const value = Python.valueToCode(block, 'TEXT', Python.ORDER_NONE) || '
|
|
91
|
+
const value = Python.valueToCode(block, 'TEXT', Python.ORDER_NONE) || "''";
|
|
92
92
|
return varName + ' = str(' + varName + ') + ' + forceString(value)[0] + '\n';
|
|
93
93
|
};
|
|
94
94
|
|
|
95
95
|
Python['text_length'] = function(block) {
|
|
96
96
|
// Is the string null or array empty?
|
|
97
|
-
const text = Python.valueToCode(block, 'VALUE', Python.ORDER_NONE) || '
|
|
97
|
+
const text = Python.valueToCode(block, 'VALUE', Python.ORDER_NONE) || "''";
|
|
98
98
|
return ['len(' + text + ')', Python.ORDER_FUNCTION_CALL];
|
|
99
99
|
};
|
|
100
100
|
|
|
101
101
|
Python['text_isEmpty'] = function(block) {
|
|
102
102
|
// Is the string null or array empty?
|
|
103
|
-
const text = Python.valueToCode(block, 'VALUE', Python.ORDER_NONE) || '
|
|
103
|
+
const text = Python.valueToCode(block, 'VALUE', Python.ORDER_NONE) || "''";
|
|
104
104
|
const code = 'not len(' + text + ')';
|
|
105
105
|
return [code, Python.ORDER_LOGICAL_NOT];
|
|
106
106
|
};
|
|
@@ -110,9 +110,9 @@ Python['text_indexOf'] = function(block) {
|
|
|
110
110
|
// Should we allow for non-case sensitive???
|
|
111
111
|
const operator = block.getFieldValue('END') === 'FIRST' ? 'find' : 'rfind';
|
|
112
112
|
const substring =
|
|
113
|
-
Python.valueToCode(block, 'FIND', Python.ORDER_NONE) || '
|
|
113
|
+
Python.valueToCode(block, 'FIND', Python.ORDER_NONE) || "''";
|
|
114
114
|
const text =
|
|
115
|
-
Python.valueToCode(block, 'VALUE', Python.ORDER_MEMBER) || '
|
|
115
|
+
Python.valueToCode(block, 'VALUE', Python.ORDER_MEMBER) || "''";
|
|
116
116
|
const code = text + '.' + operator + '(' + substring + ')';
|
|
117
117
|
if (block.workspace.options.oneBasedIndex) {
|
|
118
118
|
return [code + ' + 1', Python.ORDER_ADDITIVE];
|
|
@@ -126,7 +126,7 @@ Python['text_charAt'] = function(block) {
|
|
|
126
126
|
const where = block.getFieldValue('WHERE') || 'FROM_START';
|
|
127
127
|
const textOrder =
|
|
128
128
|
(where === 'RANDOM') ? Python.ORDER_NONE : Python.ORDER_MEMBER;
|
|
129
|
-
const text = Python.valueToCode(block, 'VALUE', textOrder) || '
|
|
129
|
+
const text = Python.valueToCode(block, 'VALUE', textOrder) || "''";
|
|
130
130
|
switch (where) {
|
|
131
131
|
case 'FIRST': {
|
|
132
132
|
const code = text + '[0]';
|
|
@@ -148,10 +148,11 @@ Python['text_charAt'] = function(block) {
|
|
|
148
148
|
}
|
|
149
149
|
case 'RANDOM': {
|
|
150
150
|
Python.definitions_['import_random'] = 'import random';
|
|
151
|
-
const functionName = Python.provideFunction_('text_random_letter',
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
151
|
+
const functionName = Python.provideFunction_('text_random_letter', `
|
|
152
|
+
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(text):
|
|
153
|
+
x = int(random.random() * len(text))
|
|
154
|
+
return text[x]
|
|
155
|
+
`);
|
|
155
156
|
const code = functionName + '(' + text + ')';
|
|
156
157
|
return [code, Python.ORDER_FUNCTION_CALL];
|
|
157
158
|
}
|
|
@@ -164,7 +165,7 @@ Python['text_getSubstring'] = function(block) {
|
|
|
164
165
|
const where1 = block.getFieldValue('WHERE1');
|
|
165
166
|
const where2 = block.getFieldValue('WHERE2');
|
|
166
167
|
const text =
|
|
167
|
-
Python.valueToCode(block, 'STRING', Python.ORDER_MEMBER) || '
|
|
168
|
+
Python.valueToCode(block, 'STRING', Python.ORDER_MEMBER) || "''";
|
|
168
169
|
let at1;
|
|
169
170
|
switch (where1) {
|
|
170
171
|
case 'FROM_START':
|
|
@@ -217,7 +218,7 @@ Python['text_changeCase'] = function(block) {
|
|
|
217
218
|
'TITLECASE': '.title()'
|
|
218
219
|
};
|
|
219
220
|
const operator = OPERATORS[block.getFieldValue('CASE')];
|
|
220
|
-
const text = Python.valueToCode(block, 'TEXT', Python.ORDER_MEMBER) || '
|
|
221
|
+
const text = Python.valueToCode(block, 'TEXT', Python.ORDER_MEMBER) || "''";
|
|
221
222
|
const code = text + operator;
|
|
222
223
|
return [code, Python.ORDER_FUNCTION_CALL];
|
|
223
224
|
};
|
|
@@ -230,30 +231,33 @@ Python['text_trim'] = function(block) {
|
|
|
230
231
|
'BOTH': '.strip()'
|
|
231
232
|
};
|
|
232
233
|
const operator = OPERATORS[block.getFieldValue('MODE')];
|
|
233
|
-
const text = Python.valueToCode(block, 'TEXT', Python.ORDER_MEMBER) || '
|
|
234
|
+
const text = Python.valueToCode(block, 'TEXT', Python.ORDER_MEMBER) || "''";
|
|
234
235
|
const code = text + operator;
|
|
235
236
|
return [code, Python.ORDER_FUNCTION_CALL];
|
|
236
237
|
};
|
|
237
238
|
|
|
238
239
|
Python['text_print'] = function(block) {
|
|
239
240
|
// Print statement.
|
|
240
|
-
const msg = Python.valueToCode(block, 'TEXT', Python.ORDER_NONE) || '
|
|
241
|
+
const msg = Python.valueToCode(block, 'TEXT', Python.ORDER_NONE) || "''";
|
|
241
242
|
return 'print(' + msg + ')\n';
|
|
242
243
|
};
|
|
243
244
|
|
|
244
245
|
Python['text_prompt_ext'] = function(block) {
|
|
245
246
|
// Prompt function.
|
|
246
|
-
const functionName = Python.provideFunction_('text_prompt',
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
247
|
+
const functionName = Python.provideFunction_('text_prompt', `
|
|
248
|
+
def ${Python.FUNCTION_NAME_PLACEHOLDER_}(msg):
|
|
249
|
+
try:
|
|
250
|
+
return raw_input(msg)
|
|
251
|
+
except NameError:
|
|
252
|
+
return input(msg)
|
|
253
|
+
`);
|
|
250
254
|
let msg;
|
|
251
255
|
if (block.getField('TEXT')) {
|
|
252
256
|
// Internal message.
|
|
253
257
|
msg = Python.quote_(block.getFieldValue('TEXT'));
|
|
254
258
|
} else {
|
|
255
259
|
// External message.
|
|
256
|
-
msg = Python.valueToCode(block, 'TEXT', Python.ORDER_NONE) || '
|
|
260
|
+
msg = Python.valueToCode(block, 'TEXT', Python.ORDER_NONE) || "''";
|
|
257
261
|
}
|
|
258
262
|
let code = functionName + '(' + msg + ')';
|
|
259
263
|
const toNumber = block.getFieldValue('TYPE') === 'NUMBER';
|
|
@@ -266,22 +270,22 @@ Python['text_prompt_ext'] = function(block) {
|
|
|
266
270
|
Python['text_prompt'] = Python['text_prompt_ext'];
|
|
267
271
|
|
|
268
272
|
Python['text_count'] = function(block) {
|
|
269
|
-
const text = Python.valueToCode(block, 'TEXT', Python.ORDER_MEMBER) || '
|
|
270
|
-
const sub = Python.valueToCode(block, 'SUB', Python.ORDER_NONE) || '
|
|
273
|
+
const text = Python.valueToCode(block, 'TEXT', Python.ORDER_MEMBER) || "''";
|
|
274
|
+
const sub = Python.valueToCode(block, 'SUB', Python.ORDER_NONE) || "''";
|
|
271
275
|
const code = text + '.count(' + sub + ')';
|
|
272
276
|
return [code, Python.ORDER_FUNCTION_CALL];
|
|
273
277
|
};
|
|
274
278
|
|
|
275
279
|
Python['text_replace'] = function(block) {
|
|
276
|
-
const text = Python.valueToCode(block, 'TEXT', Python.ORDER_MEMBER) || '
|
|
277
|
-
const from = Python.valueToCode(block, 'FROM', Python.ORDER_NONE) || '
|
|
278
|
-
const to = Python.valueToCode(block, 'TO', Python.ORDER_NONE) || '
|
|
280
|
+
const text = Python.valueToCode(block, 'TEXT', Python.ORDER_MEMBER) || "''";
|
|
281
|
+
const from = Python.valueToCode(block, 'FROM', Python.ORDER_NONE) || "''";
|
|
282
|
+
const to = Python.valueToCode(block, 'TO', Python.ORDER_NONE) || "''";
|
|
279
283
|
const code = text + '.replace(' + from + ', ' + to + ')';
|
|
280
284
|
return [code, Python.ORDER_MEMBER];
|
|
281
285
|
};
|
|
282
286
|
|
|
283
287
|
Python['text_reverse'] = function(block) {
|
|
284
|
-
const text = Python.valueToCode(block, 'TEXT', Python.ORDER_MEMBER) || '
|
|
288
|
+
const text = Python.valueToCode(block, 'TEXT', Python.ORDER_MEMBER) || "''";
|
|
285
289
|
const code = text + '[::-1]';
|
|
286
290
|
return [code, Python.ORDER_MEMBER];
|
|
287
291
|
};
|