9785
Commento:
|
10230
ready for #70
|
Le cancellazioni sono segnalate in questo modo. | Le aggiunte sono segnalate in questo modo. |
Linea 1: | Linea 1: |
## page was renamed from Fcm/Edizione/HowTo6 #acl GruppoAdmin:admin,read,write,revert GruppoOperatori:admin,read,write,revert GruppoEditori:read,write,revert CristianoLuinetti:admin,read,write,revert MarcoBuono:admin,read,write,revert AldoLatino:admin,read,write,revert GruppoFcm:read,write,revert -All:read -Known:read |
#acl GruppoAdmin:admin,read,write,revert GruppoOperatori:admin,read,write,revert GruppoEditori:read,write,revert GruppoFcm:read,write,revert palombo:admin,read,write,revert new.life:admin,read,write,revert paolettopn:admin,read,write,revert Known:read All:read |
Linea 4: | Linea 4: |
= Testo inglese = LibreOffice Part 23: Base Form Enhancements with Macros by Elmer Perry For the previous four parts of this series, we have slowly built a database document using LibreOffice's Base module. We have a database with forms to enter our data, and queries and reports for extracting the data. We now have a usable document for recording our book library. However, our current design has one flaw we need to overcome. If we need to enter a new author or media type while we are in the books form, we have to close the book form and open one of the others. If we could enter new authors and media types directly from the books form, it would behave more like an application and make data entry even easier. We can accomplish this through a few short macros. The LibreOffice Basic language is very similar to other Basic languages, such as Visual Basic for Applications. To manipulate the underlying LibreOffice document, we access the Uno framework controlling the document. The Uno framework is quite complex, but I will explain, as best I can, the properties and objects we will use. The goal is not to teach you how to write LibreOffice macros, but how you can use them. Macro Security and Options While macros allow us to do cool things in our documents, they can also cause problems. Some people use macros to compromise other people's systems, therefore, we need to take a few minutes to talk about macro security. Whether you are running LibreOffice on Linux, Mac, or Windows, malicious code in a macro can compromise your data and possibly your entire system. Macro security in LibreOffice is simple. Tools > Options opens the Options dialog for LibreOffice. Under LibreOffice, select Security. Click on the Macro Security button to pop up the macro security options. You have four options. Never use the Low security option – it will run macros without asking you. I recommend the Medium security level. With this level, you are prompted whether to run the macros when you open a document containing macros. The High and Very High options require a certificate or folder you designate as trusted. While this is great, I believe nothing trumps the instincts of the user. You usually know whether you were expecting a document to contain macros. When in doubt, click No. Click OK to save your choice and OK to close the options dialog. Now, on to the fun stuff. The Macros We will write four macros for our database document. Three will deal with opening forms, and the last will update the list boxes for authors and media types. The general idea behind macros is to accomplish tasks that are not built into the program, or to simplify complex tasks. Our macros really accomplish both, as we will simplify the tasks of adding authors and media types and provide functionality not built into the program. Before we can begin to write our macros, we need a container to hold them. Macros are contained in a module. Modules can live in the program itself or within a document. Since our macros are specific to our database file, we will embed them in the document. Macros embedded in a document are available only when the document is loaded. Macros contained in the program are available as long as the program is running. Tools > Macros > Organize Macros > LibreOffice Basic. The LibreOffice Basic Macros dialog pops up. Select book.odb from the Macro from-list. Click the New button. A dialog pops up asking you for a name for the module. Name it FormCalls. Click OK. This brings up the LibreOffice macro editor. The macro comes with a default main subroutine. We will not use this subroutine. Highlight Sub main and End Sub and press the backspace key to delete them. Our first macro is a generalized subroutine for opening a form. A generalized subroutine is written for reuse. We will call this routine twice from other routines we write. Type this subroutine into the editor: {{{ Sub OpenAForm (FormName as String) Dim GetForm as Object GetForm = ThisDatabaseDocument.FormDocuments.GetByName(FormName) GetForm.Open End Sub }}} The first line of the subroutine is called the signature. The signature determines how the subroutine is called. A signature starts with the keyword Sub, which defines this call as a subroutine. Next, the name of the subroutine. In our case, OpenAForm is the name of the subroutine. Finally in the parenthesis, we have the arguments used when calling this subroutine. In our case, we have a variable named FormName which is a type String. In the second line of the subroutine, Dim is another keyword. Dim initializes a variable as a type, and, optionally, a value. We define a variable named GetForm as a type Object. The third line assigns a value to the variable GetForm through a chain of commands in the Uno framework. ThisDatabaseDocument refers to the currently open database document. In our case, book.odb. FormDocuments is a collection of all the forms in the document. Finally, GetByName retrieves a specific form object from the collection. Notice, we pass the variable FormName from the signature to this method. Once the call is complete, the variable GetForm is the object of the form name passed to the subroutine. The fourth line calls the Open method of the form. On the fifth line, we tell Basic this is the end of the subroutine with the command End Sub. We will call the OpenAform subroutine twice. Once to open the authors form, and once to open the media form. Add these two subroutines to your editor: {{{ Sub OpenAuthorsForm(oEv As Object) OpenAForm("Authors") End Sub Sub OpenMediaForm(oEv As Object) OpenAForm("Media") End Sub }}} The signature on these two subroutines are a little different. Since we will call them from a control within a form, we need to pass the object making the call as an argument, even though we do not use it. The argument oEv is a reference to the object making the call. We will use this to our advantage later, in the last subroutine, but here we do it because it is required. These two subroutines are pretty simple. We just make a call to OpenAForm passing the name of the form we want to open, Authors or Media. The final subroutine deals with our problem of refreshing the data in the list boxes for authors and media when we add authors or media using the two subroutines above: {{{ Sub ListRefresh(oEv as Object) oEv.source.model.Refresh End Sub }}} Once again, since we will call this subroutine from a control, we need a reference to the control making the call. However, this time we will actually use the object. This subroutine makes a method call to the underlying model of the list box and refreshes the data in the list, thus updating our list of authors or media types. Save your module and close the Basic editor. Making Connections to Macros At this point, our macros do nothing. We need to connect them to objects in our form to activate them when needed. First, we will connect the open form subroutines to buttons in our form, and then we will connect the ListRefresh to the list boxes. In the database pane, click on Forms. Right-click the Books form and select edit. Add two push buttons to the form, one under the Authors table and another under the Media table. Right-click the button under the Authors table and select Control to bring up the buttons properties dialog. On the General tab, change the name to AddAuthors and the Label to Add Authors. On the Events tab, click the ellipses (…) button next to Execute Action – which brings up the Assign Action dialog. Click the Macro button to bring up the Macro Selector dialog. In the tree list under Library, select book.odb > Standard > FormCalls. Select OpenAuthorsForm from the Macro Name list and click OK. Click OK to close the Assign Action dialog. Close the buttons properties dialog. Do the same with the button under the Media table, only name it AddMedia, make the label Add Media Type, and assign the macro OpenMediaForm to the Execute Action event. Finally, we need to add the refresh subroutine to our list boxes. Right-click the Authors column in the authors table and select Column. On the Events tab, click the ellipse (…) button beside “When receiving focus”. In the Assign Action button, use the Macro button to assign the ListRefresh macro to the action. This will cause the list to update data from the Authors table when you click on a list box in the column. Do the same for the Media column in the media table. Save your changes to the Books form and close it. Testing Your Changes Any time we make changes to our forms, we will want to test them and make sure we got everything right, especially in cases where we have used macros. One simple typo could cause things to not work. Double-click the Books form to open it. Add a new book with an author and media type you have not added already. Click the Add Authors button to make sure it opens the form. Add some authors. Close the Authors form. Click on the authors dropdown list box and verify that the authors you added are there. Do the same test with the Add Media Type button and listbox. Final Thoughts and References Again, I would like to emphasize that writing macros in LibreOffice Basic is complex. Documentation is pretty sparse, but it is out there. If you are interested in taking up the challenge, here are some references to get you started: LibreOffice Basic Guide: http://wiki.documentfoundation.org/images/d/dd/BasicGuide_OOo3.2.0.odt Andrew Pitonyak's OpenOffice Macro Information: http://www.pitonyak.org/oo.php You can find the macros used in this How-To on pastebin.com at http://pastebin.com/MU2Ztizi Next time, we will move on to another part of the LibreOffice suite and explore the Math module. |
|
Linea 7: | Linea 74: |
Calc è il modulo foglio di calcolo di LibreOffice, che è compatibile con Microsoft Excel. Abbiamo già visto un uso per Calc quando abbiamo creato il database del povero uomo nel mio ultimo articolo, ma Calc è capace di più di una sola collezione di dati. Come suggerisce il nome, Calc può fare operazioni usando un ricco numero di funzioni integrate nel programma. Ciò significa che non dobbiamo calcorare manualmente il totale di qualche colonna; possiamo inserire una formula per aggiungerlo per noi. Calc ci permette anche di prevedere uno scenario “cosa accadrebbe se...” per giocare con i numeri nel vostro foglio di calcolo. | == Note alla traduzione == |
Linea 9: | Linea 76: |
Prima di addentrarci nella costruzione del foglio di calcolo del nostro bilancio, è necessario sapere alcune cose su come un file, a volte indicato come una cartella di lavoro in Calc, funziona. Ogni file può contenere alcuni fogli di calcolo diversi. In una nuova cartella di lavoro si ottengono di default tre fogli di calcolo di nome Foglio1, Foglio2 e Foglio3. Essi sono elencati sulle schede nella parte inferiore della finestra. Ogni foglio è costituito da singole cellule. Identificate le celle dalla loro lettera di colonna e numero di riga. Per esempio, la prima cella in alto a sinistra è A1, la prima colonna, prima riga. Ogni foglio di calcolo è in grado di avere 1.024 colonne e 1.048.576 righe. L'aspetto della finestra di Calc è un po' diverso rispetto alla finestra di Writer. Avete ancora una barra dei menu e una barra di formattazione, ma sotto la barra di formattazione, si ha la barra della formula. La barra della formula è il tuo amico quando si lavora in Calc. La casella più a sinistra è l'attuale casella nome della cella. Vi dice la cella selezionata o intervallo di celle. I tre pulsanti sono la procedura guidata della funzione, il tasto della somma e il tasto funzione. La casella di testo è la stringa di input. Usala per modificare il contenuto di una cella. Nella parte superiore del foglio di calcolo hai le intestazioni delle colonne (A, B, C. ..) e, lungo il lato sinistro, si hanno la intestazioni di riga (1, 2, 3 ...). Le colonne e le righe sono segnate sul foglio da linee grigio chiaro. Troverete questa griglia a portata di mano quando state disponendo il foglio di calcolo. Hai diverse scelte nel modo in cui si immettono i dati nelle celle. È possibile fare clic sulla cella e iniziare a digitare. Quando avete finito, premere Invio e si passerà alla cella sottostante. È anche possibile fare clic su una cella e inserire i propri dati nella riga di immissione della barra della formula. Questo metodo ha un inconveniente, che spiegherò in un minuto, ma a volte, è il metodo migliore per modificare il contenuto di una cella. È possibile modificare direttamente la cella facendo doppio clic sulla cella. In questo modo andrete in modalità di modifica delle celle. Questa modalità è simile alla modifica nella barra della formula. Per navigare all'interno del vostro foglio di calcolo, si può sempre prendere il mouse e fare clic sulla cella che si desidera. Tuttavia, dato che spesso le vostre mani sono già sulla tastiera, le scorciatoie da tastiera funzionano meglio. Tab vi sposta di una cella a destra. Shift-Tab vi sposta di una cella a sinistra. Invio per spostarsi una cella verso il basso e Shift-Enter vi sposta una cella in alto. Anche se non in modalità di modifica o senza l'uso della stringa di input, i tasti freccia vi spostano nella direzione della freccia. I tasti freccia sono disabilitati per la navigazione, mentre nella stringa di input e in modalità di modifica vi consente di muoverti all'interno del tuo contenuto. Ora, con questi attrezzi nella vostra cintura, costruiamo la prima sezione del nostro foglio di calcolo di bilancio. Aprite un nuovo file di Calc. Fate clic sul punto bianco grigio a sinistra della colonna e sopra l'intestazione della prima riga. In questo modo selezionare l'intero foglio. Nella barra di formattazione, impostate il carattere di un bel sans-serif come Arial e impostate la dimensione del carattere 12pt. In questo modo abbiamo impostato il font predefinito e la dimensione per il nostro intero foglio. Nella cella A1, digitate il testo "Reddito per questo periodo" e premete Invio. Per ora non preoccupatevi se il testo supera la cella. Lo sistemeremo in un minuto. Nella seconda riga della colonna A, digitate "Fonti". Giù la colonna A, a partire dalla riga 3, nei diversi tipi di reddito che hai digita, ad esempio, Lavoro, Freelance, Bonus. Io di solito aggiungo una "Varie" per quelle cose che non rientrano in altre categorie, come vincere la lotteria e rinunciare al vostro giorno di lavoro. A questo punto, alcune delle vostre fonti di reddito possono sovraccaricare le relative celle. Possiamo regolare la larghezza della colonna trascinandola facendo clic tra le intestazioni delle celle A e B. Non ci siamo ancora interessati della cella A1. Per adesso, il sovraccarico di A1 va bene, basta assicurarsi che tutte le fonti di reddito sono inserite in colonna. Spostatevi nella cella B2. Digitate "Importo". Premete Invio. Sotto la colonna B, inserite un importo per ciascuna delle fonti di reddito. Si noterà che il valore predefinito per numeri è solo qualche numero non formattato. Facciamoli sembrare come importi in valuta. Li cambieremo tutti in una volta. Potete selezionare tutte le celle numerate da cliccando con il tasto sinistro del mouse e trascinando fino ad avere evidenziato tutti i numeri. È anche possibile fare clic sulla prima cella, tenere premuto il tasto Shift e cliccate su l'ultima. Con la tastiera, utilizzare Shift in combinazione con i tasti freccia. Formato> Celle> Numeri. Selezionare la categoria Valuta. Sopra la casella Formato, selezionate il tipo corretto di valuta per il proprio paese. Selezionate un formato di valuta dalla casella del formato. Ciò è tutto sopra di voi. Dal momento che non si dovrebbe mai avere un dato negativo nelle celle del reddito, non c'è bisogno di preoccuparsi troppo dei formati che trattano i numeri negativi. Ora, ci prenderemo cura di A1 che straborda in B1. Dal momento che questo testo è una voce per la sezione, vorremmo che si estendesse lungo tutta la larghezza della sezione. Unisci celle è la risposta. Evidenziate le celle A1 e B1, e Formato> Unisci celle> Unisci e centra celle. Useremo molto unire le celle, e ciò dovrebbe diventare una delle tue usuali caratteristiche di formattazione. Purtroppo non c'è una scorciatoia da tastiera. È possibile crearne una in Strumenti > Personalizza > Tastiera, ma fate attenzione a non assegnare la scorciatoia da tastiera per una funzionalità comune o predefinita. Adesso facciamola apparire come un'intestazione. Rendiamo il carattere in grassetto, Formato > Celle > Carattere. Seleziona Grassetto sotto Tipo di carattere. Mettiamo un bordo intorno a esso per farlo risaltare solo un po' di più. Fate clic sulla scheda Bordi. Sotto Predefinito, fate clic sulla seconda casella, Imposta tutti i quattro bordi. Lasciate lo stile predefinito, ma cambiate il colore in grigio. Fate clic su OK. Con le nostre intestazioni Sorgente e Importo, vogliamo che questi risaltino pure, ma c'è bisogno di farli apparire un po' diversi per distinguerli dall'intestazione di sezione. Selezionate le due celle che contengono la Sorgente e l'Importo. Formato > Celle > Carattere. Selezionate di nuovo grassetto. Fate clic sulla scheda Bordi. Questa volta vogliamo solo un bordo tra le due celle. Fate clic nella casella Definito dall'utente tra i due box grigi che hanno una X bianca. Vedrete una linea tra i due. Cambiare il colore in grigio. Nella scheda Allineamento, modificate l'allineamento orizzontale e verticale a centrato. Nella scheda Sfondo, selezionate azzurro (Blue 8) come colore di sfondo. Fate clic su OK. Per i nostri elementi dei proventi, potremmo mettere un bordo intorno a loro, ma che può essere a volte difficile da leggere. Invece, evidenziamo le righe pari. Iniziamo con la seconda voce, evidenziate sia il nome e il suo importo. Formato > Celle > Scheda Sfondo. Selezionate un grigio chiaro per lo sfondo. Ho usato grigio 10%. Fate clic su OK. Ripetete l'operazione per tutte le righe pari. Sarebbe bello avere un divisore tra il nome e la quantità e un bordo intorno l'intera lista. Cliccate sul nome, tenete premuto il tasto Maiusc e fare clic sull'ultimo numero. Questo dovrebbe evidenziare tutti gli elementi e i loro importi. Formato > Celle > Scheda Bordo. Sotto Predefinito selezionate la seconda casella, impostate solo Bordo esterno. Noterete che il box Definite dall'utente questa volta è diverso. Ci sono quattro caselle di colore grigio con X bianco in queste. Fate clic tra le prime due caselle. Questo vi darà una linea verticale tra le celle. Se fate clic nel mezzo, si creerà una linea verticale e orizzontale che non è quello che vogliamo. Cambiate il colore in grigio e fate clic su OK. Questo completa la sezione Importi del nostro foglio di calcolo. Nel prossimo articolo continueremo con i nostri fogli di calcolo di bilancio con l'aggiunta della sezione Attività. E cominceremo cercando di far fare al nostro foglio di calcolo un po' di matematica per noi utilizzando la funzione Somma. == Note alla traduzione == |
|
Linea 41: | Linea 79: |
Linea 42: | Linea 81: |
Testo inglese
LibreOffice Part 23: Base Form Enhancements with Macros
by Elmer Perry
For the previous four parts of this series, we have slowly built a database document using LibreOffice's Base module. We have a database with forms to enter our data, and queries and reports for extracting the data. We now have a usable document for recording our book library. However, our current design has one flaw we need to overcome. If we need to enter a new author or media type while we are in the books form, we have to close the book form and open one of the others. If we could enter new authors and media types directly from the books form, it would behave more like an application and make data entry even easier. We can accomplish this through a few short macros. The LibreOffice Basic language is very similar to other Basic languages, such as Visual Basic for Applications. To manipulate the underlying LibreOffice document, we access the Uno framework controlling the document. The Uno framework is quite complex, but I will explain, as best I can, the properties and objects we will use. The goal is not to teach you how to write LibreOffice macros, but how you can use them. Macro Security and Options
While macros allow us to do cool things in our documents, they can also cause problems. Some people use macros to compromise other people's systems, therefore, we need to take a few minutes to talk about macro security. Whether you are running LibreOffice on Linux, Mac, or Windows, malicious code in a macro can compromise your data and possibly your entire system.
Macro security in LibreOffice is simple. Tools > Options opens the Options dialog for LibreOffice. Under LibreOffice, select Security. Click on the Macro Security button to pop up the macro security options. You have four options. Never use the Low security option – it will run macros without asking you. I recommend the Medium security level. With this level, you are prompted whether to run the macros when you open a document containing macros. The High and Very High options require a certificate or folder you designate as trusted. While this is great, I believe nothing trumps the instincts of the user. You usually know whether you were expecting a document to contain macros. When in doubt, click No. Click OK to save your choice and OK to close the options dialog. Now, on to the fun stuff. The Macros
We will write four macros for our database document. Three will deal with opening forms, and the last will update the list boxes for authors and media types. The general idea behind macros is to accomplish tasks that are not built into the program, or to simplify complex tasks. Our macros really accomplish both, as we will simplify the tasks of adding authors and media types and provide functionality not built into the program. Before we can begin to write our macros, we need a container to hold them. Macros are contained in a module. Modules can live in the program itself or within a document. Since our macros are specific to our database file, we will embed them in the document. Macros embedded in a document are available only when the document is loaded. Macros contained in the program are available as long as the program is running. Tools > Macros > Organize Macros > LibreOffice Basic. The LibreOffice Basic Macros dialog pops up. Select book.odb from the Macro from-list. Click the New button. A dialog pops up asking you for a name for the module. Name it FormCalls. Click OK. This brings up the LibreOffice macro editor. The macro comes with a default main subroutine. We will not use this subroutine. Highlight Sub main and End Sub and press the backspace key to delete them. Our first macro is a generalized subroutine for opening a form. A generalized subroutine is written for reuse. We will call this routine twice from other routines we write. Type this subroutine into the editor:
Sub OpenAForm (FormName as String) Dim GetForm as Object GetForm = ThisDatabaseDocument.FormDocuments.GetByName(FormName) GetForm.Open End Sub
The first line of the subroutine is called the signature. The signature determines how the subroutine is called. A signature starts with the keyword Sub, which defines this call as a subroutine. Next, the name of the subroutine. In our case, OpenAForm is the name of the subroutine. Finally in the parenthesis, we have the arguments used when calling this subroutine. In our case, we have a variable named FormName which is a type String. In the second line of the subroutine, Dim is another keyword. Dim initializes a variable as a type, and, optionally, a value. We define a variable named GetForm as a type Object. The third line assigns a value to the variable GetForm through a chain of commands in the Uno framework. ThisDatabaseDocument refers to the currently open database document. In our case, book.odb. FormDocuments is a collection of all the forms in the document. Finally, GetByName retrieves a specific form object from the collection. Notice, we pass the variable FormName from the signature to this method. Once the call is complete, the variable GetForm is the object of the form name passed to the subroutine. The fourth line calls the Open method of the form. On the fifth line, we tell Basic this is the end of the subroutine with the command End Sub. We will call the OpenAform subroutine twice. Once to open the authors form, and once to open the media form. Add these two subroutines to your editor:
Sub OpenAuthorsForm(oEv As Object) OpenAForm("Authors") End Sub Sub OpenMediaForm(oEv As Object) OpenAForm("Media") End Sub
The signature on these two subroutines are a little different. Since we will call them from a control within a form, we need to pass the object making the call as an argument, even though we do not use it. The argument oEv is a reference to the object making the call. We will use this to our advantage later, in the last subroutine, but here we do it because it is required. These two subroutines are pretty simple. We just make a call to OpenAForm passing the name of the form we want to open, Authors or Media. The final subroutine deals with our problem of refreshing the data in the list boxes for authors and media when we add authors or media using the two subroutines above:
Sub ListRefresh(oEv as Object) oEv.source.model.Refresh End Sub
Once again, since we will call this subroutine from a control, we need a reference to the control making the call. However, this time we will actually use the object. This subroutine makes a method call to the underlying model of the list box and refreshes the data in the list, thus updating our list of authors or media types. Save your module and close the Basic editor.
Making Connections to Macros
At this point, our macros do nothing. We need to connect them to objects in our form to activate them when needed. First, we will connect the open form subroutines to buttons in our form, and then we will connect the ListRefresh to the list boxes. In the database pane, click on Forms. Right-click the Books form and select edit. Add two push buttons to the form, one under the Authors table and another under the Media table. Right-click the button under the Authors table and select Control to bring up the buttons properties dialog. On the General tab, change the name to AddAuthors and the Label to Add Authors. On the Events tab, click the ellipses (…) button next to Execute Action – which brings up the Assign Action dialog. Click the Macro button to bring up the Macro Selector dialog. In the tree list under Library, select book.odb > Standard > FormCalls. Select OpenAuthorsForm from the Macro Name list and click OK. Click OK to close the Assign Action dialog. Close the buttons properties dialog. Do the same with the button under the Media table, only name it AddMedia, make the label Add Media Type, and assign the macro OpenMediaForm to the Execute Action event. Finally, we need to add the refresh subroutine to our list boxes. Right-click the Authors column in the authors table and select Column. On the Events tab, click the ellipse (…) button beside “When receiving focus”. In the Assign Action button, use the Macro button to assign the ListRefresh macro to the action. This will cause the list to update data from the Authors table when you click on a list box in the column. Do the same for the Media column in the media table. Save your changes to the Books form and close it.
Testing Your Changes
Any time we make changes to our forms, we will want to test them and make sure we got everything right, especially in cases where we have used macros. One simple typo could cause things to not work. Double-click the Books form to open it. Add a new book with an author and media type you have not added already. Click the Add Authors button to make sure it opens the form. Add some authors. Close the Authors form. Click on the authors dropdown list box and verify that the authors you added are there. Do the same test with the Add Media Type button and listbox. Final Thoughts and References
Again, I would like to emphasize that writing macros in LibreOffice Basic is complex. Documentation is pretty sparse, but it is out there. If you are interested in taking up the challenge, here are some references to get you started: LibreOffice Basic Guide: http://wiki.documentfoundation.org/images/d/dd/BasicGuide_OOo3.2.0.odt Andrew Pitonyak's OpenOffice Macro Information: http://www.pitonyak.org/oo.php You can find the macros used in this How-To on pastebin.com at http://pastebin.com/MU2Ztizi Next time, we will move on to another part of the LibreOffice suite and explore the Math module.
Traduzione italiana
Note alla traduzione
Revisione
Note alla revisione