bloco de notas

editado por eloi ribeiro

Dias Julianos com Python 2009-06-18

Arquivado em: python — Eloi @ 10:45

Algumas vezes necessitamos trabalhar com a dias julianos em vez de datas do calendário gregoriano. Aqui deixo como o calcular com python.

import time
print time.strftime("%j")

Devolve quantos dias passaram desde o inicio do ano, hoje, 2009-06-18: 169 dias.

Ou assim:

import time
import datetime
data= datetime.date(2009, 06, 18)
print data.strftime("%j")
 

Como enviar um correio electronico com python 2009-05-25

Arquivado em: python — Eloi @ 07:53

Deixo aqui uma pequena função em python para enviar correios com ou sem ficheiros em anexo. Eu costumo utilizar-la para determinados scripts que demoram muito em terminar, estando varias horas em funcionamento. Assim estando já fora do trabalho e com acesso ao correio posso saber em que estado se encontra ou se terminou com sucesso determinado script.

Nota: alterar a linhas 10 e 25 com o correio e palavra-chave correspondente. E o servidor SMTP é do gmail, só exprimentei com este. O codigo é o seguinte:

import os
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email import Encoders

def enviar_correio(para, assunto, mensagem, anexo):
    msg = MIMEMultipart()
    msg['From'] = 'o_meu_correio@gmail.com'
    msg['To'] = para
    msg['Subject'] = assunto
    if mensagem != '':
        msg.attach(MIMEText(mensagem))
    part = MIMEBase('application', 'octet-stream')
    if anexo != '':
        part.set_payload(open(anexo, 'rb').read())
        part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(anexo))
        msg.attach(part)
    Encoders.encode_base64(part)
    mailServer = smtplib.SMTP("smtp.gmail.com", 587)
    mailServer.ehlo()
    mailServer.starttls()
    mailServer.ehlo()
    mailServer.login(msg['From'], 'palavra-chave do teu correio')
    mailServer.sendmail(msg['From'], para, msg.as_string())
    mailServer.close()
    print 'Correio enviado'

# exemplo para enviar correio sem mensagem e sem anexo
enviar_correio('correio_destino@servidor.com', 'assunto', '', '')
# exemplo para enviar correio com mensagem e com anexo
enviar_correio('correio_destino@servidor.com', 'assunto', 'mensagem', '/home/utilizador/anexo.pdf')
 

Importar dados meteorologicos da web para PostgreSQL com Python 2009-01-21

Arquivado em: meteorologia, postgresql, python — Eloi @ 16:31

Supondo que temos a seguinte tabela em PostgreSQL

CREATE TABLE meteo_aeroportos(
unico character varying(15),estacao_cod character(4), data date,
t_max real, t_med real, t_min real,o_max real, o_med real, o_min real,
h_max real, h_med real, h_min real,pa_max_in real, pa_med_in real, pa_min_in real,
vi_max_km real, vi_med_km real, vi_min_km real,v_max_kh real, v_med_kh real,
vr_max_kh real, p_tot real, neblosidade real, descricao character varying(50),
id serial primary key);

e aproveitando a disponibilidade de dados meteorológicos dos aeroportos pela página de Weather Underground e com recurso a um pequeno script de Pytthon podemos ter uma base de dados com os últimos dados meteorologicos dos aeroportos que desejamos, neste caso utilizarei apenas os da Peninsula Ibérica.

#coding: latin-1
import os
import urllib2
from BeautifulSoup import BeautifulSoup
import datetime
import psycopg2

def meteo_aero(base_de_dados, utilizador, host, senha):
    conn = psycopg2.connect("dbname='%s' user='%s' host='%s' password='%s'" % (base_de_dados, utilizador, host, senha))
    cur = conn.cursor()
    print '\n    Aeroportos'
    aeroportos = ['BGC', 'BGZ', 'CHV', 'CVU', 'FAO', 'FLW', 'FNC', 'GRW', 'HOR', 'LIS', 'LPBJ', 'LPEV', 'OPO', 'PDL', 'PIX', 'PRM', 'PXO', 'SJZ', 'SMA', 'TER', 'VRL', 'AGP', 'ALC', 'BCN', 'BIO', 'BJZ', 'EAS', 'GRO', 'GRX', 'IBZ', 'LCG', 'LEGA', 'LEGT', 'LEI', 'LERT', 'LPA', 'MAD', 'MJV', 'ODB', 'OVD', 'OZP', 'PMI', 'PNA', 'REU', 'SCQ', 'SDR', 'SLM', 'SVQ', 'TFN', 'TFS', 'TOJ', 'VGO', 'VIT', 'VLC', 'VLL', 'XRY', 'ZAZ']
    print 'Descarregar e inserir...'
    for a in aeroportos:
        sql = "select extract(year from max(data)), extract(month from max(data)), extract(day from max(data)) from dados.meteo_aeroportos where estacao_cod = '%s';" % a
        cur.execute(sql)
        rows = cur.fetchall()
        for row in rows:
           ano_i = int((row[0]))
           mes_i = int((row[1]))
           dia_i = int((row[2]))
        url = 'http://www.wunderground.com/history/airport/%s/%s/%s/%s/CustomHistory.html?dayend=30&monthend=05&yearend=2009&req_city=NA&req_state=NA&req_statename=NA&format=1' % (a, ano_i, mes_i, dia_i)
        page = urllib2.urlopen(url)
        sopa = BeautifulSoup(page)
        sopa = list(sopa)
        n = len(sopa[2:-4])
        x = 1
        while x < n:
            if (x % 2 == 0):
                linha = str(sopa[x]) + ','+ a
                linha = str(linha).replace(',,', ',null,')
                linha = str(linha).replace(',,', ',null,')
                linha = str(linha).replace('\n', '')

                data    = linha.split(',')[0]
                t_max = round(((float(linha.split(',')[1]) -32) / 1.8), 2) if linha.split(',')[1] <> 'null' else linha.split(',')[1] # c = (f-32) / 1.8
                t_med = round(((float(linha.split(',')[2]) -32) / 1.8), 2) if linha.split(',')[2] <> 'null' else linha.split(',')[2] # c = (f-32) / 1.8
                t_min = round(((float(linha.split(',')[3]) -32) / 1.8), 2) if linha.split(',')[3] <> 'null' else linha.split(',')[3] # c = (f-32) / 1.8
                o_max = round(((float(linha.split(',')[4]) -32) / 1.8), 2) if linha.split(',')[4] <> 'null' else linha.split(',')[4] # c = (f-32) / 1.8
                o_med = round(((float(linha.split(',')[5]) -32) / 1.8), 2) if linha.split(',')[5] <> 'null' else linha.split(',')[5] # c = (f-32) / 1.8
                o_min = round(((float(linha.split(',')[6]) -32) / 1.8), 2) if linha.split(',')[6] <> 'null' else linha.split(',')[6] # c = (f-32) / 1.8
                h_max   = (linha.split(',')[7])
                h_med   = (linha.split(',')[8])
                h_min   = (linha.split(',')[9])
                pa_max_in = linha.split(',')[10]
                pa_med_in = linha.split(',')[11]
                pa_min_in = linha.split(',')[12]
                vi_max_km = round((float(linha.split(',')[13]) * 1.609344), 2) if linha.split(',')[13] <> 'null' else linha.split(',')[13] # Km = miles * 1.609344
                vi_med_km = round((float(linha.split(',')[14]) * 1.609344), 2) if linha.split(',')[14] <> 'null' else linha.split(',')[14] # Km = miles * 1.609344
                vi_min_km = round((float(linha.split(',')[15]) * 1.609344), 2) if linha.split(',')[15] <> 'null' else linha.split(',')[15] # Km = miles * 1.609344
                v_max_kh = round((float(linha.split(',')[16]) * 1.609344), 2) if linha.split(',')[16] <> 'null' else linha.split(',')[16] # Km = miles * 1.609344
                v_med_kh = round((float(linha.split(',')[17]) * 1.609344), 2) if linha.split(',')[17] <> 'null' else linha.split(',')[17] # Km = miles * 1.609344
                vr_max_kh = round((float(linha.split(',')[18])* 1.609344),2)if linha.split(',')[18] <> 'null' else linha.split(',')[18] # Km = miles * 1.609344
                p_tot =          round((float(linha.split(',')[19]) * 25.4),2) if linha.split(',')[19] <> 'null' else linha.split(',')[19] # mm = in * 25,4
                neblosidade =  (linha.split(',')[20])
                descricao =  (linha.split(',')[21])
                estacao_cod =  (linha.split(',')[22])
                sql = "INSERT INTO dados.meteo_aeroportos ( \
                data, t_max, t_med, t_min, o_max, o_med, o_min, h_max, h_med, h_min, pa_max_in, pa_med_in, pa_min_in, vi_max_km, vi_med_km, vi_min_km, v_max_kh, v_med_kh, vr_max_kh, p_tot, neblosidade, descricao, estacao_cod) \
                VALUES ('%s', %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, '%s', '%s');" % (data, t_max, t_med, t_min, o_max, o_med, o_min, h_max, h_med, h_min, pa_max_in, pa_med_in, pa_min_in, vi_max_km, vi_med_km, vi_min_km, v_max_kh, v_med_kh, vr_max_kh, p_tot, neblosidade, descricao, estacao_cod)
                cur.execute(sql)
            else:
                pass
            x = x + 1
    conn.commit()
    print 'Eliminar repetidos...'
    sql = 'create temp table meteo_aeroportos_t1 as select unico from dados.meteo_aeroportos group by unico having count(unico) > 1;'
    cur.execute(sql)
    sql = 'create temp table meteo_aeroportos_t2 as select max(id) as id, unico from dados.meteo_aeroportos group by unico having count(unico) > 1;'
    cur.execute(sql)
    sql = 'delete from dados.meteo_aeroportos where dados.meteo_aeroportos.unico in (select meteo_aeroportos_t1.unico from meteo_aeroportos_t1) and id not in (select id from meteo_aeroportos_t2);'
    cur.execute(sql)
    conn.commit()
    conn.close()

meteo_aero('base_de_dados', 'utilizador', 'host', 'senha')
 

Instalar geopy no Ubuntu 2009-01-13

Arquivado em: geo-codificação, python, sig, ubuntu — Eloi @ 20:11

geopy é um modulo de python para geo-codificação, infelizmente não está nos repositórios de Ubuntu. Assim que para o instalar necessitamos primeiro de instalar o modulo python-setuptools e depois descarregar geopy de subversion.

sudo apt-get install python-setuptools
svn co http://geopy.googlecode.com/svn/trunk/ geopy-trunk
cd geopy-trunk/
sudo python setup.py install

Outra coisas que temos de fazer é conseguir uma chave para utilizar a API de Google Maps. Uma vez em possessão da chave, podemos realizar um pequeno exemplo. Abrimos a linha de comandos e iniciamos python.

g = geocoders.Google('põe aqui a tua chave da API de Google Maps')
place, (lat, lng) = g.geocode("aliados, 107, porto, portugal")
print lat, lng

41.1479177 -8.6113332

Para ver mais exemplos dar uma olhadela na pagina de geopy.

 

Carregar massivamente shp’s em PostgreSQL com um script de Python 2008-12-11

Arquivado em: postgis, postgresql, python, sig — Eloi @ 08:27

Para exportar shp’s a PostgreSQL existe a ferramenta shp2pgsql que faz o tabalho na perfeição. O problema surge se em vez de uns quantos shp’s temos uma barbaridade, numa situação como esta ou automatizamos o processo ou corremos o risco de morrer de tédio. Eliminando a segunda possibilidade, cabe-nos escolher o método a usar. Podemos usar shell script, que no meu caso não estaria mal aprender, ou usar uma linguagem de programação. Assim que vou deixar aqui com um pequeno script escrito em Python para este tipo de situações.

Para usar este script temos que indicar duas coisas, a pasta onde estão os shp’s e o sistema de coordenadas(EPSG). Para facilitar o processo é conveniente ter a cartografia separada por pastas consoante o sistema de coordenadas. Por exemplo: a cartografia de Portugal que está no sistema de coordenadas 20791 está na pasta /cartografia/shp/20791/, a cartografia de Espanha em /cartografia/shp/23030/ e assim por diante.

E o que faz este script? Percorre, recursivamente (em profundidade), as pastas indicadas, procura pela extensão.shp, se a encontra, exporta para a base de dados bdg, cria um indice pelo campo de geometria (geom) e termina com um vacuum analyze.

Agora apenas temos que guardar o codigo que está a seguir a este paragrafo num ficheiro com a extensão.py, adicionar e/ou editar as duas últimas linhas em concordancia com as pastas e sistemas de coordenadas dos shp’s.

import os
import datetime
def postgis_import_shp(inicio, epsg, db, schema):
    principio = datetime.datetime.today()
    conta = 0
    l = os.walk(inicio)
    for i in l:
        directorio, subdirectorios, ficheros = i
        for f in ficheros:
            nome_completo =  os.path.join(directorio, f)
            tema = schema + '.' + f.split('.')[0]
            extensao = f.split('.')[-1]
            try:
                if extensao == 'shp':
                    os.system('shp2pgsql -s %s -g geom -W iso-8859-1 -D -I %s %s %s | psql -U postgres %s' % (epsg, nome_completo, tema, db, db))
                    os.system('psql -U postgres -d %s -c "VACUUM ANALYZE %s(geom);"' % (db, tema))
                    conta += 1
                    print '\n'
            except:
                pass
    print conta, 'shp`s importados em', datetime.datetime.today() - principio
    return

shp2postgis('/cartografia/shp/20791/','20791', 'mome_base_dados', 'nome_esquema')
shp2postgis('/cartografia/shp/23030/','23030', 'mome_base_dados', 'nome_esquema')