Mais um blog inútil.

Serious-Business

Janeiro 28, 2010

Cantina da FCT UNL no Google Calendar (com SMS)

Arquivado em: coding, serious-business — falso @ 21:54

Ora Viva amigos!
Hoje venho aqui blogar não sobre uma coisa inútil como é habitual, mas sobre algo deveras útil!

Como devem saber (se não sabem, deviam!!!) eu há uns tempos tinha feito um parser à pagina das ementas no site dos Serviços de Acção Social da Universidade Nova de Lisboa que cria um RSS Feed onde se pode ver no Google Reader (ou outro) todos os dias a ementa do dia.

Mas já há uns tempos me tinham dito que na Universidade do Minho[ 1] há um marmanjo que importa as ementas lá do sitio para o Google Calendar. E vocês perguntam qual a razão para isso né? A beleza da cena é que no Google Calendar existe uma feature que permite enviar avisos de eventos por SMS, já viram onde isto nos leva né ;-)

Então decidi por mãos à obra e comecei a programar, decidi usar Python pois as APIs dos Serviços do Google parecem ser mais viradas para essa linguagem.

O primeiro problema era fazer parse da pagina da SAS, então descobri no Google um parser de HTML lindo chamado BeautifulSoup que até tem um *slogan* todo jeitoso - You didn’t write that awful page. You’re just trying to get some data out of it. Right now, you don’t really care what HTML is supposed to look like. Neither does this parser.
Em muito pouco tempo, sem usar uma única rege x lá consegui fazer parse ao site e sacar de la todos os dados que precisava.

Depois andei a cuscar o Google Data API Developer’s Guide: Python, e com a ajuda dos exemplos rapidamente fiz uma rotina que importava o que eu precisava para o Google Calendar.

Aqui se segue o código caso alguém queira implementar o mesmo para outras faculdades da UNL.

#!/usr/bin/env python
# this script can never fail
# -*- coding: utf-8 -*-

# This program is free software. It comes without any warranty, to
# the extent permitted by applicable law. You can redistribute it
# and/or modify it under the terms of the Do What The Fuck You Want
# To Public License, Version 2, as published by Sam Hocevar. See
# http://sam.zoy.org/wtfpl/COPYING for more details.

# urle de exemplo
# http://sas.unl.pt/cantina?year_menu:int=2010&month_menu:int=1&day_menu:int=25

import urllib
from BeautifulSoup import BeautifulSoup

try:
  from xml.etree import ElementTree # for Python 2.5 users
except ImportError:
  from elementtree import ElementTree
import gdata.calendar.service
import gdata.service
import atom.service
import gdata.calendar
import atom
import getopt
import sys
import string
import time

import datetime

# ids dos calendarios. almoco - almoco dieta - jantar - jantar dieta
cal_ids = ['/calendar/feeds/XXXXXXXXXXXXXXXXXXXXXXXXXX%40group.calendar.google.com/private/full',
          '/calendar/feeds/XXXXXXXXXXXXXXXXXXXXXXXXXX%40group.calendar.google.com/private/full',
          '/calendar/feeds/XXXXXXXXXXXXXXXXXXXXXXXXXX%40group.calendar.google.com/private/full',
          '/calendar/feeds/XXXXXXXXXXXXXXXXXXXXXXXXXX%40group.calendar.google.com/private/full']

# logar-se ao google
calendar_service = gdata.calendar.service.CalendarService()
calendar_service.email = 'XXXXXXXX@gmail.com'
calendar_service.password = 'XXXXXXXX'
calendar_service.source = 'Google-Calendar'
calendar_service.ProgrammaticLogin()

def ParsaSite(ano, mes, dia):
  params = urllib.urlencode({'year_menu:int': ano, 'month_menu:int': mes, 'day_menu:int': dia})
  f = urllib.urlopen("http://sas.unl.pt/cantina?%s" % params)
  soup = BeautifulSoup(f.read())

  # todas as cantinas
  cantinas = soup.findAll(attrs={'class' : 'cantina'})
  for cantina in cantinas:
    # verifica se o conteudo da class title e da FCT
    titletag = cantina.find(attrs={'class' : 'title'})
    if titletag.renderContents().count('ncias e Tecnologia'):
      # apanha o almoco
      almoco = titletag.nextSibling.nextSibling
      # percorre todos os pratos
      almoco_p = almoco.findAll('li')
      al = {}
      for prato in almoco_p:
        key = prato.next.renderContents()
        value = prato.next.next.next.next.next.renderContents()
        al[key] = value

      jantar = almoco.nextSibling.nextSibling
      jantar_p = jantar.findAll('li')
      ja = {}
      for prato in jantar_p:
        key =  prato.next.renderContents()
        value = prato.next.next.next.next.next.renderContents()
        ja[key] = value
      return (al, ja)

def InsereEvento(calendario_id, _data, refeicao, prato):
  evento = gdata.calendar.CalendarEventEntry()
  evento.title = atom.Title(text=prato)
  #evento.where.append(gdata.calendar.Where(value_string='Cantina FCT UNL - Monte de Caparica'))

  dt = datetime.datetime(_data.year, _data.month, _data.day)

  if refeicao == 1:
    inicio = dt + datetime.timedelta(hours=11,minutes=30)
    fim = dt + datetime.timedelta(hours=14,minutes=30)
  if refeicao == 2:
    inicio = dt + datetime.timedelta(hours=18,minutes=30)
    fim = dt + datetime.timedelta(hours=20,minutes=30)

  evento.when.append(gdata.calendar.When(start_time=inicio.isoformat(), end_time=fim.isoformat()))
  calendar_service.InsertEvent(evento, calendario_id)

dt = datetime.date.today()
while dt.weekday() < 5:
  (al, ja) = ParsaSite(dt.year, dt.month, dt.day)

  i = 0

  for k, v in al.iteritems():
    if k == 'Prato':
      InsereEvento(cal_ids[i], dt, 1, v)
    if k == 'Dieta':
      InsereEvento(cal_ids[i], dt, 1, v)
    i+=1

  i = 2

  for k, v in ja.iteritems():
    if k == 'Prato':
      InsereEvento(cal_ids[i], dt, 2, v)
    if k == 'Dieta':
      InsereEvento(cal_ids[i], dt, 2, v)
    i+=1

  # incrementa a data
  dt += datetime.timedelta(days=1)

# acabou boy

O script vai ser corrido todas as segundas durante a madrugada no cron.
Sei que o código não interessa a ninguém, e o que querem é os links para adicionar os calendários ao Google Calendar, portanto aqui vão.

Props pro webmaster do site da SAS por feito um HTML bem estruturadinho.

1 - Se alguém sofrer de algum problema de atraso mental e não souber activar as SMS no Google Calendar, no link para a Universidade do Minho está um documento a explicar como se faz

Janeiro 26, 2010

WP_Birds

Arquivado em: coding, serious-business, useless — falso @ 23:44

Ora viva!

Hoje como estava aborrecido e não me apetecia ir para a rua porque está um barbeiro do caralho decidi meter o blol a validar no w3c validator, primeiro estava com alta drama por causa do penisbird no source do site, mas depois lá aprendi que em HTML também existe o CDATA, e que se o usar por exemplo dentro dum paragrafo posso meter lixo para la à vontade.
E com isto lá pus o blol a validar, mas fiquei com um bichinho atrás da orelha, porque só um penisbird quando podemos ter um molho deles, então tentei seguir as passadas do grande Mario Gamito e decidi também eu fazer um plugin para o WordPress que adiciona penisbirds aleatórios no fim do blog mesmo antes do fechar do BODY.
Sei que é a coisa mais inútil de sempre, mas, é para isso que cá estou eu!
Download: wp_birds_0.1.zip

Janeiro 25, 2010

Gripe A

Arquivado em: drama, fail, serious-business, useless — devnull @ 12:15

Pois é, está um belo dia soalheiro de inverno e este importante facto faz-me relembrar a “pandemia” que, supostamente, iria acontecer caso nao tomássemos as providências de mandar com um gel malcheiroso para as mãos cada vez que fossemos tocar em alguma coisa sem ser o nosso orgão sexual (isso era só depois de tocar).

Após ter tomado o conhecimento que o terramoto do Haiti curou a gripe A e que com esse facto provado, a OMS vem confirmar que o virus H1N1 está a perder a força, tive logo que vir aqui blogar sobre o facto de nenhum dos meus amigos/conhecidos/familiares ter apanhado este virus, sem ser a GRIPE SAZONAL QUE ACONTECE TODOS OS ANOS, SIM É UM FACTO PROVADO QUE TODOS OS ANOS O VIRUS DA GRIPE SOFRE MUTAÇÕES E QUE O NOSSO CORPO TEM QUE ARRANJAR DEFESAS PARA SE PROTEGER!!!
De qualquer das maneiras, as grandes farmacêuticas têm a agradecer a vossa ingenuidade ao porem um gel malcheiroso nas mãos, que vos faz perder os germes todos das mãos… e com eles grande parte das defesas naturais que as mãos têm contra a tal gripe sazonal entre outras maleitas.
As grandes farmaceuticas também agradecem o facto de termos comprado 6 MILHÕES de vacinas “não vá o diabo tecê-las” mais tamiflus, constipal, antigripine e o raio que os parta a todos.

Qual será o próximo animal a pegar-nos a gripe ? Espero é que ao menos seja um animal exótico, já foram as aves, os porcos, faltam as vacas que ainda só nos passaram a maluqueira delas… Ao menos que apanhasse uma gripe de um animal “como deve de ser”, de lagosta ou de macacos do madagáscar…

Enfim, venha o sol!

Janeiro 24, 2010

Holanda...

Arquivado em: drama, lulz, serious-business, work — devnull @ 04:05

A Lolanda

Mais uns dias e faz 2 anos que la estivemos…

Jornal de Notícias

Arquivado em: drama, fail, serious-business — falso @ 03:31

Ora viva!
Venho aqui reportar que os senhores webmasters do jornal de notícias estão se mesmo a cagar para os visitantes. Portanto tive de vir dramatizar sobre isso!
Já há mais de 2 meses que os avisei por email que o site deles estava com um bug, disseram que iam ver, e cagaram de alto.

O bug é o seguinte, em todos os Dossiês, ele escreve no site tudo o que se meter na variavel dossier do url. Exemplos:

http://jn.sapo.pt/dossies/dossie.aspx?content_id=1467256&dossier=Peidalha%E7o+agora+tamb%E9m+%E9+arguido http://jn.sapo.pt/dossies/dossie.aspx?content_id=1476262&dossier=Terramoto+no+Haiti+cura+Gripe+A

Pode ser que agora os senhores webmasters se dignem a resolver este bug, ou então amanha o blol já está em baixo e já tenho os senhores policias a baterem me à porta.

[Edit: Pus uma pic para que no caso de arranjarem o site saber-se como tava antes]

Janeiro 11, 2010

HD na TV Nacional

Arquivado em: drama, fail, lulz, serious-business, useless — madinfo @ 23:37

Como já todos repararam o HD está na moda…. ate o sr falso fez um post sobre HD nas consolas há dias, como tal agora resolvi dedicar um post ao HD na TV Nacional.

Sou +/- assinante da TVcabo e dos senhores Meo ambos via satélite, tanto um como o outro, e há boa moda portuguesa pintam que tem o melhor serviço HD do mundo e arredores.

Ora vejamos como funciona um novo canal HD exemplificando a FOX:

Todos se lembram da  FOX SD tinha uma boa qualidade (pronto razoável vá) já era 16:9…. até que um dia ligo tv meto na FOX e pra meu espanto era novamente 4:3, tinha qualidade manhosa cheia de pixeis em todo o lado…

Nesse mesmo dia eis que a TVcabo anuncia uma coisa INÉDITA em todo o mundo FOX  HD brevemente disponível… bem la esperei uns dias e a dita apareceu e basicamente era o canal antigo a 16:9 (de notar que só alguns programas emitem assim) qualidade +/- decente e já era o chamado HD 1080i.

E assim senhoras e senhores se enganam os tolos… devem pensar que temos memoria de peixinho dourado que daqui a 2 segundos já não lembramos o que vimos…

Quem conhece e apanha as emissões da BBC certamente conhece  a magnifica qualidade que tem estes canais tem… conseguem ser melhores que o nosso “HD”.

Em Portugal que é enfiar o máximo de canais possível no mesmo transponder e meter a bit-rate no mínimo.

Até penso que a TVcabo qualquer dia nem precisa de qualquer sistema  de codificação já que a compressão é tanta que qualquer dia ninguém vai ver mesmo nada…

Depois temos a TVI… quem não se lembra de ver uns reclames antigamente  a dizer que na novela xpto era captada em HD ?? adorei isto ja que meio mundo andou a dizer que via a novela em HD… via tv analógica…. para eles aqui fica um: LOL

Agora voltando atrás aos 1080 i que falei há pouco… o roto leitor certamente se perguntou: então mas não é 1080 p? Ao qual eu respondo: Não, pelo menos no DVB-S… actualmente não ah tecnologia para mais… nem a ultima dreambox 8000 reproduz mais que os 1080i… quanto aos restantes DVB’s sinceramente não sei nunca li acerca da coisa mas penso que devem andar na mesma camioneta…..

espero que tenham gostado… se não gostaram cheirem e ponham de parte…

PS ia para ler isto novamente para ver se fazia sentido mas como ta bué grande e não me apetece leio qualquer dia…

Dezembro 20, 2009

Jardim do Torel - Lisboa

Arquivado em: lulz, serious-business, useless — devnull @ 02:50

Ir em busca de um produto em particular que se encontrava numa loja perto do Campo Mártires da Pátria… E uma extrema vontade de ir passear. Foi assim que se iniciou a desventura da descoberta de um jardim,  num sábado de inverno soalheiro e frio.

Levantar da cama às duas da tarde que está frio… E ter uma súbita sensação de querer passear! Agarrámos na SPOT e lá fomos, comemos uma sandes num fast food pelo caminho que agora escurece cedo e já se faz tarde… Comprar o bilhete de comboio para a SPOT e lá fomos. (Sim, um bilhete de comboio para uma cadela! Infelizmente não se pode comprar de ida e volta, irónico…)

Chegando ao Cais do Sodré, dirigimo-nos à Praça do Comércio para percorrermos a Rua Augusta e olhar de surra para as montras, bancadas, performances de rua e gente… MONTES DE GENTE!). Atestámos a barriga no inicio da Rua Augusta com umas waffles simples e quentinhas (que as com cobertura iam fazer com que nos cagássemos todos). Lá percorremos a bagunça de gente que ia para ali amontoada em busca de sabe-se lá o quê…  e fomos dar ao Rossio.

Sempre em frente, pelas portas de Sto. Antão até nos depararmos com um elevador e uma subida íngreme. Chegámos à rua da Lavra com os seus práticos elevadores.
Mas decididos a ser corajosos, fizemos a inclinação a pé de 22%… chegados lá acima e com os bofes de fora, virámos para o lado esquerdo e deparamo-nos com o Jardim do Torel.

Desconhecendo totalmente aquele jardim decidimos ir investigar mais um pouco…

Com uma vista magnifica, como muitos dos miradouros de Lisboa, ficámos surpresos por ver um jardim tão limpinho e com um ar tão novo… Não vou dizer o que se vê de lá, vão lá e descubram… ;-) Tem uns banquinhos pequeninos virados para a cidade e uns “cogumelos de ferro” que ainda nao percebi para que servem porém não destoam muito do ambiente de aristocracia e nobreza que as estátuas do jardim e os edificios à volta fazem transparecer. A descida de volta pode ser feita pelas escadas presentes no jardim (sim, dá para sair “por baixo”) indo dar no final da descida, depois da passagem pela escola primária da freguesia de S. José, a uma rua perpendicular à Avenida da Liberdade.

Infelizmente não levei nem máquina fotográfica nem câmara de filmar, não podendo presentear-vos com imagens… no entanto uma breve pesquisa no google e encontram montes de informação útil e imagens boas.

Ah e o produto estava do outro lado da cidade, no Bairro Alto…

Outubro 23, 2009

Benfica 5 – Everton 0

Arquivado em: serious-business — dcoder @ 16:20

E Pluribus Unum
E Pluribus Unum

Outubro 7, 2009

As constantes do Skein

Arquivado em: serious-business — dcoder @ 01:21

Oi,

Os leitores que acompanham este blol com certeza já leram os meus posts anteriores sobre o Threefish, a cifra por trás do Skein. Já vimos como melhorar o desempenho da mesma utilizando as extensões SSE2. Há pouco reparei num detalhe que não tinha na altura — algumas das constantes utlilizadas nas rotações do Skein são múltiplos de 8. Isto permite-nos efectuar a rotação como uma permutação de bytes, como demostrado neste post.

Nas especificações originais do Skein, existiam 13 constantes múltiplas de 8: 1 para a versão de 256 bits, 2 para a de 512 bits e 10 para a de 1024 bits. As rotações implementadas na versão SSE2 são sensivelmente da forma:

; rotate xmm0 left by 5 bits
movdqa xmm1, xmm0
psllq xmm0, 5
psrlq xmm1, (64-5)
pxor xmm0, xmm1

Quando a rotação é por um múltiplo de 8, isto pode ser convertido para:

; rotate xmm0 left by 8 bits
pshufb xmm0, oword [ROT8]

Num processador actual (i.e. Core 2 45 nm ou Core i7), a versão SSE2 custa-nos pelo menos 1+1+0.33+0.33 = 2.66 ciclos. Com scheduling apropriado, a versão SSSE3 custa-nos 1 ciclo. Para aproximar a melhoria de desempenho possível com esta pequena alteração, vejamos o que acontece quando utilizamos esta optimização.

Uma cifração no Threefish de 256 bits necessita de 72*6 + 72 = 504 operações, excluindo loads, stores e permutações de variáveis inteiras. No caso de 256 bits, apenas uma das constantes é 0 (mod 8), significando que 72/8 = 9 rotações podem ser substituídas por um pshufb. Se 9 em 504 operações podem ser aceleradas 2.66 vezes, temos um speedup de 1.1%, quase insignificante.

No entanto, a versão actualizada do Skein tem novas constantes, incluindo 4 multiplos de 8 para 256 bits. Isto dá-nos um speedup possível de 4.7%. Note-se que estes números são puramente teóricos; o facto de este novo método libertar um registo pode evitar spills de registos para a stack, causando speedups bastante maiores que o esperado.

Outubro 5, 2009

Hash Joins – Oracle (e talvez outros)

Arquivado em: serious-business — drune @ 19:36

Estava aqui a ver um filme estúpido na SIC, enquanto o meu browser crashou com um pdf e então lembrei me logo de blogar sobre hash joins.

A primeira regra para se usar um hash join em detrimento de outras opções para uma operação de join é o pressuposto que ambas as tabelas têm que ter uma quantidade de dados significativa, ou seja, “grandes” tabelas.

Normalmente o optimizador da BD opta pelo uso de hash join quando não existem indices apropriados, quando o fracção de dados a juntar é grande ou simplesmente porque o conceito de ALL_ROWS está definido para o output do join e uma das anteriores condições é valida.
Numa fase inicial e quando se opta pelo hash join, o motor da BD lê a menor tabela da operação de join e coloca-a na memória. O conceito básico será a criação de um hash key por linha que servirá posteriormente para fazer o join. Essa hash table é guardada em memória e é APENAS gerada com base nas chaves existentes na tabela, chaves essas que irão ser usadas para o join com a tabela maior.

Mas perguntam vocês, mas então e se não for possível colocar as hash key na memória?

Existe efectivamente um limite de 200Mb no Oracle 10, ou seja 5% do pga_aggregate_target ou o valor da hash_area_size. Senão for possível alocar essas hash keys no limite definido o CBO (Cost based optimizer) do Oracle vai optar por não escolher um hash join já que a operação não será de todo possível ou então irá recorrer a uso do tablespace TEMP para colocar o que falta degradando assim a performance da operação.
É por norma algo dificil saber ajustar os parametros do hash_area_size que define para cada sessão o valor máximo de hash area a usar, mas usa-se convencionalmente a seguinte formula para o cálculo:

hash_area_size = 1.6 x nr de linhas da tabela menor.

Imaginemos que será possível guardar todo o conteudo da hash table em memória, o próximo passo será ler a tabela maior em FULL TABLE SCAN normalmente. Para cada hash key presente na memória o motor tentará fazer um match com a hash gerada a partir das chaves da tabela maior. Em ambas as tabelas é sempre gerada uma hash key por cada linha para permitir a comparação, excepto que é colocada na memória e outra no disco.

Performance:

Pode-vos parecer um pouco estúpido por exemplo obrigar um full table scan numa tabela como exemplo de 700 milhões de registos. Realmente, não é muito esperto até que alguém se lembrou de introduzir o conceito de paralelismo. É um conceito a explicar detalhadamente noutro post, mas com cpu’s e RAM suficientes é possível obter resultados impressionantes face ao volume de dados a ler.

Xau.