how to add code to the end of python script

103 views
Skip to first unread message

qi qifeng

unread,
Jul 19, 2023, 11:50:38 AM7/19/23
to Blockly
  const functionName =
  Blockly.Python.provideFunction_('serial_get_command', `
  def ${Blockly.Python.FUNCTION_NAME_PLACEHOLDER_}():
    while True:
    ser.flushInput()
    ser_read_buff = ser.readline()
    try:
      serobject = json.loads(ser_read_buff)
      if serobject["function"]:
        function_name = serobject["function"]
        param = serobject["param"]
        print(function_name)
        print(param)
        command = f"{function_name}({param})"
    except json.JSONDecodeError:
      pass
  `);
  Blockly.Python.finish = function(code) {
    return code+"\n"+functionName+"()";
  } I use these code to both generate head function and end command
but if i write finish command, the head function disappear, what's wrong?

qi qifeng

unread,
Jul 19, 2023, 1:14:02 PM7/19/23
to Blockly
I read doc,and I know function  Blockly.Python.finish is used for generate provideFunction_ so if i drived from finish, i have to do it myself,but I dont know
how to do it

Christopher Allen

unread,
Jul 19, 2023, 2:41:58 PM7/19/23
to blo...@googlegroups.com
Hi Qifeng,

I read doc,and I know function  Blockly.Python.finish is used for generate provideFunction_ so if i drived from finish, i have to do it myself,but I dont know how to do it

You need only call the superclass version of the method.  E.g., instead of:

  Blockly.Python.finish = function(code) {
    return code+"\n"+functionName+"()";
  }

do:

Blockly.Python.finish = function(code) {
  return super.finish(code) + '\n' + functionName + '();';
}


Best wishes,

Christopher

qi qifeng

unread,
Jul 19, 2023, 7:29:37 PM7/19/23
to Blockly
it still wrong. the error message look like these:
Uncaught SyntaxError: 'super' keyword unexpected here
and I check GPT, it say i have to use it  like these:
class MyClass extends ParentClass { finish(code) { return super.finish(code) + '\n' + this.functionName + '();'; } }
but  I dont have  ParentClass

qi qifeng

unread,
Jul 19, 2023, 7:45:19 PM7/19/23
to Blockly
it is ok now
  // Only modify Blockly.Python.finish if it hasn't been modified before
  if (!Blockly.Python.finish.modified) {
    // Save old finish function and bind to Blockly.Python
    const oldFinish = Blockly.Python.finish.bind(Blockly.Python);

    Blockly.Python.finish = function(code) {
      // Call old finish function and add call to functionName
      return oldFinish(code) + '\n' + functionName + '();';
    }

    // Mark Blockly.Python.finish as modified
    Blockly.Python.finish.modified = true;
  }

I change it like thesse,thanks

Christopher Allen

unread,
Jul 20, 2023, 7:26:08 AM7/20/23
to blo...@googlegroups.com
Hi Qifeng,

On Thu, 20 Jul 2023 at 01:29, qi qifeng <qqi...@gmail.com> wrote:
it still wrong. the error message look like these:
Uncaught SyntaxError: 'super' keyword unexpected here

Apologies—you are quite correct that I made a mistake here.  In fact, one of my colleagues pointed it out to me in chat yesterday evening but alas I did not have a chance to respond before the end of the day.

I'm glad you got it working despite my mistake, but I thought I should add some extra information for you and anyone else who might be looking at this thread in the future:

and I check GPT, it say i have to use it  like these:
class MyClass extends ParentClass { finish(code) { return super.finish(code) + '\n' + this.functionName + '();'; } }
but  I dont have  ParentClass

Though it is not yet documented in our developer site (or in our TypeScript .d.ts files), as of Blockly v10.0.0 we now provide the PythonGenerator class as an export (and similarly for the other languages we support).  Users who use a build system that supports ES Modules can access them via:

import {pythonGenerator, PythonGenerator, Order} from 'blockly/python';

class CustomPythonGenerator extends PythonGenerator {
  finish(code) {
    return super.finish(code) + '\n' + this.functionName + '();';
  }
}
const customPythonGenerator = new CustomPythonGenerator();

// Copy the default block generator functions onto custom generator:
Object.assign(customPythonGenerator.forBlock, pythonGenerator.forBlock);
// Or, alternatively, share the same dictionary object:
// customPythonGenerator.forBlock = pythonGenerator.forBlock;

From your sample code, it looks like you instead load blockly_compressed.js and python_compressed.js using <script> tags; in that case the above could instead be written as:

class CustomPythonGenerator extends python.PythonGenerator {
  finish(code) {
    return super.finish(code) + '\n' + this.functionName + '();';
  }
}
const customPythonGenerator = new CustomPythonGenerator();

Object.assign(customPythonGenerator.forBlock, python.pythonGenerator.forBlock);
// Or customPythonGenerator.forBlock = python.pythonGenerator.forBlock;

However, as you have discovered it is not necessary to do this; you can just call the method directly.  If I may make a small suggestion, however: if you are using Blockly v10 or later you code:

  // Only modify Blockly.Python.finish if it hasn't been modified before
  if (!Blockly.Python.finish.modified) {
    // Save old finish function and bind to Blockly.Python
    const oldFinish = Blockly.Python.finish.bind(Blockly.Python);

    Blockly.Python.finish = function(code) {
      // Call old finish function and add call to functionName
      return oldFinish(code) + '\n' + functionName + '();';
    }

    // Mark Blockly.Python.finish as modified
    Blockly.Python.finish.modified = true;
  }


can be simplified slightly, as follows (also updating to use the new python namespace available in v10 instead of the legacy Blockly.Python):

python.pythonGenerator.finish = function(code) {
  code = python.PythonGenerator.prototype.finish.call(this, code);
  return code + '\n' + functionName + '();';
}


(If using import as in the example I gave at the top of this message then omit the "python." prefix.) 

Technical detail: this works and is safe (but useless) to run more than once because, as of v10, the .finish method has been moved from the pythonGenerator object itself (also known as Blockly.Python) to pythonGenerator.__proto__ (also known as PythonGenerator.prototype).  For more information see proposal #7085 and proposal #7086.


Best wishes,

Christopher

qi qifeng

unread,
Jul 26, 2023, 2:25:17 AM7/26/23
to Blockly
thanks ,at final I use these code 
      Blockly.Python.finish = function(code) {
        // Call old finish function and add call to functionName
        var blocks = mainWorkspace.getBlocksByType('ser_fun',false);
        if (blocks.length>0){
          code = python.PythonGenerator.prototype.finish.call(this, code);
          return code + '\n' + functionName + '()\n';
        }else{
          return python.PythonGenerator.prototype.finish.call(this, code);;
        }
       
      }
Reply all
Reply to author
Forward
0 new messages