PYTHON-KIVY: Bottoni e interazioni con il codice

Vediamo come far interagire la parte grafica dell’UI con la logica dello script Python. Nell’esempio creiamo un interfaccia grafica con un campo di testo ed un bottone il quale quando verra’ premuto e rilasciato, modificherà il testo.

Prima della pressione sul bottone
Dopo la pressione

Vediamo il file main.py

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty

class finestraPrincipale(BoxLayout):
    bottone = ObjectProperty(None)
    testo = ObjectProperty(None)
    def saluta(self):
        self.testo.text = "Ciao Daniel!"
        
class MainApp(App):
    def build(self):
        #Classe prinmcipale che si occupa di restituire e aggiornare la UI 
        return finestraPrincipale()
    # end def
    

if __name__ == "__main__":
    MainApp().run()

ed il file main.kv

<finestraPrincipale>
    bottone: bottone
    testo: testo

    BoxLayout:
        orientation: "vertical"
        Label:
            id: testo
            text: "CIAO MONDO"
        Button:
            id: bottone
            text: "SALUTA"
            on_release: 
                root.saluta()

Capiamo il funzionamento partendo dal file main.kv. Possiamo subito notare che ogni elemento con il quale vogliamo interagire e’ provvisto di un id:

Questo id deve essere dichiarato all’inizio della sessione <‘classe’> nel file .kv in modo da fare da ‘ponte’ tra il file.kv e il file .py, questo e’ una sorta di riferimento per la comunicazione tra i due file.

Sotto la dichiarazione del Button, vediamo l’evento on_release, che richiamerà il metodo saluta() della classe finestraPrincipale che eseguirà l’azione specificata nel codice del file .py

Nel file main.py ritroveremo i riferimenti testo e bottone, che saranno due variabili a cui assoceremo l’oggetto ObjectProperty della libreria kivy.properties importato in precedenza.

Queste due variabili/oggetti, ci serviranno per interagire con i due widget della UI, infatti alla pressione e rilascio del Button, la scritta “CIAO MONDO” verrà modificata, dal metodo saluta() della classe finestraPrincipale() , in “Ciao Daniel!”

PYTHON-KIVY: file .kv per la costruzione della UI

il file che descrive la struttura dell’interfaccia utente.

Il file .kv e’ un file di testo dove risiedono tutte le istruzioni per la costruzione dell’ interfaccia grafica. Si preferisce usare un file esterno su applicazioni mediamente complesse in quanto questo ci dà la possibilità di separare la parte logica del programma da quella grafica, rendendo tutto molto più leggibile.

Per usare questo metodo ci sono alcune regole da seguire:

  • Il nome del file .kv deve essere tutto in minuscolo
  • il nome deve coincidere con lo stesso nome della classe principale del programma
  • se la classe principale contiene la scritta “App” ad esempio MainApp() il file kv dovrà escludere App, quindi dovrà essere chiamato “main.kv”
  • il file .kv dovra’ essere creato nella stessa directory del file .py

vediamo un semplicissimo esempio “Hello World ! “

file PYTHON main.py:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout

class finestraPrincipale(BoxLayout):
    pass

class MainApp(App):
    def build(self):
        #Classe prinmcipale che si occupa di restituire e aggiornare la UI 
        return finestraPrincipale()
    # end def
    

if __name__ == "__main__":
    MainApp().run()

file KV main.kv

<finestraPrincipale>
    BoxLayout:
        orientation: "vertical"
        Label:
            text: "CIAO MONDO"

Risultato

Cosi some e’ strutturato il programma ora l’applicazione python girerà in un loop infinito in quanto, il metodo .run() della classe MainApp() ereditato da App (dichiarato nella sua costruzione MainApp(App)) genera appunto il loop infinito. Questo loop infinito e’ necessario per il continuo refresh della GUI del programma scritto nel file main.py

PYTHON: Ambiente Virtuale

A cosa servono e come crearli.

Gli ambienti virtuali in python sono ambienti creati per poter installare le librerie necessarie per sviluppare un progetto, senza che vadano ad influire sugli altri progetti, o peggio ancora a danneggiare il sistema operativo principale se questo si basa su python.

Praticamente si crea un ambiente “isolato” dal sistema operativo principale dove possiamo scaricare tutte le librerie che ci servono e sopratutto in diverse versioni, senza intaccare gli altri progetti.

Gli ambienti virtuali si creano in modo diverso se ci si trova in ambiente linux o in ambiente vindows, vediamo come crearli nei due diversi S.O.

LINUX:

A apriamo una shell nella directori del progetto che in questo caso chiameremo MYPROJ

mio_pc: mkdir MYPROJ
mio_pc: cd MYPROJ

mio_pc:~/MYPROY$ python3 -m venv [nomeambiente] (es: myproj)
mio_pc:~/MYPROY$ python3 -m venv myproj
 

Con questo comando si creeranno l’ambiente virtuale generando una nuova serie di directory la principale che avra’ lo stesso nome di myproj e altre sottodirectory e files saranno:

bin, include, lib e due files : lib64 e pyvenv.cfg

A questo punto l’ambiente virtuale e’ pronto ma dovremmo attivarlo prima di poterlo utilizzare, l’attivazione si esegue dando il seguente comando nella directory dell’ambiente:

mio_pc:~/MYPROY/myproj$ source bin/activate

L’ambiente sara’ attivo e la conferma l’avremo in quanto nel prompt comarira’ tra parentesi il nome dell’ambiente virtuale:

(myproj) mio_pc:~/MYPROY/myproj$

Ora possiamo installare tutte le librerie che vogliamo senza andare ad intaccare quelle di sistema.

Se volessimo uscire dall’ambiente virtuale sara’ sufficente dare il comando deactivate in qualsiasi punto della consolle.

WINDOWS:

Per creare ambienti viruali python in windows la procedura e’ leggermente diversa ma il concetto e’ il medesimo. I comandi da dare, sempre dal promt, sono :

c:\>python -m venev [nomeambiente]

cd [nomeambiente]

c:\[nomeambiente]\Scripts\activate

Come si puo vedere cambia solamente il comando per attivare l’ambiente virtuale mente la disattivazione rimane uguale con deactivate

PYTHON: creare, leggere, scrivere files in python

In questo articolo vediamo come gestire la creazione e le altre funzioni di apertura, lettura e scrittura di file di testo nel linguaggio python. Non serve importare librerie in quanto la gestione dei file e’ nativa in python .

Creare o aprire un file.

file=open("nomefile.ext", "w")

Con questo comando cerco di aprire il file nomefile.ext se non esiste lo crea vuoto. Il parametro “w” definisce il modo di apertura del file nel seguente elenco vediamo le diverse opzioni

"a" – apre il file e aggiunge il contenuto alla fine lo crea se non esiste

"w" – apre il file in scrittura sovrascrivendo evenutuali modifiche, se non esiste lo crea

"x" – Crea il file se non esiste, restituisce errore se esiste già

in aggiunta e’ possibile specificare il tipo di file e come esso verra’ gestito:

"t" – File di testo

"b" -file binario , dati , (ad esempio i file immagini)

le opzioni si aggiungono consecutivamente ad esempio :

file = open("fileimmagine.jpg", "rb")

Questo comando aprira il fileimmagine.jpg in sola lettura e lo gestira’ come file binario

Lettura file

Per la lettura di un file di testo si possono usare diverse funzioni . read(), readline() e readlines(). Queste funzioni ovviamente restituiscono dati diversi.

file = open("filedaleggere.txt", "r")
dati = file.read()
print(dati)

read()

Questo codice apre il file in sola lettura e legge tutto il contenuto, compresa la formattazione, mettendolo nella variabile dati che poi sara’ stampato a schermo

readline()

file = open("filedaleggere.txt", "r")
dati = file.readline()
print(dati)

questo modo leggera’ la prima riga e l’assegna alla variabile dati che poi sara’ stampata, per leggere le successive righe del file si dovra’ invocare nuovamente la funzione file.readline().

readlines()

Con questa funzione il contenuto del file letto verra ritornata sottoforma di lista, e i suoi elementi saranno le righe

file = open("filedaleggere.txt", "r")
dati = file.readline()
print(dati)

il codice sopra restituira’ [‘riga1\n’,’riga2\n’, … ‘rigan\n’]

Scrittura

Per la scrittura su file esiste solo una funzione, write(), la scrittura dei dati, sara’ eseguita in base alla modalita’ con la quale e’ stato aperto il file “a” aggiungera’ i dati alla fine del file, “w” cancellera’ il contenuto.

riga = "Riga da scrivere nel file"

file = open("filedascrivere.txt", "w")
dati = file.write(riga)
file.close()

Questo codice apre il file filedascrivere.txt , cancellandolo, se non presente lo crea, poi ci scrive i dati contenuti nella variabile ‘riga’.

JAVASCRIPT: Interazione Javascript e PHP

Interazione Javascript e PHP per realizzare applicazioni client-server e gestione database

Articolo dedicato a come far interagire Javascript e PHP nel mondo del web per poter scrivere delle applicazioni web che interagiscano lato client e server per la manipolazione di dati inseriti dall’utente tramite una pagina web(lato client), come ad esempio un form e un database (lato server) per immagazzinare il dato.

Vediamo il codice HTML che crea il form, tralascio parte del codice html per creare la pagina concentrando l’attensione al puro form.

...

<form id="primoform">
 <input type="text" name="nome">
 <input type="text" name="cognome">
</form>
<button onclick="inviadati()">INVIA</button>

<div id="risultato"></div>
...

<script>
function inviadati(){
    risposta = document.getElementById("risultato");
    form=document.querySelector('#primoform');
    formData = new FormData(form);

    xhttp = new XMLHttpRequest();
    xhttp.open('POST', "saluta.php", false);
    xhttp.onreadystatechange = function (){
       if(this.readyState == 4 && this.status == 200){
         risposta.innerHTML = this.responseText;
       }
    }
   xhttp.send(formData);

}
</script>

Tralasciando la parte del form, alla pressione del <button> invia andrà in esecuzione lo script JS inviadati(). Analizziamo la funzione inviadati(), come prima cosa prendiamo la posizione in cui mettere i risultati finali dell’elaborazione quindi il div con id = ‘risposta’.

l’istruzione successiva si occupa di selezionare il form da cui estrarre i dati nel caso specifico il form con id = ‘primoform’. Ora con questo riferimento istanziamo un nuovo oggetto che conterrà tutti i campi con i relativi valori del form, con l’istruzione new FormData().

Infine con l’oggetto XMLHttpRequest() inviamo tutto allo script PHP saluta.php descritto di seguito.

<?php
$nome = $_POST['nome'];
$cognome = $_POST['cognome'];

echo "ciao ".$nome." ".$cognome." , benvenuto su questo sito";

?>

Il risultato di tutto questo sara’ la stampa a video, nello spezio definito dal div risultato, della frase “ciao nome cognome benvenuto su questo sito”

ESP32: ESP32S2mini V1.0

Questa piccola schedina di appena 3,5×2,5 cm ospita a bordo un microcontrollore ESP32 equipaggiato con 4 MB di flash per i firmware, un processore ESP32-S2FN4R2 con clock a 240Mhz, 2MB di SRAM ,un interfaccia WiFi a 2,4Ghz e BlueTooth e ben 27 GPIO settabili .

PIN OUT

Tutti i pin GPIO possono essere programmati come ADC, DAC, I2C, SPI, UART.

La programmazione può essere eseguita tramite linguaggi :

  • Arduino IDE
  • MicroPython
  • CircuitPython

Programmazione tramite Arduino IDE

La programmazione tramite ide Arduino e’ possibile caricando le librerie per la gestione schede (sulle impostazioni dell’ide) inserendo il link :

http://mcudude.github.io/MiniCore/package_MCUdude_MiniCore_index.json,https://dl.espressif.com/dl/package_esp32_index.json

Selezionando poi nel menu Strumenti->Scheda->ESP32 Arduino->ESP32S2 Dev Module

Collegando la scheda non vedremo accendersi nessun led e la porta non comparira’ nell’elenco del menu Strumenti->porta come se la scheda non venisse riconosciuta.

A questo punto e’ necessario premere, sulla scheda, contemporaneamente i tasti RESET e D per alcuni secondi, poi rilasciare il tasto RESET mantenendo premuto per alcuni secondi il tasto D, ora la porta USB verrà riconosciuta con il nome /dev/ttyACM0.

Adesso possiamo lanciare la compilazione e il caricamento del firmware. Alla fine del caricamento l’ide ci dara’ un errore di reset e ci invitera’ a eseguire un reset hardware della scheda, lanciando cosi il FW caricato. Questo errore e’ stato risolto sulle nuove versioni della scheda.

ATTENZIONE ! Purtroppo non e’ possibile usare la porta USB come uscita seriale, in quanto l’ESP32 quando e’ in modalita’ “running”, non gestisce la USB integrata, pertanto se abbiamo necessita di eseguire il debug o comunque usare delle comunicazioni seriali, dobbiamo attivare una UART convertendola in RS232 o RS485, tramite interfacce UART->RSxxx a 3,3V collegate a due GPIO o tramite translatori di livelli a delle interfaccie TTL->RSxxx

Alimentazione del Modulo

L’alimentazione del modulo può avvenire tramite la porta USB oppure tramite il piedino VBUS, l’alimentazione tramite VBUS deve essere compresa tra 3,3 e 6Vdc massimo.

Attenzione gli ingressi vanno sempre pilotati a 3,3 massimo altrimenti si rischia la “frittura” del chip

Letture ingressi analogici

La lettura analogia degli ingressi non e’ lineare da 0 a 3,3V ma si può raggiungere una buona linearità delle letture nell’intervallo 0.10 -2.50Vdc, pertanto per una lettura precisa di tensioni superiori a 2,5Vdc e’ consigliabile l’uso di un partitore di tensione con resistenze di precisione.

L’esp32-s2 ha 2 convertitori ADC 12 bit pertanto la lettura dei pin restituira’ valori da 0 a 4094.

I pin dal GPIO 1 al GPIO 10 fanno capo al ADC1, mentre i pin GPIO 11-20 fanno capo al ADC2 la tensione di riferimento interna standard e’ di 1,1 V pertanto senza modificarla, via software, sugli ingressi avremmo letture valide nell’instervallo 0 -> 1,1V

MYSQL: Connessione al server

Connettiamoci ad un server locale ed uno remoto.

Attraverso la consolle del sistema operativo (che sia Linux o Windows) e’ possibile accedere facilmente ad un server SQL con un semplice comando. In questa guida usero’ un OS linux .

da terminale eseguiamo :

user@local: mysql -u <utente> -p

Il comando ci fara’ connettere al server MYSQL installato sulla macchina locale e per accedervi ci chiedera’ la password, inserendo la password il prompt della consolle si presentera’ così:

mysql> 

Se volessimo accedere ad un server non locale sarà necessario specificarne l’ip che puo essere locale o remoto con la seguente sintassi

user@local: mysql -h <IP del server> -u <utente> -p

Ora abbiamo a disposizione una lista di comandi con i quali possiamo interagire con il server, dalla semplice query per visualizzare i dati a una serie di comandi per l’importazione ed esportazione delle tabelle o addirittura di un intero database. vediamone alcuni esempi.

Per visualizzare i database presenti sul server:

mysql> SHOW DATABASES;

per entrare in un database :

mysql> USE <nome del database>;

Per visualizzare le tabelle di un database (dopo esserci entrato):

mysql> SHOW TABLES;

Una semplice query per viasualizzare il contenuto di una tabella :

mysql> SELECT * FROM <tabella>

Esistono un infinita’ di comandi per lavorare sui database, questi comandi fanno parte di un linguaggio chiamato SQL, ne vedremo alcuni utili per la gestione dei database da consolle che sono molto utili quando si andra a lavorare con database contententi tabelle molto grosse e ricche di dati, in queste condizioni strumenti tipo phpmyadmin, che sono tools grafici per la gestione dei database, potrebbero entrare in difficolta’ e risultare lenti.

PYTHON: i file di configurazione config-parser

Ci sarà utile , nei programmi da quelli piu’ semplici a quelli piu’ complessi, sfuttare un file di testo editabile dove inserire i dati di configurazione di un programma, ad esempio dove definiamo il nome della porta seriale o i dati di accesso ad un database etc.etc.

Questi file chiamati file di configurazione sono file di testo scritti con una particolare sintassi che vengono caricati dal programma e letti, ricavando cosi’ dei valori da assegnare a delle variabili che poi utilizzeremo nel programma principale. facciamo un esempio.

Creiamo un file di testo che si chiama config.conf:

[PORTASERIALE]
device = /dev/ttyUSB0
speed = 9600

ora creeremo un file che apra una connession alla porta seriale definita nel file config.conf:

import configparser #importo il modulo per la gestione dei file di config
import pyserial #importo il modulo per la seriale

config = configparser.ConfigParser() #creo l'oggetto config
config.read("config.conf") #leggo il file

print(config.sections()) # questa riga stampera tutte le sezioni
print(config['PORTASERIALE']['device'] #questa invece stampera solo il device

dev = config['PORTASERIALE']['device']
baud = config['PORTASERIALE']['speed']

serial = serial.Serial(port = dev,baudrate = baud) #apertura della porta 

...
continuazione del codice per la ricezione dei dati 
...

Il codice con i commenti e’ abbastanza esplicativo, ho ommesso la parte di gestione della seriale in quanto non e’ fondamentale per capire la gestione del parser dei file di configurazione.

PYTHON: if __name__ == “__main__”

Vediamo cosa significa questa sintassi che troviamo spesso negli script python

Prendiamo come esempio due script python uno principale chiamato radice.py e un secondo chiamato secondo.py. Il primo script sara il file che conterra il codice principale della nostra applicazione mentre nel secondo ci saranno delle funzioni secondarie che potranno essere chiamate da radice.py importando secondo.py come modulo.

Vediamo il codice di radice.py:

Vediamo ora come si presenta lo script secondo.py:

Ora vediamo cosa succede se mandiamo in esecuzione lo script radice.py:

Verdiamo che come prima cosa, lo script, stampera’ Secondo Script in quanto alla chiamata import secondo as secondo per l’importazione del secondo script come modulo, lo stesso viene anche eseguito, pertanto se ci sono delle istruzioni fuori dalla definizione di funzioni, queste vengono processate mentre non viene processato quello che e’ contenuto nell’ if __name__ == “__main__”:

Se invece mandiamo in esecuzione direttamente lo script secondo.py:

Come si vede, verranno eseguite sia le istruzioni che non sono contenute dentro le funzioni sia le istruzioni che sono contenute nell’ if __name__ == “__main__”:

Questa e’ la funzione dell’ istruzione if __name__ == “__main__”: , quella di far eseguire determinate istruzioni solo se lo script viene invocato direttamente come programma a se stante e non quando viene chiamato come modulo da un altro script

PYTHON: connessione a un server MySQL

Usiamo la libreria pymysql, per i dettagli vai al sito https://pypi.org/project/pymysql/ per la connessione ad un database che puo essere sulla macchina locale oppure su un server remoto.

Il codice precedente non fa altro che instaurare un collegamento al database istanziando l’oggetto conn, con questo oggetto e’ possibile interagire sul database attraverso i suoi metodi.

Attraverso la print(conn.host_info) stamperemo l’ip e la porta di connessione al server sempre che la connessione sia andata a buon fine

Infine con l’istruzione conn.close() chiudiamo la connessione al server.

Ineragire con mysql

Vediamo un esempio con cui andiamo a leggere i record di una tabella.

idfornitore
1Mario Rossi
2Giuseppe Verdi
3Valerio Bianchi
tabFornitori

Questo codice stampera una tupla con all’interno il primo record dell atabella sopra descritta

Sostituendo l’istruzione result = cursore.fetchone() con l’istruzione result = cursore.fetchall() l’output sara’ una tupla di tuple contenente tutti i record della tabella.