31 de Enero de 2014 · 3 min de lectura
Un dels avantatges del Python com a llenguatge de programació és que podem fer prototipus complets, a molt alt nivell, sense sortir-nos del llenguatge i aprofitant la gran varietat de biblioteques de tercers lliures. En aquest post exposarem com ajuntarem una grapada de peces que en principi no tenen massa a veure per acabar tenir un rodó projecte de final de carrera.
Una branca molt interessant de la informàtica és la seva amalgama amb la biologia. La bioinformàtica presenta reptes en la manera de plantejar i resoldre problemes per que solen ser processos d'alta complexitat algorísmica i un volum de dades vàries vegades major que la memòria disponible. Si a més afegim que molts de cops l'especificació és poc clara i hem d'anar traduint conceptes biològics a línies de codi ens trobam en una situació on un llenguatge de molt alt nivell ens suposa un avantatge competitiu.
Al meu projecte de final de carrera consisteix en que l'usuari introdueix un conjunt d'espècies vegetals o virals mitjançant una estructura anomenada xarxa filogenètica. Aquest graf determina la semblança d'espècies i després de tota una grada de manipulacions podrem obtenir dades per l'estudi de malalties o el comportament de medicines. Tot això és molt abstracte i no sembla que tingui molt a veure amb Python, no? Si anam dividint els requeriments del nostre programa tenim:
Així doncs, tenim varis mòduls a destacar:
Podreu trobat tot el codi del projecte per mirar-lo amb calma però m'agradaria destacar com interconnectàrem algunes de les peces.
El bottle ens serveix per muntar-nos una petita plana. Indicam les rutes sobre les vistes que volem tractar i tornam un diccionari amb el context:
from bottle import route from bottle import redirect, view, post, request from bottle import Response @route("/about") @view('templates/about') def about(): return {}
Però evidentment voldrem fer coses més complicades, com aquesta vista que ens indica l'estat d'una tasca a una cua RQ:
@route("/job/soft/<queue_key>/<job_id>") def process_job_soft(queue_key, job_id): redis_connection = Redis() q = Queue.from_queue_key(queue_key, redis_connection) job = q.safe_fetch_job(job_id) if job.result: value = json.dumps(list(job.result)) return {'status': 'done', 'value': value, } else: return {'status': 'pending'}
Fins i tot podríem servir els estàtics:
from bottle import route, static_file @route('/static/<filepath:path>') def server_static(filepath): return static_file(filepath, root='./static')
Els benchmarks tardaven vàries hores en executar-se i volia poder tractar al dia següent els resultats. Per això desava els resultats mitjançant peewee:
from peewee import Model, SqliteDatabase from peewee import IntegerField, FloatField, BooleanField database_filename = "benchmarks.sqlite" db = SqliteDatabase(database_filename) class BenchmarkCase(Model): test = IntegerField() nodes = IntegerField() fulles = IntegerField() temps_soft = FloatField() es_treechild = BooleanField() n_families = IntegerField() class Meta: database = db
I així mentre podia escriure els scripts que me pintarien les gràfiques resultats. Primer obtenim les dades:
from peewee import SqliteDatabase from benchmark_classes import BenchmarkCase import numpy from scipy import stats import matplotlib.pyplot as plt TEST_NUMBER = 1 database_filename = "benchmarks.sqlite" database = SqliteDatabase(database_filename) database.connect() B = BenchmarkCase qs = B.select().where(B.test == TEST_NUMBER) grau = [q.nodes for q in qs] temps = [q.temps_families for q in qs]
I després pintam el que necessitam:
data = [grau, temps] xlabel = u"Grau d'hibridització" title = u"Correlació entre el grau d'hibridització i t. per tree-child" for x, y in zip(*data): plt.plot(x, y, 'ok') plt.xlabel(xlabel) plt.title(title) plt.grid(True) plt.ylabel(u"Temps en segons") plt.savefig("hibriditzacio.pdf") plt.close()
Hem fet una passejada a un projecte que va ajuntar no sols eines de manipulacions de grafs sinó també una petita web i la manipulació d'una bateria de proves. Totes aquestes peces han vingut de biblioteques externes lliures que sense perdre l'expressivitat de Python resolen problemes d'àmbits molt distints. Estau més que convidats a contar-nos qualsevol mòdul estrany que vos hagi tret d'un bon tràngol!