Beruflich Dokumente
Kultur Dokumente
7 9 2 0 0 5 6 1 6
> > >
Luego de esto, top nos dice:
1 0 4 6 7 c l a u d i o f 2 0 0 1 6 7 6 m 1 . 6 g 1 8 6 4 S 0 8 2 . 7 1 : 1 7 . 0 7 p y t h o n
O sea, aunque segn los clculos el programa tena que consumir 800M de memoria,
efectivamente consume 1.6G. El doble.
Por qu es esto?
Bueno, porque el ejemplo lo pens especficamente para que cree un 50% de huecos
inutilizables. La memoria est fragmentada, pues, en un 50%.
Fragmentacin 83
{footer} http://revista.python.org.ar
Pero hay algo ms grave. Si hago:
> > > d e l l
> > > d e l l l
Obtengo de top:
1 0 4 6 7 c l a u d i o f 2 0 0 1 5 3 2 m 1 . 5 g 1 8 6 4 S 0 7 5 . 6 1 : 1 7 . 9 6 p y t h o n
Si repito el ejemplo de fragmentacin, puedo comprobar que esos 1.5G estn
efectivamente libres para python:
1 0 4 6 7 c l a u d i o f 2 0 0 1 6 7 6 m 1 . 6 g 1 8 6 4 S 0 8 2 . 8 2 : 3 3 . 3 9 p y t h o n
Pero si intento liberarlos (para el sistema operativo), no puedo.
WTF?
Enter Guppy
Guppy es un pecesito rojo comunmente encontrado en las peceras de todos lados.
Esos pecesitos chiquitos, esos se llaman guppy.
Posta.
Tambin es una biblioteca de extensin para Python que contiene un mdulo, heapy,
que me permite hacer diagnstico de la memoria.
Posta.
Guppy
Veamos un ejemplo de cmo usarlo:
84 Enter Guppy
{footer} http://revista.python.org.ar
> > > f r o m g u p p y i m p o r t h p y
> > > h p = h p y ( )
> > > h p . h e a p ( )
P a r t i t i o n o f a s e t o f 2 3 7 7 8 o b j e c t s . T o t a l s i z e = 1 7 6 0 6 9 2 b y t e s .
I n d e x C o u n t % S i z e % C u m u l a t i v e % K i n d ( c l a s s / d i c t o f c l a s s )
0 1 0 6 4 2 4 5 6 9 6 6 5 2 4 0 6 9 6 6 5 2 4 0 s t r
1 5 4 3 2 2 3 1 9 6 8 6 4 1 1 8 9 3 5 1 6 5 1 t u p l e
2 3 4 5 1 1 1 2 9 6 8 6 1 0 0 6 4 8 4 5 7 d i c t ( n o o w n e r )
3 1 5 4 6 7 1 0 5 1 2 8 6 1 1 1 1 6 1 2 6 3 t y p e s . C o d e T y p e
4 6 6 0 1 0 4 5 9 2 6 1 2 1 6 2 0 4 6 9 d i c t o f m o d u l e
5 1 7 4 1 9 3 1 6 8 5 1 3 0 9 3 7 2 7 4 d i c t o f t y p e
6 1 9 4 1 8 6 0 4 0 5 1 3 9 5 4 1 2 7 9 t y p e
7 1 4 7 2 6 8 2 4 3 2 5 1 4 7 7 8 4 4 8 4 f u n c t i o n
8 1 2 4 1 6 7 5 5 2 4 1 5 4 5 3 9 6 8 8 d i c t o f c l a s s
9 1 0 2 7 4 3 6 9 7 2 2 1 5 8 2 3 6 8 9 0 _ _ b u i l t i n _ _ . w r a p p e r _ d e s c r i p t o r
O sea, Python (por el simple hecho de levantarlo) ya consume 1.7MB. En objetos
python. Heapy no cuenta lo que no son objetos Python, as que lo que reporte heapy
es todo memoria utilizada directamente por objetos Python.
Esto son cadenas, listas, diccionarios, arrays, pero no objetos mmap o memoria
utilizada por bibliotecas de extensin (ej: superficies SDL en pygame).
Diagnostiquemos ahora entonces:
> > > l = [ ]
> > > f o r i i n x r a n g e ( 1 , 1 0 0 ) :
. . .
> > > h p . h e a p ( )
P a r t i t i o n o f a s e t o f 2 6 1 2 5 4 2 o b j e c t s . T o t a l s i z e = 8 6 6 4 0 5 8 4 4 b y t e s .
I n d e x C o u n t % S i z e % C u m u l a t i v e % K i n d ( c l a s s / d i c t o f c l a s s )
0 2 5 9 9 3 8 6 9 9 8 5 4 8 3 3 3 0 4 9 9 8 5 4 8 3 3 3 0 4 9 9 s t r
1 1 3 2 0 1 0 5 1 6 6 4 0 1 8 6 5 3 4 9 9 4 4 1 0 0 l i s t
2 5 4 3 3 0 1 9 7 0 6 4 0 8 6 5 5 4 7 0 0 8 1 0 0 t u p l e
3 3 5 1 0 1 1 3 7 8 4 0 8 6 5 6 6 0 7 9 2 1 0 0 d i c t ( n o o w n e r )
4 1 5 4 7 0 1 0 5 1 9 6 0 8 6 5 7 6 5 9 8 8 1 0 0 t y p e s . C o d e T y p e
5 6 7 0 1 0 5 1 1 2 0 8 6 5 8 7 1 1 0 0 1 0 0 d i c t o f m o d u l e
6 1 7 4 0 9 3 1 6 8 0 8 6 5 9 6 4 2 6 8 1 0 0 d i c t o f t y p e
7 1 9 4 0 8 6 0 4 0 0 8 6 6 0 5 0 3 0 8 1 0 0 t y p e
Enter Guppy 85
{footer} http://revista.python.org.ar
8 1 4 7 2 0 8 2 4 3 2 0 8 6 6 1 3 2 7 4 0 1 0 0 f u n c t i o n
9 1 2 4 0 6 7 5 5 2 0 8 6 6 2 0 0 2 9 2 1 0 0 d i c t o f c l a s s
Ok, como habamos calculado, ms o menos 800M (850M) en objetos Python. Eso dice
heapy.
> > > d e l l
> > > d e l l l
> > > h p . h e a p ( )
P a r t i t i o n o f a s e t o f 2 3 8 4 4 o b j e c t s . T o t a l s i z e = 1 7 6 5 2 3 6 b y t e s .
I n d e x C o u n t % S i z e % C u m u l a t i v e % K i n d ( c l a s s / d i c t o f c l a s s )
0 1 0 6 9 0 4 5 6 9 8 9 9 6 4 0 6 9 8 9 9 6 4 0 s t r
1 5 4 3 3 2 3 1 9 7 0 6 8 1 1 8 9 6 0 6 4 5 1 t u p l e
2 3 5 1 1 1 1 3 7 8 4 6 1 0 0 9 8 4 8 5 7 d i c t ( n o o w n e r )
3 1 5 4 7 6 1 0 5 1 9 6 6 1 1 1 5 0 4 4 6 3 t y p e s . C o d e T y p e
4 6 7 0 1 0 5 1 1 2 6 1 2 2 0 1 5 6 6 9 d i c t o f m o d u l e
5 1 7 4 1 9 3 1 6 8 5 1 3 1 3 3 2 4 7 4 d i c t o f t y p e
6 1 9 4 1 8 6 0 4 0 5 1 3 9 9 3 6 4 7 9 t y p e
7 1 4 7 2 6 8 2 4 3 2 5 1 4 8 1 7 9 6 8 4 f u n c t i o n
8 1 2 4 1 6 7 5 5 2 4 1 5 4 9 3 4 8 8 8 d i c t o f c l a s s
9 1 0 2 7 4 3 6 9 7 2 2 1 5 8 6 3 2 0 9 0 _ _ b u i l t i n _ _ . w r a p p e r _ d e s c r i p t o r
WTF?
Heapy nos dice que Python ocupa de nuevo 1.7MB. Top sigue diciendo 1.6G. Yo le
creo a top.
Sucede que de hecho, el resto es espacio libre (libre para Python, no para el
sistema operativo)
Haciendo un anlisis diferencial, conseguiremos algo de perspectiva en el asunto:
> > > f r o m g u p p y i m p o r t h p y
> > > h p = h p y ( )
> > > h e a p 1 = h p . h e a p ( )
> > > # e x p e r i m e n t o
> > > h e a p 2 = h p . h e a p ( )
> > > c o s a s _ n u e v a s = h e a p 2 h e a p 1
> > > d e l l , l l
> > > b a s u r a = h e a p 3 h e a p 1
86 Enter Guppy
{footer} http://revista.python.org.ar
Resulta en 3 snapshots del heap. heap1, como est al iniciar Python. heap2, luego del
experimento, y heap3 luego de liberar todo, y dos diferenciales, cosas_nuevas, lo
que hay en heap2 de nuevo (que no est en heap1), y basura, lo que hay en heap3 que
no est en heap1 (o sea, lo que no se liber).
> > > c o s a s _ n u e v a s
P a r t i t i o n o f a s e t o f 2 5 8 8 7 2 5 o b j e c t s . T o t a l s i z e = 8 6 4 6 4 2 9 7 6 b y t e s .
I n d e x C o u n t % S i z e % C u m u l a t i v e % K i n d ( c l a s s / d i c t o f c l a s s )
0 2 5 8 8 7 0 6 1 0 0 8 5 4 1 3 4 6 6 8 9 9 8 5 4 1 3 4 6 6 8 9 9 s t r
1 2 0 1 0 5 0 6 3 0 4 1 8 6 4 6 4 0 9 7 2 1 0 0 l i s t
2 6 0 8 1 6 0 8 6 4 6 4 1 7 8 8 1 0 0 d i c t ( n o o w n e r )
3 2 0 6 7 6 0 8 6 4 6 4 2 4 6 4 1 0 0 t y p e s . F r a m e T y p e
4 2 0 2 7 2 0 8 6 4 6 4 2 7 3 6 1 0 0 d i c t o f g u p p y . e t c . G l u e . O w n e r
5 1 0 6 8 0 8 6 4 6 4 2 8 0 4 1 0 0 t y p e s . C o d e T y p e
6 2 0 6 4 0 8 6 4 6 4 2 8 6 8 1 0 0 g u p p y . e t c . G l u e . O w n e r
7 2 0 6 4 0 8 6 4 6 4 2 9 3 2 1 0 0 t u p l e
8 1 0 3 2 0 8 6 4 6 4 2 9 6 4 1 0 0 e x c e p t i o n s . K e y b o a r d I n t e r r u p t
9 1 0 1 2 0 8 6 4 6 4 2 9 7 6 1 0 0 i n t
Cabe preguntar: Slo 850M de cadenas? Y los otros 800M para completar los 1.6G?
Bueno, sucede que la memoria se parece a un queso gruyere en este momento. Hay
800M en cadenas relativamente pequeas, pero como en cada paso yo liberaba la
mitad de ellas (l l = l l [ : : 2 ] ), tambin tengo 800M de espacio libre inutilizable.
Porque en cada paso, tambin, necesito cadenas un poquito ms grandes, y no se
puede reutilizar los huecos.
A ver qu pasa al de referenciar todo:
> > > b a s u r a
P a r t i t i o n o f a s e t o f 2 9 o b j e c t s . T o t a l s i z e = 2 5 2 0 b y t e s .
I n d e x C o u n t % S i z e % C u m u l a t i v e % K i n d ( c l a s s / d i c t o f c l a s s )
0 6 2 1 8 1 6 3 2 8 1 6 3 2 d i c t ( n o o w n e r )
1 2 7 7 4 8 3 0 1 5 6 4 6 2 t y p e s . F r a m e T y p e
2 1 0 3 4 3 6 4 1 4 1 9 2 8 7 7 s t r
3 2 7 2 7 2 1 1 2 2 0 0 8 7 d i c t o f g u p p y . e t c . G l u e . O w n e r
4 2 7 8 0 3 2 2 8 0 9 0 _ _ b u i l t i n _ _ . w e a k r e f
5 1 3 6 8 3 2 3 4 8 9 3 t y p e s . C o d e T y p e
6 2 7 6 4 3 2 4 1 2 9 6 g u p p y . e t c . G l u e . O w n e r
7 2 7 6 4 3 2 4 7 6 9 8 t u p l e
Enter Guppy 87
{footer} http://revista.python.org.ar
8 1 3 3 2 1 2 5 0 8 1 0 0 e x c e p t i o n s . K e y b o a r d I n t e r r u p t
9 1 3 1 2 0 2 5 2 0 1 0 0 i n t
Ah!
Esto es importante!
Esos 29 objetos evitan que se pueda achicar el heap. Lo que me lleva
Montn (heap)
al heap.
Normalmente el heap se agranda y se achica.
Ciclo de vida del montn
El montn se expande y contrae, pero en cada ciclo puede quedar basura, o
capaz objetos tiles vivos, que impiden que se contraiga del todo. La memoria que
queda en el medio no puede ser utilizada por otros procesos, slo est libre para
Python.
Como se ve en la figura, cada vez que se achica, no lo hace completamente. A veces
quedan objetos vivos en direcciones elevadas - como el montn no puede
fragmentarse (no se puede liberar un espacio del medio del montn, slo puede
agrandarse o achicarse), esos objetos mantienen la memoria del medio reservada
para Python. Python puede reusarla, pero el resto del sistema operativo no.
Eso daa el cach de disco, daa otros procesos (capaz otros procesos Python, en un
webserver puede suceder que tengamos ms de un worker corriendo python), daa la
performance general del sistema.
Adivinen quines tienen la costumbre de dejar objetos vivos en altas direcciones de
memoria
as es. Las listas libres. Ac, con guppy encontramos 29 objetos, probablemente
todos que estn vivos gracias a alguna lista libre que los mantiene vivos. Vemos que
un par de ellos son Frames, como deca antes, los Frames causan este tipo de
88 Montn (heap)
{footer} http://revista.python.org.ar
problemas.
Todos queremos saber cmo evitar estos problemas, as que:
Guppy tips
No dejar basura por el piso
Si se van a crear muchos objetos pequeos, crear los persistentes
primero, y los transientes al final.
Compilar cdigo (ej: usar eval o hacer imports) genera cadenas
permanentes, llamadas cadenas internadas, as que compilar
on-demand tambin es algo a evitar.
SQLAlchemy y muchas otras bibliotecas tienen cachs internos,
investigar y estar al tanto de estas polticas.
Siempre que sea posible, preferir pocos objetos grandes a muchos objetos
pequeos:
Listas de strings strings separados por comas. O pipes. O enter. O
lo que sea.
Listas de nmeros a r r a y . a r r a y o n u m p y . a r r a y
Barrer de vez en cuando
Si se mantienen caches con expiracin, limpiar el cach regularmente
para quitar elementos expirados
A veces se puede desfragmentar la memoria, reconstruyendo
estructuras persistentes como los cachs
De hecho, el garbage collector de java hace esto automticamente, y
muchos proyectos buscan implementar un garbage collector similar para
Python, pero la API de extensin de Python, la Python/C, lo hace difcil al
permitir punteros directos a los PyObject, estructuras que representan los
objetos en Python)*.
El cambio es bueno
No crear estructuras eternas.
Los caches siempre expiran.
Los threads se renuevan.
Guppy tips 89
{footer} http://revista.python.org.ar
La casa es para vivirla, la oficina es para trabajar
Siempre que sea posible, realizar tareas intensivas en memoria en un
subproceso, que al terminar libera la memoria y deja todo limpito y
ordenado.
El subproceso es la oficina, ah se trabaja.
El proceso padre es mi casa, ah se vive.
Links tiles
Los slides:
http://python.org.ar/pyar/Charlas#Depuraci.2BAPM-n_y_defragmentaci.2BAPM-n_de_memoria_en_Python
Cmo mapear memoria: http://python.org.ar/pyar/MapeandoMemoria
Heapy: http://guppy-pe.sourceforge.net/
90 Links tiles
{footer} http://revista.python.org.ar
NINJA-IDE, Un IDE Pensado para Python
Autores: Diego Sermentero, Santiago
Moreno
Estudiantes de Ing. en Sistemas que les
gusta desarrollar software libre por amor al
arte.
Pgina: http://ninja-ide.org
Twitter:
@diegosarmentero
(http://twitter.com/diegosarmentero),
@f4llen_4ngel
(http://twitter.com/F4LLEN_4NGEL),
@ninja_ide
(http://twitter.com/ninja_ide)
Como comenz NINJA-IDE?
NINJA-IDE naci por unos mails enviados a PyAr, cuya temtica suele escucharse con
bastante frecuencia: Qu buen IDE para Python puedo usar?, Por qu no hay
un IDE para Python que tenga tal o cual caracterstica?, y las respuestas a
estos mails siempre terminan siendo mas o menos las mismas, ya que los IDEs
actuales que encontramos disponibles, en su gran mayora, no estaban diseados
para Python, sino que brindaban la opcin de incorporarlo mediante algn Plugin y de
esta forma se sola estar utilizando IDEs muy pesados diseados para otros fines,
donde el soporte para Python en realidad era mnimo, y aquellos que si eran para
Python terminaban siendo muy orientados a un Framework especifico o no eran
Libres. Entonces, motivados por el desafo que representaba, y por ideas interesantes
que se plantearon en la lista de correo, decidimos encarar este proyecto
enfocndonos en qu caractersticas debera tener un buen IDE para un
programador Python.
Con esto en mente comenzamos el desarroll de NINJA-IDE, el cual posee su nombre
por el acrnimo recursivo: Ninja Is Not Just Another IDE. El IDE tiene apenas unos
7 meses de desarrollo, pero gracias a las ganas y las horas de programacin que le
dedicamos, ya podemos contar con una versin 1.1 del mismo, con muchas
funcionalidades implementadas, y desde su primer semana de desarrollo NINJA-IDE
es utilizado para desarrollar NINJA-IDE, lo cual a su vez nos ayuda para encontrar
NINJA-IDE, Un IDE Pensado para Python 91
{footer} http://revista.python.org.ar
bugs y mejorar la usabilidad y prcticidad de la aplicacin, a travs de la experiencia
y uso continuo de la misma.
El proyecto esta desarrollado bajo licencia libre GPL3 y puede conseguirse el cdigo
a travs de: http://ninja-ide.googlecode.com
Algunas de las features actuales del IDE son:
Funcionalidades tpicas de cualquier IDE para el manejo de archivos, de Tabs,
indentacin automtica, Zoom en Editor, etc.
Al estar escrito en Python y utilizar PyQt, es multiplataforma y fue probado en
sistemas Linux, MAC OS X y Windows.
Resaltado de Sintaxis para un gran variedad de lenguajes (si bien esta centrado
en Python, brinda el resaltado de sintaxis para otros lenguajes ms para
comodidad del programador).
Posibilidad de usar una Consola Python desde el mismo IDE.
Permite el manejo de Proyectos en el IDE, reconociendo los mismos como
Proyectos Python y a travs del IDE crear nuevos archivos y carpetas, borrar
archivos existentes, creacin automtica de archivos __init__ con la
informacin dentro de ese mdulo, etc.
Permite ocultar y reubicar todos los paneles de la interfaz de una forma muy
simple, permitiendo que sea adaptado a los gustos del usuario.
Permite ver ms de un Editor al mismo tiempo de forma vertical u horizontal.
Extensible a travs de la incorporacin de Plugins (los cuales pueden crearse
utilizando un Plugin de NINJA-IDE para mayor simplicidad).
Maneja sesiones del IDE, para recordar que archivos y proyectos se
encontraban abiertos cuando se cerr y los recupera al abrir nuevamente una
instancia del mismo.
Soporte para Auto-completado (siendo un auto-completado especifico del objeto
al que se esta accediendo).
Notificacin de actualizaciones.
Y muchas caractersticas ms!
92 NINJA-IDE, Un IDE Pensado para Python
{footer} http://revista.python.org.ar
NINJA-IDE, Un IDE Pensado para Python 93
{footer} http://revista.python.org.ar
Quienes desarrollamos NINJA-IDE?
NINJA-IDE comenz siendo desarrollado por Santiago Moreno y Diego Sarmentero, y
a la semana de haber comenzado el proyecto ya estaba siendo utilizado para
desarrollar el mismo. Gracias a la gente de la Lista de PyAr, Blogs, etc. en muy poco
tiempo la difusin del proyecto hizo que pudiramos estar contando con Reporte de
Bugs por parte de Usuarios, Sugerencias en la lista de correo de NINJA y hasta con
aportes de cdigo por parte de usuarios y colaboradores, de los cuales algunos
pasaron a formar parte de NINJA-IDE con el rol de commiters, como es el caso de:
Martn Alderete y Matas Herranz. Y otros con el rol de contributors, como: Juan
Carlos Ojeda y Cesar Vargas.
Esta fuerte colaboracin y participacin que estamos recibiendo de la comunidad
permite que NINJA-IDE pueda crecer cada da ms, mejorando e implementando
caractersticas que los usuarios necesitan. A su vez los comentarios que recibimos de
personas usando actualmente NINJA-IDE, nos motivan a seguir trabajando duro en
esta herramienta, con la cual deseamos simplificar an ms el desarrollo de
aplicaciones Python.
Para ponerse en contacto con cualquiera de los miembros del proyecto se puede
utilizar:
La Lista de Correo de NINJA-IDE: http://groups.google.com/group/ninja-ide
94 Quienes desarrollamos NINJA-IDE?
{footer} http://revista.python.org.ar
La Lista de Correo de NINJA-IDE (Development):
http://groups.google.com/group/ninja-ide-dev
Canal IRC de NINJA-IDE: http://ninja-ide.org/support.html
Reporte de Bugs: http://code.google.com/p/ninja-ide/issues/list
NINJA-IDE en Twitter: http://twitter.com/ninja_ide
Actualmente nos pone muy contentos como desarrolladores de NINJA-IDE poder
haber conseguido el Tercer Puesto como Mejor Software Libre y el Primer Puesto
como Software Libre que necesita ms donaciones (Premio otorgado al proyecto
con mayor espectativa de crecimiento), dentro del marco del concurso de *`Portal
Programas
<http://www.portalprogramas.com/software-libre/premios/software-libre-donaciones>`_*,
habiendo conseguido estas menciones teniendo el proyecto solo unos meses de
existencia. Y a su vez, formar actualmente parte del Showcase de Aplicaciones del
programa Qt Ambassador.
Cmo decidimos que caractersticas agregar?
Al comenzar el proyecto se pens en una estructura que le permitiera al mismo
crecer e incorporar funcionalidades a lo largo del tiempo, teniendo como gua dos
factores principales: el Editor de Cdigo y el Manejo de Proyectos. La aplicacin
comenz a construirse cuidando estos dos pilares fundamentales y permitiendo que
una buena base de los mismos facilitara luego la incorporacin de nuevas
caractersticas.
El proyecto fue pasando por distintas etapas, comenzando por un buen editor con
resaltado de sintaxis, siguiendo con el manejo de archivos de proyecto, hasta agregar
caractersticas de plugins, auto-completado, manejo de sesin, etc.
Muchas veces se ve a Python como un lenguaje que presenta mayores dificultades
para brindar informacin sobre el cdigo que se esta escribiendo al no poder hacer
inferencia de los objetos en el momento de la programacin a causa del tipado
dinmico, etc. En algunos casos, es cierto que al contar con un tipado explicito se
pueden realizar anlisis ms simples y detallados, pero tambin es cierto que
actualmente existen muchas herramientas y libreras para Python que ayudan a
eliminar este tab de que no es posible contar con un IDE que brinde real asistencia
sobre el cdigo que se esta generando. Es por eso que NINJA-IDE busca permitir que
aquellos programadores que utilizan Python para desarrollar sus programas, cuenten
con las mismas facilidades y ayudas que se obtienen al desarrollar en Java o .NET con
alguno de los IDEs ms conocidos actualmente para esos lenguajes. Tomando los
Cmo decidimos que caractersticas agregar? 95
{footer} http://revista.python.org.ar
resultados y experiencias obtenidas de IDEs para otros lenguajes, se pretende lograr
un IDE pensado para Python que genere la misma satisfaccin al usarlo.
Para la sugerencia, decisin e incorporacin de nuevas caractersticas en NINJA-IDE
se suele utilizar la lista de correo para lograr una decisin colectiva por parte de los
miembros que componen el proyecto, ms que nada para saber cual ser el objetivo
de esta caracterstica, en que etapa debera incorporarse y dems detalles. Muchas
veces estas caractersticas son motivadas por alguna funcionalidad interesante vista
en otro IDE, una idea de alguno de los miembros o sugerencias del grupo de usuarios.
De este modo, cualquier persona, tanto usuario como desarrollador, puede plantear
que cosas le gustara ver implementadas en NINJA-IDE y en base a la arquitectura
del proyecto se podr definir si es necesario incorporarla como parte del IDE mismo o
como un plugin, permitiendo a la vez conocer que ideas se estn trabajando y quienes
asumen el control de las mismas para mantener al grupo de trabajo sincronizado.
96 Cmo decidimos que caractersticas agregar?
{footer} http://revista.python.org.ar
Que esperamos de NINJA-IDE?
NINJA-IDE nace para cubrir una necesidad que nos pareca importante, y adems
veamos que los enfoques actuales de los IDEs no brindaban la cobertura necesaria.
Nuestra intencin al iniciar este proyecto fue crear un entorno centrado en el
desarrollo de aplicaciones Python, pero siempre teniendo en cuenta la necesidad de
contar con una comunidad de usuarios que nos permitiera mejorar la experiencia de
uso de esta herramienta, y actualmente nos pone muy contentos poder estar
contando con la comunidad de NINJA-IDE, ya que gracias a la experiencia y
conocimiento colectivo de los usuarios es posible, que con sus sugerencias, el
desarrollo del proyecto pueda avanzar ms rpido y se tengan en cuenta muchos ms
detalles que de otra forma podran ser pasados por alto.
Planes para el Futuro
Actualmente nos encontramos en la versin 1.1 de NINJA-IDE, la cual recibe la
denominacin de Kunai. En esta primera versin estn presentes las caractersticas
mencionadas previamente, las que permitirn al desarrollador contar con un IDE
robusto y prctico, obviamente como en todo proyecto irn surgiendo mejoras y
nuevas features para implementar.
Algunas de las caractersticas que estn pensadas para ser incorporadas en la versin
2.0 de NINJA-IDE, la cual acaba de comenzar su desarrollo, son:
Implementacin de una Arquitectura dinmica y extensible.
Que esperamos de NINJA-IDE? 97
{footer} http://revista.python.org.ar
Debuguer Grfico.
Poder ver la navegabilidad y relacin de los mdulos y clases de un proyecto de
forma grfica (basado en BlueJ).
Soportar herramientas de versionado de cdigo.
Permitir la edicin colaborativa de un documento.
Diseador de interfaces Qt integrado en el IDE.
Localizador de Cdigo.
Soporte para Virtualenv.
Agregar ms features de Refactoring.
Plugins para Versionado.
Soporte para Frameworks como:
Django
Google App Engine
Y esto apenas est comenzando!
Se puede consultar las Release Notes de las versiones actuales en:
http://code.google.com/p/ninja-ide/wiki/ReleaseNotes Y un completo listado de las
Features propuestas para la Versin 2.0 en:
http://code.google.com/p/ninja-ide/wiki/Brainstorming_version2
Qu herramientas utiliza NINJA-IDE?
El IDE es desarrollado utilizando las libreras de PyQt para todo el manejo de la
interfaz grfica y algunas otras funcionalidades. Qt permiti contar con una interfaz
solida y altamente configurable, lo que hizo posible poder extender de cada elemento
necesario para modificar su comportamiento y adecuarlo a las necesidades del IDE.
En cuanto al resaltado de sintaxis, NINJA-IDE hace uso de su propio sistema de
resaltado de sintaxis utilizando funcionalidades de Qt, y permitiendo que este sistema
de resaltado sea fcilmente extensible en NINJA-IDE con la creacin de un simple
archivo JSON que describa al lenguaje que se desea incorporar. Este mtodo brinda
mejoras en la performance, pero para cubrir aquellos lenguajes que no sean
reconocidos a travs de este sistema se incorpor el uso de Pygments para el
resaltado de sintaxis de una mayor variedad de lenguajes. Aunque para la versin 2.0
del IDE se tiene pensado cubrir la gama de lenguajes soportados por Pygments
98 Qu herramientas utiliza NINJA-IDE?
{footer} http://revista.python.org.ar
directamente con NINJA-IDE para mejorar la performance del resaltado de sintaxis y
eliminar esta dependencia con una librera externa.
Para las funcionalidades de auto-completado, refactoring, y aquellas que se refieren a
la inferencia del cdigo, se utiliza Rope, la cual es una excelente librera, muy
completa para este tipo de situaciones. Rope es una herramienta que permite llevar a
un IDE para Python caractersticas de IDEs de lenguajes tipados.
Actualmente tambin es soportado el Chequeo de cdigo utilizando la librera de
Pep8, justamente para brindar informacin acerca del estado del cdigo en relacin a
las normas de la Pep8.
Extensibilidad de NINJA-IDE
NINJA-IDE cuenta con un sistema de plugins bastante completo que permite la
integracin de dichos complementos como un elemento nativo del IDE. La escritura
de Plugins es bastante sencilla y hasta se puede utilizar un Plugin de NINJA-IDE para
la escritura de Plugins para NINJA-IDE (recursivo?). Este Plugin para escribir
Plugins permite decidir con que partes del IDE el nuevo complemento se va a
relacionar y crea de forma automtica la estructura del proyecto necesario, junto al
descriptor del Plugin para que NINJA-IDE lo pueda interpretar y la clase base de ese
Plugin con los mtodos que sern necesario reimplementar, a su vez, al terminar con
la escritura del Plugin nos permite empaquetarlo para luego poder distribuirlo.
Actualmente existen 3 Plugins para NINJA-IDE disponibles:
Pastebin: el cual permite enviar cdigo a pastebin.com y devuelve el link
resultante para poder compartir ese cdigo.
PluginProject: el encargado de crear proyectos Plugins para NINJA-IDE como
mencionbamos.
ClassCompleter: completa de forma automtica algunas estructuras mientras se
esta escribiendo cdigo Python, como por ejemplo: crear el constructor de
forma automtica realizando la llamada a las Clases Padre que sean necesarias,
etc.
Para consultar mayor informacin acerca de como desarrollar un Plugin para
NINJA-IDE, se puede visitar la siguiente Wiki:
http://code.google.com/p/ninja-ide/wiki/CrearPlugins
Extensibilidad de NINJA-IDE 99
{footer} http://revista.python.org.ar
Usando libreras adicionales y virtualenv
Author: Tomas Zulberti
Los temas sobre los que voy a hablar son:
La librera estndar de Python
Qu hacer cuando algo no esta en en la librera?
Instalando libreras adicionales
Usar virtualenv para solucionar los problemas que aparecen
Python viene con cerca de 350 libreras para usar.
http://docs.python.org/library/index.html
Tienen de todo:
Trabajar con mails
Fetchear paginas
Interactuar con el sistema operativo
Trabajar con archivos comprimidos
Parsear diferentes tipos de documentos (xml, json, etc..)
MUCHAS COSAS MAS.
Antes que nada, veamos algunos ejemplos de cosas que se pueden hacer con las pilas
que trae Python.
Enviamos un mail usando una cuenta de GMail
> > > i m p o r t s m t p l i b
> > > f r o m e m a i l . M I M E T e x t i m p o r t M I M E T e x t
> > > U S E R N A M E = " t z u l b e r t i @ g m a i l . c o m " # A c a t i e n e n q u e p o n e r s u u s u a r i o
> > > P A S S W O R D = " n o s e l o s v o y a d e c i e r " # A c a p o n e n s u p a s s s w o r d
> > > m a i l S e r v e r = s m t p l i b . S M T P ( ' s m t p . g m a i l . c o m ' , 5 8 7 )
100 Usando libreras adicionales y virtualenv
{footer} http://revista.python.org.ar
> > > m a i l S e r v e r . e h l o ( )
> > > m a i l S e r v e r . s t a r t t l s ( )
> > > m a i l S e r v e r . e h l o ( )
> > > m a i l S e r v e r . l o g i n ( U S U A R I O , P A S S W O R D )
> > > m s g = M I M E T e x t ( " E s t e e s e l c o n t e n i d o d e l m a i l . . . " )
> > > m s g [ ' F r o m ' ] = U S E R N A M E
> > > m s g [ ' T o ' ] = U S E R N A M E
> > > m s g [ ' S u b j e c t ' ] = " E s t e e s e l s u j e t o "
> > > m a i l S e r v e r . s e n d m a i l ( " t z u l b e r t i @ g m a i l . c o m " , " t z u l b e r t i @ g m a i l . c o m " , m s g . a s _ s t r i n g ( ) )
Leemos una pagina web para leer el contenido de la misma.
> > > f r o m u r l l i b 2 i m p o r t u r l o p e n
> > > r e s p o n s e = u r l o p e n ( " h t t p : / / p y t h o n . o r g . a r / p y a r / " )
> > > c o n t e n i d o _ h t m l = r e s p o n s e . r e a d ( )
> > > p r i n t c o n t e n i d o _ h t m l
< ! D O C T Y P E H T M L P U B L I C " - / / W 3 C / / D T D H T M L 4 . 0 1 / / E N " " h t t p : / / w w w . w 3 . o r g / T R / h t m l 4 / s t r i c t . d t d " >
< h t m l >
< h e a d >
< l i n k r e l = " i c o n " h r e f = " / i m a g e s / p y a r . i c o " t y p e = " i m a g e / i c o " >
< m e t a h t t p - e q u i v = " C o n t e n t - T y p e " c o n t e n t = " t e x t / h t m l ; c h a r s e t = u t f - 8 " >
< m e t a n a m e = " k e y w o r d s " c o n t e n t = " P y t h o n , P y A r , P y t h o n A r g e n t i n a , u s e r g r o u p ,
g r u p o d e u s u a r i o s , c o m m u n i t y p o r t a l " >
< m e t a n a m e = " r o b o t s " c o n t e n t = " i n d e x , f o l l o w " >
< t i t l e > I n i c i o - P y A r - P y t h o n A r g e n t i n a < / t i t l e >
< s c r i p t t y p e = " t e x t / j a v a s c r i p t " s r c = " / m o i n _ s t a t i c 1 8 2 / c o m m o n / j s / c o m m o n . j s " > < / s c r i p t >
Trabajamos con archivos comprimidos
> > > i m p o r t z i p f i l e
> > > a r c h i v o _ c o m p r i m i d o = z i p f i l e . Z i p F i l e ( " E L _ A R H I V O . z i p " , " r " )
> > > f o r n a m e i n a r c h i v o _ c o m p r i m i d o . n a m e l i s t ( ) :
. . . p r i n t n a m e
> > > a r c h i v o _ c o m p r i m i d o . e x t r a c t ( )
Pero la librera de python no tiene todo:
No sabe leer algunos algunos formatos de archivos (yaml, mp3, vdeo)
Frameworks web (pylons, django, web2py)
Usar API de Youtube, Deliciosus, etc.
Usando libreras adicionales y virtualenv 101
{footer} http://revista.python.org.ar
Vimos que la librera estndar puede hacer varias cosas, pero hay cosas que son mas
fciles si se usan libreras hechos por otras personas:
Los frameworks permiten ahorrar cierto trabajo repetitivo.
Las interfaces a la API nos ahorran el hecho de tener que leer la documentacin
de las mismas
Aunque Python sabe leer archivos de texto y binarios, es mas fcil que
directamente convierta ciertos formatos de archivos a estructuras de python.
Dnde buscar libreras que no esten en python?
http://pypi.python.org/pypi
Hay cerca de 11.000 libreras para usar. Como se vio en la charla de Roberto Alsina
(import antigravity), hay para hacer de todo:
Colorear la consola
Alternativas a la consola de python (bpython, ipython)
Trabajar con formatos de archivos raros
Bajar archivos de cuevana
Bajar videos de youtube
Parsear xmls usando una sintaxis parecida a jQuery
MUCHO MAS COSAS
Cmo instalamos los paquetes de PyPi?
Primero necesitan instalar python-setuptools
Esto depende del sistema operativo:
Ubuntu:
a p t - g e t i n s t a l l p y t h o n - s e t u p t o o l s
Windows: tienen un .exe a bajarse desde ac:
http://pypi.python.org/pypi/setuptools/0.6c11#windows
102 Dnde buscar libreras que no esten en python?
{footer} http://revista.python.org.ar
Los paquetes en Python generalmente se distribuyen bajo un archivo .egg. Estos
archivos son un archivo zip (con otra extensin) que:
Tienen el cdigo
Tienen otros archivos (imagenes, sonido, docuementacin, etc..)
Tienen un archivo muy importante de metada: setup.py
Para instalar los .egg necesitan instalar primero un modulo llamado setuptools.
Una vez que instalan el modulo setuptools, van a tener disponible el comando
easy_install.
e a s y _ i n s t a l l n o m b r e L i b r e r i a
Por ejemplo:
easy_install django
easy_install yaml
easy_install pylons==1.0
easy_install -U rst2pdf
Algo importante a tener en cuenta es que el comando easy_install tambin instala
todas las dependencias. Por ejemplo, rst2pdf depende de Pygments y reportlab. Si se
ejecuta:
e a s y _ i n s t a l l r s t 2 p d f
Entonces tambin se van a instalar reportlab, y Pygments. Para los que usan Ubuntu,
easy_install funciona como apt-get.
Existe una alternativa a easy_install llamada pip. Recomiendo usar esa opcin.
e a s y _ i n s t a l l p i p
Se puede hacer todo lo que se hacia con easy_install, y tambin hace mas cosas:
Hacer bsquedas en pypi
p i p s e a r c h r s t 2 p d f
Dnde buscar libreras que no esten en python? 103
{footer} http://revista.python.org.ar
Desinstalar paquetes
p i p u n i n s t a l l r s t 2 p d f
Listar las libreras instaladas
p i p f r e e z e
Instalar todas las paquetes que est en un archivo
p i p f r e e z e > a r c h i v o C o n L i b r e r i a s . t x t
p i p i n s t a l l - r a r c h i v o C o n L i b r e r i a s . t x t
Por ejemplo:
pip install django
pip install -U rst2pdf
Sin embargo existen algunos problemas:
Es necesario ser admin/root. Es fcil cuando uno esta desarrollando, pero poco
probable en produccin.
No se pueden instalar dos versiones de la misma paquete.
Esto es importante cuando la paquete no es compatible para atrs. Algunos
ejemplos son:
SQLAlchemy
django
Por ejemplo, las aplicaciones que funcionan con django 0.9.7 no funcionan con
django 1.2, y viceversa. Por como funciona el sistema de paquetes de Python, el
mismo solo permite tener instalado una nica versin de un mismo paquete.
Por lo tanto, uno tiene que elegir que versin del paquete usar.
104 Dnde buscar libreras que no esten en python?
{footer} http://revista.python.org.ar
Usando virtualenv
Para solucionar estos problemas existe virtualenv. El mismo se encarga de crear un
entorno aislado del entorno de Python del sistema. Para eso es necesario instalarlo:
e a s y _ i n s t a l l v i r t u a l e n v
Es una nica vez que van a necesitar ser root/admin para instalar una librera. Lo
traen todos los servidores que usan permiten hostear proyectos en python.
Sino se tiene permiso de root/administrador, tambin se lo puede usar sin instalarlo
en el sistema. Para eso se bajan el comprimido desde:
http://pypi.python.org/pypi/virtualenv
Una vez instalado, lo primero que hay que hacer es crear un entorno virtual:
v i r t u a l e n v n o m b r e E n t o r n o
Esto va a crear una carpeta nombreEntorno en donde estemos parados. Si no lo
instalaron en el sistema, y se bajaron el archivo comprimido, entonces
p y t h o n v i r t u a l e n v . p y n o m b r e E n t o r n o
El comando anterior creo un entorno de Python que esta separado de la configuracin
del sistema global. Por lo tanto, uno hay no tiene problemas de permiso porque esto
lo puede crear en su carpeta.
Para decirle al sistema operativo que queremos usar el entorno creado, y no el del
sistema, es necesario activar el entorno.
Linux:
s o u r c e n o m b r e E n t o r n o / b i n / a c t i v a t e
Windows:
n o m b r e E n t o r n o \ S c r i p t s \ a c t i v a t e . b a t
Tanto en windows como en linux, cuando activen en entorno, les va a aparecer el
nombre del entorno activado entre parntesis:
Usando virtualenv 105
{footer} http://revista.python.org.ar
( n o m b r e E n t o r n o ) t z u l b e r t i @ m y h o s t : ~
Cuando uno tiene en entorno activado, uno puede ver que el python que usa no es el
global, sino que es esta dentro de la carpeta que creo virtualenv, y no el del sistema
global
( n o m b r e E n t o r n o ) t z u l b e r t i @ m y h o s t : w h i c h p y t h o n
/ h o m e / t z u l b e r t i / n o m b r e E n t o r n o / b i n / p y t h o n
Lo mismo pasa con el easy_install y pip. Tambin, todos los paquetes que se instalen
se van a instalar dentro del entorno creado.
Para dejar de usar el entorno lo que tenemos que hacer es:
Linux:
d e a c t i v e
Windows:
n o m b r e E n t o r n o \ S c r i p t s \ d e a c t i v a t e . b a t
Cmo funciona virtualenv?
Cuando uno crea un entorno, dentro del mismo se crean tres carpetas:
bin: cuando uno tiene el entorno activado, y ejecuta un comando como python,
pip o easy_install, se ejecuta alguno de los binarios que se encuentran en esa
carpeta, en vez de ejecutar los del sistema.
include: es simplemente un link al a los archivos de la instalacin de Python.
lib: esta es otra carpeta importante. Al igual que include tiene una carpeta
llamada python pero a diferencia de include, esta no es una link a la carpeta de
Python. La carpeta tiene dos cosas importantes:
Un link a algunos archivos de Python. En este caso a los .py
Una carpeta, site-packages, que es donde se instalan los paquetes
cuando uno usa pip o easy_install
106 Cmo funciona virtualenv?
{footer} http://revista.python.org.ar
Preguntas y respuestas? (Parte I)
Anteriormente comente que uno de los problemas que tenamos era que no se podan
instalar dos versiones de la misma librera. Lo que nunca hice fue comentar como se
soluciona ese problema.
La solucin es fcil. Se crea un entorno para usar con django 0.97, y otro para usar
con 1.2. Se pueden crear todos los entornos que uno quiera, y son aislados entre si.
Para los servidores de produccin, hay configuraciones se puede configurar el apache
para que use cierto entorno virtual.
Preguntas y respuestas? (Parte II)
Creo un virtualenv, lo activo, y hago pip freeze, y me aparecen cosas que nunca
instale en el entorno.
El comportamiento predeterminado de virutalenv cuando se crea un entorno, es
tambin crearlo con los paquetes que uno tiene instalado en el sistema. Para que no
haga eso, cuando se crea el entorno, se puede hacer:
v i r t u a l e n v - - n o - s i t e - p a c k a g e s n o m b r e E n t o r n o
Eso hace que cree un entorno totalmente vaci. Por ltimo, otra opcin a tener en
cuenta es python, que hace que el entorno virtual use esa versin de python (para
eso es necesario tener instalado esa version de Python). Por ejemplo, en mi maquina
tengo instalado Python 2.7 y 3.1, siendo el 2.7 el predeterminado.
Luego, cuando se cree un entorno, lo va a crear usando Python 2.7. Para que en el
entorno se use Python 3.1, se tiene que hacer:
v i r t u a l e n v - - p y t h o n = p y t h o n 3 . 1 n o m b r e E n t o r n o
Preguntas y respuestas? (Parte III)
Hay ciertos paquetes que tienen cdigo escrito en C. Qu pasa con las mismas?
En esos casos pip o easy_install van a intentar compilar el cdigo escrito en C,
cuando uno lo instala. En distribuciones como Ubuntu, recomiendo instalar:
build-essential
python-dev
Preguntas y respuestas? (Parte I) 107
{footer} http://revista.python.org.ar
Esos dos paquetes facilitan mucho la compilacin.
Sin embargo, en Windows no es tan feliz la cosa. Varios de los paquetes que tienen
cdigo en C, se distribuyen tambin en .exe. Sin embargo, los instaladores no
permiten seleccionar donde instalar las mismas. Ac
h t t p : / / w w w . d e v e l o p e r z e n . c o m / 2 0 1 0 / 0 9 / 2 3 / t h e - c o m p l e t e - g u i d e - t o - s e t t i n g - u p - p y t h o n - d e v e l o p m e n t - e n v i r o n m e n t - o n - w i n d o w s /
hay una MUY buena guia de como hacer para que compile los paquetes cuando los
baje.
Preguntas y respuestas? (Parte IV)
Recomendas instalar los paquete del sistema o usando easy_install?
Hay que tener en cuenta que varias distribuciones traen varios paquetes de python
que se pueden instalar en el sistema. Por ejemplo:
a p t - g e t p y t h o n - n u m p y p y t h o n - r e p o r t l a b p y t h o n - p i l
Pero las versiones que se pueden instalar por apt-get estn desactualizadas. Ac
vemos algunos ejemplos comparativos de versiones:
Nombre del paquete Versin de Ubuntu 10.10 Versin de Pypi
rst2pdf 0.14.2 0.16
reportlab 2.4.3 2.5
django 1.2.3 1.2.3
Por lo tanto, depende de lo que uno quiera hacer. Por ejemplo, si uno quiere hacer un
programa que funcione con Ubuntu, entonces puede crear un entorno virtual e
instalar las mismas versiones que con apt-get o directamente instalar las global
Lo que NO recomiendo es sobre escribir la versin instalada. Por ejemplo, si uno
hace:
a p t - g e t p y t h o n - r e p o r t l a b
Entonces no tiene que hacer:
e a s y _ i n s t a l l - U r e p o r t l a b
108 Preguntas y respuestas? (Parte IV)
{footer} http://revista.python.org.ar
Sin usar un entorno virtual porque puede romper algo del sistema.
Preguntas y respuestas? (Parte IV) 109
{footer} http://revista.python.org.ar
Desafo PET
Autor: Juanjo Conti y Alejandro Santos
En el nmero anterior de PET presentamos nuestro primer desafo. Consista en
proveer el programa ms corto caps de factorizar un nmero (teniendo en cuenta
algunas reglas). Hemos recibido muchas respuestas, las primeras con alrededor de
500 caracteres, y las ltimas que fueron exprimiendo cdigo byte a byte para lograr
la solucin ms corta.
De los 58 participantes que tuvimos, estamos orgullosos de contarles que tuvimos 3
ganadores. Ms an, ellos, con su solucin de 111 caracteres, llegaron al programa
ganador por distintos caminos, recortando, masajeando y perfeccionando sus
soluciones originales.
Los ganadores
Sin ms prembulos, los ganadores, junto a sus obras, son:
Chema Cortes con pet1-pych3m4.py:
n = i n p u t ( ) ; d = 1 ; r = " "
w h i l e d < n :
d + = 1 ; s = 0
w h i l e n % d < 1 : n / = d ; s + = 1
i f s : r + = " x % d " % d + " ^ % d " % s * ( s > 1 )
p r i n t r [ 3 : ] o r n
Javier Mansilla con pet1-jmansilla.py :
s = i n p u t ( ) ; _ = ' ' ; i = 1
w h i l e s > i :
c = 0 ; i + = 1
w h i l e 1 > s % i : c + = 1 ; s / = i
i f c : _ + = ' x ' + ` i ` + ' ^ % i ' % c * ( c > 1 )
Oswaldo Hernndez con pet1-hdzos.py:
n = i n p u t ( )
d , f = " " , 1
110 Desafo PET
{footer} http://revista.python.org.ar
w h i l e n > 1 :
f + = 1 ; r = 0
w h i l e n % f < 1 : r + = 1 ; n / = f
i f r : d + = " x % s " % f + " ^ % s " % r * ( r > 1 )
Mencin especial
En esta oportunidad hemos considerado dar el premio a la entrada ms tramposa a
Darni, que en lugar de que renombremos su archivo pet1-darni.py pidi que
mantengamos su seudnimo artstico
ZT1pbnB1dCgpCnM9JycKZD0xCndoaWxlIGU+MToKCXA9MDtkKz0xCgl3aGlsZSBlJWQ8MTplLz1kO3ArPTEKCWlmIHA6cys9JyB4ICVkJyVkKyhwPjEpKignXiVkJyVwKQpwcmludCBlKnNbMzpdb3IgZQ==
Este es el contenido del archivo
pet1-ZT1pbnB1dCgpCnM9JycKZD0xCndoaWxlIGU+MToKCXA9MDtkKz0xCgl3aGlsZSBlJWQ8MTplLz1kO3ArPTEKCWlmIHA6cys9JyB4ICVkJyVkKyhwPjEpKignXiVkJyVwKQpwcmludCBlKnNbMzpdb3IgZQ==.py:
i m p o r t b a s e 6 4 ; e x e c ( b a s e 6 4 . d e c o d e s t r i n g ( _ _ f i l e _ _ [ 5 : - 3 ] ) )
Informacin adicional sobre la competencia puede encontrarse en
http://python.org.ar/pyar/Proyectos/RevistaPythonComunidad/PET1/Desafio
Nuevo desafo
El nuevo desafo fue escrito por Alejandro Santos, quien adora resolver problemas, y
esta semana estuvo mandando varios Quizz a la lista de PyAr.
Gracias a Matias Tuute Bellone por leer una revisin inicial del problema.
El nmero QQQ
QQQ es la red social ms popular de pas del pas de Ainohtyp. Al estilo microblog,
QQQ es una red social donde los usuarios pueden publicar solamente la palabra QQQ.
Los usuarios tambin pueden tener de contactos a otros usuarios, pero se tienen que
aceptar mutuamente.
Los administradores de la red social armaron un listado con los usuarios ordenado
por la cantidad de contactos de cada uno, y el Rulo encabeza la lista teniendo la
mayor cantidad de contactos.
Tu trabajo es hacer un programa para averiguar cul es la mnima distancia entre
cada persona con el Rulo. Eso es, la mnima cantidad de saltos que hay entre el Rulo
y el resto. Si hay dos o ms formas de llegar al Rulo, elegir la ms corta.
Mencin especial 111
{footer} http://revista.python.org.ar
Por ejemplo, si el Rulo es amigo de Juan y Pedro, Pedro es amigo de Carla, y Carla es
amiga del Rulo, Carla tiene distancia 1 con el Rulo, y Juan y Pedro tienen ambos
distancia 1 con el Rulo.
Es posible llegar desde el Rulo a Carla por medio de Pedro, pero como Carla es amiga
del Rulo la mnima distancia es 1. Pero si Jorge es amigo de Pedro, entonces para
llegar desde el Rulo a Jorge la mnima distancia es 2 ya que se tiene que pasar por
Pedro.
Datos de entrada
Todos los datos se leen por entrada estndar.
Por cuestiones de privacidad los datos son annimos, y la nica informacin de los
usuarios es su nmero de usuario dentro de la red.
En la primer lnea hay dos nmeros N y M que dicen la cantidad de usuarios y la
cantidad de relaciones que hay en la red social, respectivamente.
Los usuarios se numeran de forma consecutiva y sin descartar ningn usuario desde
el 1 en adelante, siendo Rulo el usuario nmero 1. En las M lneas siguiente hay dos
nmeros que indican una relacin entre dos usuarios.
Algunos usuarios tienen cero contactos o no hay forma de armar la cadena de
contactos al Rulo.
Datos de salida
Imprimir por salida estndar N lineas con dos nmeros separados por un nico
espacio en blanco. El primer nmero es el nmero de usuario, y el segundo nmero
es la mnima distancia hacia el Rulo.
En caso de no poder calcular la distancia con el Rulo, mostrar el caracter X.
Ejemplo
Entrada:
8 7
1 2
1 3
1 4
2 5
112 Datos de entrada
{footer} http://revista.python.org.ar
3 5
5 6
4 6
7 8
Salida:
1 0
2 1
3 1
4 1
5 2
6 2
7 X
8 X
Los participantes deben enviar su solucin como un archivo .py (con la forma
pet2-USERNAME.py) y esta ser ejecutado con python 2.7 en la computadora de
Alejandro. El ganador del desafo ser aquel que logre la solucin que pase una
batera de pruebas especialmente confeccionada en el menor tiempo posible.
Envi tu solucin a revistapyar@netmanagers.com.ar poniendo D E S A F I O 2 en el ttulo
del mail antes del 30/05/2011.
Suerte y happy brain squshing!
Aclaraciones y Feedback
Eventuales aclaraciones y feedback para los participantes ser dado a travs de la
wiki: http://python.org.ar/pyar/Proyectos/RevistaPythonComunidad/PET2/Desafio
Aclaraciones y Feedback 113
{footer} http://revista.python.org.ar
114 Aclaraciones y Feedback
{footer} http://revista.python.org.ar
xkcd
xkcd 115
{footer} http://revista.python.org.ar
116 xkcd
{footer} http://revista.python.org.ar
Soporte Tcnico
Este cmic proviene de xkcd, un comic web de romance, sarcasmo, matemtica y
lenguaje (http://xkcd.com)
xkcd 117
{footer} http://revista.python.org.ar