Sunday, June 26, 2005

Prima prezentare

Azi am facut o chestie noua, si anume prima prezentare din viata mea (including the famous slides :)). Asta s-a intamplat cu ocazia Linuxfest, ce a avut loc la Liceul International de Informatica. Am prezentat Python destul de pe larg, n-a fost totul perfect in prezentare (nici n-as fi vrut asta :)), dar sper ca nici la limita de jos a dezastrului nu s-a situat. Oamenii au fost super OK si pe ansamblu a fost mai mult decat fain.
Ideea este ca vrem sa cream o comunitate a userilor Python din Romania ("noi", cei de la Nuxeo Romania). Pe moment nu va pot da mai multe amanunte, deoarece totul este de-abia la primii pasi. Pentru inceput ne gandim sa punem pe picioare o lista de discutii Python in limba romana, si pe urma, de ce nu, chiar intalniri in genul Linuxfest. Daca e cineva interesat, sa dea un semn :)

Saturday, June 18, 2005

BestJobs trick

Am scris un mic scriptuletz ce primeste la intrare o lista de cuvinte cheie ce sunt cautate pe BestJobs, returnand pentru fiecare cuvant din lista nr. de rezultate al cautarii.
Scriptul e urmatorul:

bestjobs.py
###########

#modul ce calculeaza nr. de locuri de munca de pe BestJobs,
#dupa o anumita lista de cuvinte cheie
import urllib
import string

def rezultate(lista_keywords = ['php', 'java', 'python']):
    #functia principala, primeste la intrare o lista de cuvinte cheie
    #dupa care se doreste a se face cautarea
    #lista_keywords e predefinita cu ['php', 'java', 'python']
    for keyword in lista_keywords:
        nr_rezultate = compute_result(keyword)
        print 'Rezultate dupa cautare %s : %d' %(keyword, nr_rezultate)

def compute_result(keyword):
    link = 'http://bestjobs.neogen.ro/?1=1&bj_nl_p=search_job_result&c_keywords=%s' %(keyword)
    pagina_rez = open_url(link)
    inc_rezultate = string.find(pagina_rez, ' Rezultate:') + len(' Rezultate:')
    sf_rezultate = string.find(pagina_rez, 'joburi', inc_rezultate)
    nr_rezultate = int(string.strip(pagina_rez[inc_rezultate:sf_rezultate]))
    return nr_rezultate

def open_url(url):
    text_pagina = ''
    try:
        file = urllib.urlopen(url)
        text_pagina = file.read()
        file.close()
    except IOError:
        print 'Nu am putut deschide ' + url

    return text_pagina

if __name__ == '__main__':
    rezultate()

E destul de "primitiv", l-am scris intr-o vineri spre sambata noapte, desi aveam alte lucruri mai importante de facut.
Totusi, daca facem

>>> import bestjobs
>>> from bestjobs import rezultate

si apoi

>>> rezultate()
Rezultate dupa cautare php : 135
Rezultate dupa cautare java : 229
Rezultate dupa cautare python : 4

Sunt un pic surprins ca Java a luat fata php-ului asa de mult (aproape dublu), ma bucur ca sunt macar 4 locuri de munca disponibile in python.
Mai ma joc un pic:

>>> rezultate(['j2ee', 'lisp', 'VB', 'zope'])
Rezultate dupa cautare j2ee : 54
Rezultate dupa cautare lisp : 0
Rezultate dupa cautare VB : 69
Rezultate dupa cautare zope : 0

Greu pentru cei ce cauta de lucru bazandu-se pe Lisp sau Zope, j2ee sta bine, VB (de la visual basic) sta mai prost decat ma asteptam.

>>> rezultate(['secretara', 'programator', 'sales%20manager'])
Rezultate dupa cautare secretara : 90
Rezultate dupa cautare programator : 188
Rezultate dupa cautare sales%20manager : 145

Pentru moment programatorii par a le fi luat "fata" sales managerilor, ma intreb pentru cat timp inca.

E tarziu in noapte, chiar am alte lucruri mai importante de facut, asa ca ma opresc aici cu joaca:) Oricine doreste poate imbunati codul de mai sus cum crede de cuviinta, numai sa ne anunte si pe noi ce rezultate a obtinut :)

Tuesday, June 14, 2005

"Greutatea" cuvintelor, sau Poisson versus atc

Back to blogging:)
Nu prea am avut timp in ultima vreme (new job + sesiune + o groaza de carti ce trebuie citite), dar acum vreo doua zile mi-am facut timp pentru a incerca sa imbunatatesc "tehnologia" din spatele MogNews.
E vorba despre tehnica de determinare a celor mai importante cuvinte dintr-un articol, ce sunt folosite intr-o etapa urmatoare pentru a imparti articolele in clustere si pentru a fi "assignate" anumitor categorii, daca e cazul. In momentul de fata folosesc modelul Poisson, conform caruia cuvintele ce descriu cel mai bine un anumit articol nu respecta distributia Poisson. Cu alte cuvinte, cu cat un cuvant se abate mai mult de la distributia Poisson caracteristica unui anumit articol, cu atat are mai mari sanse sa reprezinte un termen "cheie" pentru acel articol.
Am ales sa implementez acest model si pentru ca mi se parea destul de familiar, asta si dupa ce citisem Information Retrieval a lui CJ van Rijsbergen, unde era descris destul de inteligibil pentru un novice in IR, asa cum eram anul trecut pe vremea asta :). Totusi curand am dat peste modelul tf.idf ("term frequency and the inverse document frequency"), mai precis peste varianta acestuia, asa numitul "atc-weight". Chiar inainte sa termin implementarea pentru modelul Poisson m-am apucat sa scriu cateva randuri si pentru o posibila implementare a acestui model, dar m-am oprit undeva pe la jumatate.
Dupa un an de zile in care s-au intamplat destule, mi-am zis sa scot acest proiect de la naftalina si l-am adus aproape de finish.
La o prima comparatie cu rezultatele returnate de modelul Poisson, modelul atc se comporta mai bine pentru articolele "orfane" (care apar intr-un singur ziar), in timp ce Poisson are rezultate mai bune pentru articolele asemanatoare ce apar in mai multe ziare. S-ar putea sa ma insel, dar ma gandesc ca asa ar fi si logic. Explicatia consta in faptul ca modelul Poisson atribuie o "greutate" ("weight") unui anumit cuvant ce este valabila pentru toate articolele, in timp ce modelul atc atribuite "greutati" diferite cuvintelor pentru fiecare articol in parte.
Sper ca m-am facut inteles cat de cat:), mai urmeaza sa imi fac cat de curand timp astfel incat sa integrez modelul atc in MogContext, pentru a putea compara mai bine rezultatele obtinute de modelul Poisson si de modelul atc.
Toate acestea pe larg le gasiti si aici.

Saturday, June 04, 2005

New Google tool

Noua unealta de la Google, Google Sitemaps.
Foarte interesant:
Webmasters attempting to install and execute sitemap_gen.py should have knowledge of uploading files to their webserver, connecting to their webserver, and running scripts. In addition, Python version 2.2 must be installed on your webserver - check with your web hosting company if you are unsure.
Nu mai e mult pana cand vom fi martorii "Python world domination" :)