From a3b3ae6cc5bb45e600bb8c99189b28bf1df4ed84 Mon Sep 17 00:00:00 2001 From: Irene-Maxine <114802521+Irene-Maxine@users.noreply.github.com> Date: Tue, 15 Oct 2024 15:42:56 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=80=E4=B8=AA=E5=B0=9D=E8=AF=95=E7=94=9F?= =?UTF-8?q?=E6=88=90=E7=AC=9B=E5=8D=A1=E5=B0=94=E7=A7=AF=E7=9A=84=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- boards/default_src/python/blocks/math.js | 139 +++++++++++++++++- boards/default_src/python/generators/math.js | 14 ++ .../default_src/python_pyodide/template.xml | 7 + common/msg/blockly/zh-hans.js | 5 + 4 files changed, 164 insertions(+), 1 deletion(-) diff --git a/boards/default_src/python/blocks/math.js b/boards/default_src/python/blocks/math.js index adbc3258..4b4e9cc3 100644 --- a/boards/default_src/python/blocks/math.js +++ b/boards/default_src/python/blocks/math.js @@ -537,4 +537,141 @@ export const turn_to_int = { this.setOutput(true, Number); this.setTooltip(Blockly.Msg.MIXLY_PYTHON_TOOLTIP_TOHEX) } -}; \ No newline at end of file +}; + +export const generate_cartesian_product = { + /** + * Block for creating a list with any number of elements of any type. + * @this Blockly.Block + */ + init: function () { + this.setColour(MATH_HUE); + this.itemCount_ = 1; + this.updateShape_(); + this.setMutator(new Blockly.icons.MutatorIcon(['lists_create_with_item'], this)); + this.appendValueInput('repeat') + .appendField(Blockly.Msg.MIXLY_EVERY_PER_ELEPER_ELEMENT); + this.appendDummyInput() + .appendField(Blockly.Msg.CONTROLS_REPEAT_TITLE_TIMES); + this.setPreviousStatement(false) + this.setNextStatement(false) + this.setOutput(true) + this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_PYTHON_TOOLTIP); + }, + /** + * Create XML to represent list inputs. + * @return {Element} XML storage element. + * @this Blockly.Block + */ + mutationToDom: function () { + var container = document.createElement('mutation'); + container.setAttribute('items', this.itemCount_); + return container; + }, + /** + * Parse XML to restore the list inputs. + * @param {!Element} xmlElement XML storage element. + * @this Blockly.Block + */ + domToMutation: function (xmlElement) { + this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10); + this.updateShape_(); + }, + /** + * Populate the mutator's dialog with this block's components. + * @param {!Blockly.Workspace} workspace Mutator's workspace. + * @return {!Blockly.Block} Root block in mutator. + * @this Blockly.Block + */ + decompose: function (workspace) { + var containerBlock = + workspace.newBlock('lists_create_with_container'); + containerBlock.initSvg(); + var connection = containerBlock.getInput('STACK').connection; + for (var i = 0; i < this.itemCount_; i++) { + var itemBlock = workspace.newBlock('lists_create_with_item'); + itemBlock.initSvg(); + connection.connect(itemBlock.previousConnection); + connection = itemBlock.nextConnection; + } + return containerBlock; + }, + /** + * Reconfigure this block based on the mutator dialog's components. + * @param {!Blockly.Block} containerBlock Root block in mutator. + * @this Blockly.Block + */ + compose: function (containerBlock) { + var itemBlock = containerBlock.getInputTargetBlock('STACK'); + // Count number of inputs. + var connections = []; + var i = 0; + while (itemBlock) { + connections[i] = itemBlock.valueConnection_; + itemBlock = itemBlock.nextConnection && + itemBlock.nextConnection.targetBlock(); + i++; + } + this.itemCount_ = i; + this.updateShape_(); + // Reconnect any child blocks. + for (var i = 0; i < this.itemCount_; i++) { + if (connections[i]) { + this.getInput('ADD' + i).connection.connect(connections[i]); + } + } + }, + /** + * Store pointers to any connected child blocks. + * @param {!Blockly.Block} containerBlock Root block in mutator. + * @this Blockly.Block + */ + saveConnections: function (containerBlock) { + var itemBlock = containerBlock.getInputTargetBlock('STACK'); + var i = 0; + while (itemBlock) { + var input = this.getInput('ADD' + i); + itemBlock.valueConnection_ = input && input.connection.targetConnection; + i++; + itemBlock = itemBlock.nextConnection && + itemBlock.nextConnection.targetBlock(); + } + }, + /** + * Modify this block to have the correct number of inputs. + * @private + * @this Blockly.Block + */ + updateShape_: function () { + // Delete everything. + if (this.getInput('EMPTY')) { + this.removeInput('EMPTY'); + } else { + var i = 0; + while (this.getInput('ADD' + i)) { + this.removeInput('ADD' + i); + i++; + } + } + // Rebuild block. + if (this.itemCount_ == 0) { + this.appendDummyInput('EMPTY') + .appendField(Blockly.Msg.MIXLY_EMPTY_REMINDER); + } else { + for (var i = 0; i < this.itemCount_; i++) { + var input = this.appendValueInput('ADD' + i); + if (i == 0) { + input.appendField(Blockly.Msg.MIXLY_PRODUCT+Blockly.Msg.MIXLY_GENERATE_CARTESIAN_PRODUCT); + } + } + } + }, + getVars: function () { + return [this.getFieldValue('VAR')]; + }, + renameVar: function (oldName, newName) { + if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) { + this.setTitleValue(newName, 'VAR'); + } + } +} \ No newline at end of file diff --git a/boards/default_src/python/generators/math.js b/boards/default_src/python/generators/math.js index b5e95410..bbb12984 100644 --- a/boards/default_src/python/generators/math.js +++ b/boards/default_src/python/generators/math.js @@ -307,4 +307,18 @@ export const turn_to_int = function (_, generator) { generator.definitions_.import_hexlify = "from ubinascii import hexlify"; var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC); return ["hexlify(" + str + ').decode()', generator.ORDER_ATOMIC]; +} + +export const generate_cartesian_product = function (_, generator) { + generator.definitions_.import_itertools = "import itertools"; + var re = generator.valueToCode(this, 'repeat', generator.ORDER_ATOMIC); + var code = new Array(this.itemCount_); + var default_value = '0'; + for (var n = 0; n < this.itemCount_; n++) { + code[n] = generator.valueToCode(this, 'ADD' + n, + generator.ORDER_NONE) || default_value; + } + // var code = '[' + code.join(', ') + ']'; + // var code = 'itertools.product('+'repeat='+re+')'; + return [code, generator.ORDER_ATOMIC]; } \ No newline at end of file diff --git a/boards/default_src/python_pyodide/template.xml b/boards/default_src/python_pyodide/template.xml index 77c2ccb9..ddde0520 100644 --- a/boards/default_src/python_pyodide/template.xml +++ b/boards/default_src/python_pyodide/template.xml @@ -389,6 +389,13 @@ + + + + 2 + + + diff --git a/common/msg/blockly/zh-hans.js b/common/msg/blockly/zh-hans.js index cea1e3a2..fa7e5212 100644 --- a/common/msg/blockly/zh-hans.js +++ b/common/msg/blockly/zh-hans.js @@ -3906,4 +3906,9 @@ ZhHans.MIXLY_TIMESTAMP_TO_DATA ="转化为日期"; ZhHans.MIXLY_TO_INDEX_SEQUENCE = "的序号和内容组合为索引序列"; ZhHans.MIXLY_INDEX = "序号"; ZhHans.MIXLY_TOTO_INDEX_SEQUENC_TOOLTIP = "将列表的所有项和序号组合为索引序列,例如(0,'A')为一个索引序列"; +ZhHans.MIXLY_generate_cartesian_product_TOOLTIP = "生成所给参数的笛卡尔积,每个元素重复次数根据参数决定"; +ZhHans.MIXLY_PRODUCT = "生成"; +ZhHans.MIXLY_GENERATE_CARTESIAN_PRODUCT = "笛卡尔积"; +ZhHans.MIXLY_EVERY_PER_ELEPER_ELEMENT = "每个元素重复"; +ZhHans.MIXLY_EMPTY_REMINDER = "至少需要一个可迭代对象"; })(); \ No newline at end of file