Python Development Environment/it

Un semplicistico Ambiente di sviluppo per Python all'interno di FreeCAD

Python è un ambiente di programmazione che è stato incorporato nel sistema di FreeCAD. Usando Python molte operazioni offerte da FreeCAD sono accessibili tramite programmazione. Di solito i programmi Python per FreeCAD sono sviluppati per essere eseguiti nella console Python o attraverso la facilitazione Macro di FreeCAD (vedere Come installare le macro).

Gli strumenti disponibili per lo sviluppo di programmi in Python sono numerosi. I fattori di complicazione per lo sviluppo di Python da usare con FreeCAD sono due: in primo luogo gli strumenti non hanno alcun supporto per le numerose strutture di dati e punti di accesso di FreeCAD; in secondo luogo non funzionano "all'interno FreeCAD". Ciò significa che è possibile utilizzarlo per sviluppare del codice all'esterno di FreeCAD e non essere in grado di testarlo nell'ambiente di destinazione; oppure si può sviluppare Python nell'ambiente di destinazione (ad esempio l'ambiente FreeCAD), ma non avere alcun supporto da parte gli strumenti di sviluppo. Nessuna di queste è una soluzione accettabile.

Introduzione
Lo sviluppo di software moderni nello standard commerciale di solito è fatto con un set di strumenti genericamente denominato 'IDE'. Tipicamente questi strumenti sono i seguenti 3:


 * editor di codice sorgente
 * uno strumento di building automatico
 * un debugger

che sono standard, mentre i seguenti sono presenti in alcuni IDE ma non in altri:


 * un tool di building automatico
 * un compilatore e/o un interprete integrato
 * un sistema di controllo di versione
 * strumenti per costruire la Graphical User Interface (GUI)
 * un navigatore di classi
 * un analizzatore di oggetti
 * un diagramma della gerarchia delle classi

Una sintesi dello stato di questi strumenti all'interno FreeCAD è ('N/A' significa 'Non disponibile', ('Not Available')):

Esistono molti strumenti per supportare le funzioni di cui sopra per la programmazione Python, ma purtroppo non si integrano con l'ambiente di sviluppo di FreeCAD.

Un elenco di IDE per Python si trova a Integrated Development Environments for Python

Editor
Vi è un editor per Python come parte di FreeCAD, esso viene avviato facendo clic sul pulsante Modifica in Macro->Macros... Se si desidera utilizzare un editor esterno più performante allora ci sono numerosi editor Python disponibili per molte piattaforme e con diversi livelli di funzionalità. Utilizzando un editor esterno si ha il vantaggio di poter usare l'area di visualizzazione di FreeCAD per l'output (sia grafico che testuale nella console) mentre il codice sorgente viene visualizzato in un'altra applicazione. Un elenco di editor per Python secondo la piattaforma è disponibile all'indirizzo Python Editors

Nota : Per i Macintosh l'editor di testo TextWrangler funziona bene. Ha l'evidenziazione del codice ed eccellenti funzioni di ricerca. Ci sono opzioni per eseguire i lavori in Python, ma ovviamente non funzionano con l'ambiente FreeCAD.

Macro Source Code Directories
There are two directories used by FreeCAD, by default they are the same directory but they are pointed to by different callable point in FreeCAD:
 * FreeCAD.ConfigGet("UserAppData")
 * FreeCAD.ParamGet('User parameter:BaseApp/Preferences/Macro').GetString('MacroPath')

The first one "UserAppData" points to a directory where things like configuration files or other files intended for the user but not to be edited by the user may be stored.

The second one "MacroPath" points to a directory where the Python files which are macro files for FreeCAD are stored. To mark a Python file as a macro file for FreeCAD, the file extension is changed from ".py" to ".FCMacro".

By default these two directories are the same location but this is not necessary. It might be convenient to alter the location for the macro files (*.FCMacro) to a different location.

Editing files located in the "MacroPath" is straight forward, the text editor will accommodate this. For ease of use of FreeCAD Macro files, it is advisable to keep all the macro files in the directory pointed to by "MacroPath".

To alter the "MacroPath" directory, use Tools->Edit Parameters and then select Preferences/Macro/MacroPath where the text may be double-clicked and edited. Alternatively "MacroPath" can be altered by the code:

Debugger
Debuggers typically provide two main features (amongst others):
 * breakpoints in the source code
 * variable inspection

I punti di interruzione Breakpoints sono "trappole" che vengono inserite nel codice, se il percorso di esecuzione attraverso il codice incontra uno di questi punti di interruzione, l'esecuzione viene fermata o sospesa. Notare che l'esecuzione non viene interrotta, dato che quando un programma viene interrotto tutte le informazioni residenti in memoria, come variabili vanno perse. Mentre il programma è sospeso il contenuto delle variabili può essere ispezionato e talvolta alterato (dipende dalla capacità del debugger). Generalmente il codice sorgente non può essere cambiato, ma alcuni ambienti supportano anche questo. Quando si è pronti, l'esecuzione del codice sorgente può essere ripresa. Nel codice possono essere inseriti numerosi punti di interruzione e tramite questi punti si possono realizzare numerose sospensioni. Lo scopo del debugger è di fare in modo che l'esecuzione con i punti di interruzione e le sospensioni sia funzionalmente identico all'esecuzione senza punti di interruzione.

Le ispezioni delle variabili sono disponibili durante la sospensione dell'esecuzione causata da un punto di interruzione. In generale il contenuto delle variabili può essere visualizzato, e molti debugger supportano anche l'editing dei contenuti prima di riprende l'esecuzione.

Anche se è previsto, per FreeCAD non è ancora disponibile un debugger con tutte le funzionalità. Questa sezione descrive alcune soluzioni alternative per l'interim fino a quando il debugger non sarà rilasciato.

Breakpoint
Implementando i punti di interruzione si coinvolge un livello di supervisione del codice che gestisce l'esecuzione del codice in fase di sviluppo. Al momento tale livello di codice per lo sviluppo Python all'interno di FreeCAD non è disponibile. Come sostituto debole, il seguente codice è un'opzione. Invece di sospendere l'esecuzione del codice, ferma completamente l'esecuzione dividendo un numero per zero. Questa è davvero una scelta molto debole rispetto ad un corretto debugger con i punti di interruzione, inoltre questa opzione è utile solo se è usata insieme alla routine mostrata nella prossima sezione 'Variable Inspection'. Breakpoint Code

Console Traceback

Quando un programma fallisce durante l'esecuzione, Python genera ciò che è noto come un traceback che elenca l'ordine di esecuzione del programma (cioè quale programma ha chiamato quale programma, in quale ordine).

Per il codice di esempio

otteniamo il seguente traceback

Leggendo il traceback possiamo stabilire che:
 * un messaggio di 'Breakpoint: amalgamation routine' è stato inviato dal breakpoint che ha la stringa 'amalgamation routine'
 * l'errore di esecuzione si è verificato alla riga 28 del modulo 'myNewMacro'
 * la routine 'myNewMacro' è stata chiamata dalla riga 40 del modulo 'testStub'

Assumendo che la stringa passata alla chiamata del breakpoint sia significativa allora la posizione del breakpoint può essere determinata facilmente. Notare che in un sistema complesso all'interno del traceback possono esserci decine o addirittura centinaia di voci.

Per diventare produttivi con questi punti di interruzione, continuare con la sezione successiva.

Variable Inspection
La seconda caratteristica principale di un debugger è quella di esaminare ed eventualmente modificare il contenuto delle variabili. Ancora una volta, fino a quando il debugger FreeCAD per Python non sarà pronto dobbiamo dipendere da soluzioni alternative.

Una caratteristica del sistema FreeCAD è la fornitura di variabili globali. Queste variabili sono create dal codice Python e risiedono nella memoria di FreeCAD fino a quando l'utente esce da FreeCAD. La forma di queste variabili è:

L'istruzione crea una variabile Python nella memoria di FreeCAD che è completamente accessibile dal codice Python, di fatto si comporta esattamente come una normale variabile Python. Però, dopo che l'esecuzione del codice Python termina, non importa se è eseguito come una macro o attraverso la console, la variabile 'FreeCAD.myVariable' rimane nella memoria con il valore di 123. Inserire:

produce il contenuto della variabile sulla console. Questo valore rimane in FreeCAD fino a quando non viene modificato o l'utente esce da FreeCAD. Ciò significa che il valore è presente e disponibile per essere letto da un successivo programma Python. Esso può essere controllato dalla console, in qualsiasi momento, digitando il suo nome. Quindi un programma chiamato 'Program A':

può essere eseguito e può caricare i valori nella variabile globale. Più tardi può essere eseguito un secondo programma chiamato 'Programma B' che può recuperare i valori:

Presumibilmente il 'Programma B' passa poi a fare calcoli che coinvolgono i valori lasciati in FreeCAD.myVariable. In qualsiasi momento l'utente può digitare nella console per ispezionare il contenuto delle variabili:

Una cosa importante da tenere presente con le variabili globali di FreeCAD è che esistono nella memoria e vengono perse quando il programma viene chiuso. Esse non sono salvate con i documenti, ma esistono solo nella memoria.

Uso
A questo punto possiamo mettere insieme le due fasi e usarle per rintracciare gli errori nel codice. Non è molto pratico da usare, ma è solo una alternativa finché il debugger di FreeCAD non sarà pronto.

It's probably easiest to present through an example, say the following program is being debugged:

Execution of the program on the console yields:

which is not what we expected! Assuming we are unable to see the errors we can use our unsophisticated breakpoint and variable examiner as follows. We can insert a line to copy the value of the variable we are wondering about to a global variable, then we can place a breakpoint to halt execution there:

Now when we run the program we get:

Probably things don't look so good, but what we can now do is inspect the value of the Python variable 'temporaryVariable1' as we assigned it's value to the global variable 'FreeCAD.saveMyVariable':

Remembering that the variable 'FreeCAD.saveMyVariable' holds the value of the Python variable 'temporaryVariable1' we can now determine the error in the value and start tracing back to determine where the error came from. When we are looking at 'FreeCAD.saveMyVariable' it is important to realise that the variable 'temporaryVariable1' is no longer available - it has been garbage collected away by the Python system.

Once the error has been located in the statement

and corrected to:

Then we can run the program again, and get the value of '11' which is still not right. We can make more assignments to FreeCAD global variables, have multiple breakpoints (although the first one encountered will stop execution)

We now have two breakpoints (although one is commented out) and two FreeCAD global variables in use. There is no practical limit to the global variables available from FreeCAD so there is no need to economise unnecessarily. We can now produce the following on the console:

Some points about the use of the FreeCAD global variables:
 * Python treats these variables identically to any other Python variable
 * these variables may hold any Python data type - anything a regular Python variable would hold
 * these variables may be used to 'bring out' the contents of a Python variable so we can see them
 * also these variables may be used to 'supply' values to a Python variable by setting their value from the console prior to running a routine, or setting it in a previous Python program
 * these variables may be used to pass data between two programs that run at different points in time
 * (to repeat) these variables are only for the duration of the FreeCAD session, once the user Quits from FreeCAD then the variables are lost

Variable Watcher
There is a utility Global Variable Watcher to help monitor the global variables of FreeCAD. It can display the contents of a global variable either on request or on a timed basis.

Name Space Clash
One thing to be aware of is as there is no management of global variable names by FreeCAD so there is the possibility of changing a variable from the system or another piece of code. Consequently it is a good idea to prefix your variables with something unique such as the routine name. For example to use a variablefrom a routine called 'alpha1' the global name could be 'FreeCAD.alpha1MyVariable'.

Coding Framework
When developing small pieces of Python code in FreeCAD it may be sufficient to use the Python console. However as the number of lines of code grows it makes more sense to store them in a file. Python can be in any file ending with the extension ".py", however FreeCAD also provides a mechanism called Macro for storing such programs and interacting with them (e.g. editing, running). Python in regular '.py' files may only run from the Python console while python in macro file '.FCMacro' can be run from the FreeCAD interface for executing macros. One downside with the FreeCAD menu interface is it is menu based with a control window and potentially causes some clutter on the on-screen GUI.

An easier approach is to take the Python code and instead of starting it from the FreeCAD Macro menu, start it from a toolbar. A Python routine linked to a button on a toolbar may be executed by one click. Also as the toolbars are floating windows they do not clutter the on-screen display. In fact if the FreeCAD window is less then the physical size of the screen the toolbar may be left to float outside of the FreeCAD window. This is beneficial when screen snapshots are required of the FreeCAD display. Also the toolbar can be much smaller than the macro control window displayed by the Macro menu of FreeCAD.

Connecting a macro to a button on a toolbar is covered in How to Install Macros and How to Customise a Toolbar. It can take a number of minutes to connect a macro to button on toolbar, select an icon etc. This is not always required as sometimes you simply want to quickly flesh out a piece of code which will then be integrated in some other code. For this situation a Test Stub can be beneficial. There is no real definition for what a test stub would entail, it really depends on the person and the application area. An example is shown below:

This test stub also serves as a template for code with locations defined for the different aspects of a large Python program. When executed the test stub program simply generates a message showing it's name and finishes. In using a test stub, any main line code written is placed at the very end of the file with code for class definition, functions etc. placed in the previous sections. The template can easily be altered to match the situation. Obviously for a program of 5 lines there is no need for such an amount of documentation.

By keeping a button permanently on a toolbar and linking that button to the test sub, there is always an area to write code and execute it immediately. The execution will be independent of the Python console. Also the execution can be independent of the screen GUI. Output from the program under development will appear as it should on the screen without any other artifacts from the programming environment. The Python console can be hidden to increase display area or used for any other purpose if needed. When execution is handled by the button on the toolbar the console is not required.

When the code is finished then is can simply be copied/pasted over to another file and the text stub left empty until the next time it is needed.

Multiple pieces of code can be developed using the same test stub with some extra code for providing multiple buttons which is located at PySide Beginner Examples - More Than 2 Buttons.

More PySide Support

For more support using the PySide GUI there is the page PySide

More Python Programming Support

For more assistance with Python coding, there is a macro written to aid in developing Python code, is it located at Python Assistant Window

Putting It All Together
Screen management can be a challenge when developing code that has complex and detailed graphical output like FreeCAD does. The following system works well:
 * FreeCAD for console, report, GUI display
 * toolbar to invoke code being developed
 * external editor to modify code
 * PAW (Python Assistant Window) to aid Python code generation

Screen Management

With the test stub operated from a toolbar, and an external editor used, the window layout on the screen will be something like:



"tree" in the diagram refers to the Combi or Tree browsers, the Python console and Report view are combined into the lower window and selectable by buttons. By selective use of the tools the development stream can be optimised, the above is only one idea. Tailouring is done on a personal basis.

Miscellaneous Links
Some other links about IDEs for Python which might be of interest are:
 * Comparison of Python IDEs for Development
 * Choosing the Best Python IDE
 * Your Development Environment
 * PyCharm Community Edition IDE