Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Python.print()

When Python is executed externally, in Windows, a DOS-console is openned and it is possible to use the Python function print() to show values in this console:

...

But when executing python code inside GiD, this console does not exists, and thus, this command cannot be used, except when using IDLE shell ( Utilities -> Tools -> Develop -> Console Python… ) .

Python print to file

To debug Python code it is always possible (inside and outside GiD) to print data of variables to a file, with something like this:

Code Block
languagepy
f=open('C:/temp/my_debug.txt','a')
f.write('hello world\n')
f.close()

Python

...

The scenery of use python in GiD is not usual:

  • The ‘normal’ case is to run a python.exe process that evaluate the code of a .py python file.

In the ‘normal’ case it is easy to use the Visual Studio Code editor, install the Python extension of Microsoft, and open a .py file, set breakpoints with <F9> and start debugging with <F5> and see the value of variables, stack trace, etc when the flow reaches a break point.

  • The GiD case run a gid.exe that has embedded a Tcl interpreter and at run time is loaded the tohil package that create an embedded Python interpreter and add Tcl commands to call Python to this interpreter . At run time it is also possible that this Python interpreter import the tohil module that add Python functions to call the Tcl interpreter.

Note: Running python.exe and importing tohil will create a new Tcl interpreter (not related at all with the one embedded in GiD, then GiD commands cannot be used)

It is possible in this case to do a ‘remote debugging’ with Visual Studio Code, connecting the debugger with the embedded Python of a running gid.exe in a host and port (e.g. localhost and 5678)

but before gid must start a server on this host and port calling our Tcl proc GiD_Python_StartDebuggerServer

Code Block
languagetcl
proc GiD_Python_StartDebuggerServer { } {
    tohil::import debugpy
    #tohil::exec "debugpy.log_to('[GidUtils::GetTmp]')"
    set my_python [file join [gid_filesystem::get_folder_standard scripts] tohil/python/bin/x64/python.exe]
    #to avoid a bug of debugpy that use sys.executable and try to run another gid.exe!!. see https://github.com/microsoft/debugpy/issues/262
    tohil::exec "debugpy.configure(python='$my_python')"
    tohil::exec "debugpy.listen(5678)"
    #tohil::exec "debugpy.wait_for_client()"
    return 0
}

Note: The required Python module debugpy is pre-installed in our tohil’s Python copy

Then open the folder with the .py file in VS Code,

open the file gid_meshing.py and set an stop <F9> in the line np.set_printoptions(threshold=np.inf)

Then click in the lower state bar to set as python interpreter the one of GiD (probably initially points to another Python of our system),

e.g. select

<GiD>\scripts\tohil\python\bin\x64\python.exe

...

Then start GiD and call GiD_Python_StartDebuggerServer

(e.g. can write -np- GiD_Python_StartDebuggerServer, or un-comment the line of meshio.tcl #GiD_Python_StartDebuggerServer)

And the first time that run the debug in VS Code <F5> it ask the configuration way to debug: select for example attach to remote debug, configuring the host=localhost and port=5678

this information is stored in the file .vscode/launch.json, with a content like this

Code Block
languagejson
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Attach localhostt:5678",
            "type": "python",
            "request": "attach",
            "connect": {
                "host": "localhost",
                "port": 5678
              },
            //"processId": "${command:pickProcess}",
            //"justMyCode": true
        }
    ]
}

In GiD go to menu Files->Import->Meshio

and select some mesh file, like a Kratos .mdpa file to be imported.

then the debugger will be stopped in our break point and can inspect variables, etc.

...

Python show text with W

If pyhton is running in GiD then can call the Tcl GiD procedure called W that show text in a window

e.g.

Code Block
languagepy
import tohil
tcl=tohil.import_tcl()
a=5.2
tcl.W(a)

will show a GiD window with the value of the variable a

Python force reload a file

Using our Tcl command GiD_Python_Import_File (that do tohil::import) will import a module in Python,

but if we are developing and modify the .py file doing a new import don’t refresh the code in the interpreter.

A trick to do it it to use the Tcl command GiD_Python_Source,then the new code of the file is used without need to restart GiD.

In fact it seems that this is similar to use in Python the function reload of the importlib module

...

languagepy

...

show text with GiD’s proc W

If Python is running in GiD then the Tcl GiD procedure W can be called, which shows text in a window.
e.g.

Code Block
languagepy
GiD_Python_Exec {
  import tohil
  tcl=tohil.import_tcl()    ;# defines in python all defined Tcl proc's at this time
  a=5.2
  tcl.W(a)
  b=a*3
  tcl.W(b)
}

Will show a GiD window with the value of the variables 'a' and 'b'

...

Important note:

Tcl follows a ’lazy' approach, this means that at a certain point in time of execution, only the procedures do exist that have been called or that have been defined from the current or previous loaded scripts.

tcl = tohil.import_tcl() is a tohil module command that creates a Python object with methods for each Tcl proc and commands, so that calling the Tcl procs looks very much like calling any Python function.
tcl = tohil.import_tcl() uses Tcl’s introspection capabilities to map Tcl procs and commands to methods of the Python object. It will only map existing Tcl procs and commands at the time of invocation!
This means that the above code will fail if the Tcl proc W has never been called before.
To make sure the above code works, first execute -np- W "Hello World" in GiD’s command line and then execute the above code.

Using tohil.call('W','hello world') will work as it delegates to the internal tohil Tcl interpreter the execution of the string list parameters, instead of calling the Tcl-proc directly. This way the internal Tcl interpreter will look for the definition of the procedure W if it does not exists, and execute it with 'hello world' as parameter.

tcl.W() can also be called from the IDLE shell window of GiD Utilities-->Tools-->Python console...:

...

Warning: It seems that tcl’s command update cannot be called from the IDLE shell window, showing following message ( MS Windows and Linux):

...

But if you click ‘OK’ the code will continue its execution.
Be aware that the command update is used in several GiD's windows and utilities, so this error message will appear several times.
Note: on macOS tcl’s command update will cause GiD likely to crash.

And in windows also crash, to avoid it we have modified the source code of Modules\_tkinter.c and recompiled.