Occams Razor 03-01-02

Embed Size (px)

Citation preview

  • 8/6/2019 Occams Razor 03-01-02

    1/54

  • 8/6/2019 Occams Razor 03-01-02

    2/54

  • 8/6/2019 Occams Razor 03-01-02

    3/54

    EditorialPrimer Aniversario

    by The Occam Team

    OccamsRazor

    Nmero 3, Ao 2008

    Direccin:

    David Martnez Oliveira

    Editores:

    David Martnez OliveiraFernando Martn Rodrguez

    Colaboradores:

    Fernando Martn Rodrguez,Oscar Martnez Mozos, Silvia

    Carril Caldelas, Gonzalo Barrio,Francisco Miguel Bellas Alez,

    Gavin Mathews, LauraRodrguez Gonzlez, Er

    Interprete, Er Escribano, Er dela Secci, Er del Aberno

    Maquetacin y Grafismo

    Publicidad

    Occams Razor [email protected]

    ImpresinPor ahora tu mismo. . . Si te

    apetece

    c2007, 2008, 2009 TheOccams Razor TeamEsta obra est bajo una licenciaReconocimiento 3.0 Espaa de

    Creative Commons. Para veruna copia de esta licencia, visite

    http://creativecommons.org/licenses/by/3.0/es/ o envie unacarta a Creative Commons, 171Second Street, Suite 300, San

    Francisco, California 94105,USA.

    Primer Aniversario!!!. Bueno este es el nmero 3, pero eso no quita queya haya pasado un ao desde que empezamos este proyecto, con el primernmero de Occams Razor. Por si alguien no se enter el genial Donald Knuthcreador de TEXcumpli 70 aos el pasado 11 de Enero, y desde aqu queremosdedicarle este nmero de Occams Razor, el cual no existira sin su genialidad(o al menos sera bastante diferente). Feliz Cumpleaos!

    A modo de celebracin de nuestro primer aniversario, hemos intentado queeste nmero fuera ms variado y un poco especial. Al final hemos terminadocon ms de 50 pginas que esperamos que disfrutis.La otra novedad que trae este nmero, y que anunciamos en un conocido forotras el lanzamiento del nmero 2 de la revista, es el cambio de su licencia dedistribucin para hacer que Occams Razor sea un poco ms libre.En otro orden de cosas, en este nmero 3 de Occams Razor os encontrarislas secciones que por mrito propio se estn convirtiendo en fijas: Ratas deBiblioteca, Mala Bestia, M Rpido y el Reverso Tenebroso. Ellas son lasencargadas de mantener el contenido tcnico relacionado directamente con elmundo de la tecnologa informtica.Como decamos ms arriba este nmero es ms variado que los anteriores gra-cias a nuevas colaboraciones externas que nos acercan a la tecnologa desdeotros puntos de vista y campos profesiones. As scar Martnez nos proporcio-na una excelente introduccin al mundo de la Inteligencia Artificial y SilviaCarril nos ayuda, con su artculo Trujamana o Localizadora, a comprender

    mejor una profesin con la que estamos en contacto cada da pero que siguesiendo una gran desconocida.En esta misma lnea de aplicacin directa de la tecnologa, Francisco Bellasnos cuenta cmo utilizar el programa Odeon para que aprendamos un pocode Acstica Arquitectnica.Fernando Martn nos ofrece, en este nmero, dos excelentes artculos. Por unaparte, Fernando contina explicndonos como funcionan los sistemas de reco-nocimiento biomtrico abordando en esta ocasin el anlisis del iris. Por otra,Fernando en colaboracin con Gonzalo Barrio, nos ofrece un interesantsimoy original artculo de investigacin histrica sobre cmo pudo funcionar elTelgrafo de Gauss.Como podis ver seguimos evolucionando hacia la revista que queremos lle-

    gar a ser. Cada vez nos vamos acercando ms a los contenidos Tecnolgicosy Cientficos (estos ltimos nos estn costando) que estamos buscando, siem-pre en torno a las ciencias de la computacin que, cada vez ms, se estnconvirtiendo en el nexo de unin de este mundo multidisciplinar.Como siempre deseamos que este joven proyecto, que por ahora solo cuentaun ao, os resulte interesante. Muchas gracias por vuestro apoyo!!!

    The Occams RazorTeam

    Las opiniones expresadas en los artculos, as como los contenidos de los mismos, son responsa-

    bilidad de los autores de stos.Puede obtener la versin electrnica de esta publicacin, as como el cdigo fuente de la mismay los distintos ficheros de datos asociados a cada artculo en el sitio web:http://webs.uvigo.es/occams-razor

    3| OCCAMs Razor

  • 8/6/2019 Occams Razor 03-01-02

    4/54

    RINCN DE LOS LECTORES

    El Rincn de los lectoresVuestros comentarios, sugerencias,...

    por The Occams Razor Team

    SSH

    enviado por Luis Rodrguez

    Simplemente sealar que los usuarios de Windowspueden descargarse en el sitio annimo de ftp del la-boratorio de mi escuela(ftp://ftp.lab.fi.uva.es/pub/ssh/Windows)el software cliente Open SSH, que permite acceder me-diante ssh a una mquina remota.Un saludo y enhorabuena por la revista.

    MS SSH

    enviado por Cruz Enrique Borges Hernndez

    Muy buen artculo, pero creo q se os ha olvidado men-cionar la kioslave fish que te permite acceder desdecualquier aplicacin kde a fichero remotos a travs dessh. Es extremadamente til ;)Muchas gracias por ambos apuntes, aqu los ponemospara el resto de lectores.

    ERROR EN ARTCULO SSH

    enviado por Gerardo Elian Gidoni

    Gerardo nos apunt un error en el artculo SSH queseguro que muchos habis detectado, y nos propor-ciona una detallada explicacin que reproducimos acontinuacin... an no sabemos como ha podido pa-sar :P.Muchas gracias Gerardo por esta contribucin.Buenas,

    Antes que nada recin acabo de conocer la revista yme han gustado mucho los artculos que le.Interesante proyecto, felicitaciones :-)Por otro lado creo haber encontrado un error en el ar-tculo sobre tneles SSH donde se habla de redireccinde puertos remotos. (paginas 8 y 9).Pego ac el fragmento.Podemos utilizar el flag -R para conseguir un resulta-do similar. La sintaxis es idntica, pero en este caso elpuerto de redireccin se abrir en la mquina remota.Como podis imaginar, nuestra mquina proyecto-xpuede ser cualquier servicio interno de la red remota:servidores web, pop, etc... Por ejemplo, si la mquina

    proyecto-x ofrece un interfaz web, una vez estable-cido el tnel, solo tenemos que apuntar nuestro nave-

    gador a la url: http://entrada/1234 si la redireccinde puertos es remota, o a http://localhost:1234 sioptamos por la redireccin local.

    occam@razor$ ssh -R1234:proyecto-x:5000 entrada

    Password:

    occam@entrada$....

    [En otro terminal]

    occam@razor$ nc entrada 1234

    Bienvenido al Proyecto X

    }

    Creo que se ha confundido la idea de -R. El par-metro -R sirve para hacer lo opuesto a -L. Unasituacin acorde a la utilidad de -R sera:Necesitamos acceder al puerto 5000 de proyecto-xpor medio de entrada pero entrada no acepta co-nexiones desde el exterior, por lo que desde razor nopodramos iniciar la conexin. Entonces la idea seraque DESDE entrada iniciemos la conexion HACIArazor, entonces haramos

    usuario@entrada$ ssh -R1234:proyecto-x:5000 razor

    Esto nos permitira acceder ahora a proyecto-x ini-

    ciando una conexion al puerto 1234 de razor. En-tonces ahora si haramos:

    occam@razor$ nc localhost 1234Bienvenido al Proyecto X

    Adems donde dice:Por ejemplo, si la mquina proyecto-x ofrece uninterfaz web, una vez establecido el tnel, solo te-nemos que apuntar nuestro navegador a la url:http://entrada/1234 si la redireccin de puertos esremotaEsto ultimo tampoco seria cierto.Espero no haberme confundido y que les sean tilesmis comentarios.saludos!- http://gerelblog.blogspot.com

    ENVIADNOS...

    Vuestros comentarios, sugerencias, ideas, crti-cas (constructivas claro), correcciones, solucio-nes, disoluciones o cualquier cosa que se os ocu-rra... a:

    [email protected]

    LOS ESPERAMOS!!!!

    OCCAMs Razor | 4

  • 8/6/2019 Occams Razor 03-01-02

    5/54

    RATAS DE BIBLIOTECA

    TCClibUtiliza C como tu lenguaje de Script

    por Er Interprete

    Pensando en incorporar un lenguaje descript a tu aplicacin?. Python, Java, Ruby, Gui-le?... eso es para nenazas. Los programadores deverdad usan C incluso para sus scripts.

    Bromas a parte, en este nmero vamos a hablar detcclib, una librera que se distribuye junto a TCC (elTiny C Compiler o Compilador C Pequeito).

    TCC es un compilador de C desarrollado por Fabri-ce Bellard. Es muy pequeo y rpido. Como os podisimaginar no es gcc, pero para ciertas aplicaciones pue-de resultar muy til.Lo que tcclib nos permite, es compilar cdigo C ennuestras aplicaciones de una forma muy fcil y sen-cilla. Ah es nada!. Como siempre vamos directos alcdigo.

    COMPILANDO Y EJECUTANDO

    Aqu tenis el cdigo de un pequeo programa queutiliza tcclib para leer un fichero de texto, compilar-

    lo y ejecutarlo. Este ejemplo es una modificacin delprograma de prueba incluido con las fuentes de tcc,bsicamente para que ocupe poco y nos quepa en estaseccin :). Como siempre recordad que las comproba-ciones de error han sido eliminadas.

    #include #include < s tr i n g . h>#include < l i b t c c . h>

    / A qu i r a e l API q u e o fr ec em os a l o s s c r i pt s /

    void mi_func ( char s t r ) {

    pr in tf ("PRINCIPAL(mu_funcion): %s " , st r ) ;}

    i n t

    main ( i nt argc , char arg v [ ] ){

    TCCState s ;FILE f ;char b [ 1 0 2 4 ] ;i n t ( un_script )( char ) ;unsigned long v ;

    / Lee s c r i p t /memset ( b , 0 , 1 0 2 4 ) ;

    f = f op e n ( a r gv [ 1 ] , " r t " ) ;f re a d ( b , 1 02 4 , 1 , f ) ; f c l o s e ( f ) ;

    / C o n f igu r a mo s y co mp i l am o s /

    s = t cc _n ew ( ) ;p r i n t f (" S ett i n g c o m p i l er %p \n " , s ) ;tcc_set_output_t yp e ( s , TCC_OUTPUT_MEMORY) ;t c c _ c om p i l e_ s t r in g ( s , b ) ;

    / A a di mo s n u e s t r o e s p e c i a l API /tcc_add_symbol ( s , "mi_func" ,

    ( unsigned long)&mi_func ) ;t c c _ r e l o c a t e ( s ) ;

    / Ejecutamos /tcc_get_symbol ( s , &v , "mi_script " ) ;m i _ s c r i p t = ( void) v ;mi_scrip t ( "Hola ! ! ! " ) ;t c c _ d e l e t e ( s ) ;

    }

    S, vale, esto parece un poco ms complicado que loque solemos incluir en esta seccin, pero enseguidaveremos que es mucho ms sencillo de lo que parece.

    TCC y tcclib compilan cdigo C

    realmente rpidoLo que este programa hace es cargar un fichero detexto que contendr cdigo C. La nica condicin quedebe cumplir es definir la funcin "mi_script", querecibir como parmetro una cadena de caracteres.

    Por otra parte, el programa exporta una funcin, lla-mada mi_func que puede ser utilizada por nuestrosscripts, para, por ejemplo, comunicarse con la aplica-cin principal... seguro que se os ocurren mil ideas.

    LAS LLAMADAS A TCCLIBComo podis observar, utilizamos una variable del ti-po TCCState para referirnos a lo que podramos lla-mar nuestra instancia del compilador. Una vez creada(con tcc_new), procedemos a configurarla. En nuestrocaso simplemente indicamos que queremos compilaren memoria (tcc_set_output_type).

    tcclib es capaz de generar ejecutables, libreras din-micas o cdigo objeto, adems de la compilacin enmemoria que a nosotros nos interesa.

    Tras esto, utilizamos tcc_compile_string. Esta fun-

    cin, como os podris imaginar, transforma una ca-dena de caracteres que contiene cdigo C en cdigoejecutable... es decir, compila la cadena, como su pro-pio nombre indica :).

    5| OCCAMs Razor

  • 8/6/2019 Occams Razor 03-01-02

    6/54

    RATAS DE BIBLIOTECA

    Ahora que tenemos nuestro cdigo compilado, nos in-teresan dos cosas. La primera es que nuestro scriptpueda llamar a funciones definidas por nuestro pro-grama y por tanto se pueda utilizar como un lenguajede script. La segunda es poder referenciar las funcio-nes definidas por nuestro script y que hemos compi-lado en memoria, para, por tanto, ejecutar el cdigo

    que contiene.Lo primero se consigue con la llamada a la funcintcc_add_symbol. Esta funcin recibe como parme-tros el nombre de la funcin que se desea aadir (real-mente un smbolo) al sistema, y un puntero al cdigode dicha funcin.Para lo segundo (ejecutar el cdigo que proporcio-na el script) utilizamos la funcin tcc_get_symbol,que realiza la operacin complementaria atcc_add_symbol. En el programa es necesario utili-zar una variable auxiliar debido a como est definidaesta funcin.Una cosa importante. Antes de poder ejecutarla funcin tcc_get_symbol, es necesario ejecutartcc_relocate. No vamos a entrar en explicaciones, pe-ro esta funcin lleva a cabo el proceso de relocacinque normalmente realiza el cargador de programas oel linker dinmico.

    tcclib nos permite compilar, lin-kar y ejecutar de forma sencilla

    Tened en cuenta que tcclib nos permite llevar a cabotodo un proceso que normalmente requiere de variasherramientas: compilador, linker, cargador.

    EL SCRIPT

    Ahora que ya sabemos como funciona nuestro progra-ma, vamos a escribir nuestro primer script y ver sitodo esto funciona.

    i n t m i _ sc r i p t ( char st r ){

    p r i n t f ( " H ol a s o y un s c r i p t . ""Miparmetro es : %s \n" );

    mi_func (" Sc rip t l lamandoa t ie rr a ! ! " ) ;

    return 0 ;}

    Simple no?, pero con bastante informacin. Lo pri-mero que vemos es que se trata de cdigo C estndar.Lo segundo es que estamos utilizando la funcin printfsin ms. Esto es as porque nuestro programa princi-pal incluye la librera C estndar. Para utilizar otraslibreras, echadle un ojo a la funcin tcc_add_file.Lo tercero es que estamos ejecutando la funcinmi_func que nuestro programa principal exporta.Gay!. Basta de rollo, vamos a compilar y comprobarel resultado de una ejecucin.

    occam@razor $ gcc -o test test.c \

    > /usr/local/lib/libtcc.a -ldl

    occam@razor $ ./test script.c

    Hola soy un script. Mi parmetro es: Hola!!!

    PRINCIPAL:Script llamando a tierra!!

    Como podis ver, libtcc es una librera esttica y nor-malmente la tendris instalada en /usr/local/lib. Lalibrera dl (dynamic linking) tambin es necesaria. Sino la utilizis obtendris un error referente a funcionescomo dlopen o dlsym.

    Usando TCC podis utilizar ellenguaje C como lenguaje descript ejecutando cdigo nativo!!

    Lo segundo es que si habis copiado los ejemplos alpi de la letra, veris que vuestro programa no produ-ce la salida esperada... veris algunos "marcianitos".El script tiene un error. Es muy tonto, as que seguroque ya lo habis visto. Lo interesante de esto es que

    solo tenis que abrir el script con vuestro procesadorde textos favorito. modificarlo y ya est... no hay quecompilar nada, como si estuviramos trabajando enPerl, Python, TCL o similares :).

    COMENTARIOS FINALES

    Al principio de este texto oa comentbamos que tcces un compilador muy rpido y pequeo. Esto es algomuy interesante, pero tiene como principal contrapar-tida que el cdigo generado, no est tan optimizadocomo el que pueda generar gcc. Este es el precio apagar por la velocidad y la versatilidad de disponer

    de un compilador como parte de nuestros porgramas.Con esto queremos decir que, cada cosa es para lo quees, y no existen las panaceas :).Por otra parte, en el momento de escribir este artculo,fu necesario obtener tcc de su CVS de desarrollo ensavanah. El paquete en la web, no compila en los siste-mas modernos y las distribuciones, al menos Ubuntu,solo incluyen el compilador tcc, y no la librera tcclib.El proceso de instalacin es el habitual configure, ma-ke y make install.La versin del CVS parece que tambin funciona enWindows, pero eso no lo hemos probado, as que si

    alguno se anima a probarlo y confirmarlo, esperamossus comentarios.Por ltimo, y como viene siendo habitual, recomen-daros que le echis un ojo a libtcc.h. Veris que hayvarias funciones que aqu no hemos comentado peroque os resultarn muy tiles en vuestros programas.Tambin os recomendamos una visita a la pgina delseor Fabrice Bellard (http://fabrice.bellard.free.fr/),donde encontraris cosas realmente interesantes... Aalguien le suena qemu?Hasta el prximo nmero.

    OCCAMs Razor | 6

  • 8/6/2019 Occams Razor 03-01-02

    7/54

    MALA BESTIA

    vim. Pequeo pero MatnO lo quieres o lo odias

    por Er Escribano

    S compaeros, vim, la versin mejorada devi es una mala bestia, ah donde lo veis. En es-te artculo vamos a profundizar en las caracte-rsticas menos conocidas y ms potentes de esteomnipresente editor de textos, que no son pocas.

    Muchos os preguntaris: Por qu debera aprender

    a utilizar vim cuando tengo unos editores tan chulosque me hacen la vida tan sencilla y que puedo empe-zar a manejar con mi ratn sin conocer ningn oscuroconjunto de comandos?. A esta pregunta podramosresponder de tres formas.La primera es que menudo pedazo de pulmones quetenis para soltar del tirn semejante pregunta :).La segunda es que usis el sistema UNIX que usis, loms probable es que el editor que os encontris segurosea vi. Da igual que se trate de un Linux, un Solariso un HP-UX, vi estar all. S vale, vi no es vim, peroel uso bsico de ambos editores es el mismo.La tercera es que vim es una mala bestia. En segui-da veris la potencia de este pequeo editor de textosque, os enamorar o conseguir que terminis odin-dolo completamente :).

    LO BSICO

    Por si algn despistado no ha utilizado nunca vim,vamos a incluir esta pequea seccin con lo bsico pa-ra, simplemente, poder usarlo. Lo primero que debesaber el no iniciado sobre vim es que tiene tres modosde funcionamiento. A saber:El modo edicin/insercin. Este es el modo que cual-

    quier usuario espera en un editor de textos... pulsasteclas y el texto comienza a aparecer en el documento.

    Vim es mucho ms fcil de utili-zar de lo que parece

    El modo comando. En este modo, cuando un usua-rio pulsa una tecla le indicar a vim que realice unadeterminada accin. Podis pensar en ello como en

    Hot-keys para acceder a un men, pero sin men.Finalmente, vim proporciona un modo de linea de co-

    mando en el que podemos pedirle que haga cosas mscomplejas que las que nos permite el modo comando.Por defecto, vim arranca en el modo comando. Parapoder escribir, necesitamos cambiar a modo edici-

    n/insercin. Esto se puede hacer con distintos coman-dos, es decir, pulsando alguna de estas teclas:

    i Inicia insercin en la posicin del cursora Inicia insercin despus de la posicin del cursorA Inicia insercin al final de la lnea actualo Inicia insercin en una nueva lnea, debajo de la ac-

    tualO Inicia insercin en una nueva lnea, encima de la ac-

    tual

    Para volver al modo comando, basta con pulsar la te-

    cla ESC. Aunque existen multitud de comandos, losque probablemente mas utilicis (y con los que se pue-de escribir cualquier texto) son los siguientes:

    0 Mueve el cursor al principio de la lnea$ Mueve el cursor al final de la lnea

    dd Borra/Corta la lnea actualD Borra los caracteres desde la posicin del cur-

    sor hasta el final de la lneaJ Junta la lnea inferior y la lnea actualx Borra el carcter sobre el que se encuentra el

    cursor/cadena Busca cadena en el texto hacia delante?cadena Busca cadena en el texto hacia atrs

    n Busca la siguiente ocurrencia de una bsquedainiciada con / o ?

    N Busca la ocurrencia anterior.yy Copia la lnea actualp Pega la/s lneas copiadas/cortadas debajo de

    la lnea actualP Pega la/s lneas copiadas encima de la lnea

    actual

    Finalmente, para iniciar el modo de lnea de coman-do, solo tenemos que pulsar el carcter : cuando nosencontremos en modo comando. En la parte inferiordel texto aparecern los : y a continuacin podremosescribir nuestro comando. En esta seccin para no ini-ciados, los comandos mnimos que tenis que conocerson estos:

    :w nombre Graba los cambios en un fichero llamadonombre

    :w Graba los cambios:q Sale:q! Fuerza salida aunque existan cambios sin

    grabar.:wq Graba los cambios y sale

    Bueno, hasta aqu lo ms bsico para poder trabajar

    con vim. Si os fijis, aprendiendo estos pocos coman-dos podris utilizar vim para cualquier tarea bsica. Ycomo podis comprobar no es tan terrible... de hecho,enseguida veris que es una pasada.

    7| OCCAMs Razor

  • 8/6/2019 Occams Razor 03-01-02

    8/54

    MALA BESTIA

    ALGUNAS GENERALIDADES

    Si os habis fijado en los comandos que forman nues-tra gua bsica de supervivencia con vim, todos ellosguardan una cierta simetra. Por ejemplo, la diferen-cia entre maysculas y minsculas es en general muyevidente (comandos o o n), la letra elegida para elcomando suele estar relacionada con lo que hace (i in-

    sertar, a aadir, p pegar, n siguiente -next/,...), peroadems, existen una serie de caractersticas generalesen el modo comando.La ms importante es la capacidad de repetir un cier-to comando tantas veces como deseemos, simplementeescribiendo un numero antes de ejecutar el comando.Por supuesto, esto hay que realizarlo en modo coman-do. Veamos algunos ejemplos:

    Podemos repetir cualquier co-mando precedindolo de un n-meroSi pulsamos 10 seguido del comando x, ejecutaremos elcomando borrar caracteres 10 veces, con lo que borra-remos 10 caracteres. Si queremos borrar las dos lneas

    justo debajo de nuestra posicin pulsaremos 2dd. Ysi queremos borrar las cuatro lneas de arriba pulsare-mos 4DD... No, si pulsis 38FF no saldr una macizapechugona.Este ltimo comando dd, no solamente borra lneas,sino que adems las copia, de forma que se puedenpegar posteriormente. Es el equivalente al Cortar de

    los clsicos mens de edicin de la mayora de aplica-ciones grficas.En general, cortar lneas para borrar trozos de nues-tro texto o copiarlos es bastante tedioso, as que vimproporciona un modo de seleccin visual:

    SHIFT+V Activa el modo de seleccin visual paralneas. En este modo solo podremos se-leccionar lneas completas.

    CTRL+V Idem pero para bloques... ste tenis queprobarlo. Pocos editores son capaces dehacer esto :).

    Una vez que tengis seleccionado vuestro bloque detexto (se mostrar en vdeo inverso), solo tenis queejecutar el comando que queris sobre l. As, ddcortar el bloque seleccionado o yy lo copiar, deforma que podremos pegarlo posteriormente con elcomando p en otra parte del documento.Enseguida veremos que esta forma de seleccin se pue-

    de utilizar directamente en el modo de lnea de coman-dos.Por ltimo comentar que tenemos una tercera opcinpara manejar bloques dentro de nuestro documento.Son las marcadores o bookmarks.Para poner una marca en una lnea solamente tenemosque pulsar la tecla m, seguida de un carcter. Este ca-rcter sera el identificador de nuestra marca. As lasecuencia de teclas ma, adems de un homenaje t-cito a la legendaria serie de televisin El Equipo A,asignar el marcador a a la lnea actual.Pulsando la tecla seguida del nombre del marca-dor, nos moveremos a la posicin asociada al mismo.Como veremos muy pronto, podremos utilizar marca-dores para referenciar bloques de texto, en comandosms complejos.

    LINEA DE COMANDOS

    Bien, vamos a empezar con las cosas interesantes. Lamayora de lo que comentaremos a continuacin tieneque ver con el modo de lnea de comandos de vim,que si recordis se activa pulsando la tecla : cuandoestamos en el modo comando.Quizs el comando mas til, o al menos el que yo msuso es el comando s. Los que hayis trabajado consed o Perl lo conoceris bien. Este comando permitelocalizar un patrn en el texto (utilizando expresionesregulares) y sustituirlo por otra cosa. Su sintaxis esesta:

    s/origen/destino/flags

    El flag que ms nos interesar es el g, que realiza laoperacin sobre todas las ocurrencias de origen enuna determinada lnea. Si no utilizamos este flag lasustitucin se realizar, nicamente, sobre la primeraocurrencia.

    El modo lnea de comando es elque nos ofrece las posibilidadesms interesantes

    Veamos un ejemplo. Supongamos que estamos hacien-do nuestra pgina web y decidimos que queremos me-ter las imgenes en un directorio en lugar de dejarlasen el directorio base con las pginas. Abrimos nuestrapagina en vim y ejecutamos:

    :%s/src="\(.*\)"/src="images\/\1"/

    El carcter % al principio de la lnea indica que elcomando se ejecutar sobre todo el fichero, de lo con-trario, solo se ejecutara sobre la lnea actual. En lugardel % podemos proporcionar rangos especficos:

    OCCAMs Razor | 8

  • 8/6/2019 Occams Razor 03-01-02

    9/54

    MALA BESTIA

    :1,5s/pepe/Manolo/

    :1,$s/Gavilan/Paloma/

    :10,$s/foo/bar/

    :a,bs/AAAA/BBB/

    Si os decimos que el carcter $ representa el finaldel fichero y que a y b son marcas de las que habla-mos antes.... estas expresiones no tienen ningn secre-to verdad?Si recordis, algunas lneas antes hablbamos del mo-do de seleccin visual a los que accedamos con lascombinaciones de teclas SHIFT + V o CTRL + V. Siseleccionis un bloque de texto de esta forma y entrisen modo linea de comandos (pulsando :) vim autom-ticamente seleccionar ese rango para la ejecucin delcomando que deseemos. Lo que veris es algo comoesto:

    :

    Si, como os podis imaginar son dos marcas quevim genera automticamente en el modo de seleccinvisual.

    El comando s/// da otra dimen-sin al concepto de buscar y sus-tituir

    Por si alguno no est familiarizado con las expresio-nes regulares, vamos a hacer dos comentarios sobre elejemplo anterior. El primero es que el uso de los parn-

    tesis (que hay que escapar con el carcter \) permitenguardar en memoria el texto que cumple la expre-sin regular dentro de ellos. En nuestro ejemplo, nosestamos quedando con el nombre de la imagen, quedebe estar entre comillas.Para utilizar estos valores en la segunda parte del co-mando s utilizamos la expresin \n, donde n repre-senta el parntesis n-simo de la primera parte. Comopodis ver, las expresiones regulares pueden llegar aser muy engorrosas debido a la necesidad de escaparlos caracteres que tienen significado propio... pero sonrealmente potentes.Por cierto, si no lo habis probado, que sepis que lalnea de comandos de vim funciona como la de bash,es decir, con el cursor arriba podis acceder a los co-mandos que acabis de escribir (vamos la historia) ycon el tabulador podis autocompletar los comandos.Esto ser ms interesante un poco ms adelante.

    COMANDOS INTERESANTES

    vim proporciona una inmensa cantidad de comandos,para que cualquiera pueda estar entretenido un buenrato leyendo. Para los que os guste leer, aqu esta elprimer comando interesante:

    :help

    :)... S, podis hartaros de leer la ayuda de vim o seguirleyendo este artculo. Comentar en este punto, que la

    ayuda de vim es excelente. Todo lo que comentemosen este artculo est en la ayuda on-line, pero aqu oslo presentamos ms resumido y sencillo :).Hay dos comandos especialmente tiles y potentes. Elprimero es ! y el segundo es r.El comando !, permite ejecutar un comando shell,bueno, no solo eso, permite pasarle al comando shell

    parte del texto que estamos escribiendo y sustituirlopor la salida del programa que ejecutemos.El comando r permite leer datos de un fichero, perosi lo que sigue es una ! y un comando shell, lo queobtendremos es la salida de ese comando.Por ejemplo, para aadir la fecha actual a nuestro do-cumento, solo tenemos que ejecutar:

    :r ! date

    O para incluir un bonito calendario en nuestro docu-mento solo tenemos que :

    :r ! cal 1 2008

    Pero como os decamos, el comando ! es realmente po-tente. Veamos un ejemplo de una aplicacin realmentecomn... quedar a tomar unas birras. Alguien enva laconvocatoria por correo (por ejemplo), y la gente seempieza a anotar y a proponer el da que le viene bien.El pringao responsable de organizar esto, es ademsun geek y mantiene su lista en un fichero de texto queedita con vim. El fichero sera algo como esto:

    Pepe 14

    Manolo 17

    Josefina 11

    Eufrasia 13

    Si ahora queremos ordenar nuestro fichero por nom-bre, solo tenemos que ejecutar un comando como este.

    :% ! sort

    O si los quiere ordenar por la fecha que prefieran, solotiene que ejecutar:

    :% ! sort -k 2

    :)... podis ejecutar cualquier programa shell, pasarleun fragmento de texto para que lo procese y sustituirla salida del programa en el texto que estis escribien-

    do...ALGO UN POCO MS VISUAL

    Aunque en un primer momento, vim parece bastanteaustero visualmente hablando, como se suele decir, lasapariencias engaan. Disponemos de varios comandospara dividir la pantalla y de esta forma ver varios fi-cheros a la vez.Si queremos dividir la pantalla verticalmente solo te-nemos que ejecutar un comando como este:

    :vsplit otro_fichero.txt

    Pero si lo que nos mola es hacerlo horizontalmente, nohay problema.

    :split otro_fichero_mas.txt

    9| OCCAMs Razor

  • 8/6/2019 Occams Razor 03-01-02

    10/54

    MALA BESTIA

    Para navegar a travs de los distintos ficheros, enmodo comando, pulsamos la tecla CTRL seguida de

    ww.

    vim nos permite colapsar y ex-pandir bloques de texto de formamuy sencilla.

    Pero eso no es todo. Como muchos habris observado,los editores ms modernos, sobre todo los orientadosa programacin, proporcionan una facilidad para co-lapsar bloques de texto de forma que podemos quitarde nuestra vista partes del texto que no nos interesanen un momento dado..., comentarios, funciones sobre

    las que no estamos trabajando, etc... Bien, pues estafuncionalidad tambin esta disponible en vim.Para colapsar un bloque de texto, lo seleccionamosutilizando el modo de seleccin visual, por ejemplo, ypulsamos las teclas zF. Para expandir un bloque detexto colapsado solo tenis que situaros en la lnea deturno y pulsar za.Podemos anidar estos bloques de texto e ir expandin-dolos uno a uno, o expandirlos todos de una sola vezutilizando el comando zA... como es lgico :). Paravolver a colapsar un determinado bloque solo tenisque volver a pulsar zc o zC si queremos aplicar la

    operacin sobre todos los bloques recursivamente.

    VIM Y LOS PROGRAMADORES

    A juzgar por la cantidad de caractersticas relaciona-das con la programacin, muchos programadores de-ben utilizar vim. Vamos a ver algunas de las ms im-portantes de estas caractersticas a continuacin.Como comentamos un poco ms arriba, la capacidadde colapsar y expandir bloques de texto es muy tilcuando se escriben programas, permitindote dispo-ner de ms sitio para ver las cosas que realmente teinteresan.

    Esta funcionalidad, cuando estamos programando sevuelve mas til ejecutando el siguiente comando::set foldmethod=syntaxA partir de ese momento, no necesitaremos seleccionar

    bloques de texto, vim los seleccionar por nosotros de-pendiendo del realzado de sintxis que est utilizando.

    Existen otros mtodos que pueden resultar mas tilespara otras aplicaciones.Tambin vimos como podemos ejecutar comandosshell desde vim, pero adems, para el caso de compila-cin de programas, vim ofrece una serie de facilidadesadicionales.El primer comando que nos interesa es make, que ob-viamente realiza la misma operacin que el programahomnimo disponible en nuestros sistemas. Sin embar-go, este comando nos proporciona algunas ventajas.Vamos a verlo.Escribid un sencillo programa C, con algn error in-tencionado. Grabad el fichero con el nombre miprogra-ma.c (esto se hace con el comando :w miprograma.c)y luego ejecutad lo siguiente

    : make miprograma

    Veremos una serie de errores, y tras pulsar una teclavolvemos a nuestro editor. Ahora escribid el siguientecomando:

    : copen

    Mola!... todos los errores listados... pero lo mejor detodo es que podemos navegar por ellos, ya sea a travsde la propia ventana (Quickfix List) o utilizando loscomandos :cnext y :cprev.

    OCCAMs Razor | 10

  • 8/6/2019 Occams Razor 03-01-02

    11/54

    MALA BESTIA

    Si, tenis razn, es un poco pesado el escribir todoel rato esos comandos tan largos... as que vamos amapear unas teclas al efecto.

    : map :cn

    : map :cp

    Vaya!, no est nada mal. Como podis ver asignar

    comandos a teclas o combinaciones de las mismas esbastante sencillo :). Ms sobre esto dentro de un mo-mento.Una vez que hayis corregido todos vuestros errores,podis cerrar la ventana con el comando :close

    ALGUNAS AYUDAS MS A LA PRO-GRAMACIN

    Algo que siempre se necesita, especialmente los queutilizan Python. El indentado. Aunque existen multi-tud de opciones para controlar esta importante carac-terstica, los comandos son especialmente tiles,permitiendo disminuir o aumentar el nivel de inden-tado de un determinado bloque de texto o linea.Si se os ha ido de madre la edicin, recordad que siem-pre podis hacer un:

    !%indent

    Para que alguien deje las cosas en orden por vosotros:).

    La otra caracterstica til a la hora de escribir progra-mas de un cierto tamao, es la navegacin a travs delcdigo. Aqu tenemos dos funcionalidades muy tiles:abrir ficheros cuyo nombre se encuentra en el texto, ylos tags.

    Las facilidades que vim ofrece alos programadores, hacen de luna excelente eleccin para estatarea.

    Vamos con la funcionalidad para abrir ficheros referen-ciados en nuestro texto. Un caso tpico son los includesde los programas C. Para usar esta funcionalidad solo

    tenis que poner el cursor sobre el nombre del fichero,en vuestro programa y pulsar las teclas gf.Para que esta funcionalidad resulte til necesitamosalgo para poder navegar por los ficheros que tenemosabiertos en nuestro editor. Para ello, disponemos dedos opciones: los buffers y los tabs.Para acceder a la lista de buffers abiertos en un de-

    terminado momento utilizamos el comando :files o:buffers. Este comando nos proporcionara una listanumerada. Podemos utilizar esos nmeros junto conel comando :buffer para movernos a travs de nuestralista de buffers.Como es habitual, disponemos de un montn de co-mandos para manipular estos buffers. Los ms intere-santes los comentamos a continuacin:

    :buffers Lista de buffers:buffer N o :b N Edita el buffer N

    :bn Nos movemos al buffer siguiente:bp Nos movemos al buffer anterior

    :sbn N Divide la pantalla y va al buffer N

    La otra opcin para trabajar con varios ficheros a lavez es utilizar tabs. Los tabs, a diferencia de los buffersse muestran en la parte superior de la pantalla.

    En nuestro ejemplo anterior, en el que abramos unfichero .h, si pulsamos CTRL+W antes del comando

    gf, el fichero .h se abrir en un nuevo tab. Pode-mos comprobar la lista de tabs, as como su contenidoutilizando el comandos :tabs.Y a que no os imaginis como podis pasar de un tab aotro?... Si, claro que s, utilizando los comandos :tabny tabp.El otro comando relativo a los tabs que os puede in-teresar es :tabe nombre-fichero. Como os imaginaris,este comando abrir el fichero indicado en un nuevotab para su edicin.

    USANDO TAGS

    Otra funcionalidad de inters para los programadoreses el uso de los tags. Los tags nos permiten acceder deforma rpida a las definiciones de funciones dentro deun programa.

    11| OCCAMs Razor

  • 8/6/2019 Occams Razor 03-01-02

    12/54

    MALA BESTIA

    Los tags son generados por un programa externo lla-mado ctags. Podis ejecutarlo desde la lnea de co-mandos o directamente desde vim:

    :!ctags *c *h

    Los comandos mas interesantes para trabajar con tagsson los siguientes:

    :tag Localiza el tag tagnameCTRL-] Nos mueve al tag sobre el que

    se encuentra el cursorCTRL-T Vuelve a la posicin anterior

    :ptag Localiza el tag tagname, y loabre en una ventana de pre-view

    CTRL-W } Muestra el tab bajo el cursoren una ventana de preview

    CTRL-W z Cierra la ventana de previewabierta con el comando ante-rior

    Si el fichero de tags para nuestro programa ha sido ge-nerado, podemos acceder a una determinada funcinal lanzar vim, utilizando la siguiente lnea de coman-dos:

    $ vim -t funcion

    De esta forma, vim buscar que fichero define la fun-cin que pasamos como parmetro y lo abrir auto-mticamente.

    VIM PARA NO PROGRAMADORES

    Hasta ahora hemos visto un montn de funcionalida-des orientadas a la programacin, pero vim es un edi-tor de propsito general y ofrece otras funcionalidadesque muchos usuarios genricos agradecern.Lo primero que puede resultar interesante para elusuario comn es la posibilidad de utilizar el ratn.Para ello ejecutamos el siguiente comando:

    :set mouse=a

    El uso del ratn se puede activar de forma indepen-diente en cada uno de los modos de operacin de vim(normal, visual, insercin,...). El carcter a en el co-mando anterior indica a vim que active el ratn entodos los modos.Activar el ratn nos permitir posicionar el cursor ennuestro texto o utilizar la rueda para desplazar el tex-to arriba o abajo. Tambin podremos utilizar el ratnpara seleccionar bloques de texto en modo visual. Allcada cual, la verdad es que una vez que te acostum-bras a utilizar las teclas, el ratn es mucho ms lento:).Otra funcionalidad que puede resultar til es el uso deabreviaturas, sobre todo cuando estamos escribiendo

    un documento en el que ciertas palabras largas se repi-ten con mucha frecuencia. Para crear una abreviaturautilizamos el comando :iabbrev o simplemente iab. Porejemplo:

    :iab ester esternocleidomastoideo

    A partir de ese momento, cada vez que escribamosla palabra ester en nuestro texto, se sustituir auto-mticamente por el nombre completo de este conocidomsculo.Podemos eliminar las abreviaturas con el comando

    :una o :unabbreviate o eliminarlas todas con el co-mando :iabclear.La i al principio del comando le indica a vim quela abreviatura se utilizar en modo insercin, es de-cir, cuando estamos escribiendo. Pero podemos crearabreviaturas para el modo lnea de comandos. Esto seconsigue sustituyendo la i inicial por una c.

    :cab ls files

    Ahora cada vez que escribamos ls en la lnea de co-mandos este ser sustituido por files.

    MAPEADODe forma similar funciona el mapeado, pero en estecaso asociamos secuencias de caracteres a teclas con-cretas de nuestro teclado. Al igual que sucede con lasabreviaturas, el mapeado de teclas se puede realizarde forma independiente para los distintos modos deoperacin. Concretamente.

    normal nmap o mapvisual vmap o mapinsert imap o map!

    command-line cmap o map!operator-pending omap o map!

    La forma de utilizar estos comandos es muy senci-lla, y ya la introdujimos de forma indirecta cuandohablamos de las facilidades que vim nos ofreca paraprogramar. Pero las posibilidades que el mapeado deteclas de vim nos ofrece van mucho ms all. Veamossolo un par de ejemplos:

    :imap n

    Este comando nos permite utilizar la tecla F3 en mo-do edicin a modo de buscar siguiente. Cada vezque pulsemos F3 la secuencia de teclas ESC, cursor

    derecho, comando n y vuelta a modo insercin seejecutar. Si recordis, el comando n nos permite mo-vernos a la siguiente ocurrencia de una bsqueda, peropara ello debemos estar en modo comando (pulsando).Y aqu un par de mapeados que os pueden resultartiles o cuanto menos familiares:

    :map :w

    :vmap yy

    :imap p

    Finalmente, y para terminar con este grupo de faci-

    lidades para lidiar con tareas repetitivas, vim, comola mayora de editores de textos, permite grabar se-cuencias de operaciones y posteriormente repetirlas deforma muy sencilla.

    OCCAMs Razor | 12

  • 8/6/2019 Occams Razor 03-01-02

    13/54

    MALA BESTIA

    Para empezar a grabar nuestras acciones tenemos queutilizar el comando q, seguido de un caracter queidentificar la secuencia de acciones que realizaremosa continuacin. Cuando hayamos terminado, simple-mente debemos pulsar q de nuevo para finalizar lagrabacin.A partir de este momento cada vez que pulsemos la

    tecla @ seguida del identificador que seleccionamosal iniciar nuestra grabacin, la secuencia de accionesgrabadas ser reproducida.Esta funcionalidad, en combinacin con la capacidadde vim para ejecutar un comando varias veces sim-plemente indicando el nmero de vez que lo queremosejecutar, es una muy potente herramienta para llevara cabo modificaciones mecnicas en un texto de formamuy rpida.

    PERSONALIZANDO VIM

    A lo largo de este artculo hemos visto un montn de

    caractersticas muy interesantes de vim, pero ningu-na de ellas permanente, es decir, cuando cerremos lasesin actual, perderemos todas nuestra abreviaturas,mapeados de teclas y dems configuraciones.Semejante mala bestia no poda haber pasado por altoalgo tan obvio como esto, y por su puesto que no lo hahecho. Para ello no tenemos ms que editar el fichero.vimrc que encontraremos en nuestro directorio home.No tenis ms que editarlo y aadir cualquiera de loscomandos que hemos visto en este artculo, o cualquierotros que hayis encontrado vosotros mismos (hay unmontn ms :)Uno de los comandos que es recomendable aadir a.vimrc es syntax on, en el caso que os hayis percata-do que el realzado de sintaxis no funciona por defectoen vuestra instalacin de vim.Otros comando de inters, y del que no hemos habla-do explcitamente a lo largo de este artculo es set.Este comando nos permite establecer los valores deciertas variables globales de vim que condicionan sucomportamiento. Algunas de estas variables las hemosido introduciendo junto con la funcionalidad relacio-nada, pero hay otras muchas. Aqu os incluimos unalista de las ms tiles:

    set number Muestra nmeros de lneaset tabstop=4 Modifica el tamao de los ta-buladores

    set list Muestra caracteres especia-les

    set incsearch Realiza las bsquedas segnla tecleamos

    set laststatus=2 Muestra la barra de estadopermanentemente

    set autoindent Activa la autoindentacin.til para programar

    set bg=dark Modifica los colores si el fon-do de pantalla es oscuro

    set bg=light Idem pero con fondo de pan-

    talla claro.set all Muestra el estado de todas

    las variables.

    No, no existe un comando unset. Normalmente paradesactivar una opcin se utiliza el mismo parmetroutilizado para activarla, pero precedido de no. As,los siguientes comandos desactivan las opciones ante-riores.

    set nonumber

    set nolist

    set noincsearchset noautoindent

    Por supuesto todos estos comandos los podis incluiren vuestro .vimrc para que cada vez que lo arranquistodo est como a vosotros os gusta :)

    MS PERSONALIZACIN

    Esta seccin es solo para los ms curiosos, o simple-mente para los que hayis ledo hasta aqu. No vamosa profundizar en ellas porque normalmente, un usua-rio normal no tendr que utilizarlas nunca, pero un

    usuario avanzado, debe, al menos, saber que existen.Pues s, vim proporciona su propio lenguaje de scrip-ting, con el que poder aadir nuevos comandos si esque habis encontrado algo que todava no hace. Ellenguaje es relativamente sencillo y en internet po-dris encontrar varios tutoriales para iniciaros en l.La otra funcionalidad que podis personalizar es elrealzado de sintaxis. Si bien, pocas cosas debe haberpor ah que vim no sea capaz de colorear, sois muylibres de crear vuestros propios ficheros de realzadode sintaxis para aplicaciones completas.Si estis en este punto, debis saber que todos los fi-cheros que utiliza vim se encuentran en /usr/share/-vim/. All encontraris scripts, ficheros de sintaxis yun montn de sorpresas ms.

    PARA TERMINAR

    Y para terminar un poco de humor. En vuestra sesinde vim teclead alguno de los siguientes comandos:

    :help!

    :help 42

    :help holy-grail

    :help quotes

    Si queris pasar un rato divertido no podis dejar de

    instalar y probar vigor, una versin de vi con un asis-tente como el mtico clip aquel que no nos dejaba enpaz.Tambin existen versiones grficas de vim comogvim que nos proporciona un men para acceder c-modamente a la mayora de las funcionalidades quenos ofrece. Si con todo lo que os hemos contado, toda-va os sigue pareciendo difcil de usar, probad creamfor vim, una serie de macros orientados a facilitar lavida del principiante.Finalmente, si queris comparar ficheros y visualizargrficamente sus diferencias... ah est vimdiff.

    Esto es todo... quin lo dira verdad?... Menuda malabestia!!!.Por cierto, hemos dejado lo mejor para la seccin detrucos. No os la perdis.

    13| OCCAMs Razor

  • 8/6/2019 Occams Razor 03-01-02

    14/54

    DIVULGACIN

    En este artculo hacemos una pequea in-troduccin a la inteligencia artificial (IA). Estadisciplina comprende muchas y diversas reas deconocimiento e investigacin, y sus metodologascada vez se usan ms en la tecnologa actual. Se-guro que habris odo hablar de coches inteligen-tes, bsquedas inteligentes en la web, etc. Aun-que el nivel de inteligencia de estos sistemas esun poco relativo, si es cierto que utilizan mtodos

    provenientes del rea de inteligencia artificial. Eneste artculo tambin nos centraremos un poqui-to en un subcampo bastante importante de la IAllamado machine learning (aprendizaje).

    QU ES LA INTELIGENCIA ARTIFI-CIAL?

    Esta es una buena pregunta que, por desgracia, notiene una contestacin clara. Probablemente la ima-gen ms extendida de la inteligencia artificial podra

    ser la de un robot que se comporta como un humanoadems de parecerse a l, algo al estilo de la pelcu-la Yo, Robot. Sin embargo, la IA comprende muchasotras reas aparte de la robtica.Buscar una nica definicin para la IA es difcil, ases que vamos a recoger diferentes ideas sobre lo quees un sistema inteligente y organizarlas un poco deacuerdo con su finalidad. Nos basaremos en la cla-sificacin que Russell y Norvig presentan en su libroArtificial Intelligence: A modern approach [5]. Las dis-tintas definiciones estn organizadas en la Tabla 1, ya continuacin pasamos a explicarlas en ms detalle.

    Los sistemas que actan como humanos pretenden te-ner un comportamiento similar al de una persona. Eneste caso se supone que el hombre es el ser ms in-teligente, y comparamos la inteligencia de las mqui-

    nas con la suya. El cientfico Alan Turing propuso en1950 el test de Turing. En este test, una persona en-tabla una conversacin durante 5 minutos con el sis-tema artificial que queremos probar. El test se suponesuperado por el sistema artificial si durante ms del30 % del tiempo, la persona no sabe distinguir si lascontestaciones provienen de una persona o de un sis-tema artificial. Existen varios sistemas para engaar ala gente durante una conversacin, como por ejemploel chatbot Mgonz o los programas Eliza y Alice.Sin embargo ninguno ha sido capaz de superar el 30 %

    ante un jurado preparado.

    Es posible que algn lector cinfilo haya pensado en lapelcula Blade Runner al oir hablar del test de Turing.En esta pelcula el polica caza-replicantes (HarrisonFord) aplica un test a las personas para detectar si sonreplicantes. El test de la pelcula se basa en la diferen-te respuesta emptica y emocional de un ser artificialcon respecto a un humano. En realidad el test de em-pata en Blade Runner est muy bien fundamentado,ya que uno de los principales problemas que se plan-tean en la inteligencia artificial es como hacer que un

    robot tenga sentimientos.

    Siguiendo con la clasificacin de sistemas inteligentes,los sistemas que piensan como humanos intentan mo-delar el funcionamiento de la mente humana. A estose dedica ms concretamente la ciencia cognitiva, uncampo interdisciplinar que une la IA junto con la psi-cologa y la neurociencia, con la finalidad de intentarentender como funciona el cerebro de las personas. l-timamente existe un gran inters en informtica e IApor los denominados sistemas cognitivos.

    La idea es crear sistemas artificiales que emulen laforma de entender el mundo tal y como lo hacen laspersonas. Algunos grandes proyectos europeos de in-vestigacin como CoSy [1] se dedican a este rea.

    OCCAMs Razor | 14

  • 8/6/2019 Occams Razor 03-01-02

    15/54

    DIVULGACIN

    Los sistemas que piensan de forma razonada se ba-san en las reglas de la lgica: Scrates es un hombre;todos los hombres son mortales; por lo tanto Scra-tes es mortal. Un sistema basado en reglas de lgicapretende representar los distintos elementos que exis-ten en el mundo y la relacin entre ellos. El principalproblema de este enfoque es que no parece muy facti-

    ble representar todo lo que existe junto con todas susrelaciones.

    Los sistemas que piensan de for-ma razonada se basan en las re-glas de la lgica

    Por ltimo, los sistemas que actan de forma razo-nada vendran a estar representados por agentes ra-cionales. Estos agentes perciben el entorno, razonansobre l, y actan de forma que maximizan la probabi-

    lidad de conseguir un objetivo. Pongamos por ejemploun computador que juega al ajedrez, el famoso DeepBlue de IBM. Deep Blue tiene que localizar las pie-zas del contrario, entender la situacin del juego, y ge-nerar un movimiento que maximice sus posibilidadesde ganar. A lo mejor, alguno se preguntar porqu di-ferenciar los sistemas que actan como humanos de losque actan de forma razonada. Creo que la respues-ta podra ser esta: los humanos, por suerte, tambinactuamos por sentimientos y, a veces, por intuicin.

    Tabla 1. Clasificacin de Sistemas Inteligentes

    La clasificacin anterior es un poco terica e inclu-so filosfica. Sin embargo, podemos presentar la IAsimplemente listando las disciplinas que abarca. Al-gunos ejemplos son: lenguaje natural, representacin

    del conocimiento, razonamiento, aprendizaje, robti-ca, planificacin, visin artificial, teora de juegos, yotras ms. Todas ellas se basan fundamentalmente enla lgica y las matemticas, siendo muy importantesla estadstica y la probabilidad. En este artculo va-mos a centrarnos en el aprendizaje, por ser una de lasreas ms importante dentro de la IA. En la siguien-te seccin describiremos ms detalladamente lo que seentiende por aprendizaje en IA, y despus trabajare-mos con un ejemplo prctico.

    MACHINE LEARNING (APRENDIZAJE)Para describir lo que es Machine Learning (ML), usa-

    remos algunas de las ideas del libro de Tom MitchellMachine Learning [4]. Segn este libro, ML es el cam-po relacionado con las ideas necesarias para construir

    programas que automticamente mejoran (o apren-den) con la experiencia. Esta definicin puede ser unpoco confusa, ya que puede dar la idea de un progra-ma que mejora con el paso del tiempo. Sin embargo,la mayora de las tcnicas utilizadas en ML estn rela-cionadas con aprendizaje en una sola vez, es decir, elsistema aprende de ejemplos que se le muestran una

    vez y luego aplica su aprendizaje posteriormente, pe-ro no modifica lo aprendido la primera vez. Aunquetambin existen mtodos para que el ordenador mo-difique sus modelos aprendidos con el paso del tiempo(aprendizaje continuo), stos todava forman una par-te pequea dentro de ML.

    Otra cuestin importante es qu se entiende poraprender cuando hablamos de ordenadores. En ge-neral, cuando se habla de aprender, la idea es la deencontrar un modelo, basado generalmente en la esta-dstica y la probabilidad, que explique algo, de formaque posteriormente el ordenador sea capaz de recono-

    cer de nuevo ese algo cuando se le presente. Cuandohablo de algo me refiero a situaciones, objetos, accio-nes, o cualquier otra cosa que se os pueda ocurrir quepueda ser reconocido de alguna forma.

    Seamos ms concretos poniendo algunos ejemplos. Po-demos querer programar un ordenador para que reco-nozca los distintos tipos de fruta cuando se le pre-senten. En este caso hablamos de reconocimiento deobjetos. Tambin podemos programar un reconocedorde lenguaje natural. En este caso clasificamos sonidosen palabras y palabras en frases. En cualquiera de losdos casos anteriores el ordenador primero tiene queaprender. En el caso de la fruta, tiene que aprender loque es una manzana y como se diferencia de una na-ranja. En el caso de lenguaje natural, el sistema tieneque aprender cuales son los fonemas que forman unapalabra. Por ejemplo, los fonemas m + e + s +

    a, y por este orden, forman la palabra mesa. Ade-ms, mesa es ya una palabra completa y no habrque aadir ms fonemas, excepto si es plural. Comovemos aqu, existen muchas y diferentes situaciones enlos que el ordenador puede aprender.

    Los sistemas supervisados usanejemplos para aprender

    En este artculo nos centraremos en el aprendizaje su-pervisado. En este tipo de aprendizaje, el ordenadorcrea su modelo usando ejemplos que se le muestran

    junto con su clasificacin. En el ejemplo de la fruta, leensearamos al ordenador cada vez una fruta y le di-ramos su nombre, entonces el ordenador generara unmodelo en base a los ejemplos que le enseamos con su

    correspondiente clasificacin. Despus de aprender, elordenador debera de ser capaz de acertar el nombrede las piezas de fruta que le enseemos posteriormen-te.

    15| OCCAMs Razor

  • 8/6/2019 Occams Razor 03-01-02

    16/54

    DIVULGACIN

    La clasificacin de objetos nos sirve para introducirun nuevo problema muy importante en ML, y es, cu-les son las caractersticas o atributos que el ordenadordebe usar para su modelo. Por ejemplo, en el caso dela fruta, el nombre del vendedor al que se la compra-mos no parece un buen atributo para clasificarla. Sinembargo, el color parece mucho ms adecuado, o qui-

    zs la forma, o el tamao, o quizs estas tres ltimasal mismo tiempo.

    Creo que ahora tenemos un poco ms claro lo queesperamos de un algoritmo de aprendizaje. Primero,que sepa elegir los atributos adecuadas para su mode-lo. Y segundo, que sepa establecer los parmetros delmodelo.

    Cuando hablamos de aprender un modelo, nos refe-rimos la mayor parte de las veces a entrenar un cla-sificador. Un clasificador, tambin llamado hiptesis,es una funcin que clasifica unos atributos de entra-da dentro de uno de los posibles conceptos de salida.

    Pongamos un ejemplo extrado del libro Data Mining,de Witten y Frank [6]. La idea es aprender un clasi-ficador para determinar cuando un da es bueno para

    jugar al ftbol. Para ello tenemos recogidas una seriede medidas durante 14 das con nuestra opinin sobresi el da es bueno o no.

    Tabla 2. Valores de los Atributos para 14 das.

    Tabla 3. Conjunto de Reglas.

    La Tabla 2 muestra los atributos de cada da juntocon su clasificacin para jugar al ftbol (SI o NO),en el atributo jugar. Ahora tenemos que escribir unprograma que analice los datos y nos devuelva nuestroclasificador.

    UN CLASIFICADOR SENCILLO: UNAREGLA

    Uno de los clasificadores mas sencillos que podemosobtener es una simple regla if-then-else. Este cla-sificador se denomina tambin 1R (1-Rule). La idea es

    elegir un slo atributo de entre todos para clasificar elda. Por supuesto, habr que elegir el atributo con elque menos nos equivoquemos. La idea del clasificador1R es la siguiente [6].

    Cogemos un atributo, previsin, y establecemos unode sus valores, soleado, y miramos el valor que se re-pite ms en el atributo que queremos aprender, ennuestro caso jugar. Al atributo a aprender tambinse le denomina concepto y a sus valores se les deno-mina clases. Bien, pues de acuerdo con la Tabla 2, sislo elegimos el atributo previsin junto con su va-lor soleado, entonces la clase que ms se repite en el

    concepto jugar es NO (3 veces NO y 2 veces SI). ComoNO es el ms repetido, creamos una regla del tipo:

    if previsin = soleado then jugar = NO

    Si aplicamos slo esta regla, nos habremos equi-vocado en dos ocasiones de las 5 posibles cuandoprevisin=soleado (las dos veces en que jugar=SI),es decir, cometemos un error de 2/5.

    Ahora repetimos el proceso con el resto de atributos ysus valores, obteniendo la Tabla 3. Vemos que en esta

    tabla tambin hemos calculado un error total por cadaconjunto de reglas correspondiente a un solo atributo.Para ello simplemente sumamos los errores de cadaregla.

    OCCAMs Razor | 16

  • 8/6/2019 Occams Razor 03-01-02

    17/54

    DIVULGACIN

    Ahora slo nos falta elegir el conjunto de reglas corres-pondiente al atributo con menor error total. En nues-tro caso podemos elegir entre el atributo previsin oel atributo humedad, pues los dos tienen un error totalde 4/14. Siguiendo la idea de Occams razor, elegimosla regla ms simple:

    if humedad = alta then jugar = NO

    elseif humedad = normal then jugar = SI

    Alternativamente, la regla eligiendo el atributoprevisin sera como sigue:

    if previsin = soleado then jugar = NO

    elseif previsin = nublado then jugar = SI

    elseif previsin = lloviendo then jugar = SI

    El pseudocdigo para calcular el conjunto de reglasfinal podra ser algo parecido al siguiente:

    Para cada atributo,

    Para cada valor del atributo,

    encontrar la clase ms frecuente

    generar una regla asignando esta clase

    Calcular el ratio de error total del \

    conjunto de reglas

    Elegir el conjunto de reglas con menor error total

    Bueno, pues ya hemos programado un algoritmo deaprendizaje para saber si jugar al ftbol o no. Ahoraslo sera cuestin de utilizar la regla final elegida yaplicarla a cada nuevo da.Vamos a repasar cuales son las diferentes componen-tes del sistema de aprendizaje de 1R. Primero tenemoslos datos iniciales (Tabla 2) tambin llamados datosde entrenamiento. Luego tenemos la forma del modelo(o hiptesis) que queremos aprender, en este caso unaregla if-then-else. Luego tenemos el mtodo paraelegir los parmetros de nuestro modelo (pseudocdi-go). Y finalmente tenemos los parmetros de nuestromodelo, que son el atributo elegido (humedad) y susvalores (alta, normal). Este esquema de aprendizajees el ms comn en los mtodos de Machine Learning.Y llegados a este punto terminamos esta breve intro-duccin a la inteligencia artificial y al aprendizaje. Es-peramos que os haya gustado y que en alguno se haya

    despertado el inters por la IA. Tambin nos gustaramucho que nos dierais vuestra opinin para saber siqueris que sigamos con este tema.

    ALGUNAS NOTAS ADICIONALES

    El libro Artificial Intelligence: A modern ap-proach [5] es una lectura bsica para todo aquel

    que quiera introducirse en la IA. Este libro esusado por ms de 1000 universidades en 91 pa-ses. Del mismo modo los libros Machine Lear-ning [4] y Data Mining [6] son referencia obliga-da en el rea de aprendizaje. Todos los mtodosexplicados en el libro Data Mining, incluido 1R,estn progamados en lenguaje Java y pueden ser

    encontrados en el software de aprendizaje de li-bre distribucin WEKA [2]. De hecho, parte dellibro explica como usar WEKA.

    La vida de Alan Turing es muy interesante. Tra-baj como desencriptador durante la segundaguerra mundial y fue perseguido por sus ten-dencias homosexuales. Su muerte an no estaaclarada. Adems del test de Turing, Alan Tu-ring tambin creo la mquina de Turing, base lainformtica actual. Podis encontrar ms infor-macin en [3] y por supuesto tambin en Wiki-pedia.

    El chatbot Mgonz y los programas Eliza yAlice (o sus diversas implementaciones) pue-den encontrarse fcilmente en Internet. Intentadcharlar con alguno si tenis tiempo.

    Cognitive Systems for Cognitive Assistants(CoSy) [1] es el proyecto dentro del cual estoyrealizando mi doctorado. Este proyecto gan elpremio a la mejor propuesta en el marco europeoFP5. Mi labor se centra en el escenario de ex-ploracin y representacin de entornos cerrados(Explorer).

    Sobre el Autor

    Me llamo scar Martnez Mozos y trabajo como inves-tigador en la universidad Albert-Ludwigs-UniversitaetFreiburg, en Freiburg, Alemania. Actualmente escribomi tesis doctoral sobre robtica mvil, bajo la supervisindel catedrtico Wolfram Burgard, un investigador impor-tante en este tema. Anteriormente estuve realizando in-vestigacin en visin artificial y natural en el Institutode Bioingeniera en la universidad Miguel Hernndez, enElche, Alicante. Mis reas de investigacin son, principal-

    mente, aprendizaje, robtica mvil, visin, e inteligenciaartificial en general. Para ms informacin podis visitarmi pgina web:http://www.informatik.uni-freiburg.de/ omartine/Tambin podis poneros en contacto conmigo en la direc-cin de email: [email protected] encantado de contestar a vuestros correos sobreeste o cualquier otro tema.

    Referencias

    [1] http://www.cognitivesystems.org/.

    [2] http://www.cs.waikato.ac.nz/ml/weka/.

    [3] http://www.turing.org.uk/.

    [4] Tom M. Mitchell. Machine Learning. McGraw Hill,1997.

    [5] Stuart Russell and Peter Norvig. Artificial Intelli-gence: A Modern Approach. Prentice Hall, secondedition, 2003.

    [6] Ian H. Witten and Eibe Frank. Data Mining. MorganKaufmann, 2000.

    17| OCCAMs Razor

  • 8/6/2019 Occams Razor 03-01-02

    18/54

    M RPIDO

    S, ya estamos muy cerca de disponer denuestra propia versin de inetd. Nuestro propiosuperdemonio. Como os adelantbamos en el n-mero anterior una de las cosas que nos falta por

    hacer es que nuestro servidor pueda escuchar envarios puertos a la vez y ejecutar distintos pro-gramas en funcin del puerto utilizado.

    Por cierto, antes de empezar, coged la ltima versinde nuestro demonio, la que hicimos en el nmero ante-rior, ya que la tomaremos como base en este artculoy la iremos modificando poco a poco. Os recomenda-mos que descarguis el paquete asociado de nuestraweb, para ir probando sobre la marcha lo que aqucontamos... hace que todo esto sea mucho ms fcilde entender.

    MANOS A LA OBRA

    Lo primero que tenemos que hacer, y esto no tienenada que ver con las redes, es proporcionar a nuestroprograma la lista de los puertos, y de los programasasociados a cada puerto que queremos que maneje.Nuestro querido superdemonio inetd hace esto utili-zando el fichero /etc/inetd.conf que ya conocemos.Nosotros, para mantener nuestro programa sencillosimplemente tomaremos esa informacin de la lneade comandos. Cada cual que lo haga como prefiera.

    La funcin que interpreta la lnea de comandos y lasconstantes y variables asociadas son estas:

    #define N_PUERTOS 10

    s t a t ic i n t s [N_PUERTOS] ;s t a t i c c ha r prg [ N_PUERTOS] ;

    voidp r oc e s a _p a r am s ( in t argc , char argv [ ] ){

    i nt i , j = 1 ;

    f o r ( i = 0 ; i < N_PUERTOS;

    prg [ i ] = NULL, s [ i++] =

    1) ;

    i = 0 ;while ( ar gv [ j ] && i < N_PUERTOS)

    {s [ i ] = c r e a _ s e r v e r _ s o c k e t ( a t o i ( a r g v [ j + + ] ) ) ;p r g [ i ++] = s t r d u p ( a r g v [ j + + ] ) ;

    }}

    ATENCIN:

    Nios, no hagis esto en vuestras casas, el uso devariables globales suele producir graves efectos secun-darios... y puede haceros perder horas buscando erro-

    res... Nosotros es que somos asn y necesitamos quelos listados no sean muy largos para que los podisseguir, pues nos hemos permitido algunas licencias.

    Como podis ver simplemente declaramos dos matri-ces. La primera contendr nuestros sockets de servi-dor, en los que vamos a esperar las conexiones, y lasegunda contendr los nombres de los programas aejecutar cuando se acepte una conexin en uno de lossockets s. S, podis crear una estructura para mane-

    jar las dos cosas juntas... es ms largo (por eso no lo

    hemos hecho), pero queda mejor :)Ahora aadimos una llamada a esta nueva funcin alprincipio de nuestro main, pasndole como parme-tros argc y argv.

    OCCAMs Razor | 18

  • 8/6/2019 Occams Razor 03-01-02

    19/54

    M RPIDO

    in t m ai n ( in t argc , char argv [ ] ){

    p r o ce s a _p a r am s ( a r g c , a r g v ) ;. . .

    }

    SOCKETS BLOQUEANTESHasta este momento, hemos estado utilizando una se-mntica bloqueante con nuestros sockets. Lo que estosignifica es que si queremos leer algo de la red y nohay nada que leer, nuestro proceso quedar bloqueadoen esa instruccin hasta que recibamos algn dato.

    Los sockets bloqueantes bloqueannuestro proceso hasta que puedancompletar una cierta operacin

    Aceptar conexiones es un caso particular de lectura,y por lo tanto, cuando ejecutamos la llamada al sis-tema accept y no existe ninguna conexin pendiente,nuestro proceso queda bloqueado en esa instruccinhasta que alguien se conecte con nosotros. Si quere-mos aceptar conexiones en varios puertos diferentes...pues tenemos un problema.Si escribimos un cdigo como el siguiente, que es lonico que podemos hacer por el momento:

    in t s a1 , s a2 , s 1 , s 2 ;

    s a 1 = c r e a _ s er v e r _ so c k e t ( 2 0 0 0 ) ;s a 2 = c r e a _ s er v e r _ so c k e t ( 3 0 0 0 ) ;

    while ( 1 ) {s 1 = a c e p t a _ c on e x i on ( s a 1 ) ;s 2 = a c e p t a _ c on e x i on ( s a 2 ) ;. . .

    }

    Como podis observar, estamos creando nuestros dossockets de servidor y a continuacin comenzamos aaceptar conexiones.El problema es que si nuestro socket es bloqueante,nuestro programa se quedar parado en el primer ac-cept (el del puerto 2000).

    Pero si en ese momento llega un intento de conexin alsegundo puerto (el 3000), nuestro programa no podratenderlo, ya que est parado, esperando conexionesen el primer puerto (el 2000)... es decir, todava no seha ejecutado el segundo acepta_conexion.De la misma forma, si recibimos un intento de cone-xin en el puerto 2000, pasaremos a esperar conexio-nes en el puerto 3000, de forma que un nuevo intentode conexin al puerto 2000 tampoco sera atendido.Existen tres formas fundamentales de lidiar con estasituacin.La primera consiste en crear una proceso o mejor una

    hebra, por cada puerto en el que queramos aceptaruna conexin. Todas ellas se ejecutarn concurrente-mente y no habr problema con quedarse bloqueadoen la llamada al sistema accept.

    La segunda consiste en hacer que nuestros sockets uti-licen una semntica no bloqueante. En este caso, elproceso no se bloquear en las llamadas al sistema co-mo accept o read. Si hay algo que leer o una conexinque aceptar el resultado ser el habitual, sino recibi-remos un error indicando que no hay nada que hacer.Para el problema que nos ocupa, estaramos continua-

    mente ejecutando accept y, la mayor parte del tiempoobteniendo como resultado un error indicando que nohay nada que hacer. Como los sockets son ahora nobloqueantes, si no hay nada que hacer con uno de ellos,pasaremos al siguiente y as sucesivamente.La desventaja de esta forma de trabajar es que nues-tro programa tiene que hacer lo que se conoce comoespera activa, es decir, estaremos comprobando el es-tado de nuestros sockets continuamente, consumiendoCPU en el proceso.La tercera forma de manejar mltiples conexiones, yen general la buena, aunque eso siempre depende de

    la aplicacin, es utilizar la llamada al sistema select.Esta es la que nosotros utilizaremos con nuestro su-perdemonio.

    SELECT

    La llamada al sistema select nos permite monitori-zar conjuntos de descriptores de ficheros. En lo quea nosotros respecta esos descriptores de ficheros se-rn sockets, pero en general pueden ser de cualquiertipo, una FIFO, un dispositivo en /dev o la entradaestndar.Podemos monitorizar estos conjuntos de descriptores

    respecto a tres tipos diferentes de eventos, a saber:lectura, escritura y excepciones. Nosotros solo usare-mos el evento de lectura, si bien los dems funcionande la misma forma.

    La llamada al sistema select nospermitir manejar varios socketsa la vez

    Cuando ejecutamos una llamada a select desde nues-tro programa, ste pasar al estado dormido, hasta

    que alguno de los eventos configurados ocurra o paseun cierto tiempo (ahora veremos como configurarlo).Una vez que uno de esos eventos ocurre, podremosllevar a cabo nuestra lectura, escritura o manejo deexcepcin sin tener que esperar.La forma de utilizar select consta de tres partes:

    Configuracin de la lista de descriptores de fi-chero a monitorizar y del timeout

    Ejecucin de select y gestin de errores

    Comprobacin del estado de los sockets y accinpertinente.

    19| OCCAMs Razor

  • 8/6/2019 Occams Razor 03-01-02

    20/54

    M RPIDO

    AADIENDO SELECT A NUESTROPROGRAMA

    Con todo lo que hemos visto hasta el momento, lafuncin main de nuestro nuevo servidor tendr la si-guiente apariencia. La reproducimos entera por como-didad.

    in t m ai n ( in t argc , char argv [ ] ){

    f d _ s e t r f d s ;stru ct t i m e v a l tv ;i nt n , max , i ;i nt t e r m i n a r = 0 ;

    p r o ce s a _p a r am s ( a r g c , a r g v ) ;

    while ( ! t e r m i n a r ){

    max = p r e p a r a _ s e l e c t (& r f d s , &t v ) ;i f ( ( n = s e l e c t ( max , &r f d s ,

    NULL, NULL, &tv )) < 0)p e r r o r ( " s e l e c t : " ) ;

    e l s e{

    i f ( ! n )

    { p r i n t f ( " Me a b u r r o ! \ n " ) ;continue ;

    }/ Comprobamos s oc ke ts /p r o c e s a _c o n e x i o n e s (& r f d s ) ;

    }}

    return 0 ;}

    Lo primero que encontramos es nuestra funcin pro-cesa_params que ya hemos comentado. A continua-cin nos encontramos un bucle infinito, en el que es-taremos infinitamente aceptando conexiones y ejecu-tando procesos.

    En el cdigo se pueden apreciar claramente las trespartes necesarias para el uso de select. La funcin pre-para_select se encarga de la configuracin de la listade descriptores de ficheros a monitorizar y la configu-racin del timeout.Esta funcin tambin nos devuelve el valor mximoen la lista de descriptores de ficheros creada, valorque select espera como primer parmetro.A continuacin nos encontramos con la ejecucin deselect propiamente dicha. En este caso solamente es-tamos monitorizando un conjunto de descriptores pa-ra el evento de lectura. Los dos NULLs que siguen a

    continuacin contendran, respectivamente, las listasde descriptores para escritura y para excepciones.

    El timeout de select nos permiteejecutar cdigo mientras espera-mos por la red.

    La llamada al sistema select devolver un valor ne-gativo en caso de error (como es habitual), el valor 0si ha vencido el timeout configurado con la variable

    tv sin recibir ningn evento y un nmero positivo, in-dicando cuantos de nuestros descriptores de ficheroshan recibido un evento en el caso de que algn eventohaya sucedido.

    Como podis ver el las lneas de cdigo anteriores,en el caso de recibir un evento la funcin proce-sa_conexiones es ejecutada. En breve veremos lo quehace dicha funcin.

    CONFIGURANDO SELECT

    Para la configuracin de select utilizamos una sencilla

    funcin llamada prepara_select. Esta funcin recibedos parmetros. El primero es una variable del tipofd_set en el que almacenaremos la lista de descrip-tores de fichero que queremos monitorizar para loseventos de lectura.

    El macro FD_SET nos permitedeterminar los socket que selectmonitorizar

    Si quisiramos monitorizar los otros tipos de eventos(escritura, excepcin), tendramos que utilizar dos va-riables adicionales.La segunda variable es la que nos permite configurarel timeout, es decir, el tiempo que nuestro procesopermanecer dormido como mximo. Si durante esetiempo no recibimos ningn evento, select retornarel valor 0 y nos permitir llevar a cabo las accionesque consideremos oportunas. Normalmente volver aconfigurar y ejecutar select.Ambos parmetros se pasan como punteros a la fun-cin para permitir que sta los modifique.

    i ntp r e p a r a_ s e l e c t ( f d _ s e t r f d s , stru ct t i m e v a l tv ){

    i nt i , max ;

    max = 0 ;FD_ZERO( r f d s ) ;f o r ( i = 0; i < N_PUERTOS && s [ i ] != 1; i++)

    {FD_SET( s [ i ] , r f d s ) ;i f ( s [ i ] > max) max = s [ i ] ;

    }max++;

    tv> t v _ s e c = 4 ;tv>t v _ u s e c = 0 ;

    return max;}

    Como podis ver en el cdigo de prepara_select, elmanejo de las variables del tipo fd_set se lleva a ca-bo con los macros FD_ZERO y FD_SET. El primerode ellos vaca la lista de descriptores que contiene lavariable, mientras que el segundo aade un descriptorde fichero a la lista que se indica.Es necesario saber cual es el mayor valor del descrip-tor de fichero que se aade a la lista. Este es el primerparmetro que select espera.Tras inicializar nuestra lista de descriptores de fiche-ros, configuramos el timeout a utilizar. En este ejem-

    plo es de 4 segundos. Observad que select permite es-pecificar el timeout con una precisin de microsegun-dos (s para eso es el campo tv_usec de la estructuratimeval).

    OCCAMs Razor | 20

  • 8/6/2019 Occams Razor 03-01-02

    21/54

    M RPIDO

    PROCESANDO CONEXIONES

    Tras la ejecucin de select, si se ha producido algnevento, tenemos que procesarlo. Los casos de error ytimeout se procesan directamente en la funcin main.El tercer caso, un intento de conexin a alguno denuestros puertos lo procesamos en una funcin a par-te.

    voidp r o c e s a _c o n e x i o n e s ( f d _ s e t r f d s ){

    i nt i , a s ;

    f o r ( i = 0; i < N_PUERTOS; i++)i f ( s [ i ] ! = 1 && FD_ISSET( s [ i ] , rfds ))

    {p r i n t f ( " Co n e x i on a %d \ n" , i ) ;a s = a c e p t a _ c o n e x i o n ( s [ i ] ) ;p r i n t f ( " Co n e x i on a c e p t a d a e n %d \ n" , a s ) ;p r o c e s a ( a s , s [ i ] , p r g [ i ] ) ;p r i n t f ( " E j e c u ta n d o % s \ n" , p r g [ 1 ] ) ;

    }}

    Esta funcin, simplemente recorre la lista de nuestrossockets, para averiguar cual de ellos fue el responsabledel evento que estamos procesando. Esta comproba-cin se lleva a cabo con el FD_ISSET, el cual nosindicar si el descriptor de fichero indicado ha recibi-do un evento dentro de la lista de descriptores (nuestravariable rfds) que se pasa como segundo parmetro.

    Sabremos que socket ha produ-cido el evento gracias al macroFD_ISSET

    Si hemos recibido uno de esos eventos de lectura, esosignifica que alguien est tratando de conectarse a unode nuestros sockets, as que simplemente aceptamos laconexin con la misma funcin acepta_conexion quedefinimos en el artculo anterior y ejecutamos el pro-ceso asociado a ese puerto con la funcin procesa.Esta funcin procesa ha sido modificada ligeramen-te para que funcione con el nuevo esquema de gestinde conexiones, y la veremos un poco ms adelante.Para los ms impacientes, esta modificacin consiste,simplemente, en que la funcin procesa cierra el so-

    cket de comunicacin en el proceso padre despus decrear el proceso hijo. Si no hacemos esto, todas las co-nexiones permanecern abiertas, puesto que el socketsigue abierto en el proceso padre, aunque el procesohijo lo haya cerrado (todos los descriptores de ficherosse cierran automticamente cuando un proceso mue-re).Si queris ver cual es el efecto de esto, solo tenis quecomentar la lnea con el close al final de la funcin

    procesa.

    LA NOCHE DE LOS MUERTOS VIVIEN-TES

    Bien, ya casi hemos terminado. En este punto tododebera funcionar perfectamente. Para comprobarlosimplemente compilamos nuestro nuevo super-server

    y lo ejecutamos.

    $ make server\_simple4

    $ ./server_simple4 2000 ./echo.pl 4000 ./echo.pl

    Si ahora nos conectamos al puerto 2000 o al puerto4000 de localhost, nuestro pequeo servidor de echoescrito en Perl, se ejecutar y nos responder con lomismo que nosotros le digamos.Realizad unas cuantas conexiones y luego ejecutad ps:

    $ ps -e

    13614 pts/8 Z+ 0:00 [echo.pl]

    13620 pts/8 Z+ 0:00 [echo.pl]

    13627 pts/8 Z+ 0:00 [echo.pl]

    $

    S, efectivamente. Son zombies (eso es lo que significala Z de la tercera columna).En la seccin consultorio del primer nmero de Oc-cams Razor le contbamos a Van Helsing como tra-tar con estos malditos, pero por si alguien no tiene amano ese legendario nmero, vamos a contaros comosolucionar este problemilla aqu.En nuestro caso particular, lo solucin que vamos aadoptar es la de proporcionar una manejador de sea-les para poder ejecutar la llamada al sistema waitpid,cada vez que algn proceso hijo muera, y de esta for-ma dejar que vaya hacia a luz... a un mundo mejor...El manejador de seales sera algo tal que as:

    void h a n dl e r ( i nt s ){

    p i d _t p i d ;

    i nt s t a t u s ;

    p i d = w a i t p i d ( 1, &st at us , WNOHANG ) ;

    p r i n t f ( " C h i l d d o ne w i t h s t a t u s %d \ n" , s t a t u s ) ;}

    Y en nuestra funcin main, al principio de la misma,tendremos que aadir una lnea como esta:

    signal (SIGCHLD, handler);

    La seal SIGCHLD (de children... nios) se enva ca-da vez que un proceso hijo termina su ejecucin. Sinembargo, esta ejecucin no es completa hasta que el

    proceso padre se da por enterado... es decir, ejecutala llamada al sistema wait. Si el proceso padre no eje-cuta esa llamada al sistema, el proceso hijo mantienesus recursos en memoria an cuando su ejecucin yaha terminado, convirtindose en un proceso zombie...ni vivo ni muerto.

    Si no tenemos cuidado nos inva-dirn los zombies

    Nuestro manejador de seales nos va a asegurar que

    cada vez que uno de nuestros hijos pase a mejor vida,nosotros nos enteremos y podamos ejecutar la llama-da al sistema wait y dejar as que el pobre descanseen paz.

    21| OCCAMs Razor

  • 8/6/2019 Occams Razor 03-01-02

    22/54

    M RPIDO

    UN POCO MS DE FLEXIBILIDAD. TC-CLIB

    Habis ledo ya la seccin ratas de biblioteca?... Puesa que estis esperando. En este nmero os contamoscomo utilizar tcclib para generar cdigo en tiempo deejecucin a partir de fuentes C. Pues bien, no estaranada mal utilizar esta librera en nuestro superservi-

    dor para poder escribir servicios de red m rpido...vamos a ver como hacerlo.Para que el cdigo no nos quede demasiado largo de-clararemos algunas variables globales ms y almace-naremos el cdigo C a ejecutar en un fichero llamado

    script.c que se encontrar en el mismo directorio quenuestro servidor.

    TCCLib nos permitirimplemen-tar nuestros servicioscomo fiche-ros de texto

    Tambin aprovecharemos nuestra sencilla funcin pa-ra interpretar la lnea de comandos. Ahora, las cade-nas que acompaan a los puertos van a representarfunciones en el fichero script.c, en lugar de procesosexternos.Para inicializar tcclib y cargar y compilar el cdigo enel fichero script.c vamos a declarar una nueva variableglobal, definir un tipo para referenciar nuestros pun-teros a funciones y escribir una pequea funcin queinicialice nuestro compilador run-time:

    typed ef i n t (MIFUNC) ( void ) ;s t a t i c TCCState t c c ;

    in t c a r g a _ c o d i g o ( TCCS ta te s , char n f ){

    FILE f ;char b [ 1 0 2 4 ] ;

    / L ee f i c h e r o /me ms et ( b , 0 , 1 0 2 4 ) ;f = f op en ( n f , " r t " ) ; f r e ad ( b , 1 02 4 , 1 , f ) ;f c l o s e ( f ) ;

    t cc _s e t_ ou tp ut _t yp e ( s , TCC_OUTPUT_MEMORY);t c c _ c o m p il e _ s t r i ng ( s , b ) ;t c c _ r e lo c a t e ( s ) ;return 0 ;

    }

    De forma m rpida, hemos declarado el tipo de lasfunciones que implementarn nuestros nuevos servi-cios. Se trata de funciones que retornan un entero yno reciben ningn parmetro.Dependiendo de vuestras necesidades concretas podiscambiar este tipo segn os convenga. A continuacindeclaramos la variable que contendr nuestro entornode compilacin en memoria, y que inicializaremos enla funcin carga cdigo. Una vez ms recordad questa no es la mejor forma de hacer esto. Las variablesglobales dan problemas.Para simplificar el resto del cdigo definimos tambin

    una sencilla funcin para obtener los punteros a lasfunciones en nuestro fichero script.c.

    MIFUNC l ee _f un ci on (TCCState s , char nombre_func){

    MIFUNC u n_ sc ri pt ;unsigned long v ;

    tcc_get_symbol (s , &v , nombre_func);u n _ s c r i p t = ( void) v ;

    return u n _ s c r i p t ;}

    Ahora tenemos que hacer algunos cambios a nuestrasfunciones para adaptarlas a la nueva funcionalidad.

    PEQUEOS CAMBIOS

    Lo primero que vamos a hacer es aadir una nuevavariable en la que almacenar el puntero a la funcinen script.c que asociaremos a cada servicio. Esto esfcil, junto al resto de variables s y prg aadimos estanueva lnea:

    static MIFUNC mifunc[N_PUERTOS];

    Ahora ya podemos modificar nuestra funcin proce-sa_params para que resuelva la direccin en memoriade la funcin que se recibe a travs de la lnea decomandos. La versin modificada de procesa_paramsser la siguiente:

    voidp r o ce s a _p a r am s ( in t argc , char argv [ ] ){

    i nt i , j = 1 ;

    f o r ( i = 0 ; i < N_PUERTOS;prg [ i ] = NULL, s [ i++] = 1) ;

    i = 0 ;while ( ar gv [ j ] && i < N_PUERTOS)

    {s [ i ] = c r e a _ s e r v e r _ s o c k e t ( a t o i ( a r g v [ j + + ] ) ) ;p r g [ i ] = s t r d u p ( a r g v [ j + + ] ) ;m i f u n c [ i + +] = l e e _ f u n c i o n ( t c c , p r g [ i ] ) ;

    }}

    Como podis observar simplemente hemos aadidouna nueva lnea dentro del bucle principal de la fun-cin que inicializa nuestra matriz de punteros a fun-ciones. Ahora, por cada puerto en el que nuestro ser-vidor escuchar tendremos un socket, una cadena conel nombre de una funcin y el puntero a esa funcinen memoria.

    Unos pequeos cambios y tendre-mos nuestro server funcionandode nuevo

    La funcin procesa_conexiones tambin necesita unapequea modificacin. En este caso sustituiremos lalneas:

    procesa (as, s[i], prg[i]);

    por

    procesa (as, s[i], mifunc[i]);

    OCCAMs Razor | 22

  • 8/6/2019 Occams Razor 03-01-02

    23/54

    M RPIDO

    Es decir, en lugar de pasar el nombre del programaexterno a ejecutar, pasamos el puntero a la funcin aejecutar.Finalmente, la funcin procesa tambin debe ser mo-dificada. la nueva versin quedara tal que as:

    in t p r oc e s a ( in t s , in t sa , MIFUNC la_ fun cio n ){

    p id _t p id ;

    i f ( ( p id = f o rk ( ) ) < 0 )f p r i n t f ( s t d e r r , " No pu ed o c r e a r e l p r o c e s o " ) ;

    e l s e{

    i f ( ! p i d ) / P r oc e so h i j o /{

    c l o s e ( s a ) ;

    du p2 ( s , 0 ) ;c l o s e ( s ) ;d up 2 ( 0 , 1 ) ;d up 2 ( 0 , 2 ) ;

    l a _f u n ci o n ( ) ;e x it ( 0 ) ;

    }}

    c l o s e ( s ) ;return 0 ;}

    Como podis ver el tercer parmetro de la funcinahora es un puntero a una funcin, en lugar del nom-bre del proceso externo a ejecutar, y la llamada alsistema execv ha sido sustituida por la llamada a lafuncin que recibimos como parmetro.

    En unas pocas lneas de texto po-demos implementar algunos ser-

    vicios comunesPara minimizar el nmero de cambios, hemos mante-nido la llamada a fork para crear un nuevo proceso, sibien en este caso la creacin de una hebra sera menoscostosa... Bien, ah tenis una cosilla para entretene-ros.Finalmente, el bloque de inicializacin en nuestro pro-grama principal tambin se ver ligeramente modifi-cado... no as el bucle principal que no requiere ningncambio. Este bloque de inicializacin ser ahora:

    main ...

    tcc = tcc_new ();

    carga_codigo (tcc, "script.c");

    signal (SIGCHLD, handler);

    procesa_params (argc, argv);

    PROBANDO NUESTRO SUPERSER-VER

    Para probar nuestro super servidor de la muerte, tene-mos que escribir un fichero script.c con las funcionesen C que queremos ejecutar cada vez que un cliente

    se conecte a alguno de nuestros servicios.Nosotros hemos escrito este sencillo script.c

    #include #include < s t r i n g . h>

    i nt s e r v_ e c ho ( void ){

    char b u f f e r [ 1 0 2 4 ] ;i nt l e n ;

    l e n = r e a d ( 0 , b u f f e r , 1 0 2 4 ) ;w r i te ( 1 , b u f f e r , l e n ) ;

    return 0 ;}

    i nt s e r v_ t i me ( void ){

    t i me _ t h o ra ;char la_hora ;

    t i m e (& h o r a ) ;l a _ h o r a = ( char) c t i m e (& h o ra ) ;w r i t e ( 1 , l a_ ho ra , s t r l e n ( l a _h o ra ) ) ;

    }

    i nt s e r v_ c h ar g e n ( void ){

    while ( 1 ){

    i f ( ( w r i t e ( 1 , "AAAAAAAAAAAAAAAAAAAA" , 2 0 ) ) < 0 )break ;

    }

    }

    El fichero define tres funciones que ofrecen tres sen-cillos servicios que normalmente inetd implementa deforma interna: el servicio de echo, el servicio de horay el servicio de generacin de caracteres.Ahora ya podemos ejecutar nuestro flamante servidorcon, por ejemplo, esta lnea de comandos:

    ./server_tcclib 2000 serv_echo 3000 serv_time 4000 serv_chargen

    Ya podis utilizar nc o telnet para comprobar comovan nuestros nuevos servicios.

    ESTO ES TODOBueno, esperamos que os haya resultado interesanteesta breve explicacin de cmo programar vuestro pro-pio superdemonio. El resultado final os proporcionaun esqueleto general para poder implementar senci-llos protocolos m rpido, sin tener que escribir niuna lnea de cdigo relacionada con la red.Hemos dejado algunas cosas en el tintero para que osentretengis con ellas... siempre es ms divertido des-cubrir las cosas por uno mismo que que nos las cuen-ten. Con lo que os hemos contado hasta aqu, podisdescargar las fuentes de inetd (o su hermano mayorxinetd) y estudiar el cdigo y averiguar hasta el lti-mo detalle de esta aplicacin UNIX que ha estado ahdesde el principio.Como siempre, estaremos encantados de saber devuestros xitos as como de cualquier uso curioso omejora que hagis sobre estos sencillos esqueletos deprograma que os ofrecemos. Por supuesto, sern pu-blicados en el prximo nmero con vuestras explica-ciones.En el prximo nmero nos introduciremos en un nue-vo y excitante campo de la programacin... pero estoes una sorpresa.

    23| OCCAMs Razor

  • 8/6/2019 Occams Razor 03-01-02

    24/54

    EN LA PRCTICA

    Trujamana o LocalizadoraIntroduccin a la Localizacin de Software

    por Silvia Carril Caldelas ([email protected])

    Ttrujamn, na. (Del r. hisp. turgumn,

    este del r. cls. turguman, intrprete, es-te del arameo rabnico turgman[a] y siriacotargmana, y estos del acadio targamanu[m] oturgamanu[m]). 2. p. us. intrprete (|| de len-guas)

    Hace aos que ante la pregunta: En qu trabajas?he desistido de intentar dar una explicacin lgica einteligible a mi interlocutor. El responder Soy loca-lizadora de software da pie a las reacciones y expre-siones faciales ms sorprendentes.

    Lo cierto es que la ma es una profesin cada vez msen auge y, definitivamente, una cuyos resultados sondisfrutados a diario por millones de usuarios de or-denadores y, sin embargo, contina siendo una grandesconocida... no slo para los propios usuarios sinotambin para programadores e ingenieros informti-cos.La globalizacin (ese concepto tan de moda ahora)ana a gentes y pases de todo el mundo. No obstan-te, aunque cada vez nos parecemos ms un espaolde Espaa y un americano de los EE.UU., continahabiendo grandes diferencias, singularidades y barre-

    ras (por llamarle de algn modo). Una de ellas es elidioma y el uso que cada individuo hace del mismo ensu vida cotidiana. Uno de esos usos es el que hacemosa diario millones de usuarios informticos totalmenteajenos al hecho de que en esa aplicacin de softwareque estamos utilizando sin darle mayor relevancia seha invertido mucho tiempo y esfuerzo para lograr quellegue a nosotros en nuestro propio idioma.

    QU ES LA LOCALIZACIN?

    El concepto de localizacin o internacionalizacin esmuy simple, es decir, es la adaptacin de aplicacio-

    nes de software a otros entornos, particularmente deotros pases y culturas. Entre otros aspectos es res-ponsable de asegurar aspectos, obvios para los usua-rios de idiomas con base en el alfabeto romano, como

    la capacidad para representar y visualizar los sistemasalfabticos de un idioma en cuestin. Y sa es tan slola punta del iceberg...

    La diferencia entre internacionalizacin (generalmen-te, abreviado como i18n o I18n o I18N) y localizacin(generalmente, abreviado como L10n o l10n) es sutilpero importante. La internacionalizacin es la adapta-cin de productos para su uso potencial virtualmenteen cualquier parte del mundo, mientras que la locali-zacin implica la inclusin de caractersticas particu-lares para su uso con una configuracin regional es-pecfica. Ambos procesos se complementan entre s yson necesarios conjuntamente para lograr un sistemaque funcione de modo global.

    Los procesos de internalizaciny localizacin se abrevian comoi18n y L10n

    As pues, la internacionalizacin y la localizacin sonalgo mucho ms amplio y complejo que la traduccin.Abarcan no solamente el aspecto esencial de la trans-posicin de un idioma a otro del cdigo que compo-ne una aplicacin sino que van ms all. Adems delos aspectos puramente lingsticos, en su aplicacin

    tambin tratan cuestiones culturales y tcnicas. Estosincluyen entre otros:

    La adaptacin de formatos de hora y fecha pa-ra cada pas, as como los diferentes calenda-rios existentes. Por ejemplo, el formato de fechahabitual en EE.UU. es especificar mes/da/ao(10/12/2007), mientras que en Espaa lo habi-tual es el formato da/mes/ao (12/10/2007).

    La adaptacin de formatos de nmero y separa-dores. Mientras que en ingls los nmeros deci-

    males se representan mediante un punto, en es-paol se utiliza una coma. As 225.32 en inglsse representa como 225,32 en espaol.

    OCCAMs Razor | 24

  • 8/6/2019 Occams Razor 03-01-02

    25/54

    EN LA PRCTICA

    La adaptacin de formatos de moneda. De nue-vo, en la mayora de los pases anglosajones elsmbolo que representa la moneda del pas se si-ta antes de la cifra unido a sta sin espacios(225.32). Lo correcto en castellano es que elsmbolo vaya despus de la cifra separado porun espacio en blanco (225,3