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.

PYTHON: Gestire i file CSV con la libreria CVS

In python esiste la libreria CSV completa per gestire la lettura e scrittura dei file CSV, creando una lista per ogni riga del file letto ed accetando in ingresso una lista/tupla per ogni riga da scrivere.

Vediamo con un esempio la lettura di alcuni dati meteo e la conversione della temperatura da gradi celsius a gradi Fahrenheit.

Il file CSV in ingresso :

I commenti al codice spiegano tutto, in sostanza viene caricato il file datimeteo.csv visualizzato nell’immagine precedente, con il caricamento si ottiene un oggetto iterabile che tramite il for viene iterato riga per riga. Ad ogni iterazione il valore della temperatura che risiede nell’elemento 2 della lista cvs_reader, viene passato come argomento alla funzione convFareneit() la quale ritorna il valore di temperatura convertito.

A questo punto sempre durante l’iterazione della riga vengono copiati gli altri valori in una lista di tuple che poi useremo come fonte dati per la generazione del nuovo file CSV.

L’uso del comando try:/except ,consente allo script di non bloccarsi durante la lettura della prima riga del file dove risiedono i nomi dei campi, infatti la funzione convFareneit() tenterebbe di convertire il valore letto ‘temp’ in un numero float, generando un errore e bloccando lo script.

Alla fine dell’iterazione di tutte le righe viene creato un nuovo file CSV ed iterando la lista di touple creata con il nome di newdataset scriviamo riga per riga i nuovi valori. Il risultato nell’immagine sotto:

Il codice non e’ ottimizzato, infatti la conversione si potrebbe fare anche tramite delle funzioni comprension, ma lo scopo principale di questo articolo e’ quello di mostrare la lettura e scrittura di file CSV.

JAVASCRIPT: Alert e Conferma

alert()

Come inserire un pupup di alert o conferma in una pagina HTML o PHP per eseguire un comando javascript o un comando derivato da una chiamata javascript? Vediamo i codici.

E questo e’ il risultato

Cliccando sul bottone “CHIEDI CONFERMA” apparira’ il popup sopra con la possibilita’ di premere solamente OK e far procedere lo script della funzione chiediconferma().

confirm()

il confirm invece da’ la possibilita’ di dare o meno la conferma al comando, vediamo il codice

che produrra’

Il codice javascript fara comparire il popup e chiedera’ se confermare o meno l’azione, se l’utente preme su OK la condizione dell’ if(test) sara’ vera ed eseguira’ il codice conseguente , altrimenti verra’ eseguito il codice compreso nell‘else.

prompt()

Con questo metodo, oltre che hai due pulsanti Annulla e OK sara’ presente anche un campo editabile dove inserire una stringa.

A questo punto oltre che a verificare l’avvenuta pressione del tasto OK l’if verifichera’ che il nome inserito sia “Mario” , se fosse qualsiasi altro nome o venisse premuto il tasto Annulla il codice eseguito sara’ quello dell’ else

PYTHON: list-set-dictionary comprehension

Le comprehension (comprensione) e’ una forma di scrittura del codice, che serve ad ottimizare la generazione di liste, set e dizionari la sua sintassi e’ la seguente

per le liste:

lista = [ <espressione sulla variabile> for <variabile> in <input_> <filtro opzionale> ]

per le set:

lista = { <espressione sulla variabile> for <variabile> in <input_> <filtro opzionale> }

per i dictionary:

dic = { <espressione(variabile Key): espressione(variabile Value)> for variabile Key,variabileValue in <input_key, input_value> <filtro opzionale> }

Dettagli dei parametri:

  • <espressione sulla variabile> e’ un esperssione matematica o una funzione che agisce sul valore della variabile ricavato dal <input_> il quale puo essere una qualsiasi struttura dati o funzione
  • <input_> struttura o funzione (es. range()) che fa da base dati per la generazione della nuova struttura dati
  • <filtro opzionale> e’ una condizione if che se rispettata scrvie il dato nella nuova struttura, altrimenta la scarta.

Vediamo alcuni esempi :

#genero una set di divisi per due
list1 = [12,13,14,15,16,17,18]
set2 = {x/2 for x in list1}
print(set2)

#genero una lista di divisi per due sono se interi 
list2 = [12,13,14,15,16,17,18]
set3 = [x/2 for x in list2 if x%2 == 0]
print(set3)

#genero un dizionario delle temperature massime per mese
mesi = [('GENNAIO',-1),('FEBBRAIO',-2),('MARZO', 4),('APRILE',9)]
temp_mesi = { m: t for m,t in mesi  }
print(temp_mesi)

#genero un dizionario dei mei con temperature massime sotto 0
temp_mesi_freddi = { m: t for m,t in mesi if t < 0}
print(temp_mesi_freddi)

######risultati 
{6.0, 7.0, 8.0, 7.5, 6.5, 8.5, 9.0}
[6.0, 7.0, 8.0, 9.0]
{'GENNAIO': -1, 'FEBBRAIO': -2, 'MARZO': 4, 'APRILE': 9}
{'GENNAIO': -1, 'FEBBRAIO': -2}

PYTHON: Iteratori Customizzati

Sono Iteratori creati ad-hoc dal programmatore, praticamente sono delle CLASSI che implementano almeno i due metodi __iter__() e __next__()

nel metodo __iter__() Avviene l’inizializzazione dell’iteratore e il suo return (di solito viene ritornato l’oggetto stesso)

nel metodo __next__() ritorna il prossimo elemento nella sequenza e solleva l’eccezione StopIteration alla fine degli elementi

Facciamo un esempio di un iteratore che ad ogni chiamata restituise il valore precedente aumentato di 1.44 partendo da 0

class numeri:
    #inizializzo l'iteratore partendo da 0
    def __iter__(self):
        self.x = 0
        return self

    #calcolo valore successivo restituito ad ogni chimata next(<oggetto>)
    def __next__(self):
        a = self.x
        self.x += 1.44
        return round(a,2)

oggetto = numeri()

#converto in iteratore
test = iter(oggetto)
#scorro iteratore
for i in range(0,100):
    print(next(test))

I commenti al codice dicono tutto, l’unica cosa e’ che questo iteratore non finira’ mai di generare in quanto nella dichiarazione del metodo __next__() non c’e’ limite, pertanto lanciando un for i in range(oggetto) il ciclo durerebbe all’infinito. Se ad esempio volessimo fermare la generazione al numero superiore a 144.00 dovremmo modificare il codice nel modo seguente:

class numeri:
    def __iter__(self):
        self.x=0
        return self
    def __next__(self):
        a = self.x
        self.x +=1.44
        if(a <= 144):
            return round(a,2)
        else:
            StopIteration
    
oggetto = numeri()

test = iter(oggetto)

for i in range (0,120):
    print(next(test))

In fine vediamo un esempio di iteratore customizzato con la possibilita’ di passergli dei parametri (esempio range(0,100):

class numeriDispari(object):
    def __init__(self, max):
        self.max = max #imposto il valore massimo
        self.n = -1 #imposto la partenza che sara sempre 1 
    
    def __next__(self):
        self.n += 2 #incremeto di 2 il valore precedente 
                    ( all inizio self.n = -1, quindi self.n + 2 = 1)
        if self.n > self.max:
            raise StopIteration #se supero il valore max fermo l'iterazione
        else:
            return self.n #altrimenti rimando il valore calcolato
    def __iter__(self):
        return self
    
#stampo i primi 10 numeri dipsari
numeri = numeriDispari(10)
for n in numeri:
    print(n)
#creo una lista dei primi 80 numeri dipari
numeri_d = [ x for x in numeriDispari(100) if x < 80]
print(numeri_d)

I commentio nel codice spiegano il funzionamento

PYTHON: Iterabili e iteratori

In python i concetti iterabile e iteratori possono essere cosi descritti:

Iterabile: Oggetto o struttura dati (liste,touple etc etc) che puo essere trasformato in un iteratore, un altro esempio di iterabile sono le stringhe. l’oggetto iterabile rimane in memoria e puo’ essere usato in qualsiasi momento durante l’uso nel codice

Iteratore: Oggetto o struttura dati che puo’ essere ‘attraversato, scandito’ con i metodi __iter()__ e __next()__ e “ricoda” il suo stato mentre si attraversa. L’oggetto iteratore, una volta “attraversato” viene eliminato e quindi non e’ possibile riutilizzarlo o scorrerlo avanti e indietro. In generale un iteratore non genera i dati che ha dentro di se ma tiene traccia della loro posizione nella fonte da cui li preleva

Facciamo un esempio con una stringa che e’ un oggetto iterabile:

str = "ciao daniel"
print(str)

str_iterabile = iter(str)
print(str_iterabile)

Questo codice restituira’ :

ciao daniel

<str_iterator object at 0x7f421ca85278>

Come vediamo la prima print stampa correttamente la stringa mentre la seconda stampera’ la locazione di memoria dell’oggetto iterabile. per stampare il contenuto dell’oggetto str_iterabile dovremmo usare il metodo next()

str = "ciao daniel"
print(str)

str_iterabile = iter(str)
print(next(str_iterabile))

che restituira’:

ciao daniel
c

Quali sono i principali vantaggi nell’uso di un iteratore?

il principale vantaggio sta’ nel occupare poca memoria nel trattare molti dati, ad esempio la lettura di un file CSV tramite un iteratore legge ed elabora una riga alla volta per poi passare alla successiva ‘dimenticandosi’ dei dati precedenti

PYTHON: generatori

I generatori sono delle speciali funzioni che restituiscono un iterabile, un esempio di generatore e’ la funzione range(x,y,z) usata per generare una sequenza di interi che parte da x fino ad y con passo z.

ad esempio la chiamata range(0,10,1) assegnata al comando print mi crea una lista di valori da 0 a 10 con passo 1

x = range(0,10,1)
print(list(x)

Questo codice restituira una lista [0,1,2,3,4,5,6,7,8,9]

Creiamo adesso un generatore che restituisca una lista di valori calcolati

def generatore(x):
    for y in range(0,x)
    y = y - 1
    yield y

test = generatore(4)
print(list(test))

Questo codice resittuira’ una lista [-1,0,1,2]

Vediamo di capire come funziona. Alla prima chiamata di test = generatore(4) entro nella funzione generatore(x), la funziona mi genera un elenco di naturali che partono da 0 a 4, al primo ciclo y vale 0 -1 = -1, al secondo giro di for y = 1 -1 = 0 e cosi’ via.

Scrittura dei generatori in modalita’ COMPREHENSION

La modalita’ comprehension (compressa) e’ una modalita di scrittura in python molto utilizzata sia nei generatori che nelle creazione di strutture dati tipo liste, touple dizionari etc etc. vediamo ora come scrivere lo stesso generatore di prima in modalita’ comprehension:

test= ( y-1 for y in range(10))
print(list(test))

Queste due righe daranno come risultato lo stesso di quello precedente!