-
OSMQuake
Pubblicato il luglio 23rd, 2009 Nessun commentoA quasi tre mesi dalla presentazione ufficiale ad OSMit, pubblico finalmente il codice di OSMQuake purtroppo ancora incompleto e con il codice ancora molto sporco e incasinato (l’ho scritto in tre ritagli di tempo la sera tardi).
Ho aspettato così tanto perché mi sarebbe piaciuto completare alcune parti del software che avevo implementato soltanto in parte purtroppo però in questo periodo non ho molto tempo e preferisco pubblicare il codice in modo che chiunque voglia contribuire (anche per disegnare un logo ad esempio) possa farlo.
Il codice sorgente si trova attualmente qui, se qualcuno volesse collaborare posso metterlo su google code e usare svn per la gestione della versione.
Questo è il risultato dell’elaborazione di stamattina sull’Italia centrale.
Già dalla mappa è possibile vedere cosa manca:
- Il raggio del marker è direttamente proporzionale alla magnitudo ma il colore dovrebbe essere inversamente proporzionale al tempo, cosicchè i terremoti più recenti siano di un rosos più intenso.
- Sarebbe bello avere una didascalia con qualche indicazione riguardo i range di dimensioni e di colori e delle statistiche generate automaticamente
Per generare la mappa precedente basta avviare OSMQuake e poi premere sul tasto “Scarica” per effettuare il parsing della pagina e salvare gli eventi in un database sqlite (notare in basso a sinistra il numero degli eventi scaricati):
A questo punto si possono scegliere i parametri di filtraggio, lo zoom della mappa e il tipo di mappa (Mapnik, Osmarender e OpenArial) e si clicca su Genera mappa. A questo punto il software mostra le tile da scaricare e le dimensioni della mappa in pixel e inizia a scaricare le tile necessarie. Dopo di che le unisce e disegna sopra la mappa i marker calcolando dinamicamente il raggio.
Il risultato finale è una nuova finestra con la mappa:
Cosa funziona in OSMQuake:
- Parsing della pagina
- Riempimento del database con gli eventi
- Filtraggio per magnitudo
- Filtraggio per profondità
- Scelta dello zoom
- Scelta del server
- Calcolo delle tile da scaricare
- Calcolo delle dimensioni della mappa in pixel
Cosa non funziona (ancora!) in OSMQuake:
- Filtraggio degli eventi in base alla distanza da un punto geografico
- Calcolo dell’area coperta dalla mappa
- Filtraggio in base alla regione (ho già i bbox delle regioni italiane che mi ha dato Niccolò Rigacci ma non ho avuto il tempo di creare un dizionario con i bbox)
- Per generare una nuova mappa con la stessa istanza è necessario cancellare a mano le tile (io uso uno script in bash)
- Prima di scaricare di nuovo gli eventi è necessario cancellare il file del database (il file prova)
Cosa sarebbe mi piacerebbe implementare in OSMQuake:
- Riscrivere il codice ad oggetti
- Implementare il threading per lo scaricamento delle tile (la policy del tile server di OpenStreetMap permette solo due thread)
- Permettere di mantenere un database storico degli eventi e di filtrarli anche per periodo per creare delle mappe mensili o settimanali di una determinata zona
- Permettere l’esportazione deglio eventi sismici in KML
Qualsiasi contributo è benaccetto!
-
OSMit 2009
Pubblicato il giugno 9th, 2009 Nessun commentoChe dire di OSMit 2009? Semplicemente un’esperienza fantastica che ha riunito buona parte delle persone che gravitano intorno al progetto.
Guest star è stato il fondatore stesso di OpenStreetMap – Steve Coast – con cui non poteva mancare una foto che è stato così gentile sa spiegarmi personalmente come funziona il tile cache server personalizzato di Cloudmade.
Durante i due giorni della conferenza si sono discussi temi importanti e ci sono state dimostrazioni reali di possobili applicazioni di mappe e dati messi a disposizione dal progetto OpenStreetMap.
Io ho presentato il software OSMQuake, di cui a breve rilascerò il codice, per visualizzare gli ultimi eventi sismici dell’Istituto Nazionale di Geofisica sulle mappe di OpenStreetMap.
Di seguito poteve visualizzare le slide con slideshare e da scaricarle da qui.
-
Visualizzare gli ultimi eventi sismici dal sito INGV (usando OpenStreetMap)
Pubblicato il aprile 18th, 2009 11 commentiStamattina un amico (TheDom), studente dell’Università dell’Aquila fortunatamente scampato al terremoto, mi ha chiesto di aiutarlo a creare uno script che si interfacciasse con il sito dell’Istituto Nazionale di Geofisica e Vulcanologia e che visualizzasse i dati degli ultimi eventi sismici e restituisse un link ad OpenStreetMap per visualizzare la cartina.
Guardando il codice dell’homepage del sito mi sono accorto che i singoli eventi erano racchiusi nel tag <tr class=”print_light”> e i dati dell’evento erano racchiusi nei tag figli <td class=”td_events”>.
<tr class="print_light" [...]> <td class="td_events">1206577780</td> <td class="td_events"> </td> <td class="td_events">2009/04/11</td> <td class="td_events">16:18:34</td> <td class="td_events">42.264</td> <td class="td_events" width="45px">13.486</td> <td class="td_events">9</td> <td class="td_events">Ml:2.8</td> <td class="td_events"> </td> <td class="td_events">Valle_dell'Aterno</td> </tr>
Considerata la regolarità del codice, ho sfruttato le potenti funzionalità del modulo di parsing BeautifulSoup, per raccogliere facilmente i dati dal sito.Il cuore dello script è costituito dalla funzione DataCollect che, preso il codice della pagina in input, trova tutti i tag che corrispondono a <tr class=”print_light”>. In seguito, cercando all’interno dei singoli tag <tr>, restituisce, sotto forma di lista, il testo contenuto nei tag figli <td>.
def DataCollect(pagina,id): """Restituisce una lista con i dati desiderati""" lista = [] dati = pagina.findAll('tr',attrs={"class":"print_light"})[id] dati = dati.findAll('td',attrs={"class":"td_events"}) for i in dati: lista.append(i.string) return lista
La riga di codice numero 4 trova tutti i tag tr avente gli attributi definiti nel dizionario {“class”:”print_light”} passato come variabile. Considerando che l’istanza findAll dell’oggetto pagina restituisce, sotto forma di tupla, il contenuto dei singoli tag tr, è possibile accedere al contenuto di un solo tag tr usando gli indici della tupla (il numero tra parentesi quadre). Dopodiché è possibile rieseguire una seconda istanza findAll sull’oggetto dati (riga 5), che come abbiamo visto in precedenza contiene solo il contenuto di un solo tag, cercando questa volta tutti i tag td. A questo punto l’oggetto dati è una tupla contenente tutti i tag td, figli del tag tr (quelli mostrati nel codice html precedente). Infine basta iterare all’interno di questa tupla (riga 6), assegnando ad una lista (inizializzata alla riga 3) il contenuto dei signoli tag td ottenuti attraverso l’istanza string (riga 7).La funziona Parsing legge semplicemente il contenuto della pagina html e lo passa a BeautifulSoup per l’elaborazione.
def Parsing(link): """Restituisce il parsing della pagina""" try: socket = urlopen(link) testo = BeautifulSoup(socket.read()) socket.close() except: return ("""Si è riscontrato un errore durante l'apertura del link, prima \ di procedere:\t 1) controllare la connessione ad internet\t 2) assicurarsi che il link esista\t 3) assicurarsi che il link sia scritto correttamente (ricordarsi di scrivere \ anche http://)\t 4) controllare i permessi per accedere alla rete.""") return testo
Alla riga 5 la funzione apre il link dell’home page dell INGV e alla riga 6 l’istanza read(), che restituisce il contenuto html della pagina, viene passata all’elaboratore BeautifulSoup.Infine l’ultima funzione, formatta l’output in maniera colorata e più “umana” sfruttando il modulo scritto da Checkm.
def HeartquakePrint(lista): """Formatta e stampa i dati dell'evento sismico""" print cms.color("<red>Dati riepilogativi evento sismico</red>") print cms.color("<green>Link diretto:</green> <yellow>http://cnt.rm.ingv.it/~earthquake/data_id/%s/event.php</yellow>") % lista[0] print cms.color("<green>Data:</green> <yellow>%s</yellow>") % lista[2] print cms.color("<green>Ora:</green> <yellow>%s</yellow>") % lista[3] print cms.color("<green>Latitudine:</green> <yellow>%s N</yellow>") % lista[4] print cms.color("<green>Longitudine:</green> <yellow>%s E</yellow>") % lista[5] print cms.color("<green>Link OpenStreetMap:</green> <yellow>http://www.openstreetmap.org/?lat=%s&lon=%s&zoom=17&layers=B000FTF</yellow>") % (lista[4],lista[5]) print cms.color("<green>Magnitudo:</green> <yellow>%s</yellow>") % lista[7] print cms.color("<green>Distretto sismico:</green> <yellow>%s</yellow>\n") % lista[9]Il modo più semplice per eseguire lo script (sia su windows che su linux) è quello di scaricare l’archivio contenente tutti i file necessari all’esecuzione da qui. Scompattarlo ed eseguirlo digitando in un terminale:
$: python script.py
Questo è il risultato finale:
-
Pycp: usare cp con una progress bar
Pubblicato il aprile 11th, 2009 Nessun commentoPer quanti usano ancora il comando del terminale cp per copiare i file risuslterà comodo installare pycp, un wrapper di cp scritto in python che implementa una progress bar tetstuale per ogni singolo file trasferito.
E’ molto comondo nel caso di trasferimento di grosse cartelle, in cui il cursore rimane immobile (sembra quasi bloccato) fino a trasferimento completato. Con pycp è possibile vedere, oltre alla progress bar, anche la velocità di trasferimento e l’ETA (estimated time of arrival) di ogni singolo file!
Per installarlo è necessario scaricare ed installare prima il modulo python-progressbar:
$: wget http://pypi.python.org/packages/source/p/progressbar/progressbar-2.2.tar.gz
$: tar xvf progressbar-2.2.tar.gz
$: cd tar xvf progressbar-2.2.tar.gz
$: sudo python setup.py install
A questo punto scarichiamo ed installiamo pycp:
$: wget http://yannick-lm.dyndns.org/soft/pycp/pycp-3.2.tar.gz
$: tar xvf pycp-3.2.tar.gz
$: cd tar xvf pycp-3.2.tar.gz
$: sudo python setup.py install
Per evitare di ricordarsi di digitare pycp al posto di cp è possibile creare un alias per la nostra shell, editando il file ~/.bashrc:
$: vim .bashrc
Inserendo la riga:
alias cp=’pycp’
Carichiamo le modifiche:
$: source .bashrc
In questo modo al comando cp verrà automaticamente sostituito pycp.
-
Utilizzare sul proprio pc TangoGPS e le mappe di OpenStreetMap
Pubblicato il agosto 18th, 2008 2 commentiSe inserire le mappe di OpenStreetMap nel proprio sito/blog è una grande soddisfazione, soddisfazione ancora più grande è vedere le mappe di OpenStreetMap funzionanti su un navigatore GPS.
Nella mailinglist italiana di OpenStreetMap si parlava di OpenMoko e di TangoGPS, il navigatore per palmari scritto in python
che utilizza le mappe di OSM, e ovviamente io non potevo resistere alla tentazione di provare il navigatore sul mio pc utilizzando l’antenna esterna che uso per raccogliere le tracce e una penna bluetooth da due soldi.Se usate Ubuntu (o Debian) è possibile scaricare il pacchetto .deb direttamente dal sito (link diretto) e poi da terminale digitare:
$: sudo dpkg -i tangogps_0.9.2_i386.debUna volta installato il software dobbiamo solo collegare l’antenna al demone che gestisce il gps (gpsd), per farlo ho seguito pedissequamente l’ottima guida del blog di michelem.
Una volta configurato il tutto (basta seguire la guida che non riporterò qui) ho avviato TangoGps e mentre iniziavo a cercare il pulsante per scaricare le mappe il software si è agganciato all’antenna e ha scaricato automaticamente le mappe di OpenStreetMap, fenomenale!
Ecco uno screenshot (click sull’immagine per ingrandire), il cerchietto blu è dove si trova la finestra della mia stanza… precisissimo!
Forza che aspettate, correte fuori di casa e mappate tutto quello che vi capita a tiro per avere la soddisfazione di utilizzare le mappe che avrete contribuito a creare.
-
Trasformare in massa tracce igc e nmea in tracce gpx
Pubblicato il agosto 17th, 2008 3 commentiDurante l’openstreecamping2008 abbiamo avuto la necessità di trasformare, con gpsbable, le decine di tracce igc, il formato di tracking che utilizza il cellulare di Fradeve, raccolte durante i giri in bici in formato gpx che è il formato utilizzato da josm.
Dopo qualche giorno ci siamo resi conto che era noioso ridigitare ogni volta il comando dal terminale (ovviamente non tutto, ma modificando semplicemente il nome del file nel comando precedente) e potevamo perdere tempo prezioso in questo modo? Ovviamente no!
Mentre Fradeve leggeva la biografia di Torvalds (ve la consiglio) e il caldo era insopportabile, ho scritto un piccolo script in python per convertire in massa file igc e nmea in file gpx.
Credo sia possibile farlo anche in bash, ma non conoscendo il bash ho preferito usare il python e in particolare il modulo os, contenuto nella libreria standard, che permette al programma di interfacciarsi con il sistema operativo.
Clic qui per scaricare lo script
Qualche commento al codice:
if formato in ListaFormati : ListaFile = CercaFile(os.listdir('.') , formato) else : print "Formato inesistente o non ancora implementato, esco dal programma." exit()Controlla il formato passato come argomento al programma e, se corretto (i formati accettati sono igc e nmea), restituisce una lista, attraverso la funzione os.listdir(cartella), con tutti i file contenuti nella cartella passata come argomento.
def CercaFile(lista, flag): for i in lista: if flag in i: gpx.append(i) return gpxLa funzione CercaFile restituisce una nuova lista contenente soltanto i file con l’estensione interessata (igc o nmea), eliminando tutti gli altri file inutili.
if ListaFile != []: c = 0 for i in ListaFile: stringa = "gpsbabel -i " + formato + " -f '" + i + "' -o gpx -F '" + i[0:-3] + "'gpx" os.system(stringa) c = c + 1 print "Ho trasformato " +str(c)+ " file in gpx ed ho cancellato i file " + formato + "" else: print "Non ci sono file da convertire, ciao!"Controlla che ci siano file da convertire, in caso positivo passa al sistema, attraverso il la funzione os.system, il comando gpsbabel necessario alla conversione dei file. La stringa che può sembrare complicata serve a trasformare i file mantenendo il nome originale.
Per eseguire lo script basta copiare i file da trasformare nella stessa cartella dove è presente lo script e poi da terminale digitare:
$: python trasforma.py formatodove formato deve essere sostituito con igc o con nmea a seconda del formato di partenza dei file.
Semplice, veloce ed efficace a patto di aver gpsbabel installato, ovviamente!
-
Estrapolare dati dai file gpx
Pubblicato il luglio 31st, 2008 6 commentiDopo l’avventurosa e faticosissima biciclettata di sabato scorso sulla strada che porta a Castel del Monte (foto), che ovviamente abbiamo mappato (permalink osm), mi sono chiesto quale fosse la variazione di pendenza che le nostre povere gambe hanno dovuto sopportare e mi sono subito messo all’opera per scrivere un rudimentale parser in Python sfruttando il modulo BeautifulSoup (installabile dai repository di Ubuntu)
Avendo più tempo a disposizione mi piacerebbe scrivere l’interfaccia grafica del programmino e far disegnare il grafico ad uno dei potenti widget di wxPython, ma purtroppo adesso devo accontentarmi di questo script molto semplice ma al tempo stesso efficace.
Clic qui per scaricare lo script.
Anche se lo script è semplicissimo aggiungo qualche commento:
</code> try: NomeFile = sys.argv[1] except: print "Argomento mancante o non valido" exit()
Controlla che il nome del file sia stato passato come argomento.
</code> try: gpx = open(NomeFile,'r') except: print "Impossibile leggere il file, controllare che lo stesso esista e che sia leggibile" exit()
Tenta di aprire il file gpx passato come argomento.
</code> xml = gpx.read() gpx.close() soup = BeautifulStoneSoup(xml) dati = open('dati.txt','w') n = 0 for i in soup.findAll('ele'): dati.write(i.string + '\n') n = n + 1 dati.close()Il file viene letto e il suo contenuto, salvato nella variabile xml, viene passato al parser xml di BeautifulSoup, a questo punto viene invocata la funzione findAll che restituisce una lista contenente tutti i tag <ele> (compreso il contenuto dei tag).
L'istanza string, richiamata sui singoli elementi della lista, restituisce solo il contenuto dei tag <ele> senza il tag stesso, infine i contenuti vengono salvati su un file txt separati da un carriage return.
Per eseguire correttamente lo script è sufficiente eseguire lo script digitando da terminale:
$: python altitudine.py nomefile.gpx
e poi ricopiare i valori del file dati.txt in un foglio di calcolo e far elaborare il grafico dal software (ovviamente consiglio sempre di utilizzare OpenOffice.org - Calc).
Questo è il grafico elaborato dai gpx del percorso verso Castel del Monte (clic per ingrandire):
-
Montare partizioni remote con pyNeighborhood
Pubblicato il giugno 20th, 2008 Nessun commentoGli utenti Gnome che, come me, sono passati a Xfce sentiranno la mancanza di un tool grafico che permetta il mount delle partizioni remote di Windows.
Si potrebbe confezionare un bash script che, utilizzando il comando mount.smbfs, monti le partizioni remote ogni volta che ne abbiamo bisogno,però se si cambia spesso rete oppure la rete è molto complessa (come quella mostrata dall’immagine presa dal sito del programma) lo script andrebbe riadattato oppure andrebbe modificato in modo da scegliere quali partizioni remote montare (usando smbclient -L).
Mentre aspettiamo che le funzionalità di mount remote vengano implementate in Thunar, possiamo utilizzare un programmino scritto in Python: pyNeighborhood.Il programma è presente nei repository di Xubuntu per cui per installarlo basta digitare da un terminale:
$: sudo apt-get install pyneighborhood mcPer qualche oscuro motivo è necessario installare, anche se non è tra le dipendeze necessarie, il file-manager midnight commander (pacchetto mc) per far fuzionare correttamente pyNeigborhood.
L’installazione crea anche l’icona nella categoria rete, però avviando il programma dal menù non è possibile montare nessuna partizione sia perché pyNeigborhood non ha i privilegi necessari ad eseguire il mount sia perché è necessario creare prima la cartella di mount.
Per ovviare è necessario:- modificare la voce di menù, con un terminale e i privilegi da amministratore apriamo il file /usr/share/applications/pyNeighborhood.desktop
$: sudo mousepad /usr/share/applications/pyNeighborhood.desktop- modifichiamo la stringa Exec=pyNeighborhood in Exec=gksu pyNeighborhood, in questo modo il programma verrà avviato con i permessi necessari al suo funzionamento
creare la cartella in cui effettuare il mount (di default /mnt/Network):
$: sudo mkdir /mnt/NetworkCome usare pyNeighborhood
Al primo avvio del programma è necessario scansionare i gruppi di lavoro, per farlo basta fare clic con il pulsante destro sull’icona Groups e selezionare la voce Scan using msbrowse, alla fine della scansione cliccare sul gruppo desiderato e avviare una nuova scansione per rilevare i dispositivi appartenenti al gruppo.
Cliccare su uno dei dispositivi della lista e avviare la scansione per rilevare le partizioni condivise, fare clic con il destro sulla partizione da montare e selezionare mount.That’s all!
-
Salvare la banca dati Inran in un file sqlite3
Pubblicato il aprile 29th, 2008 2 commentiGiocherellando con i moduli di python per la gestione dei database sqlite3, per il parsing delle pagine web e con le espressioni regolari ho scritto un piccolo programmino che permette di effettuare l’html screen scraping delle pagine componenti la banca dati dell’Inran e di salvare i dati riguardanti la composizione nutrizionale di 790 alimenti in un database ordinato sqlite3.
Ho pensato di pubblicare il programma, con licenza GPL3, pensando che possa essere utile a qualcuno, comunque ho già cominciato a scrivere l’interfaccia grafica per accedere ed elaborare i dati (una specie di calcolatore di calorie) sperando che possa tra qualche tempo entrare a far parte del programma per la gestione e l’archiviazione delle ricette che ho intenzione di scrivere.
</p> <p style="text-align: left;">#! /usr/bin/python #-*- coding: utf-8 -*- # Script per effetuare il parsing delle pagine dati INRAN e per # salvare i dati in maniera ordinata in un database SQlite3 # Copyright (C) 2008 Alessandro De Noia <alessandro .denoia@gmail.com> # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import re, sqlite3, string from BeautifulSoup import BeautifulSoup from time import time from urllib import urlopen def NormalizeStr(FoodStr): """Restituisce la stringa senza il commento tra parentesi quadre e senza apici Return a new string without the comment in the square brackets and without the apices """ if string.find(FoodStr, "[") == -1: NewFoodStr = FoodStr else: NewFoodStr = FoodStr[0:(string.find(FoodStr, "[")-1)] return string.join(string.split(NewFoodStr,'\''),"\\''") def NormalizeNum(DataNum): """Restituisce un numero float cambiando la virgola in punto o altrimenti cambia la stringa None nel valore NULL Return a float number turning the comma into a dot or else change the string None into the value NULL""" if string.find(DataNum, ",") != -1: NewDataNum = round(float(string.join(string.split(DataNum,","),".")),2) elif (DataNum == "None") or (DataNum == "tr") or (DataNum == " "): NewDataNum = -1.00 else: NewDataNum = round(float(DataNum),2) return NewDataNum def Database(): """Crea, popola e riempie il database con i dati acquisiti Create, populate and fill the database with the acquired data""" data = ['']*22 rows = ('inran_id', 'pe', 'acqua', 'proteine', 'lipidi', 'carboidrati', 'amido', 'zucchero', 'fibra', 'energia_c', 'energia_j', 'sodio', 'potassio', 'ferro', 'calcio', 'fosforo', 'tiamina', 'riboflavina', 'niacina', 'vit_a', 'vit_c', 'vit_e') categories = ('cereali', 'legumi', 'verdure', 'frutta', 'carni_fresche', 'carni_trasformate', 'fast_food', 'frattaglie', 'pesca', 'latte', 'formaggi', 'uova', 'olii', 'dolci', 'vari', 'alcooliche') Nid = 0 conn = sqlite3.connect("inran") cur = conn.cursor() cur.execute("""CREATE table inran (id INTEGER PRIMARY KEY, inran_id FLOAT, categoria VARCHAR NOT NULL, alimento VARCHAR NOT NULL, pe FLOAT DEFAULT 100, acqua FLOAT DEFAULT NULL, proteine FLOAT DEFAULT NULL, lipidi FLOAT DEFAULT NULL, carboidrati FLOAT DEFAULT NULL, amido FLOAT DEFAULT NULL, zucchero FLOAT DEFAULT NULL, fibra FLOAT DEFAULT NULL, energia_c FLOAT DEFAULT NULL, energia_j FLOAT DEFAULT NULL, sodio FLOAT DEFAULT NULL, potassio FLOAT DEFAULT NULL, ferro FLOAT DEFAULT NULL, calcio FLOAT DEFAULT NULL, fosforo FLOAT DEFAULT NULL, tiamina FLOAT DEFAULT NULL, riboflavina FLOAT DEFAULT NULL, niacina FLOAT DEFAULT NULL, vit_a FLOAT DEFAULT NULL, vit_c FLOAT DEFAULT NULL, vit_e FLOAT DEFAULT NULL)""") for category in categories: try: socket = urlopen('http://www.inran.it/servizi_cittadino/per_saperne_di_piu/tabelle_composizione_alimenti/composizione/'+category) except: print("Impossible to resolve the host, please check internet connection") exit() page = BeautifulSoup(socket.read()) socket.close() food = page.findAll('td', {"class":re.compile("descrizione_[1-2]")}) FoodData = page.findAll('td', {"class":re.compile("dato_[1-2]")}) n = 0 for i in food: StrSql = ("""INSERT INTO inran (id, categoria, alimento) VALUES (%d,'%s','%s')""") % (Nid, category, NormalizeStr(i.string)) cur.execute(StrSql) data = FoodData[(22*n):(22*(n+1))] m = 0 for k in data: StrSql2 = ("UPDATE inran SET %s=%f WHERE id=%d") % (rows[m], NormalizeNum(str(k.string)), Nid) cur.execute(StrSql2) m = m + 1 n= n + 1 Nid = Nid + 1 cur.close() conn.commit() conn.close() time1 = time() print("-------------------------------------------------------------") print("Sto creando il database, attendere") print("-------------------------------------------------------------") Database() time2 = time() print("-------------------------------------------------------------") print("Database creato in %f secondi") % (time2 - time1) print("-------------------------------------------------------------") <p style="text-align: left;">Scaricate il file da qui e poi eseguitelo da un terminale semplicemente digitando (è necessario avere installato il modulo BeautifulSoup dai repository di Ubuntu):
$: python iran.pyEssendo scritto in python funziona su qualsiasi sistema operativo con python 2.5 e i relativi moduli installati.













