<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Luciano&#039;s webpage &#187; procrastination</title>
	<atom:link href="http://www.lucianobello.com.ar/category/life/procrastination/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.lucianobello.com.ar</link>
	<description>Luciano Bello - My personal webpage</description>
	<lastBuildDate>Thu, 19 Jan 2012 14:37:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Corriendo Debian en un server fanless</title>
		<link>http://www.lucianobello.com.ar/post/debian_in_afanless_server/</link>
		<comments>http://www.lucianobello.com.ar/post/debian_in_afanless_server/#comments</comments>
		<pubDate>Sun, 15 Jan 2012 23:04:03 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[debian]]></category>
		<category><![CDATA[depression]]></category>
		<category><![CDATA[free software]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[hardware]]></category>
		<category><![CDATA[planeta]]></category>
		<category><![CDATA[procrastination]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=1955</guid>
		<description><![CDATA[Debido a una reciente mudanza, he bajado unos servers que tenía corriendo en casa de mis padres. Sin embargo, en mi nuevo hogar estoy en proceso de generar una nueva DMZ, esta vez, sin ventiladores. El primer paso de este proceso ocurrió en forma de weekend project y consiste en hacerme de un &#8220;servidor&#8221;. Las [...]]]></description>
			<content:encoded><![CDATA[<p>Debido a <a href="http://www.lucianobello.com.ar/post/avancez_en/">una reciente mudanza</a>, he bajado unos servers que tenía corriendo en casa de mis padres. Sin embargo, en mi nuevo hogar estoy en proceso de generar una nueva DMZ, esta vez, sin ventiladores.</p>
<p>El primer paso de este proceso ocurrió en forma de <em>weekend project</em> y consiste en hacerme de un &#8220;servidor&#8221;. Las comillas hacen referencia a que no se trata de un gran server sino un procesador ARM de 200Mhz y 32MB de RAM, lo que es suficiente para que corra Debian y algunos otros servicios que pueden ser interesantes.</p>
<h1>Los ingredientes</h1>
<ul>
<li>Un <em>all-in-one LAN server</em> que es la forma en que <a href="https://www.dealextreme.com/">DealExtreme</a> llama a unos dispositivos con chips de la familia str8132. Dado que vamos a instalar <a href="https://code.google.com/p/snake-os/">snake-os</a> en ellos (en este caso se trata de la versión 1.3.2-20111019), es importante chequear <a href="https://code.google.com/p/snake-os/wiki/SnakeOS_compatible_hardwares">la lista de compatibilidad</a>. En particular me hice de un <a href="https://www.dealextreme.com/p/standalone-bittorrent-bt-client-usb-nas-ftp-samba-printer-upnp-sharing-network-lan-server-26320">NS-K330</a> por 40 dólares.<br />
<img src="https://img.dxcdn.com/productimages/sku_26320_2_small.jpg" alt="" /></li>
<li>Storage USB, puede ser en la forma de <a href="https://es.wikipedia.org/wiki/Memoria_USB">stick</a> o como disco portable.</li>
<li>Un <em>RS232 to TTL level converter</em>, también conocido como <em><a href="https://www.dealextreme.com/p/usb-cable-for-nokia-n1200-1208-1650-2630-2670-13638">cable para Nokia N1200/1208/1650/2630/2670</a></em>. Es para conectarse por serie a la consola. No lo necesitamos ahora mismo, pero está bueno tenerlo a mano en caso de <a href="https://en.wikipedia.org/wiki/Brick_%28electronics%29"><em>brickearlo</em></a>, aunque es un procedimiento que no explicaré esta vez.</li>
</ul>
<h1>Instalación de Snake-OS</h1>
<p>Es realmente sencillo. Lo primero es bajar snake-os, desde <a href="https://code.google.com/p/snake-os/downloads/">la sección de <em>downloads</em> de la web</a>. Es importante que el archivo sea de la forma snakeos-&lt;versión&gt;-<strong>from-original</strong>.zip Instalar el que dice from-snake lleva definitivamente al brickearlo y <a href="https://code.google.com/p/snake-os/wiki/SerialConnectionHowToNSK330">recuperarlo puede ser complejo</a>.<br />
Desde la página de administración del dispositivo hay que subir el archivo snakeos-&lt;versión&gt;-from-original.bin contenido en el zip bajado. Confirmar el md5sum no está de más.</p>
<h1>Acceso inicial</h1>
<p>Los datos para acceder a la nueva interfaz con el browser:</p>
<blockquote><p>http://192.168.0.240 (si es que no hay un DHCP en la red)<br />
usuario: admin<br />
contraseña: snake</p></blockquote>
<p>Por SSH la contraseña de root la misma y, al cambiarla por la página de administración, se cambia en todos los accesos.</p>
<h1>Post instalación</h1>
<p>Incluso cuando <a href="https://www.facebook.com/maxiberta">Max</a> opine que el uso de memoria virtual está rumbo a la extinción (lo cierto es que tal vez no es la mejor idea cuando el <a href="https://es.wikipedia.org/wiki/Unidad_de_estado_s%C3%B3lido">storage es de estado sólido</a> como en los pendrives), activé el uso de SWAP desde el menú <em>Service-Swapfile</em>.</p>
<p>Si se quieren las mismas prestaciones que se tenían con el firmware original, hay que instalar unos paquetes adicionales. El sistema de paquetes que utiliza snake-os es <a href="https://en.wikipedia.org/wiki/Opkg">opkg</a> y tiene que ser primero activado desde <em>Service-Opkg</em>. Los paquetes pueden bajarse desde <a href="https://code.google.com/p/snake-os/downloads/list">la página de download de snake-os</a> y se instalan desde <em>System-Packages</em>. En particular, pueden ser interesantes (siempre pensando en los features originales):<br />
<strong><a href="http://www.transmissionbt.com/">Transmission</a></strong>: Es un cliente de BitTorrent, para dejar tus descargas corriendo. Es bastante mejor que el original.<br />
<strong><a href="http://sourceforge.net/projects/minidlna/">miniDLNA</a></strong>: Es el server de streaming compatible con DLNA/UPnP-AV. Está un poco verde, pero <a href="https://code.google.com/p/snake-os/wiki/MiniDLNA">se está trabajando en su mejora</a>.</p>
<h1>Corriendo Debian dentro</h1>
<p>Las instrucciones están <a href="https://code.google.com/p/snake-os/wiki/Debian_Chroot">acá</a>. Aunque esto es lo más obvio y necesario:</p>
<blockquote><p>wget http://snake-os.googlecode.com/files/debian_chroot.tgz<br />
tar -xvf debian_chroot.tgz<br />
mount -o bind /proc /usb/sda1/debian/proc<br />
mount -o bind /dev /usb/sda1/debian/dev<br />
chroot /usb/sda1/debian/
</p></blockquote>
<p>Esta instalación base requiere unos 200MB. Tiene todo el potencial de un Debian (¡porque lo es!).<br />
Claro que falta ajustar varios detalles, pero será la piedra inicial para el resto.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/debian_in_afanless_server/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>¿para qué sirve?</title>
		<link>http://www.lucianobello.com.ar/post/para-que-sirve/</link>
		<comments>http://www.lucianobello.com.ar/post/para-que-sirve/#comments</comments>
		<pubDate>Wed, 31 Aug 2011 23:14:39 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[hardware]]></category>
		<category><![CDATA[home]]></category>
		<category><![CDATA[life]]></category>
		<category><![CDATA[procrastination]]></category>
		<category><![CDATA[sweden]]></category>
		<category><![CDATA[wtf?!]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=1720</guid>
		<description><![CDATA[La casa en la que estoy está amueblada. Tiene muchas cosas muy útiles. Y otras no tanto. La siguiente es una lista de cosas que no se (o no sabía) para que sirven (click sobre la foto para agrandarla): Resuelto! Se trata de un afilador de cuchillos. Raps Olja significa aceite de canola. Simpática la [...]]]></description>
			<content:encoded><![CDATA[<p>La casa en la que estoy está amueblada. Tiene muchas cosas muy útiles. Y otras no tanto. La siguiente es una lista de cosas que no se (o no sabía) para que sirven (click sobre la foto para agrandarla):</p>
<table>
<tr>
<td><a href="https://picasaweb.google.com/lh/photo/OTAWUC8AI9A8vpxuscE27w?feat=embedwebsite"><img src="https://lh4.googleusercontent.com/-32LfOYfqdD8/Tl62M616BCI/AAAAAAAADQ4/FlsC21Mhdl0/s144/20110823_152347.JPG" height="108" width="144" /></a></td>
<td><b>Resuelto!</b> Se trata de un afilador de cuchillos.</td>
</tr>
<tr>
<td><a href="https://picasaweb.google.com/lh/photo/T5pihUQwA4K3vC08267DuQ?feat=embedwebsite"><img src="https://lh4.googleusercontent.com/-p6BJdt6c3ro/Tl62OOZtqsI/AAAAAAAADQ8/iHDWKknhhOc/s144/20110823_152953.JPG" height="144" width="108" /></a></td>
<td><a href='http://translate.google.com/#sv|en|raps%20olja'>Raps Olja</a> significa <em>aceite de canola</em>. Simpática la traducción de Google cuando se lo pone <a href='http://translate.google.com/#sv|en|rapsolja'>todo junto</a>. ¿Se puede usar como cualquier aceite? ¿Sirve para algo en particular?</td>
</tr>
<tr>
<td><a href="https://picasaweb.google.com/lh/photo/meVMz0NIFQKU5KJwkZ4kiA?feat=embedwebsite"><img src="https://lh6.googleusercontent.com/-Y_uc75KSFCk/Tl62PKZTAzI/AAAAAAAADRA/gOooQlo2LWg/s144/20110823_153048.JPG" height="108" width="144" /></a></td>
<td>Candelabro de 7 <em>velas</em>. Parece ser algún motivo navideño. Sin embargo puede <a href="https://picasaweb.google.com/lh/photo/F5hB9r6fEKep4NzHstv_-A?feat=directlink">verse en uso en Agosto</a>. </td>
</tr>
<tr>
<td><a href="https://picasaweb.google.com/lh/photo/09MW74IWRP0SCK3jsztxFg?feat=embedwebsite"><img src="https://lh3.googleusercontent.com/-XSICI3cBzfs/Tl62QtGSUJI/AAAAAAAADRE/aehtPNqTNQw/s144/20110823_152322.JPG" height="108" width="144" /></a></td>
<td>Está en las ventanas. Dando vuelta a la rueda se abre una pequeña hendija en la parte superior.</td>
</tr>
<tr>
<td><a href="https://picasaweb.google.com/lh/photo/GNm1v2MSZgV9RXAQDOYMkw?feat=embedwebsite"><img src="https://lh4.googleusercontent.com/-RbEKTYQbKUo/Tl62RrpLUmI/AAAAAAAADRI/2H9YhigUS_A/s144/20110823_152302.JPG" height="108" width="144" /></a></td>
<td><strong>cuasi-Resuelto!</strong>En la canilla de la cocina esta esta llave de cuarto de vuelta. No parece tener efecto. Me han dicho que <em>es para el lavavajillas</em> (que no tengo). No se los detalles.</td>
</tr>
<tr>
<td><a href="https://picasaweb.google.com/lh/photo/DU09zvgVYvWHCC02VnnbGQ?feat=embedwebsite"><img src="https://lh3.googleusercontent.com/-SjXZkUewep4/Tl62TM9AzQI/AAAAAAAADRM/GZORiQYresc/s144/20110823_152214.JPG" height="108" width="144" /></a></td>
<td>Estos pequeños cubos son parcialmente huecos. El agujero no llega a atravesarlos. Los encontré cerca de la ventana.</td>
</tr>
<tr>
<td><a href="https://picasaweb.google.com/lh/photo/78ASDIDx8RhxizPIWfPuAQ?feat=embedwebsite"><img src="https://lh5.googleusercontent.com/-ct2fH_VTdNk/Tl62UggQrbI/AAAAAAAADRQ/u8SK6pyADMw/s144/20110823_172425.JPG" height="108" width="144" /></a></td>
<td>Es un alambre con ventosas en las puntas y unos pequeños brochecitos. Esta en el baño. Puede ser para colgar la ropa, aunque no creo que soporte el peso. ¿Tal vez ropa interior?</td>
</tr>
</table>
<p>Aportes son bienvenidos :)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/para-que-sirve/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Ciudad K explicado</title>
		<link>http://www.lucianobello.com.ar/post/ciudad-k-explicado/</link>
		<comments>http://www.lucianobello.com.ar/post/ciudad-k-explicado/#comments</comments>
		<pubDate>Fri, 10 Jun 2011 20:34:42 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[academy]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[procrastination]]></category>
		<category><![CDATA[social networking]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=1619</guid>
		<description><![CDATA[Primero lo primero, visita: www.ciudadkexplicado.com.ar A continuación la explicación de qué es eso. Cada vez que voy al viejo continente redescubro la tele española. Está llena de programas de humor, muchos de ellos increíblemente graciosos, incluso cuando varias gracias se pierden por no ser local. La última vez que estuve ahí no fue la excepción. [...]]]></description>
			<content:encoded><![CDATA[<p>Primero lo primero, visita:<br />
<center><span style="font-size: medium;"><a href="http://www.ciudadkexplicado.com.ar/">www.ciudadkexplicado.com.ar</a></span></center><br />
A continuación la explicación de qué es eso.</p>
<p><img style="margin-left: 10px; margin-right: 10px;" src="http://www.lucianobello.com.ar/blog/Ciudadk1.jpg" align="right" /> <img style="margin-left: 10px; margin-right: 10px; margin-top: 10px;" src="http://www.lucianobello.com.ar/blog/Ciudadk2.jpg" align="right" /> <img style="margin-left: 10px; margin-right: 10px; margin-top: 10px;" src="http://www.lucianobello.com.ar/blog/Ciudadk3.jpg" align="right" />Cada vez que voy al viejo continente redescubro la tele española. Está llena de programas de humor, muchos de ellos increíblemente graciosos, incluso cuando varias gracias se pierden por no ser local. <a href="http://www.lucianobello.com.ar/post/%C2%A1nos-vemos-en-espana/">La última vez que estuve ahí</a> no fue la excepción. <a href="http://sanchezpaz.blogspot.com/">Santiago</a> me habló de un programa llamado <a href="http://www.rtve.es/television/ciudad-k/">Ciudad K</a> (sin relación con los <a href="http://www.nestorkirchner2011.com/">K de acá</a>).</p>
<p><a href="http://www.rtve.es/television/ciudad-k/">Ciudad K</a> es un ya finalizado show de 14 capítulos, dirigido por el genial <a href="http://www.mimesacojea.com/">José Antonio Pérez</a>, que fusiona el humor y el geekismo de forma épica. En esta hipotética ciudad, los habitantes tiene un nivel cultural e intelectual sobresaliente y las situaciones son de lo más bizarras. <a href="http://www.rtve.es/alacarta/videos/television/ciudad---capitulo-1/694053/">Todos los capítulos se encuentran en línea</a> y son altamente recomendables.</p>
<p>Les hablé de esta serie a muchos conocidos freaks/nerds/geeks, y con ellos solemos comentar algunos gags que allí aparecen. Así fue como hemos notamos que ninguno de nosotros entendía todos los chistes, dado que abarcan un amplio espectro entre física, tecnología, economía, cine, artes plásticas, psicología y otras ramas de la cultura y la ciencia. De hecho, rápidamente descubrimos que conversar sobre Ciudad K era una <strong>muy divertida forma de aprender nuevas cosas, especialmente en las áreas en las que uno es un completo ignorante</strong>.</p>
<p>Así fue como levanté <a href="http://www.ciudadkexplicado.com.ar">www.ciudadkexplicado.com.ar</a>, un espacio en donde espero que se pueda conversar sobre los temas que se tocaron en la serie mientras se aprenden cosas nuevas y posiblemente inútiles.</p>
<p>Este viejo <em>procrastination project</em> lo tenía pendiente desde hacía meses y lo que se ve (así de feo) es el resultado de un arrebato de aburrimiento y de las ganas de saber que tan lejos se puede llegar con <a href="https://sites.google.com/">Google Sites</a>. Pasé por varios vericuetos técnicos que, supongo, explicaré en otro post.</p>
<p>PD: <a href="https://twitter.com/#!/mimesacojea/status/77872650474618880">Lo lamento José, soy un tío</a> :P</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/ciudad-k-explicado/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>alchemy: jugando a ser dios (ó cómo hacer trampa con Python)</title>
		<link>http://www.lucianobello.com.ar/post/jugando-a-ser-dios/</link>
		<comments>http://www.lucianobello.com.ar/post/jugando-a-ser-dios/#comments</comments>
		<pubDate>Sat, 04 Jun 2011 15:05:54 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[geek]]></category>
		<category><![CDATA[procrastination]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=1597</guid>
		<description><![CDATA[Creo que esto de usar Python para hacer trampa se me está volviendo vicio. Es que hay veces que las cosas te piden a gritos que tomes un atajo. Y esto fue lo que me pasó esta semana. Primero un poco de contexto. La semana pasada conocí, a través de Microsiervos, un juego llamado Alchemy. [...]]]></description>
			<content:encoded><![CDATA[<p>Creo que esto de usar Python para hacer trampa <a href="/post/how-to-hack-a-h4ckc0nt3st/">se me está volviendo vicio</a>. Es que hay veces que las cosas te piden a gritos que tomes un atajo. Y esto fue lo que me pasó esta semana.</p>
<p>Primero un poco de contexto. La semana pasada conocí, a través de <a href="http://juegos.microsiervos.com/ingenio/alchemy.html">Microsiervos</a>, un juego llamado <a href="http://alchemy.l8r.pl/">Alchemy</a>. Consiste en combinar los cuatro elementos clásicos griegos (tierra, agua, fuego y aire) para generar nuevos elementos y a su vez, otros con estos.<br />
<img src="http://juegos.microsiervos.com/images/alchemy.jpg" alt="" /><br />
Se los comenté a varios conocidos y se engancharon. El tope (al menos de momento) es 200 elementos y, como se trata de un juego muy divertido y adictivo, en un tiempo razonable se puede superar los 100. Los elementos son cada vez más complejos, incluso uno se empieza a obsesionar con la idea de crear <em>human</em> :P</p>
<p>El problema llega cuando uno se estanca y la tentación de hacer trampa se hace inevitable.</p>
<p><strong>Atención: a partir de este momento el post es una especie de <a href="https://secure.wikimedia.org/wikipedia/es/wiki/Spoiler">spoiler</a> en donde se explica cómo llegar al final del juego sin <em>jugarlo</em>. Si estás jugándolo y lo disfrutas, deja de leer inmediatamente.</strong></p>
<p>Con mirar rápidamente el código de la página, uno puede descubrir cómo funciona. Parece haber un <a href="http://alchemy.l8r.pl/library.xml">archivo en donde se definen las relaciones de los elementos por un número identificador</a> y <a href="http://alchemy.l8r.pl/en_us.xml">otro donde está se mapean estos identificadores a nombres</a>. El siguiente script me ayudó a organizar la información muy rápidamente:<br />
<div id="wpshdo_1" class="wp-synhighlighter-outer"><div id="wpshdt_1" class="wp-synhighlighter-collapsed"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_1"></a><a id="wpshat_1" class="wp-synhighlighter-title" href="#codesyntax_1"  onClick="javascript:wpsh_toggleBlock(1)" title="Click to show/hide code block">alchemy.py</a></td><td align="right"><a href="#codesyntax_1" onClick="javascript:wpsh_code(1)" title="Show code only"><img border="0" style="border: 0 none" src="http://www.lucianobello.com.ar/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_1" onClick="javascript:wpsh_print(1)" title="Print code"><img border="0" style="border: 0 none" src="http://www.lucianobello.com.ar/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_1" class="wp-synhighlighter-inner" style="display: none;"><pre class="python" style="font-family:monospace;"><ol><li class="li1"><div class="de1"><span class="co1">#!/usr/bin/python</span></div></li><li class="li1"><div class="de1"><span class="kw1">import</span> <span class="kw3">urllib</span></div></li><li class="li1"><div class="de1"><span class="kw1">from</span> <span class="kw3">xml</span>.<span class="me1">dom</span> <span class="kw1">import</span> minidom</div></li><li class="li1"><div class="de1"><span class="kw1">from</span> <span class="kw3">optparse</span> <span class="kw1">import</span> OptionParser,OptionValueError</div></li><li class="li1"><div class="de1">library_xml = <span class="kw3">urllib</span>.<span class="me1">urlopen</span><span class="br0">&#40;</span><span class="st0">&quot;http://alchemy.l8r.pl/library.xml&quot;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">relations = minidom.<span class="me1">parse</span><span class="br0">&#40;</span>library_xml<span class="br0">&#41;</span>.<span class="me1">documentElement</span>.<span class="me1">getElementsByTagName</span><span class="br0">&#40;</span><span class="st0">'entry'</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">name_xml = <span class="kw3">urllib</span>.<span class="me1">urlopen</span><span class="br0">&#40;</span><span class="st0">&quot;http://alchemy.l8r.pl/en_us.xml&quot;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">names = minidom.<span class="me1">parse</span><span class="br0">&#40;</span>name_xml<span class="br0">&#41;</span>.<span class="me1">documentElement</span>.<span class="me1">getElementsByTagName</span><span class="br0">&#40;</span><span class="st0">'library'</span><span class="br0">&#41;</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.<span class="me1">getElementsByTagName</span><span class="br0">&#40;</span><span class="st0">'entry'</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">elementsID=<span class="kw2">dict</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">elementsNAME=<span class="kw2">dict</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1"><span class="kw1">class</span> Element<span class="br0">&#40;</span><span class="br0">&#41;</span>:</div></li><li class="li1"><div class="de1">    <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>,<span class="kw2">id</span>,name<span class="br0">&#41;</span>:</div></li><li class="li1"><div class="de1">        <span class="kw2">self</span>.<span class="kw2">id</span>=<span class="kw2">int</span><span class="br0">&#40;</span><span class="kw2">id</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">        <span class="kw2">self</span>.<span class="me1">name</span>=<span class="kw2">str</span><span class="br0">&#40;</span>name<span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">        <span class="kw2">self</span>.<span class="me1">compoundBy</span>=<span class="br0">&#91;</span><span class="br0">&#93;</span></div></li><li class="li1"><div class="de1">        <span class="kw2">self</span>.<span class="me1">compose</span>=<span class="br0">&#91;</span><span class="br0">&#93;</span></div></li><li class="li1"><div class="de1">    <span class="kw1">def</span> AddCompoundBy<span class="br0">&#40;</span><span class="kw2">self</span>,components<span class="br0">&#41;</span>:</div></li><li class="li1"><div class="de1">        components.<span class="me1">getElementsByTagName</span><span class="br0">&#40;</span><span class="st0">'parent'</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">        compoundBy=<span class="br0">&#91;</span><span class="br0">&#40;</span><span class="kw2">int</span><span class="br0">&#40;</span>i.<span class="me1">getAttribute</span><span class="br0">&#40;</span><span class="st0">'id'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw1">for</span> i <span class="kw1">in</span> components.<span class="me1">getElementsByTagName</span><span class="br0">&#40;</span><span class="st0">'parent'</span><span class="br0">&#41;</span><span class="br0">&#93;</span></div></li><li class="li1"><div class="de1">        <span class="kw2">self</span>.<span class="me1">compoundBy</span>.<span class="me1">append</span><span class="br0">&#40;</span>compoundBy<span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">        <span class="kw1">return</span> compoundBy</div></li><li class="li1"><div class="de1">    <span class="kw1">def</span> <span class="kw4">__str__</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:</div></li><li class="li1"><div class="de1">        <span class="kw1">return</span> <span class="st0">&quot;%s (%i)&quot;</span> <span class="sy0">%</span> <span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">name</span>,<span class="kw2">self</span>.<span class="kw2">id</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1"><span class="kw1">for</span> name <span class="kw1">in</span> names:</div></li><li class="li1"><div class="de1">    id_=name.<span class="me1">getAttribute</span><span class="br0">&#40;</span><span class="st0">'id'</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">    name_=name._get_childNodes<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#91;</span>0<span class="br0">&#93;</span>.<span class="me1">data</span></div></li><li class="li1"><div class="de1">    element_=Element<span class="br0">&#40;</span>id_,name_<span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">    elementsID<span class="br0">&#91;</span><span class="kw2">int</span><span class="br0">&#40;</span>id_<span class="br0">&#41;</span><span class="br0">&#93;</span>=element_</div></li><li class="li1"><div class="de1">    elementsNAME<span class="br0">&#91;</span><span class="kw2">str</span><span class="br0">&#40;</span>name_<span class="br0">&#41;</span><span class="br0">&#93;</span>=element_</div></li><li class="li1"><div class="de1"><span class="kw1">for</span> rel <span class="kw1">in</span> relations:</div></li><li class="li1"><div class="de1">    element=elementsID<span class="br0">&#91;</span><span class="kw2">int</span><span class="br0">&#40;</span>rel.<span class="me1">getAttribute</span><span class="br0">&#40;</span><span class="st0">'id'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#93;</span></div></li><li class="li1"><div class="de1">    <span class="kw1">for</span> parent <span class="kw1">in</span> rel.<span class="me1">getElementsByTagName</span><span class="br0">&#40;</span><span class="st0">'parents'</span><span class="br0">&#41;</span>:</div></li><li class="li1"><div class="de1">        childs=element.<span class="me1">AddCompoundBy</span><span class="br0">&#40;</span>parent<span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">        elementsID<span class="br0">&#91;</span>childs<span class="br0">&#91;</span>0<span class="br0">&#93;</span><span class="br0">&#93;</span>.<span class="me1">compose</span>.<span class="me1">append</span><span class="br0">&#40;</span><span class="br0">&#91;</span>element.<span class="kw2">id</span>,elementsID<span class="br0">&#91;</span>childs<span class="br0">&#91;</span>1<span class="br0">&#93;</span><span class="br0">&#93;</span>.<span class="kw2">id</span><span class="br0">&#93;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">        <span class="kw1">if</span> childs<span class="br0">&#91;</span>0<span class="br0">&#93;</span><span class="sy0">!</span>=childs<span class="br0">&#91;</span>1<span class="br0">&#93;</span>:</div></li><li class="li1"><div class="de1">            elementsID<span class="br0">&#91;</span>childs<span class="br0">&#91;</span>1<span class="br0">&#93;</span><span class="br0">&#93;</span>.<span class="me1">compose</span>.<span class="me1">append</span><span class="br0">&#40;</span><span class="br0">&#91;</span>element.<span class="kw2">id</span>,elementsID<span class="br0">&#91;</span>childs<span class="br0">&#91;</span>0<span class="br0">&#93;</span><span class="br0">&#93;</span>.<span class="kw2">id</span><span class="br0">&#93;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1"><span class="kw1">def</span> default<span class="br0">&#40;</span><span class="kw3">parser</span><span class="br0">&#41;</span>:</div></li><li class="li1"><div class="de1">    <span class="kw1">if</span> <span class="kw2">len</span><span class="br0">&#40;</span><span class="kw3">parser</span>.<span class="me1">rargs</span><span class="br0">&#41;</span> == 0 <span class="kw1">or</span> <span class="st0">&quot;all&quot;</span> <span class="kw1">in</span> <span class="kw3">parser</span>.<span class="me1">rargs</span>:</div></li><li class="li1"><div class="de1">        elements = elementsNAME.<span class="me1">keys</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">    <span class="kw1">else</span>:</div></li><li class="li1"><div class="de1">        elements = <span class="kw3">parser</span>.<span class="me1">rargs</span></div></li><li class="li1"><div class="de1">    <span class="kw1">return</span> elements</div></li><li class="li1"><div class="de1"><span class="kw1">def</span> forWhat<span class="br0">&#40;</span>option, opt_str, value, <span class="kw3">parser</span><span class="br0">&#41;</span>:</div></li><li class="li1"><div class="de1">    elements = default<span class="br0">&#40;</span><span class="kw3">parser</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">    <span class="kw1">for</span> element_ <span class="kw1">in</span> elements:</div></li><li class="li1"><div class="de1">        <span class="kw1">try</span>:</div></li><li class="li1"><div class="de1">            element=elementsNAME<span class="br0">&#91;</span>element_<span class="br0">&#93;</span></div></li><li class="li1"><div class="de1">            <span class="kw1">for</span> compose <span class="kw1">in</span> element.<span class="me1">compose</span>:</div></li><li class="li1"><div class="de1">                <span class="kw1">print</span> <span class="st0">&quot;%s = %s + %s&quot;</span> <span class="sy0">%</span> <span class="br0">&#40;</span>elementsID<span class="br0">&#91;</span>compose<span class="br0">&#91;</span>0<span class="br0">&#93;</span><span class="br0">&#93;</span>.<span class="me1">name</span>,elementsID<span class="br0">&#91;</span>compose<span class="br0">&#91;</span>1<span class="br0">&#93;</span><span class="br0">&#93;</span>.<span class="me1">name</span>,element.<span class="me1">name</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">        <span class="kw1">except</span>:</div></li><li class="li1"><div class="de1">            <span class="kw1">raise</span> OptionValueError<span class="br0">&#40;</span><span class="st0">'element error: %s does not exist'</span> <span class="sy0">%</span> <span class="br0">&#40;</span>element_,<span class="br0">&#41;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1"><span class="kw1">def</span> how<span class="br0">&#40;</span>option, opt_str, value, <span class="kw3">parser</span><span class="br0">&#41;</span>:</div></li><li class="li1"><div class="de1">    <span class="kw1">if</span> <span class="kw2">len</span><span class="br0">&#40;</span><span class="kw3">parser</span>.<span class="me1">rargs</span><span class="br0">&#41;</span> == 0 <span class="kw1">or</span> <span class="st0">&quot;all&quot;</span> <span class="kw1">in</span> <span class="kw3">parser</span>.<span class="me1">rargs</span>:</div></li><li class="li1"><div class="de1">        elements = elementsNAME.<span class="me1">keys</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">    <span class="kw1">else</span>:</div></li><li class="li1"><div class="de1">        elements=<span class="kw3">parser</span>.<span class="me1">rargs</span></div></li><li class="li1"><div class="de1">    <span class="kw1">for</span> element_ <span class="kw1">in</span> elements:</div></li><li class="li1"><div class="de1">        <span class="kw1">try</span>:</div></li><li class="li1"><div class="de1">            element=elementsNAME<span class="br0">&#91;</span>element_<span class="br0">&#93;</span></div></li><li class="li1"><div class="de1">            <span class="kw1">for</span> formula <span class="kw1">in</span> element.<span class="me1">compoundBy</span>:</div></li><li class="li1"><div class="de1">                <span class="kw1">print</span> <span class="st0">&quot;%s = %s + %s&quot;</span> <span class="sy0">%</span> <span class="br0">&#40;</span>element.<span class="me1">name</span>, elementsID<span class="br0">&#91;</span>formula<span class="br0">&#91;</span>0<span class="br0">&#93;</span><span class="br0">&#93;</span>.<span class="me1">name</span>, elementsID<span class="br0">&#91;</span>formula<span class="br0">&#91;</span>1<span class="br0">&#93;</span><span class="br0">&#93;</span>.<span class="me1">name</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">        <span class="kw1">except</span>:</div></li><li class="li1"><div class="de1">            <span class="kw1">raise</span> OptionValueError<span class="br0">&#40;</span><span class="st0">'element error: %s does not exist'</span> <span class="sy0">%</span> <span class="br0">&#40;</span>element_,<span class="br0">&#41;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1"><span class="kw1">def</span> myaddition<span class="br0">&#40;</span>a,b,c<span class="br0">&#41;</span>:</div></li><li class="li1"><div class="de1">    ret=<span class="kw2">set</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">    <span class="co1"># a = b + c</span></div></li><li class="li1"><div class="de1">    addition=<span class="st0">&quot;%s%s%s&quot;</span> <span class="sy0">%</span> <span class="br0">&#40;</span>a,b,c<span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">    ret.<span class="me1">add</span><span class="br0">&#40;</span><span class="st0">&quot;<span class="es0">\&quot;</span>%s<span class="es0">\&quot;</span> [shape=point,style=filled,label=<span class="es0">\&quot;</span><span class="es0">\&quot;</span>,height=.1,width=.1]&quot;</span> <span class="sy0">%</span> <span class="br0">&#40;</span>addition,<span class="br0">&#41;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">    ret.<span class="me1">add</span><span class="br0">&#40;</span><span class="st0">&quot;<span class="es0">\&quot;</span>%s<span class="es0">\&quot;</span>-&gt;<span class="es0">\&quot;</span>%s<span class="es0">\&quot;</span> [weight=1];<span class="es0">\&quot;</span>%s<span class="es0">\&quot;</span>-&gt;<span class="es0">\&quot;</span>%s<span class="es0">\&quot;</span> [weight=1];<span class="es0">\&quot;</span>%s<span class="es0">\&quot;</span>-&gt;<span class="es0">\&quot;</span>%s<span class="es0">\&quot;</span> [weight=2]&quot;</span> <span class="sy0">%</span> <span class="br0">&#40;</span>b, addition,c,addition,addition,a<span class="br0">&#41;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">    <span class="kw1">return</span> ret</div></li><li class="li1"><div class="de1"><span class="kw1">def</span> graph<span class="br0">&#40;</span>option, opt_str, value, <span class="kw3">parser</span><span class="br0">&#41;</span>:</div></li><li class="li1"><div class="de1">    elements = default<span class="br0">&#40;</span><span class="kw3">parser</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">    ret=<span class="st0">''</span><span class="st0">'digraph G {</span></div></li><li class="li1"><div class="de1"><span class="st0">        overlap=scale</span></div></li><li class="li1"><div class="de1"><span class="st0">        splines=true</span></div></li><li class="li1"><div class="de1"><span class="st0">        rankdir=TB<span class="es0">\n</span>'</span><span class="st0">''</span></div></li><li class="li1"><div class="de1">    connections=<span class="kw2">set</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">    <span class="kw1">for</span> element_ <span class="kw1">in</span> elements:</div></li><li class="li1"><div class="de1">        element=elementsNAME<span class="br0">&#91;</span>element_<span class="br0">&#93;</span></div></li><li class="li1"><div class="de1">        <span class="kw1">try</span>:</div></li><li class="li1"><div class="de1">            <span class="kw1">for</span> formula <span class="kw1">in</span> element.<span class="me1">compoundBy</span>:</div></li><li class="li1"><div class="de1">                a=element.<span class="me1">name</span></div></li><li class="li1"><div class="de1">                b=elementsID<span class="br0">&#91;</span>formula<span class="br0">&#91;</span>0<span class="br0">&#93;</span><span class="br0">&#93;</span>.<span class="me1">name</span></div></li><li class="li1"><div class="de1">                c=elementsID<span class="br0">&#91;</span>formula<span class="br0">&#91;</span>1<span class="br0">&#93;</span><span class="br0">&#93;</span>.<span class="me1">name</span></div></li><li class="li1"><div class="de1">                connections|=myaddition<span class="br0">&#40;</span>a,b,c<span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">            <span class="kw1">for</span> compose <span class="kw1">in</span> element.<span class="me1">compose</span>:</div></li><li class="li1"><div class="de1">                a=elementsID<span class="br0">&#91;</span>compose<span class="br0">&#91;</span>0<span class="br0">&#93;</span><span class="br0">&#93;</span>.<span class="me1">name</span></div></li><li class="li1"><div class="de1">                b=element.<span class="me1">name</span></div></li><li class="li1"><div class="de1">                c=elementsID<span class="br0">&#91;</span>compose<span class="br0">&#91;</span>1<span class="br0">&#93;</span><span class="br0">&#93;</span>.<span class="me1">name</span></div></li><li class="li1"><div class="de1">                connections|=myaddition<span class="br0">&#40;</span>a,b,c<span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">        <span class="kw1">except</span>:</div></li><li class="li1"><div class="de1">            <span class="kw1">raise</span> OptionValueError<span class="br0">&#40;</span><span class="st0">'element error: %s does not exist'</span> <span class="sy0">%</span> <span class="br0">&#40;</span>element_,<span class="br0">&#41;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">    <span class="kw1">for</span> conn <span class="kw1">in</span>  connections:</div></li><li class="li1"><div class="de1">        ret+=conn+<span class="st0">';<span class="es0">\n</span>'</span></div></li><li class="li1"><div class="de1">    ret+=<span class="st0">'}'</span></div></li><li class="li1"><div class="de1">    <span class="kw1">print</span> ret</div></li><li class="li1"><div class="de1"><span class="kw3">parser</span> = OptionParser<span class="br0">&#40;</span><span class="st0">&quot;usage: %prog [options] [ELEMENTS|all]&quot;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1"><span class="kw3">parser</span>.<span class="me1">add_option</span><span class="br0">&#40;</span><span class="st0">&quot;-g&quot;</span>, <span class="st0">&quot;--how&quot;</span>, action=<span class="st0">&quot;callback&quot;</span>, callback=how, dest=<span class="st0">&quot;how&quot;</span>, <span class="kw2">help</span>=<span class="st0">&quot;how can I get ELEMENT&quot;</span>, default=<span class="kw2">False</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1"><span class="kw3">parser</span>.<span class="me1">add_option</span><span class="br0">&#40;</span><span class="st0">&quot;-f&quot;</span>, <span class="st0">&quot;--forWhat&quot;</span>, action=<span class="st0">&quot;callback&quot;</span>, callback=forWhat, dest=<span class="st0">&quot;forWhat&quot;</span>, <span class="kw2">help</span>=<span class="st0">&quot;for what elements can ELEMENT be used&quot;</span>, default=<span class="kw2">False</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1"><span class="kw3">parser</span>.<span class="me1">add_option</span><span class="br0">&#40;</span><span class="st0">&quot;-c&quot;</span>, <span class="st0">&quot;--graph&quot;</span>, action=<span class="st0">&quot;callback&quot;</span>, callback=graph, dest=<span class="st0">&quot;graph&quot;</span>,   <span class="kw2">help</span>=<span class="st0">&quot;graph the parents/childs from/to ELEMENT&quot;</span>, default=<span class="kw2">False</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1"><span class="br0">&#40;</span>options, args<span class="br0">&#41;</span> = <span class="kw3">parser</span>.<span class="me1">parse_args</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div></li></ol></pre></div></div></p>
<p>Así, si quiero saber cómo obtener el elemento <em>egg</em>:<br />
<code><br />
$ ./alchemy.py -g egg<br />
egg = life + stone<br />
egg = bird + bird<br />
egg = turtle + turtle<br />
egg = lizard + lizard<br />
</code><br />
Si quiero saber para que me pueden servir los elemetos <em>dough</em> y <em>sea</em>:<br />
<code>$ ./alchemy.py -f dough sea<br />
bread = fire + dough<br />
cookie = fruit + dough<br />
ocean = water + sea<br />
seaweed = plant + sea<br />
beach = sand + sea<br />
wave = wind + sea<br />
tides = moon + sea<br />
seasickness = sickness + sea<br />
algae = plant + sea<br />
horizon = sky + sea<br />
</code><br />
Para obtener todas las combinaciones:<br />
<code>$ ./alchemy.py -g all</code><br />
que da <a href="http://www.lucianobello.com.ar/blog/alchemy_all.txt">este</a> listado. Me pareció interesante hacer algunos grafos con estos datos. Así se puede ver la sección local de <em>light bulb</em>:<br />
<code>./alchemy.py -c "light bulb" | dot -Tpng > light_bulb.png ; display light_bulb.png</code><br />
<img src="http://www.lucianobello.com.ar/blog/alchemy_graph.png" alt="" /><br />
Claro que también se puede hacer el grafo completo (si se tiene memoria y tiempo):<br />
<code>$ ./alchemy.py -c all | neato -Tpng > all.png ; display all.png</code><br />
Así se genera una imagen enorme de la que se puede ver un fragmento a continuación (<a href="http://www.lucianobello.com.ar/blog/alchemy_all.jpg">click acá</a> para verla completa, son 13MB 12027x 13593).<br />
<img src="http://www.lucianobello.com.ar/blog/alchemy_all_.png"/><br />
Fue divertido, incluso cuando evidentemente no fui el primero en notar esto y basta con<a href="https://encrypted.google.com/search?q=alchemy.l8r.pl+cheats"> googlear un poco para conocer las soluciones</a>. En lo personal, consideré parte del juego escribir el código que lo resuelve y lo usé de excusa para hacer algo con <a href="http://docs.python.org/library/optparse.html">optparse</a>, que lo tenía pendiente.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/jugando-a-ser-dios/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>parser para fórmulas de lógica proposicional (o una somera introducción a pyparsing)</title>
		<link>http://www.lucianobello.com.ar/post/parser-para-formulas-de-logica-proposicional-o-una-somera-introduccion-a-pyparsing/</link>
		<comments>http://www.lucianobello.com.ar/post/parser-para-formulas-de-logica-proposicional-o-una-somera-introduccion-a-pyparsing/#comments</comments>
		<pubDate>Mon, 28 Mar 2011 17:13:29 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[academy]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[procrastination]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[university]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=1515</guid>
		<description><![CDATA[La semana pasada empecé a cursar, de oyente, dos materias en Exactas: Lógica y Computabilidad y Teoría de Lenguajes. En la primera, empezamos a estudiar algunos conceptos de cálculo proposicional. Al final de la clase, el profesor sugirió escribir un pequeño parser que reconozca fórmulas de lógica proposicional. Dado que venía con ganas de entender [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://arte.atompedia.com/googleimages/arte.png/m/224753" align="right" />La semana pasada empecé a cursar, de oyente, dos materias en <a href="http://exactas.uba.ar/">Exactas</a>: <a href="http://cms.dm.uba.ar/academico/materias/1ercuat2011/logica_y_computabilidad/">Lógica y Computabilidad</a> y <a href="http://dc.uba.ar/materias/tl">Teoría de Lenguajes</a>. En la primera, empezamos a estudiar algunos conceptos de <a href="https://secure.wikimedia.org/wikipedia/es/wiki/L%C3%B3gica_proposicional">cálculo proposicional</a>. Al final de la clase, el profesor sugirió escribir un pequeño parser que reconozca fórmulas de lógica proposicional. Dado que venía con ganas de entender mejor <a href="http://pyparsing.wikispaces.com/">pyparsing</a>, me pareció que podía ser una buena forma de empezar.</p>
<p>Primero, <a href="http://pc-matias.dm.uba.ar/LyC/Cignoli-Martinez.pdf">la teoría</a>. Dado el alfabeto <img src='http://s.wordpress.com/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' />, <img src='http://s.wordpress.com/latex.php?latex=A%5E%2A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A^*' title='A^*' class='latex' /> es el conjunto de palabras que pueden formarse combinando sus elementos.<br />
<img src='http://s.wordpress.com/latex.php?latex=A%3D%5C%7B%20%5Cto%20%2C%20%5Cwedge%20%2C%20%5Cvee%20%2C%20%5Cneg%20%2C%20%28%20%2C%20%29%20%2C%20p%20%2C%20%5Cprime%20%5C%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A=\{ \to , \wedge , \vee , \neg , ( , ) , p , \prime \}' title='A=\{ \to , \wedge , \vee , \neg , ( , ) , p , \prime \}' class='latex' /><br />
Existe un tipo particular de palabras, a las que llamamos variables.<br />
<img src='http://s.wordpress.com/latex.php?latex=Var%3D%5C%7Bp%20%2C%20p%5Cprime%2C%20p%5Cprime%5Cprime%20%2C%20%20%5Cldots%20%5C%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='Var=\{p , p\prime, p\prime\prime ,  \ldots \}' title='Var=\{p , p\prime, p\prime\prime ,  \ldots \}' class='latex' /><br />
Es un conjunto infinito y, dado que puede ser tedioso contar la cantidad de <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Prime_%28symbol%29">primas</a>, las variables pueden ser referenciadas como <img src='http://s.wordpress.com/latex.php?latex=p_n&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_n' title='p_n' class='latex' />, donde <em>n</em> es la cantidad de primas. Así, parece razonable pensar que no todas las palabras son <em>válidas</em> a la hora de escribir una fórmula (que es como llamaremos a las palabras válidas).</p>
<p>Ejemplos de fórmulas:
<ul>
<li> <img src='http://s.wordpress.com/latex.php?latex=%20p_2&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt=' p_2' title=' p_2' class='latex' />
<li> <img src='http://s.wordpress.com/latex.php?latex=%20%28%20%28%20p_3%20%5Cwedge%20p_5%20%29%20%5Cto%20%28%20%5Cneg%20p_2%20%5Cvee%20p_5%20%29%20%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt=' ( ( p_3 \wedge p_5 ) \to ( \neg p_2 \vee p_5 ) )' title=' ( ( p_3 \wedge p_5 ) \to ( \neg p_2 \vee p_5 ) )' class='latex' />
<li> <img src='http://s.wordpress.com/latex.php?latex=%20%5Cneg%20%5Cneg%20%28%20p%5Cprime%20%5Cvee%20p_%7B1232%7D%20%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt=' \neg \neg ( p\prime \vee p_{1232} )' title=' \neg \neg ( p\prime \vee p_{1232} )' class='latex' />
</ul>
<p>Ejemplos de no-fórmulas (palabras que no forman una fórmula):
<ul>
<li> <img src='http://s.wordpress.com/latex.php?latex=%20%5Cneg%5Cprime&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt=' \neg\prime' title=' \neg\prime' class='latex' />
<li> <img src='http://s.wordpress.com/latex.php?latex=%20%28%20p_2%20%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt=' ( p_2 )' title=' ( p_2 )' class='latex' />
<li> <img src='http://s.wordpress.com/latex.php?latex=%20p_3%20%5Cvee%20%5Cwedge%20&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt=' p_3 \vee \wedge ' title=' p_3 \vee \wedge ' class='latex' />
</ul>
<p>Si bien es más o menos intuitivo qué es una fórmula y qué no, es necesario definirlo en un sentido formal. Así  <img src='http://s.wordpress.com/latex.php?latex=%20Form%20%5Csubset%20A%5E%2A%20&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt=' Form \subset A^* ' title=' Form \subset A^* ' class='latex' /> y es el conjunto de las palabras que cumplen:
<ol TYPE="i">
<li> si <img src='http://s.wordpress.com/latex.php?latex=%5Calpha%20%5Cin%20A%5E%2A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\alpha \in A^*' title='\alpha \in A^*' class='latex' /> y <img src='http://s.wordpress.com/latex.php?latex=%5Calpha%20%5Cin%20Var&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\alpha \in Var' title='\alpha \in Var' class='latex' />, entonces <img src='http://s.wordpress.com/latex.php?latex=%5Calpha%20%5Cin%20Form&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\alpha \in Form' title='\alpha \in Form' class='latex' />
<li> si <img src='http://s.wordpress.com/latex.php?latex=%5Calpha%20%5Cin%20Form&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\alpha \in Form' title='\alpha \in Form' class='latex' />, entonces <img src='http://s.wordpress.com/latex.php?latex=%5Cneg%20%5Calpha%20%5Cin%20Form&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\neg \alpha \in Form' title='\neg \alpha \in Form' class='latex' />
<li> si <img src='http://s.wordpress.com/latex.php?latex=%5Calpha%2C%5Cbeta%20%5Cin%20Form&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\alpha,\beta \in Form' title='\alpha,\beta \in Form' class='latex' />, entonces <img src='http://s.wordpress.com/latex.php?latex=%28%20%5Calpha%20%5Ccircledast%20%5Cbeta%29%5Cin%20Form&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='( \alpha \circledast \beta)\in Form' title='( \alpha \circledast \beta)\in Form' class='latex' />. Donde <img src='http://s.wordpress.com/latex.php?latex=%5Ccircledast%3D%5Cvee%2C%5Cwedge%2C%5Cto%20&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\circledast=\vee,\wedge,\to ' title='\circledast=\vee,\wedge,\to ' class='latex' />
</ol>
<p>Nada más es una fórmula.</p>
<p>Ahora, a la práctica. Queremos escribir un parser que, dada una palabra, reconozca si es una fórmula. Y para esto vamos a jugar con el módulo <a href="http://pyparsing.wikispaces.com/">pyparsing</a>, para python.</p>
<p>Lo primero es definir el conjunto de variables.<br />
<code><br />
>>> from pyparsing import Word<br />
>>> variable=Word('Pp',"0123456789'")<br />
>>> variable.parseString('p1')<br />
(['p1'], {})<br />
>>> variable.parseString("P'")<br />
(["P'"], {})<br />
</code><br />
Así, <tt>variable</tt> reconoce los posibles nombres de variables. Toda expresión que sea parseable por <tt>variable</tt>, es una formula. Para el punto <i>ii.</i> hay que definir una estructura recursiva. Utilizaremos el <i>bang</i> (<tt>!</tt>) para la negación.<br />
<code>from pyparsing import Forward<br />
formula=Forward()<br />
ii='!' + formula<br />
</code><br />
Caso similar en el punto <i>iii.</i>. Para esto hay que definir los operadores, que son <i>and</i> (<tt>&#038;</tt>), <i>or</i> (<tt>|</tt>) y  <i>then</i> (<tt>&lt;</tt>).<br />
<code><br />
operador=Word('&#038;|>',max=1)<br />
iii='('+formula+operador+formula+')'</code><br />
Por último, definimos una fórmula cómo una variable (<i>i.</i>) o una negación de una fórmula (<i>ii.</i>) o una operación entre fórmulas (<i>iii.</i>).<br />
<code><br />
formula << ( variable | ii | iii )<br />
</code><br />
Y esto es, básicamente, nuestro parser:<br />
<code><br />
>>> formula.parseString("(p1 | p4)")<br />
(['(', 'p1', '|', 'p4', ')'], {})<br />
</code><br />
Lo dicho, con un poco más de contexto y en un único archivo, a continuación:<br />
<div id="wpshdo_2" class="wp-synhighlighter-outer"><div id="wpshdt_2" class="wp-synhighlighter-collapsed"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_2"></a><a id="wpshat_2" class="wp-synhighlighter-title" href="#codesyntax_2"  onClick="javascript:wpsh_toggleBlock(2)" title="Click to show/hide code block">logicparser.py</a></td><td align="right"><a href="#codesyntax_2" onClick="javascript:wpsh_code(2)" title="Show code only"><img border="0" style="border: 0 none" src="http://www.lucianobello.com.ar/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_2" onClick="javascript:wpsh_print(2)" title="Print code"><img border="0" style="border: 0 none" src="http://www.lucianobello.com.ar/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_2" class="wp-synhighlighter-inner" style="display: none;"><pre class="python" style="font-family:monospace;"><ol><li class="li1"><div class="de1"><span class="kw1">from</span> pyparsing <span class="kw1">import</span> Forward, Word</div></li><li class="li1"><div class="de1"><span class="kw1">import</span> <span class="kw3">sys</span> </div></li><li class="li1"><div class="de1">expression=<span class="kw3">sys</span>.<span class="me1">argv</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span></div></li><li class="li1"><div class="de1">variable=Word<span class="br0">&#40;</span><span class="st0">'Pp'</span>,<span class="st0">&quot;0123456789'&quot;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">operador=Word<span class="br0">&#40;</span><span class="st0">'&amp;|&gt;'</span>,<span class="kw2">max</span>=<span class="nu0">1</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">formula=Forward<span class="br0">&#40;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">ii=<span class="st0">'!'</span> + formula</div></li><li class="li1"><div class="de1">iii=<span class="st0">'('</span>+formula+operador+formula+<span class="st0">')'</span></div></li><li class="li1"><div class="de1">formula <span class="sy0">&lt;&lt;</span> <span class="br0">&#40;</span> variable | ii | iii <span class="br0">&#41;</span></div></li><li class="li1"><div class="de1"><span class="kw1">print</span> expression,<span class="st0">&quot; - es formula? &quot;</span>,</div></li><li class="li1"><div class="de1"><span class="kw1">try</span>:</div></li><li class="li1"><div class="de1">    palabras = formula.<span class="me1">parseString</span><span class="br0">&#40;</span>expression.<span class="me1">strip</span><span class="br0">&#40;</span><span class="br0">&#41;</span>,parseAll=<span class="kw2">True</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">    <span class="kw1">print</span> <span class="st0">&quot;TRUE&quot;</span>,</div></li><li class="li1"><div class="de1">    <span class="kw1">print</span> palabras</div></li><li class="li1"><div class="de1"><span class="kw1">except</span>:</div></li><li class="li1"><div class="de1">    <span class="kw1">print</span> <span class="st0">&quot;FALSE&quot;</span></div></li></ol></pre></div></div></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/parser-para-formulas-de-logica-proposicional-o-una-somera-introduccion-a-pyparsing/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>how to hack a h4ckc0nt3st</title>
		<link>http://www.lucianobello.com.ar/post/how-to-hack-a-h4ckc0nt3st/</link>
		<comments>http://www.lucianobello.com.ar/post/how-to-hack-a-h4ckc0nt3st/#comments</comments>
		<pubDate>Sun, 27 Feb 2011 22:34:31 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[ego]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[procrastination]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=1502</guid>
		<description><![CDATA[Hace unas horas acabo de volver de A Coruña, donde pasé unos excelentes días entre charlas y talleres de excelente nivel técnico y amigos en las Jornadas de Seguridad Informáticas organizadas por GSIC. Pero este post tiene otro objetivo que contar lo lindo que fue. Así que si esperabas algo blando, puedes dejar de leer [...]]]></description>
			<content:encoded><![CDATA[<p>Hace unas horas acabo de volver de A Coruña, donde pasé unos excelentes días entre charlas y talleres de excelente nivel técnico y amigos en las <a href="http://www.gsicoruna.com/jornadas">Jornadas de Seguridad Informáticas</a> organizadas por <a href="http://www.gsicoruna.com/index.html">GSIC</a>.</p>
<p>Pero este post tiene otro objetivo que contar lo lindo que fue. Así que si esperabas algo blando, puedes dejar de leer acá :P (las fotos estarán online en breve). Lo que sigue es la respuesta larga a la pregunta que me realizaron varias veces en los últimos días: <em>¿Estas jugando al h4ckc0nt3st?</em>. La respuesta corta era <em>sí, lo estoy haciendo en este exacto momento, aunque no de la forma tradicional</em>.</p>
<h3>El contexto</h3>
<p>Durante la conferencia,  <a href="https://twitter.com/mgesteiro">Miguel</a> organizó un muy divertido hack contest. El objetivo era llegar a una respuesta a través de la resolución de diferentes desafíos. Dicha respuesta se metía en un formulario web (que escuchaba en http://10.20.63.1:666) y de esta forma se acumulaban puntos.</p>
<h3>El hack</h3>
<p>Dado que la red sobre la que se hacía el concurso era una wifi abierta y que el servidor recibía las respuestas de los participantes en texto plano (no usaba <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Secure_Sockets_Layer">SSL</a>), pensé que sería divertido escuchar las respuestas de los demás concursantes. El paso siguiente de enviar dichas respuestas a mi nombre resultó inevitable. De esta forma, cada vez que alguien enviaba una posible respuesta a un desafío, yo también respondía lo mismo. Logré automatizar ello con las siguientes líneas:<br />
<code><br />
tshark -T fields -e data -i mon0 -R 'ip.dst == 10.20.63.1 and tcp.dstport == 666 and ip.src != mi.propia.ip ' | ./loro.py</code><br />
Donde <tt>loro.py</tt> este archivo:<br />
<div id="wpshdo_3" class="wp-synhighlighter-outer"><div id="wpshdt_3" class="wp-synhighlighter-collapsed"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_3"></a><a id="wpshat_3" class="wp-synhighlighter-title" href="#codesyntax_3"  onClick="javascript:wpsh_toggleBlock(3)" title="Click to show/hide code block">loro.py</a></td><td align="right"><a href="#codesyntax_3" onClick="javascript:wpsh_code(3)" title="Show code only"><img border="0" style="border: 0 none" src="http://www.lucianobello.com.ar/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_3" onClick="javascript:wpsh_print(3)" title="Print code"><img border="0" style="border: 0 none" src="http://www.lucianobello.com.ar/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_3" class="wp-synhighlighter-inner" style="display: none;"><pre class="python" style="font-family:monospace;"><ol><li class="li1"><div class="de1"><span class="co1">#!/usr/bin/python</span></div></li><li class="li1"><div class="de1"><span class="kw1">import</span> <span class="kw3">sys</span></div></li><li class="li1"><div class="de1"><span class="kw1">import</span> <span class="kw3">binascii</span></div></li><li class="li1"><div class="de1"><span class="kw1">import</span> <span class="kw3">socket</span></div></li><li class="li1"><div class="de1"><span class="kw1">for</span> line <span class="kw1">in</span> <span class="kw3">sys</span>.<span class="me1">stdin</span>:</div></li><li class="li1"><div class="de1">    todecode=line.<span class="me1">strip</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">    decode=<span class="kw3">binascii</span>.<span class="me1">a2b_hex</span><span class="br0">&#40;</span>todecode<span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">    <span class="kw1">if</span> <span class="st0">'acceder'</span> <span class="kw1">in</span> decode <span class="kw1">or</span> <span class="st0">'enviar'</span> <span class="kw1">in</span> decode :</div></li><li class="li1"><div class="de1">        datas=decode.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">'<span class="es0">\n</span>'</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">        <span class="kw1">if</span> <span class="st0">'desafio'</span> <span class="kw1">in</span> datas<span class="br0">&#91;</span>0<span class="br0">&#93;</span>:</div></li><li class="li1"><div class="de1">            <span class="kw1">for</span> i,j <span class="kw1">in</span> <span class="kw2">enumerate</span><span class="br0">&#40;</span>datas<span class="br0">&#41;</span>:</div></li><li class="li1"><div class="de1">                <span class="kw1">if</span> <span class="st0">'Cookie'</span> <span class="kw1">in</span> j: datas<span class="br0">&#91;</span>i<span class="br0">&#93;</span>=<span class="st0">'Cookie: HCWSSESSID=&quot;your cookie goes here&quot;'</span></div></li><li class="li1"><div class="de1">            tosend=<span class="st0">'<span class="es0">\n</span>'</span>.<span class="me1">join</span><span class="br0">&#40;</span>datas<span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">            <span class="kw3">sys</span>.<span class="me1">stderr</span>.<span class="me1">write</span><span class="br0">&#40;</span>tosend<span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">            s = <span class="kw3">socket</span>.<span class="kw3">socket</span><span class="br0">&#40;</span><span class="kw3">socket</span>.<span class="me1">AF_INET</span>, <span class="kw3">socket</span>.<span class="me1">SOCK_STREAM</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">            s.<span class="me1">connect</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="st0">'10.20.63.1'</span>, 666<span class="br0">&#41;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">            s.<span class="me1">send</span><span class="br0">&#40;</span>tosend<span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">            s.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">            <span class="kw1">print</span> <span class="st0">'-'</span><span class="sy0">*</span><span class="nu0">30</span></div></li></ol></pre></div></div></p>
<h3>La explicación</h3>
<p><a href="http://www.wireshark.org/docs/man-pages/tshark.html">Tshark</a> es la versión de consola de <a href="http://www.wireshark.org/">wireshark</a>. Este toma los paquetes de una interfaz en modo monitor (lee <a href="http://aircrack-ng.org/doku.php?id=iwl3945">esto</a> para aprender cómo). El modificador <tt>-f</tt> es el encargado de darme solo aquellos paquetes que vayan al servidor. Excluir del filtro a mi propia IP evita que el sniffer vea mis replayes y entre en loop (tardé en darme cuenta de esto, perdona Miguel por floodear tus logs). El script <tt>loro.py</tt> recibe el campo <tt>data</tt> de los por <tt>stdin</tt> (línea (#) 5), lo decodifica en <a href="https://secure.wikimedia.org/wikipedia/en/wiki/ASCII">ascii</a> (#7), y chequea si es una respuesta (#8). Después lo divide y busca la cookie (# 9 a 11). Al encontrarla, la reemplaza por mi propia cookie (#12, fue una suerte práctica que no caducara). Luego vuelve a juntar todo (#13), lo imprime en stderr (#14, con fines de logging, nada más) y lo envía de nuevo al server (# 15 a 18).</p>
<p>Como dicen por acá, <em>¡a que mola!</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/how-to-hack-a-h4ckc0nt3st/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>exportando cumpleaños de Facebook a Google Calendar</title>
		<link>http://www.lucianobello.com.ar/post/fb2gc/</link>
		<comments>http://www.lucianobello.com.ar/post/fb2gc/#comments</comments>
		<pubDate>Wed, 09 Feb 2011 18:55:20 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[geek]]></category>
		<category><![CDATA[life]]></category>
		<category><![CDATA[procrastination]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[social networking]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=1480</guid>
		<description><![CDATA[Ocurre que soy realmente malo para recordar eventos. Muchas veces me comprometí a estar en dos lados simultáneamente y me olvido de hacer tal o cual cosa. Mi desorden se extiende a cosas repetitivas, como los cursos o cumpleaños. Para intentar apalear este mal, utilizo Google Calendar intensamente. Es por esto que intenté exportar las [...]]]></description>
			<content:encoded><![CDATA[<p>Ocurre que soy realmente malo para recordar eventos. Muchas veces me comprometí a estar en dos lados simultáneamente y me olvido de hacer tal o cual cosa. Mi desorden se extiende a cosas repetitivas, como los cursos o cumpleaños. Para intentar apalear este mal, utilizo <a href="http://www.google.com/calendar">Google Calendar</a> intensamente. Es por esto que intenté exportar las fechas de cumpleaños a mis calendarios. Pero cuando intenté hacerlo <em>out-of-the-box</em> me encontré con unos incordios:</p>
<ul>
<li>No hay forma de exportar solo un subconjunto de las fechas</li>
<li>Con los cambios de <a href="http://en.wikipedia.org/wiki/Daylight_saving_time">DST</a>, hay eventos que duran dos días</li>
<li>Los eventos no son de <em>días completos</em>, sino que van de 12am a 12am</li>
<li>No quedan como eventos editables <em>normales</em></li>
</ul>
<p>Los eventos se ven algo así:<br />
<img class="alignnone" src="http://www.lucianobello.com.ar/blog/fbbirthdays5.png" /><br />
Y la verdad que están horribles. Así que realicé estos 5 sencillos pasos:</p>
<h3>Paso 1</h3>
<p>Fui <a href="http://www.facebook.com/#!/?sk=bd">a los eventos de cumpleaños en mi perfil</a>, donde puse <em>exportar cumpleaños</em>.<br />
<img src="http://www.lucianobello.com.ar/blog/fbbirthdays0.png" alt="" /><br />
Así, facebook me proveyó una URL, que empieza con <em>webcal://</em><br />
<img src="http://www.lucianobello.com.ar/blog/fbbirthdays1.png" alt="" /></p>
<h3>Paso 2</h3>
<p>Esta URL, reemplazando <em>webcal</em> por <em>http</em>, la utilicé para obtener los eventos, en formato CSV:<br />
<code>wget "http://www.facebook.com/ical/b.php?uid=2XXXXXX4&amp;key=3XXXXXXX8" -O facebook.csv</code></p>
<h3>Paso 3 (opcional)</h3>
<p>Dada mi política de <em>aceptar-todo-contacto</em> en Facebook hay muchos eventos que no quisiera incluir en mi calendario. Por lo que generé una lista de los que sí quiero tener:<br />
<code>rgrep "^SUMMARY" facebook.csv &gt; lista.txt</code><br />
Y después borré de <tt>lista.txt</tt> aquellos que quería excluir.</p>
<h3>Paso 4</h3>
<p>Escribí el siguiente script:<br />
<div id="wpshdo_4" class="wp-synhighlighter-outer"><div id="wpshdt_4" class="wp-synhighlighter-collapsed"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_4"></a><a id="wpshat_4" class="wp-synhighlighter-title" href="#codesyntax_4"  onClick="javascript:wpsh_toggleBlock(4)" title="Click to show/hide code block">fb2gc.py</a></td><td align="right"><a href="#codesyntax_4" onClick="javascript:wpsh_code(4)" title="Show code only"><img border="0" style="border: 0 none" src="http://www.lucianobello.com.ar/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_4" onClick="javascript:wpsh_print(4)" title="Print code"><img border="0" style="border: 0 none" src="http://www.lucianobello.com.ar/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_4" class="wp-synhighlighter-inner" style="display: none;"><pre class="python" style="font-family:monospace;"><ol><li class="li1"><div class="de1"><span class="co1">#!/usr/bin/python</span></div></li><li class="li1"><div class="de1"><span class="kw1">import</span> <span class="kw3">datetime</span></div></li><li class="li1"><div class="de1"><span class="kw1">import</span> <span class="kw3">sys</span></div></li><li class="li1"><div class="de1"><span class="kw1">print</span> <span class="st0">''</span><span class="st0">'BEGIN:VCALENDAR</span></div></li><li class="li1"><div class="de1"><span class="st0">PRODID:localscript</span></div></li><li class="li1"><div class="de1"><span class="st0">VERSION:2.0</span></div></li><li class="li1"><div class="de1"><span class="st0">CALSCALE:GREGORIAN</span></div></li><li class="li1"><div class="de1"><span class="st0">METHOD:PUBLISH</span></div></li><li class="li1"><div class="de1"><span class="st0">X-WR-CALNAME:</span></div></li><li class="li1"><div class="de1"><span class="st0">X-WR-TIMEZONE:America/Argentina/Buenos_Aires</span></div></li><li class="li1"><div class="de1"><span class="st0">X-WR-CALDESC:</span></div></li><li class="li1"><div class="de1"><span class="st0">BEGIN:VTIMEZONE</span></div></li><li class="li1"><div class="de1"><span class="st0">TZID:America/Argentina/Buenos_Aires</span></div></li><li class="li1"><div class="de1"><span class="st0">X-LIC-LOCATION:America/Argentina/Buenos_Aires</span></div></li><li class="li1"><div class="de1"><span class="st0">BEGIN:STANDARD</span></div></li><li class="li1"><div class="de1"><span class="st0">TZOFFSETFROM:-0300</span></div></li><li class="li1"><div class="de1"><span class="st0">TZOFFSETTO:-0300</span></div></li><li class="li1"><div class="de1"><span class="st0">TZNAME:ART</span></div></li><li class="li1"><div class="de1"><span class="st0">DTSTART:19700101T000000</span></div></li><li class="li1"><div class="de1"><span class="st0">END:STANDARD</span></div></li><li class="li1"><div class="de1"><span class="st0">END:VTIMEZONE'</span><span class="st0">''</span></div></li><li class="li1"><div class="de1">day=<span class="kw3">datetime</span>.<span class="me1">timedelta</span><span class="br0">&#40;</span>1<span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">fd = <span class="kw2">open</span><span class="br0">&#40;</span> <span class="kw3">sys</span>.<span class="me1">argv</span><span class="br0">&#91;</span>1<span class="br0">&#93;</span> <span class="br0">&#41;</span></div></li><li class="li1"><div class="de1"><span class="kw1">try</span>:</div></li><li class="li1"><div class="de1">    mylist=<span class="kw2">open</span><span class="br0">&#40;</span> <span class="kw3">sys</span>.<span class="me1">argv</span><span class="br0">&#91;</span>2<span class="br0">&#93;</span> <span class="br0">&#41;</span>.<span class="me1">readlines</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">    nolist=<span class="kw2">False</span></div></li><li class="li1"><div class="de1"><span class="kw1">except</span>:</div></li><li class="li1"><div class="de1">    nolist=<span class="kw2">True</span></div></li><li class="li1"><div class="de1">va = <span class="kw2">False</span></div></li><li class="li1"><div class="de1">person=<span class="st0">&quot;&quot;</span></div></li><li class="li1"><div class="de1"><span class="kw1">for</span> line <span class="kw1">in</span> fd.<span class="me1">readlines</span><span class="br0">&#40;</span><span class="br0">&#41;</span>:</div></li><li class="li1"><div class="de1">    <span class="kw1">if</span> <span class="st0">'BEGIN:VEVENT'</span> <span class="kw1">in</span> line:</div></li><li class="li1"><div class="de1">        person=<span class="st0">'BEGIN:VEVENT<span class="es0">\n</span>'</span></div></li><li class="li1"><div class="de1">    <span class="kw1">elif</span> <span class="st0">'DTSTART'</span> <span class="kw1">in</span> line:</div></li><li class="li1"><div class="de1">        dateS=line.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">':'</span><span class="br0">&#41;</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">'T'</span><span class="br0">&#41;</span><span class="br0">&#91;</span>0<span class="br0">&#93;</span></div></li><li class="li1"><div class="de1">        date=<span class="kw3">datetime</span>.<span class="me1">date</span><span class="br0">&#40;</span><span class="kw2">int</span><span class="br0">&#40;</span>dateS<span class="br0">&#91;</span>0:4<span class="br0">&#93;</span><span class="br0">&#41;</span>,<span class="kw2">int</span><span class="br0">&#40;</span>dateS<span class="br0">&#91;</span>4:6<span class="br0">&#93;</span><span class="br0">&#41;</span>,<span class="kw2">int</span><span class="br0">&#40;</span>dateS<span class="br0">&#91;</span><span class="nu0">6</span>:<span class="nu0">8</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">        tomorrow=date+day</div></li><li class="li1"><div class="de1">        person+=<span class="st0">'DESCRIPTION:Imported from Facebook<span class="es0">\n</span>STATUS:CONFIRMED<span class="es0">\n</span>DTSTART;VALUE=DATE:%s<span class="es0">\n</span>DTEND;VALUE=DATE:%s<span class="es0">\n</span>TRANSP:TRANSPARENT<span class="es0">\n</span>'</span> <span class="sy0">%</span> <span class="br0">&#40;</span>date.<span class="me1">strftime</span><span class="br0">&#40;</span><span class="st0">&quot;%Y%m%d&quot;</span><span class="br0">&#41;</span>,tomorrow.<span class="me1">strftime</span><span class="br0">&#40;</span><span class="st0">&quot;%Y%m%d&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">    <span class="kw1">elif</span> <span class="st0">'END:VEVENT'</span> <span class="kw1">in</span> line:</div></li><li class="li1"><div class="de1">        person+=<span class="st0">'END:VEVENT<span class="es0">\n</span>'</span></div></li><li class="li1"><div class="de1">        <span class="kw1">if</span> va:</div></li><li class="li1"><div class="de1">            <span class="kw1">print</span> person,</div></li><li class="li1"><div class="de1">    <span class="kw1">elif</span> <span class="st0">'SUMMARY'</span> <span class="kw1">in</span> line:</div></li><li class="li1"><div class="de1">        person+=line</div></li><li class="li1"><div class="de1">        va=nolist <span class="kw1">or</span> line <span class="kw1">in</span> mylist</div></li><li class="li1"><div class="de1">    <span class="kw1">elif</span> <span class="st0">'DURATION'</span> <span class="kw1">in</span> line:</div></li><li class="li1"><div class="de1">        <span class="kw1">pass</span></div></li><li class="li1"><div class="de1">    <span class="kw1">else</span>:</div></li><li class="li1"><div class="de1">        person+=line</div></li><li class="li1"><div class="de1"><span class="kw1">print</span> <span class="st0">'END:VCALENDAR'</span></div></li></ol></pre></div></div><br />
El cual convierte los eventos de <em>facebook</em> en eventos <em>lindos</em>. Se ejecuta así:<br />
<code>./fb2gc.py facebook.csv lista.txt > miscumples.csv<br />
</code> El parámetro <tt>lista.txt</tt> es optativo, si pasaste por el Paso 3.</p>
<h3>Paso 5</h3>
<p>El archivo generado se pueden importar en Google Calendar, en un calendario existente.<br />
<img src="http://www.lucianobello.com.ar/blog/fbbirthdays3.png" alt="" /><br />
<img src="http://www.lucianobello.com.ar/blog/fbbirthdays4.png" alt="" /><br />
Y ahora, tengo agendados los cumpleaños de forma mucho más agradable.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/fb2gc/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>operating elements of a finite lattice is now easy(?)</title>
		<link>http://www.lucianobello.com.ar/post/lattice/</link>
		<comments>http://www.lucianobello.com.ar/post/lattice/#comments</comments>
		<pubDate>Tue, 07 Dec 2010 01:13:28 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[free software]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[procrastination]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[sorry for my english]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=1444</guid>
		<description><![CDATA[In the context of my recent readings about Information Flow analysis, I wrote a little (tiny) Python module to operate elements of a finite lattice. Here is the code and usage tutorial. Comments are welcome. Patches to my broken English in the main page are very welcome.]]></description>
			<content:encoded><![CDATA[<p><img src="http://image.absoluteastronomy.com/images/encyclopediaimages/l/la/lattice_of_the_divisibility_of_60.svg.png" align="right" />In the context of my recent readings about Information Flow analysis, I wrote a little (tiny) Python module to operate elements of a finite lattice. Here is <a href="https://code.google.com/p/python-lattice/">the code and usage tutorial</a>. Comments are welcome. Patches to my broken English in the main page are <strong>very</strong> welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/lattice/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>/home/duijvestijn</title>
		<link>http://www.lucianobello.com.ar/post/homeduijvestijnen/</link>
		<comments>http://www.lucianobello.com.ar/post/homeduijvestijnen/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 17:17:45 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[favorites]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[home]]></category>
		<category><![CDATA[life]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[planet]]></category>
		<category><![CDATA[procrastination]]></category>
		<category><![CDATA[sorry for my english]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=1368</guid>
		<description><![CDATA[I have a new guest in my apartment. Give a warm welcome to the Adrianus Johannes Wilhelmus Duijvestijn&#8216;s spirit. Thanks a lot to Bartu and Rezlaj, who carried out the necessary seance that make this possible. The complete photo set is here. If you do not have the slightest idea of what I&#8217;m talking about, [...]]]></description>
			<content:encoded><![CDATA[<p>I have a new guest in my apartment. Give a warm welcome to the <a href="http://www.squaring.net/history_theory/duijvestijn.html">Adrianus Johannes Wilhelmus Duijvestijn</a>&#8216;s spirit.</p>
<p><center><img src="/fotos/duijvestijn/duijvestijn1.jpg"/></center></p>
<p>Thanks a lot to <a href="http://www.piumacharles.com/">Bartu and Rezlaj</a>, who carried out the necessary seance that make this possible.</p>
<p><center><img src="/fotos/duijvestijn/duijvestijn2.jpg"/></center></p>
<p>The complete photo set is <a href="/fotos/duijvestijn/">here</a>. If you do not have the slightest idea of what I&#8217;m talking about, take a look to <a href="http://en.wikipedia.org/wiki/Squaring_the_square#Simple_squared_squares">Wikipedia</a> or <a href="/post/diseccion_perfecta/">my previous post (Spanish only)</a>.</p>
<p><small>(esta entrada también <a href="/post/homeduijvestijnes/">está disponible en Español</a>)</small></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/homeduijvestijnen/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>/home/duijvestijn</title>
		<link>http://www.lucianobello.com.ar/post/homeduijvestijnes/</link>
		<comments>http://www.lucianobello.com.ar/post/homeduijvestijnes/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 17:17:03 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[geek]]></category>
		<category><![CDATA[home]]></category>
		<category><![CDATA[life]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[planeta]]></category>
		<category><![CDATA[procrastination]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=1373</guid>
		<description><![CDATA[Tengo un nuevo huésped en mi departamento. Denle una cálida bienvenida al espíritu de Adrianus Johannes Wilhelmus Duijvestijn. Muchísimas gracias a Bartu y a Rezlaj, quienes llevaron a cabo la sesión de espiritismo necesaria para hacer esto posible. Todas las fotos están disponibles aquí. Si no tienes la menor idea de a qué se refiere [...]]]></description>
			<content:encoded><![CDATA[<p>Tengo un nuevo huésped en mi departamento. Denle una cálida bienvenida al espíritu de <a href="http://www.squaring.net/history_theory/duijvestijn.html">Adrianus Johannes Wilhelmus Duijvestijn</a>.</p>
<p><center><img src="/fotos/duijvestijn/duijvestijn1.jpg"/></center></p>
<p>Muchísimas gracias a <a href="http://www.piumacharles.com/">Bartu y a Rezlaj</a>, quienes llevaron a cabo la sesión de espiritismo necesaria para hacer esto posible.</p>
<p><center><img src="/fotos/duijvestijn/duijvestijn2.jpg"/></center></p>
<p>Todas las fotos están disponibles <a href="/fotos/duijvestijn/">aquí</a>. Si no tienes la menor idea de a qué se refiere esto, échale un ojo a la <a href="http://en.wikipedia.org/wiki/Squaring_the_square#Simple_squared_squares">Wikipedia (solo en inglés)</a> o a <a href="/post/diseccion_perfecta/">mi entrada anterior</a>.</p>
<p><small>(this post is <a href="/post/homeduijvestijnes/">available in English too</a>)</small></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/homeduijvestijnes/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>disección perfecta de polígonos for dummies</title>
		<link>http://www.lucianobello.com.ar/post/diseccion_perfecta/</link>
		<comments>http://www.lucianobello.com.ar/post/diseccion_perfecta/#comments</comments>
		<pubDate>Tue, 15 Jun 2010 19:23:29 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[favorites]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[procrastination]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=1326</guid>
		<description><![CDATA[Por razones que explicaré en una próxima entrada de este mismo blog, últimamente he estado divagando alrededor del concepto de la disección perfecta de polígonos. Y es este divague el que me gustaría compartir con ustedes en este (demasiado) extenso post. Empezando por el principio, ¿qué es un polígono? En términos wikipediables: un polígono es [...]]]></description>
			<content:encoded><![CDATA[<p>Por razones que explicaré en una próxima entrada de este mismo blog, últimamente he estado divagando alrededor del concepto de la <strong>disección perfecta de polígonos</strong>. Y es este divague el que me gustaría compartir con ustedes en este (demasiado) extenso post.</p>
<p>Empezando por el principio, ¿qué es un <strong>polígono</strong>? En <a href="http://es.wikipedia.org/wiki/Polígono">términos wikipediables</a>:</p>
<blockquote><p>un polígono es una figura geométrica formada por segmentos consecutivos no alineados, llamados lados.</p></blockquote>
<p>Nos gusta que los segmentos no estén alineados, porque así forman ángulos, que es parte de la <a href="http://es.wikipedia.org/wiki/Pol%C3%ADgono#Etimolog.C3.ADa">definición etimológica</a>. Por otro lado, el hecho de que los segmentos sean consecutivos, garantiza que la figura quede cerrada. En particular, nos vamos a centrar en polígonos que sean:</p>
<ul>
<li>planos. Es decir, bidimensionales, de lo que se pueden dibujar en un papel.</li>
<li>simples. Es decir, que sus lados no se corten entre sí.</li>
<li>convexos. Es decir, si al atravesarlo con cualquier recta lo corta en no más de dos puntos.</li>
<li>con hasta un máximo de 4 lados. Es decir, triángulos y cuadriláteros</li>
</ul>
<p>En definitiva, vamos a referirnos a figuras sencillas donde algunas regularidades nos sean agradables, como el hecho de que los lados sean del mismo tamaño o que tenga algunos ángulos iguales.</p>
<p>Una vez acotado el universo de polígonos vayamos a la siguiente parte del asunto: <strong>la disección</strong>. Esta idea es bastante intuitiva. El objetivo es tomar un polígono y subdividirlo en otros. A estos <em>otros</em> los vamos a llamar <em>elementos</em>, dado que forman y son parte del polígono grande inicial. La cantidad de elementos es el <em>orden</em> de la disección. Un factor interesante que vamos a agregar a esta definición informal es que los elementos solo pueden variar en su proporción u orientación, por ejemplo que sean todos cuadrados o todos triángulos rectángulos, pero no mezclados.</p>
<p><img src="http://www.quilt-lovers-guide.com/images/QuarterSquareTrianglesBlock.jpg" alt="" width="150" height="153" align="right" /></p>
<p>Vamos a por un ejemplo inicial sencillo. Si tomamos un cuadrado, podemos dividirlo en cuatro triángulos isósceles rectángulos del mismo tamaño, como en la figura de la derecha . Así tenemos un <em>polígono interesante</em> (el cuadrado) que puede ser dividido en cuatro <em>polígonos interesantes</em> (los triángulos rectángulos isósceles). Sin un gran esfuerzo de imaginación, también podríamos dividir un cuadrado en 4 cuadrados (pero es una imagen que evitaremos, que me hace acordar a una empresa monopolizadora).</p>
<p>Así obtenemos disecciones de polígonos, que a primera vista, no parecen ninguna genialidad. Sin embargo, algunas ideas interesantes empiezan a surgir. Por ejemplo, dado que tanto el contenedor como los elementos son <em>interesantes</em>, la noción recursiva aflora. Otros conceptos llamativos, como el de  <a href="http://es.wikipedia.org/wiki/Teselaci%C3%B3n#Teselados_regulares">teselado regular</a>, <a href="http://mathworld.wolfram.com/TrianglePacking.html">temas de empaquetamiento</a> o <a href="http://mathworld.wolfram.com/MrsPerkinssQuilt.html">el problema de Mrs. Perkins&#8217;s Quilt </a>pueden desprenderse desde este punto.</p>
<p>Nosotros vamos a tomar otro camino al agregar el último ingrediente de esta receta: la disección <strong>perfecta</strong>, que pide que los elementos sean todos de distinto tamaño. Acá se pone más interesante y mucho menos obvio. Volvamos a nuestro ejemplo de dividir un cuadrado en triángulos rectángulos isósceles, pero esta vez hagamos una disección perfecta. A continuación, la propuesta de <a href="http://at.yorku.ca/t/o/p/c/16.htm">Arthur Stone</a>:</p>
<p><center><img align=center src="http://www.squaring.net/tri/gfx/x7-7PA.jpg" alt="" width="300" height="300" /></center></p>
<p>El número es el largo del cateto de triángulo. Estamos entrando en un terreno donde ahora las cosas son difíciles de imaginar a primera vista. Uno podría empezar a preguntarse en cuántas formas distintas se pueden hacer estas disecciones, si es que hay mas de una. Y si hubiese, cómo se pueden construir. En un <a href="http://linkinghub.elsevier.com/retrieve/pii/S0095895600919877">interesante y largo paper de 1999</a>, Skinner II et. al. proponen una analogía con <a href="http://es.wikipedia.org/wiki/Leyes_de_Kirchhoff_de_circuitos_el%C3%A9ctricos">la primera ley de Kirchhoff (si, esa sobre los nodos de los circuitos eléctricos)</a> para ayudar a la construcción de disecciones perfectas de cuadrados. Este método genera disecciones a triángulos rectángulos isósceles que cortan la diagonal principal de cuadrado que los contiene (lo que permite generar disecciones simples, explicadas más adelante). Como en el siguiente ejemplo extraído de la <a href="http://www.lucianobello.com.ar/blog/On_the_Dissection_of_Rectangles_into_Right-Angled_Isosceles_Triangles.pdf">página 33 del paper</a>:</p>
<p><center><img src="http://www.lucianobello.com.ar/blog/square_12_15_skinner.jpg" alt="" /></center></p>
<p>La siguiente pregunta es si existen disecciones perfectas en otras formas <em>interesantes</em>. Por ejemplo, Brooks et. al. <a href="http://www.math.niu.edu/~rusin/known-math/99/equilateral">demostraron que no es posible</a> dividir un triángulo equilátero en triángulos equiláteros de forma perfecta. En <a href="http://projecteuclid.org/euclid.dmj/1077492259">ese mismo trabajo de 1940</a> se señala que, a diferencia de la perfectibilidad, era posible hacer una disección de equiláteros en equiláteros que fuese <strong>simple</strong>.</p>
<p>Se dice que una disección es <strong>simple</strong> cuando ningún subconjunto de 2 o más elementos forma una figura de las informalmente definidas como <em>interesante</em>. Por ejemplo, en el caso de la distribución propuesta por Stone que ya mencionamos, el subconjunto de elementos pintado con verde forma un triángulo rectángulo isósceles:<br />
<center><img src="http://www.lucianobello.com.ar/blog/x7-7PA.jpg" alt="" /></center><br />
Por lo que definimos esta disección como <strong>compuesta</strong> en contraposición a la <strong>simple</strong> que expone Skinner et. al.</p>
<p>Una disección puede ser simple y no perfecta, o viceversa. Así, y como venía diciendo, Brooks et. al. dicen que es posible dividir un triángulo equilátero en triángulos equiláteros de forma simple, aunque imperfecta. Dicha forma fue presentada por <a href="http://www.squaring.net/history_theory/brooks_smith_stone_tutte_II.html">William Tutte</a>, un famoso criptoanalista británico, y es así:<br />
<center><img src="http://www.squaring.net/tri/gfx/wtt-15-39.gif" alt="" /></center><br />
Y como en la vida misma, lo simple y lo perfecto perecen ser cualidades que cuesta ver en conjunto. Pero que, para belleza de la cosas, no es imposible de encontrar. Así es que me gustaría presentarles el cuadrado de menor orden que puede dividirse en cuadrados de forma simple y perfecta, descubierto por <a href="http://www.squaring.net/history_theory/duijvestijn.html">Adrianus Johannes Wilhelmus Duijvestijn</a> la noche del 22 de Marzo de 1978:</p>
<p><center><img src="http://mathworld.wolfram.com/images/eps-gif/PerfectSquare21_1100.gif" alt="" /></center></p>
<p>Esta disección en 21 cuadrados desiguales que no forman subconjuntos de cuadrados es lo que se conoce como <strong>la disección de Duijvestijn</strong>, y se pueden <a href="http://math-art.spreadshirt.com/duijvestijn-dissection-A4632968">comprar remeras con su estampa</a>. Si bien Duijvestijn ya había descubierto disecciones perfectas simples del cuadrado de ordenes superiores, había probado, junto a <a href="http://www.squaring.net/history_theory/chris_bouwkamp.html">Bouwkamp</a>, que no era posible crear estas disecciones en órdenes menores a 20. De ahí el esfuerzo por encontrar la más pequeña de las posibilidades.</p>
<p>Espero no haberlos aburrido en demasía. Para mí fue muy entretenido y aprendí muchísimo sobre álgebra y geometría, así como formas de representación imaginativas de conceptos geométricos que permiten razonar de forma algorítmica. Si quieren aprender más sobre los temas tratados en esta entrada, pueden consultar la página <a href="http://www.squaring.net/">Squaring.net</a> que está totalmente dedicada a este tipo de puzzles e incluye biografía de las personalidades referentes del área, así  como otros temas relacionados. Este post está fuertemente basado en esta web. El artículo de <a href="http://mathworld.wolfram.com/PerfectSquareDissection.html">Wolfram MathWorld</a> al respecto también es muy entretenido. Se puede chusmear la página de wikipedia sobre el problema de <a href="http://en.wikipedia.org/wiki/Squaring_the_square">Squaring the square</a> para una idea más breve de la representación de Smith.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/diseccion_perfecta/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>(hot) boxing network</title>
		<link>http://www.lucianobello.com.ar/post/hot-boxing-network/</link>
		<comments>http://www.lucianobello.com.ar/post/hot-boxing-network/#comments</comments>
		<pubDate>Tue, 12 Jan 2010 22:58:49 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[geek]]></category>
		<category><![CDATA[hardware]]></category>
		<category><![CDATA[life]]></category>
		<category><![CDATA[procrastination]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=1277</guid>
		<description><![CDATA[Hace unos días comenté que, por razones de practicidad, metí todos mis aparatos de redes en una caja. Si bien le puse alguna ventilación no forzada, varios amigos y conocidos insistieron en la alta temperatura que podía llegar a alcanzarse dentro del susodicho tupperware. Desde mi punto de vista, no hay (había) nada de que [...]]]></description>
			<content:encoded><![CDATA[<p>Hace unos días <a href="http://www.lucianobello.com.ar/post/boxing-network/">comenté</a> que, por razones de practicidad, metí todos mis aparatos de redes en una caja. Si bien le puse alguna ventilación no forzada, <a href="http://www.facebook.com/notes/luciano-bello/boxing-network/246818258745">varios amigos y conocidos insistieron</a> en la alta temperatura que podía llegar a alcanzarse dentro del susodicho tupperware. Desde mi punto de vista, no hay (había) nada de que preocuparse.</p>
<p>Pero hablar es gratis, así que decidí ir a los papeles y a las pruebas concretas, para lo que, evidentemente, era necesario un termómetro. Fue así como encontré la excusa para hacerme de <a href="http://www.tumedicion.com/product_info.php?cPath=1_85&amp;products_id=36">uno</a>, tal como se puede ver:</p>
<p><img src="http://www.lucianobello.com.ar/blog/boxing_thermometer.png" alt="" /><br />
Ahora puedo saber que dentro de la caja la temperatura ronda los 48ºC, aunque tiene picos de 50ºC cuando hace calor en el living. En lo personal, era más o menos lo que calculaba. El sensor lo fijé a la tapa superior, con lo que voy a suponer que es el lugar más caliente de la caja (aunque tal vez lo sea entre los transformadores, no se&#8230;).</p>
<p>Con la intensión de ver que tan grave puede ser esto para los equipos en su interior, me puse a recolectar las especificaciones de la parte electrónica (¿debería preocuparme también por las condiciones en la que trabajan los transformadores?). Aquí, la lista de dispositivos con el rango de temperatura operativo y links a las fuentes:</p>
<ul>
<li>Access Point <a href="http://www.d-link.com/products/?pid=18">D-Link DWL-800AP+</a>: <a href="ftp://ftp10.dlink.com/pdfs/products/DWL-800AP+/DWL-800AP+_ds.pdf">de 0º a 55ºC</a></li>
<li> Router+switch <a href="http://www.linksysbycisco.com/US/en/products/BEFSX41">Linksys BEFSX41</a>:  <a href="http://downloads.linksysbycisco.com/downloads/datasheet/BEFSX41v2_ds.pdf">de 0ºC a</a><a href="http://downloads.linksysbycisco.com/downloads/datasheet/BEFSX41v2_ds.pdf"> <strong><span style="color: #ff0000;">40ºC</span></strong></a></li>
<li>Cable Modem <a href="http://www.cisco.com/web/consumer/support/modem_DPC2100.html">Scientific Atlanta DPC2100</a>: <a href="http://www.arenaservicesinc.com/manuals/Cable_Modems/SA/DPC2100datasheet.pdf">de 0ºC a <strong><span style="color: #ff0000;">40ºC</span></strong></a></li>
<li>SIP terminal <a href="http://www.grandstream.com/products/ht_series/ht486/ht486.html">Grandstream HandyTone 486</a>: <a href="http://downloads.linksysbycisco.com/downloads/datasheet/BEFSX41v2_ds.pdf">de 0ºC a</a><a href="http://www.grandstream.com/products/ht_series/general/marketing/ht_brochure_english.pdf"> <strong><span style="color: #ff0000;">40ºC</span></strong></a></li>
</ul>
<p>Para mi sorpresa (es que claramente soy un ignorante) 3 de los 4 aparatos tienen temperaturas máximas de operación de 40ºC, ~10ºC menos de lo que se respira por esos lares.</p>
<p>Evidentemente, estimados comentaristas, tenían razón. Es que soy un cabeza dura, ya lo saben. El hecho es que tal vez sí debería preocuparme un poco más por bajar la temperatura de ese cajón si es que quiero que mi pequeña red siga funcionando.</p>
<p><strong>update 16 Jan 2010 12:01:10 -0300</strong>: Finalmente le puse un ventilador que expulse aire en la tapa (no solo fue la sugerencia de muchos, también era el único lugar donde cabía). Uno de fuente de PC, <a href="http://en.wikipedia.org/wiki/Brushless_DC_electric_motor"><em>brushless</em></a>.</p>
<p><img src="http://www.lucianobello.com.ar/blog/boxing_fan.png" alt="" /><br />
En el mismo lugar de medición, en el que antes tenía 48ºC ahora tengo entre 37ºC y 38ºC, lo cual es buenísimo. Un amigo me sugirió que mida entre los dispositivos. Ahí la historia cambia: 43ºC (no tengo idea de cual era antes en esta ubicación). Tal vez pueda hacer un sistema de tuberías para hacer correr aire entre ellos.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/hot-boxing-network/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>boxing network</title>
		<link>http://www.lucianobello.com.ar/post/boxing-network/</link>
		<comments>http://www.lucianobello.com.ar/post/boxing-network/#comments</comments>
		<pubDate>Sat, 09 Jan 2010 19:55:33 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[geek]]></category>
		<category><![CDATA[hardware]]></category>
		<category><![CDATA[life]]></category>
		<category><![CDATA[procrastination]]></category>
		<category><![CDATA[sorry for my english]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=1274</guid>
		<description><![CDATA[Since I am a housewife (i.e. since I live on my own) my concerns have been extended to foreign horizons, such as taming dust and lint. All my network devices and wires has a particular magnetism for them. To make things worse, the devices cleaning is quiet hard. So, I decide to boxing them. All [...]]]></description>
			<content:encoded><![CDATA[<p>Since I am a housewife (i.e. since I live on my own) my concerns have been extended to foreign horizons, such as taming dust and lint. All my network devices and wires has a particular magnetism for them. To make things worse, the devices cleaning is quiet hard.</p>
<p>So, I decide to <em>boxing</em> them. All you need is a big tupperware and few rubber bands. Here is the process to build it:<br />
<center><img src="http://www.lucianobello.com.ar/blog/boxing_process.gif" alt="boxing process" /></center><br />
And this is done:<br />
<center><img src="http://www.lucianobello.com.ar/blog/boxing.png" alt="boxing" /></center></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/boxing-network/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>La UTN tiene dueño (wtf)</title>
		<link>http://www.lucianobello.com.ar/post/la-utn-tiene-dueno-wtf/</link>
		<comments>http://www.lucianobello.com.ar/post/la-utn-tiene-dueno-wtf/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 15:25:49 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[procrastination]]></category>
		<category><![CDATA[social networking]]></category>
		<category><![CDATA[university]]></category>
		<category><![CDATA[wtf?!]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=1270</guid>
		<description><![CDATA[Hernán me pasó un excelente link de Linkedin (redundancia necesaria), la red social orientada a negocios y el mundo profesional, cuya captura reproduzco a continuación: Mucho se me ha escuchado putear sobre el corporativismo en la universidad en este blog y otros entornos. Pero este fallido es como demasiado :P El tiempo de estudio es [...]]]></description>
			<content:encoded><![CDATA[<p>Hernán me pasó un excelente link de <a href="http://www.linkedin.com/">Linkedin</a> (redundancia necesaria), la red social orientada a negocios y el mundo profesional, cuya captura reproduzco a continuación:<br />
<center><img src="http://www.lucianobello.com.ar/blog/UTN_owned_wtf.png" alt="" /></center><br />
Mucho se me ha escuchado putear sobre el corporativismo en la universidad en este blog y otros entornos. Pero este <a href="http://es.wikipedia.org/wiki/Acto_fallido">fallido</a> es como demasiado :P<br />
El tiempo de estudio es un bonus wtf (y yo que siempre pensé que mis 8 años de carrera habían sido demasiados)&#8230; </p>
<p><small>El borroneo sobre el nombre tiene como fin no darte el dato directamente, una situación parecida a la ocurrida <a href="http://www.lucianobello.com.ar/post/not-yours/#comment-1409">acá</a>. Ya sé que lo podés conseguir, bien por ti.</small></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/la-utn-tiene-dueno-wtf/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>removing your facebook photo tags automagically</title>
		<link>http://www.lucianobello.com.ar/post/rmfb-en/</link>
		<comments>http://www.lucianobello.com.ar/post/rmfb-en/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 16:22:35 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[planet]]></category>
		<category><![CDATA[procrastination]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[social networking]]></category>
		<category><![CDATA[sorry for my english]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=1242</guid>
		<description><![CDATA[Este post también está escrito en español aquí. Privacy at Facebook is heavy-duty. As a big fan of the Worlds Collide Theory I hate be tagged compulsively. I would like to select in which photos appear in my profile and feed. Since I couldn&#8217;t find that option in the setting menu, I looked for the [...]]]></description>
			<content:encoded><![CDATA[<p><small>Este post también está escrito en español <a href="http://www.lucianobello.com.ar/post/rmfb-es/">aquí</a></small>.</p>
<p>Privacy at <a href="http://www.facebook.com/privacy/">Facebook</a> is heavy-duty. As a big fan of the <a href="http://www.urbandictionary.com/define.php?term=Worlds Collide Theory">Worlds Collide Theory</a> I hate be tagged compulsively. I would like to select in which photos appear in my profile and feed. Since I couldn&#8217;t find that option in the setting menu, I looked for the answer in my favorite scripting language: <a href="http://www.python.org/">Python</a>.</p>
<p><a href="http://python.pastebin.com/f55c5896f">This 60-lines-long script</a> removes your tag from the latests photos where you has been labelled. You can download it from <a href="http://www.lucianobello.com.ar/rmfb/">here</a>. You may run it hourly (or every 15 minutes, or every 5 minutes, depends how paranoid you are) via <a href="http://en.wikipedia.org/wiki/Cron">cron</a> or whatever.</p>
<p>Any improvement is welcome. It probably runs on Windows too. If you managed to do it, leave a comment for the others.</p>
<p><strong>NEW VERSION!</strong> (available <a href="http://www.lucianobello.com.ar/rmfb/">here</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/rmfb-en/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>remover tu etiqueta de las fotos de facebook automágicamente</title>
		<link>http://www.lucianobello.com.ar/post/rmfb-es/</link>
		<comments>http://www.lucianobello.com.ar/post/rmfb-es/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 16:21:24 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[geek]]></category>
		<category><![CDATA[planeta]]></category>
		<category><![CDATA[procrastination]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[social networking]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=1245</guid>
		<description><![CDATA[This post has been written in English too. La privacidad en Facebook es un asunto complejo. Como gran suscriptor a la Teoría de Colisión de Mundos es que odio ser etiquetado en fotos de forma compulsiva. Me gustaría tener alguna forma de elegir en que fotos aparezco en mi perfil y actualizaciones. Dado que no [...]]]></description>
			<content:encoded><![CDATA[<p><small>This post has been written <a href="http://www.lucianobello.com.ar/post/rmfb-en/">in English too</a></small>.</p>
<p>La privacidad en <a href="http://www.facebook.com/privacy/">Facebook</a> es un asunto complejo. Como gran suscriptor a la <a href="http://www.urbandictionary.com/define.php?term=Worlds Collide Theory">Teoría de Colisión de Mundos</a> es que odio ser etiquetado en fotos de forma compulsiva. Me gustaría tener alguna forma de elegir en que fotos aparezco en mi perfil y actualizaciones. Dado que no pude encontrar tal opción entre la configuración, busqué la respuesta en mi lenguaje de scripting favorito: <a href="http://www.python.org/">Python</a>.</p>
<p><a href="http://python.pastebin.com/f55c5896f">Este script de 60 lineas</a> remueve tu etiqueta de las últimas fotos donde te hayan tagueado. Puede ser descargado desde <a href="http://www.lucianobello.com.ar/rmfb/">aquí</a>. Hay que correrlo cada hora (o cada 15 minutos, o cada 5, dependiendo de que tan paranoico seas) a través de <a href="http://en.wikipedia.org/wiki/Cron">cron</a> o como sea.</p>
<p>Cualquier mejora es bienvenida. Posiblemente también corra en Windows. Si lograste hacer esto, deja un comentario que pueda serle útil a otros.</p>
<p><strong>¡NUEVA VERSIÓN!</strong> (disponible <a href="http://www.lucianobello.com.ar/rmfb/">aquí</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/rmfb-es/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>La ley de Benford y la vida real &#8482;</title>
		<link>http://www.lucianobello.com.ar/post/la-ley-de-benford-y-la-vida-real-tm/</link>
		<comments>http://www.lucianobello.com.ar/post/la-ley-de-benford-y-la-vida-real-tm/#comments</comments>
		<pubDate>Mon, 08 Dec 2008 19:38:36 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[books & reading]]></category>
		<category><![CDATA[favorites]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[probability & statistics]]></category>
		<category><![CDATA[procrastination]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=1043</guid>
		<description><![CDATA[Lo prometido. Hoy me gustaría hablarles algo que no tenía idea que existía y que me encontré en el apéndice 9 del libro La Proporción Áurea de Mario Livio. Es de esos sorprendentes conceptos que destruyen la intuición. Por un lado es simple desde lo formal, pero esconde algo casi mágico. Dicho concepto es: La [...]]]></description>
			<content:encoded><![CDATA[<p>Lo prometido. Hoy me gustaría hablarles algo que no tenía idea que existía y que me encontré en el apéndice 9 del libro <a href="http://www.elbuscon.es/L9788434455313-proporcion-aurea.html"><em>La Proporción Áurea</em> de Mario Livio</a>. Es de esos sorprendentes conceptos que destruyen la intuición. Por un lado es simple desde lo formal, pero esconde algo casi mágico. Dicho concepto es: <a href="http://es.wikipedia.org/wiki/Ley_de_Benford">La ley de Benford</a></p>
<p>Para los que no hicieron click en el link anterior y dado que la entrada en la <a href="http://es.wikipedia.org/">Wikipedia en español</a> sobre el tema deja bastante que desear (estoy corrigiéndola), acá está mi breve explicación:</p>
<p><em><strong>La ley de Benford</strong>, también conocida como <strong>la ley del primer dígito</strong>, dice que, en los números que existen en <em>la vida real</em><sup>TM</sup>, la primer cifra tiene muchas más posibilidades de ser 1 que otro valor. Además, según crece este primer dígito, más improbable es que se encuentre en la primera posición.</em></p>
<p>A por un ejemplo, que seguro es más fácil. Tomemos una tabla con estadísticas cualquiera, como ser el <a href="http://en.wikipedia.org/wiki/Provinces_of_Argentina#Demographics">área o población de las provincias argentinas</a>, la <a href="http://en.wikipedia.org/wiki/List_of_football_(soccer)_stadiums_by_capacity">capacidad de los estadios del mundo</a>, los <a href="http://www.luchemos.org.ar/espa/estadis.htm">muertos por accidentes de tránsito</a> o las estadísticas de visitas en tu blog. Como todo en estadística, mientras más grande la muestra mejor, así que vayan a por tablas realmente grandes.</p>
<p>Intuitivamente, uno podría pensar que, para cualquier número, las posibilidades que empiece con 1 son las mismas que con 9. Es decir, al agarrar una pelota de números cualquiera de <em>la vida real</em><sup>TM</sup> se podría llegar a creer que, si la cantidad es lo suficientemente grande, más o menos 1/9 de la muestra empezarán con 1 (nótese que no tiene sentido que los valores empiezen en 0, por lo que las opciones son 9). Esto es porque creemos que los números que estamos analizando se comportan como si fuesen aleatorios. Si tiramos una moneda al aire una gran cantidad de veces, cerca de la mitad de las oportunidades será seca. Es algo que aprendimos hace mucho y nos parece intutivo que la naturaleza se comporte así. Como si $deity hubiese tirado un dado gigante para decidir el largo de un río, la población de un país o el precio de las acciones en el MERVAL.</p>
<p>Como en mi disco todavía tengo los datos utlizados para el post <a href="http://www.lucianobello.com.ar/post/la-chica-bajo-la-curva-dating-pool/"><em>la chica bajo la curva (dating pool)</em></a> voy a utilizar la cantidad de casados, por provincia, por edad (puede descargarse desde <a>acá</a>). En mi caso son 30843 regitros. Esta linea de bash cuenta cuantos de los valores empienzan con cada cifra:<br />
<tt><br />
$ for i in $(cat provincia_indec.csv  | grep años | cut -d ';' -f 4); do echo ${i:0:1}; done | sort | uniq -c<br />
10350 1<br />
5581 2<br />
3550 3<br />
2744 4<br />
2159 5<br />
1903 6<br />
1815 7<br />
1406 8<br />
1335 9</tt><br />
<img src="http://upload.wikimedia.org/wikipedia/de/thumb/8/84/Benford.svg/250px-Benford.svg.png" alt="" align="right" />Puede verse que el 33.56% de las cifras empiezan con 1 y que, mientras mayor es el valor del primer dígito, menor es la cantidad de ocurrencias.</p>
<p>En efecto, nuestro nuevo amigo <a href="http://en.wikipedia.org/wiki/Frank_Benford">Benford</a> describe este fenómeno y nos dice que, la probabilidad <em>p</em> de que el dígito <em>d</em> aparezca en el primer lugar está dado por la siguiente fórmula:<br />
<img src="http://upload.wikimedia.org/math/2/b/0/2b09f4eb994720c9bd2be2ed10f966d2.png" alt="" /></p>
<p>En el ejemplo anterior, el dígito 1 se encuentra en 10350/30843=0.336 de los casos. Puede verse que la predicción de la fórmula es bastante buena, ya que log<sub>10</sub>(1+1)=0.301. En la siguiente figura puede verse como se ajusta la fórmula a los datos de la práctica (primer dígito de la cantidad de personas casadas por provincia, por edad según el censo 2001):<br />
<img src="http://www.lucianobello.com.ar/blog/benford_casados_edad_provincia.png" alt="" /><br />
De hecho, la misma fórmula puede aplicarse a más de un dígito. Por ejemplo, la probabilidad de que una cifra empiece con 42 (primer dígito 4, segundo 2) es log<sub>10</sub>(1+1/42)=0.010219. Modificando levemente el script (<em>${i:0:2}</em>) podemos estudiar la cantidad de cifras por la repetición de sus primeros dos números y compararlos con su valor teórico:<br />
<img src="http://www.lucianobello.com.ar/blog/benford_casados_edad_provincia1.png" alt="" /><br />
Impresionante.. no?</p>
<p>¿Y porqué pasa esto? Ocurre que a las magnitudes del <em>mundo real</em><sup>TM</sup> están distribuidas de forma logarítmica.<br />
<img src="http://upload.wikimedia.org/wikipedia/commons/a/ae/Logscale.png" alt="" /></p>
<p>Recordemos la fórmula: p<sub>(d)</sub>=log<sub>10</sub>(1+1/<em>d</em>)=log<sub>10</sub>(<em>d</em> + 1) − log<sub>10</sub>(<em>d</em>)<br />
Es decir, cuenta cuántos números hay entre <em>d</em> y <em>d+1</em> dentro de la escala logarítmica.</p>
<p>La mejor explicación que recibí para este fenómeno habla de un cambio de escala. Supongamos por un momento que la distribución de los primeros dígitos de lo largo de los ríos, lo alto de las montañas, lo profundo de los posos es constante. Ahora imaginemos que $deity se levanta una mañana y duplica el tamaño del planeta (o del universo, ustedes elijen). Las medidas que empezaban por 1 hora pasan a empezar por 2 o 3 (160*2=320). Lo que empezaba por 2 ahora lo hace por 4 o por 5 (290*2=580). El 3 se va a 6 o 7 (384*2=768). El 4 a 8 y 9.</p>
<p>¡Pero todos aquellas medidas que empezaban por 5, 6, 7, 8 y 9 ahora empiezan por 1! Si realizamos esta operación varias veces los valores se amontonan rápidamente en los iniciados por 1, generando la escala logarítmica en cuestión. Y acá está el tema. La mayoría de los valores de <em>la vida real</em><sup>TM</sup> son resultados de multiplicaciones.</p>
<p>El siguiente gráfico invita a comparar las superficies rojas (valores que inician con 1) y azules (valores que inician con 8) para estudiar sus probabilidades de ocurrencia en el primer dígito:<br />
<img src="http://upload.wikimedia.org/wikipedia/commons/e/e0/BenfordBroad.gif" alt="" /><br />
Las distribuciones que cubren muchos órdenes de magnitud (que varían mucho entre número y número) cumplen relativamente bien con la ley de Benford. Sin embargo puede no ocurrir así siempre:<br />
<img src="http://upload.wikimedia.org/wikipedia/commons/c/c8/BenfordNarrow.gif" alt="" /><br />
Nótese que la clave está en las grandes magnitudes (recuerden la explicación del universo que se duplica). Existen tablas de números de <em>la vida real</em><sup>TM</sup> que no cumplen la ley dada que estan acotadas en cuento a su rango, por ejemplo los datos <a href="http://es.finance.yahoo.com/q/hp?s=^MERV">del cierre del MERVAL de los últimos 3 años</a>. Si bien son números grandes, su máximo y mínimo es acotado. Imagino (no tengo uno a mano) que los precios unitarios de los productos en un ticket de supermercado tampoco se agustan a la ley por razones parecidas. La <a href="http://www.ole.clarin.com/estadisticas/primeraa/a2008/goleadores.html">tabla de goleadores de un torneo de fútbol padece el mismo trauma</a>. ¿Se les ocurre algún otro ejemplo excepcional a la regla?</p>
<p>Espero hayan aprendido algo nuevo y ahora quieran a la matemática un poquito más :)</p>
<p>PD: Me olvidaba. Tarea para el hogar: Demostrar que <em>la vida real</em><sup>TM</sup> incluye a Fibonacci ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/la-ley-de-benford-y-la-vida-real-tm/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>la chica bajo la curva (dating pool)</title>
		<link>http://www.lucianobello.com.ar/post/la-chica-bajo-la-curva-dating-pool/</link>
		<comments>http://www.lucianobello.com.ar/post/la-chica-bajo-la-curva-dating-pool/#comments</comments>
		<pubDate>Mon, 13 Oct 2008 04:55:15 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[favorites]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[probability & statistics]]></category>
		<category><![CDATA[procrastination]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=967</guid>
		<description><![CDATA[Hace poco más de un año, como muchos de ustedes seguramente, leí esta simpática tira de XKCD. En ese momento empecé a buscar datos sobre la población para ver que tan real era ello. La pseudo-investigación se fue de cause y terminé en cualquier parte hasta que lentamente perdí el rumbo sin la más mínima [...]]]></description>
			<content:encoded><![CDATA[<p>Hace poco más de un año, como muchos de ustedes seguramente, leí <a href="http://xkcd.com/314/">esta simpática tira de XKCD</a>. En ese momento empecé a buscar datos sobre la población para ver que tan real era ello. La pseudo-investigación se fue de cause y terminé en cualquier parte hasta que lentamente perdí el rumbo sin la más mínima intención de retomarlo.</p>
<p>Un par de semanas atrás, y por razones que no viene al caso, volví al tema desde cero. En este caso llegué a cosas medianamente concretas (dentro del delirio, claro). Así que aquí están algunos de los resultados que me gustaría compartir con ustedes.</p>
<h1>Introducción:</h1>
<p>Para aquellos que no tienen idea de los que estoy hablando, una breve introducción. En la <a href="http://xkcd.com/">famosa tira cómica</a> se plantea una sencilla hipótesis que puede resumirse en la siguiente pregunta: &#8220;¿a partir de qué edad tus posibilidades de tener pareja empiezan a bajar?&#8221;</p>
<p>Para esto tengamos en cuenta dos elementos:</p>
<ul>
<li> A mayor edad, menores las posibilidades de soltería. Es decir, si una persona tiene 20 años es más probable de que esté soltera a que ocurra lo mismo con alguien de 40 años.
<li> A mayor edad, mayor es el rango de edad de los candidatos. Para poner un ejemplo, no es lo mismo que una persona de 40 salga con otra de 55 que un joven de 18 salga con alguien de 33. Es claro <a href="http://www.smh.com.au/ffximage/2008/10/10/hefholly3_wideweb__470x374,0.jpg">no hay edades para el amor</a>, pero estamos hablando de posibles candidatos. Incluso hablamos de las posibilidades de tener cosas en común, de fijarse en el otro. <a href="http://en.wikipedia.org/wiki/Randall_Munroe">Randall Munroe</a>, el autor de la tira, propone una fórmula a la que llama <a href="http://www.google.com/search?q="standard+creepiness+rule"">&#8220;standard creepiness rule&#8221;</a> (algo así como &#8220;regla estándar de <em>viejo-verdez</em>&#8220;, asquerosidad, o algo del estilo). Según él (y <a href="http://forums.xkcd.com/viewtopic.php?t=11765">muchos parecen coincidir</a>), las personas no salen con alguien que tenga la mitad de su edad más siete. Por ejemplo, en mi caso y con 27 años, mi cota inferior está dada por <em>(27/2)+7=20.5</em>, lo que parece bastante razonable o, al menos, políticamente correcto. Esta misma fórmula también sirve como cota superior, ya que uno es el límite inferior de alguien mayor. Para mi edad corresponde a 40 años porque <em>40=(27-7)*2</em>. Nótese que para una persona de 20 años sus candidatos van entre 17 y 26, mientras que para alguien de 30 sus opciones van entre 22 y 46. Se supone que hay más personas entre el segundo rango que el primero, al menos hasta que la taza de mortalidad empieza a hacer de las suyas.
</ul>
<h1>Primera aproximación:</h1>
<p>Lo interesante de esta situación es la posibilidad de analizarla con datos reales. Son datos que existen, que <a href="http://www.indec.mecon.ar/webcenso/provincias_2/P92.pdf">se preguntan en los censos</a>, pero que no siempre están disponibles para cualquier mortal. Por suerte el <a href="http://">INDEC (Instituto Nacional de Estadística y Censos)</a> provee la información de una forma que, aunque críptica para el recién llegado, resulta interesante cuando uno le encuentra la vuelta. Así que fue <a href="http://www.indec.mecon.ar/webcenso/index.asp">allí</a> a donde fui, a buscar el universo de la población argentina.</p>
<p>Tomando toda la población mayor a 14 años, por edades simples y situación conyugal, calculé la cantidad de personas candidatas para cada edad, tiendo en cuenta los rangos de edades de esos posibles candidatos. Consideremos candidatos a las personas no casadas (solteros, divorciados, separados legales y viudos). Aquí el gráfico:</p>
<p><img src="http://www.lucianobello.com.ar/blog/datingpool_resultado1_abs.png" /></p>
<p>Nótese la forma de <em>W-invertida</em> de la gráfica. El máximo absoluto se encuentra a los 27 años. Es decir, en este momento me encuentro en el cenit de la soltería. Es interesante observar, que después del punto de inflexión de los 41, a los 47 vuelve a haber un máximo. Llamemos a este punto <i><a href="http://www.imdb.com/title/tt0116313/">El club de la divorciadas</a></i> ;). Las estadísticas demuestran que la frase &#8220;la vida da revancha&#8221; tiene fundamento estadístico.</p>
<p>Pero los valor absolutos siempre me parecieron lejanos. Soy de los que disfruta hablar en términos de porcentaje, de probabilidades, es decir, en términos relativos. Así fue como generé este segundo gráfico, con la intención de responder a la pregunta &#8220;Si conozco a 100 personas dentro de mi rango de edad, ¿cuántas estarán no-casadas?&#8221;:</p>
<p><img src="http://www.lucianobello.com.ar/blog/datingpool_resultado1_rel.png" /></p>
<p>Así, la cantidad de personas sin compromisos maritales dentro de un rango, sobre la cantidad total de personas de ese rango da un porcentaje de disponibilidad para cada edad. Acá la cosa se pone algo más pesimista, asegurando una clara caída hasta los 44 años, edad desde la cual se inicia un tímido y poco constante ascenso.</p>
<h1>Segunda aproximación:</h1>
<p>Esta visión es más <em>egocentrista</em> y está pensada en términos totalmente propios. En lo personal, estoy interesado por personas de género femenino, que no solo no estén casadas, sino que además no convivan en pareja (las considero personas en relaciones lo suficientemente fuertes como para quitarlas del conjunto de candidatas). A estas limitaciones le sumaré la restricción geográfica de que tenga residencia dentro de <a href="http://es.wikipedia.org/wiki/Buenos_Aires">mi ciudad natal</a> y alrededores, por lo que solo tendré en cuenta personas dentro de <a href="http://es.wikipedia.org/wiki/Conurbano_bonaerense">Buenos Aires y conurbano bonaerence</a>. La ubicación geográfica puede acarrear cambios culturales que tengan efectos en la situación conyugal de las personas, por lo que considero importante tenerlo en cuenta.</p>
<p>Felizmente INDEC tiene una forma rápida de filtrar por estas restricciones, así que <a href="http://www.lucianobello.com.ar/blog/dto_partido.txt">seleccioné las regiones geográficas</a> y construí <a href="http://www.lucianobello.com.ar/blog/filtro.txt">un filtro</a> donde solo se refiera a personas de sexo femenino que no estén conviviendo con una pareja.</p>
<p>Nuevamente, las mismas gráficas:<br />
<img src="http://www.lucianobello.com.ar/blog/datingpool_resultado2_abs.png"/><br />
<img src="http://www.lucianobello.com.ar/blog/datingpool_resultado2_rel.png"/><br />
Esta vez la <em>W-invertida</em> refleja un máximo absoluto muy diferente al inicial, 53 años. Tal vez se parezca más al modelo que, creo que intuitivamente, proponía <a href="http://en.wikipedia.org/wiki/Randall_Munroe">Munroe</a>. En el gráfico de porcentajes, la caída es mucho más brusca y profunda, perdiendo más de una decena de puntos en su mínimo, que además se da bastante antes, a los 38 años. La pendiente de ascenso es empinada y termina por provocar mayores valores hacia el final de la esperanza de vida que la aproximación anterior.</p>
<h1>Suposiciones y limitaciones:</h1>
<p>Estos análisis son un emporio de suposiciones y limitaciones. Después de todo, dicen que la estadística es la ciencia del prejuicio. Acá una lista de suposiciones que pueden ser ampliamente discutibles:</p>
<ul>
<li>Los homosexuales y religiosos existen en cantidades despreciables. Así que todo hombre soltero busca una mujer y viceversa.
<li> Las personas con alguna relación de pareja no convivientes son consideradas disponibles. El INDEC no pregunta acerca de estado amoroso de las personas.
<li> La cantidad de personas con <em>n y medio</em> edad es la mitad de la cantidad de personas con <em>n</em> edad.
<li> La fórmula &#8220;standard creepiness rule&#8221; es válida. Aunque posiblemente pueda repetirse la experiencia con fómulas que mejor se ajusten a cada cultura. En lo personal, creo tener poco en común con alguien de 40 años. De hecho, formulas independientes para el hombre y la mujer creo que serían más aplicables. Tal vez los hombres tiene un target más orientado a la izquierda del eje. Pero es medio que gusto de cada uno.
<li> La información del censo corresponde a datos de 2001. Extrapolarlos no tiene sentido, ya que insertaría muchísimo error. Lo dicho, lo interesante son los números en proporciones.
<li> La definición de &#8220;candidato&#8221; esta dada por edad, género, posición geográfica y estado conyugal. No se contempló gustos y esas cosas de esas que hace que las parejas funcionen&#8230; o eso dicen :P.
</ul>
<p>Todo lo necesario para repetir la experiencia se encuentra <a href="http://www.lucianobello.com.ar/blog/dating_pool.tar.gz">acá</a>. Enjoy it &#8230; que yo voy a estar buscando a esa chica bajo la curva :)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/la-chica-bajo-la-curva-dating-pool/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Asimov, Leibniz, pi, python, floats y evadirse de la realidad</title>
		<link>http://www.lucianobello.com.ar/post/asimov-leibniz-pi-python-floats-y-evadirse-de-la-realidad/</link>
		<comments>http://www.lucianobello.com.ar/post/asimov-leibniz-pi-python-floats-y-evadirse-de-la-realidad/#comments</comments>
		<pubDate>Tue, 09 Sep 2008 00:10:00 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[books & reading]]></category>
		<category><![CDATA[favorites]]></category>
		<category><![CDATA[procrastination]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[π]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=896</guid>
		<description><![CDATA[La matemática tiene cosas sorprendentemente lindas. Y una de las que siempre me gustó de forma especial es la formula de Leibniz para el cálculo de π. También conocida como la serie de Gregory-Leibniz es una simpática manera de expresar el más famoso de los números irracionales: O para aquellos no gustan de las notación [...]]]></description>
			<content:encoded><![CDATA[<p>La matemática tiene cosas sorprendentemente lindas. Y una de las que siempre me gustó de forma especial es <a href="http://en.wikipedia.org/wiki/Leibniz_formula_for_pi">la formula de Leibniz para el cálculo de π</a>. También conocida como la serie de Gregory-Leibniz es una simpática manera de expresar el más famoso de los números irracionales:<br />
<img src="http://www.lucianobello.com.ar/blog/pi2.png" alt="" align="middle" /><br />
O para aquellos no gustan de las notación <a href="http://en.wikipedia.org/wiki/Summation#Capital-sigma_notation">sigma-grande</a>:<br />
<img src="http://www.lucianobello.com.ar/blog/pi1.png" alt="" align="middle" /><br />
Como verán, se trata de una serie sumamente simple y elegante. Y como suele ocurrir con estas cosas, aparecen en la vida de uno en momentos extraños, casi que al rescate.</p>
<p><img title="pi" src="http://imgs.xkcd.com/comics/pi.jpg" alt="" width="469" height="247" align="left" />Anoche me hallé frente a la biblioteca buscando nada en espacial. Necesitaba despejar la cabeza, olvidarme de los asuntos terrenales asociados con las complejas interacciones y relaciones humanas.</p>
<p>Fue en esa circunstancia que me encuentro con <em><a href="http://www.tematica.com.ar/libros/ciencias_de_la_salud__naturales_y_divulgacion_cientifica--7/divulgacion_cientifica--1/en_general--1/de_los_numeros_y_su_historia--119120.htm">De los números y su historia</a></em> de <a href="http://es.wikipedia.org/wiki/Isaac_Asimov">Isaac Asimov</a> (que puede ser descargado desde <a href="http://www.librosmaravillosos.com/delosnumerosysuhistoria/index.html">aquí</a>). Mientras lo hojeaba vi la formula de Leibniz, promediando el <a href="http://www.librosmaravillosos.com/delosnumerosysuhistoria/capitulo06.html">capítulo 6</a> e inmediatamente atrajo mi atención.</p>
<p>Después de expresar la serie, Asimov explica:</p>
<p><em>&lt;&lt;Ustedes podrán condenar mi falta de perseverancia, pero los invito a calcular la serie de Leibniz simplemente hasta donde la hemos escrito más arriba, es decir hasta 4/15. Incluso pueden enviarme una postal para darme el resultado. Si al terminar se sienten desilusionados al descubrir que su respuesta no está tan cerca de π como lo está el valor 355/113, no se den por vencidos. Sigan sumando términos. Sumen 4/17 al resultado anterior, luego resten 4/19, después sumen 4/21 y resten 4/23, etcétera. Pueden seguir hasta donde lo deseen, y si alguno de ustedes descubre cuántos términos se requieren para mejorar el valor 355/113, escríbanme unas líneas y no dejen de decírmelo. &gt;&gt;</em><br />
En efecto, la fracción <a href="http://www.google.com/search?q=355%2F113">355/113</a> parece ser la forma que mejor balancea precisión y simpleza a la hora de arrimarse a π desde lo números racionales, quedando a solo <a href="“http://www.google.com/search?q=355%2F113-pi”">2.66764189 × 10<sup>-7</sup> de distancia</a>. Mucha gente también utiliza la relación 22/7, aunque con menor precisión.</p>
<p>El desafío propuesto parecía interesante. Resultaba una entretenida oportunidad de jugar con <a href="http://docs.python.org/tut/node16.html">floats en python</a>, que siempre a resultado ser bastante <a href="http://www.wordreference.com/es/translation.asp?tranword=tricky">tricky</a> (además de ser un excusa para despejar la cabeza).</p>
<p>Empecé por escribir una <a href="http://www.lucianobello.com.ar/blog/asimov_simple.py">versión relativamente obvia</a> de la solución, que me dijo que al llegar al cociente 7497257 (n=3748629 en la sumatoria de Leibniz) el valor de la sumatoria estaría en 3.14159292035, quedando a 2.66764081935 x 10<sup>-7</sup> de π. Dado que los decimales (floats, representaciones de punto flotante) en Python <a href="http://www.google.com/search?q=python+&quot;0.10000000000000001&quot;+&quot;0.1&quot;">no se comportan de forma intuitiva</a>, decidí hacer <a href="http://www.lucianobello.com.ar/blog/asimov.py">una segunda versión</a>.</p>
<p>En <a href="http://www.lucianobello.com.ar/blog/asimov.py">esta versión</a> traté de mudarme al predecible mundo de los enteros. Y obtuve valores levemente distintos. En el cociente 7497247 (n=3748624) se obtiene la primera aproximación mejor que 355/113, que es 3.141592386825&#8230;  (a 2.66764162 x 10<sup>-7</sup> de π)</p>
<p>Tampoco estoy seguro de que la segunda solución sea la correcta. Me pregunto cual será el promedio de valores en las postales que la <a href="http://en.wikipedia.org/wiki/Janet_Asimov">viuda Asimov</a> seguramente guarda en una caja de zapatos.</p>
<p>El hecho es que fue entretenido intentarlo y tal vez continúe con la experiencia la próxima vez que quiera desconectarme del mundo. Después de todo, como dijo el mismo <a href="http://es.wikiquote.org/wiki/Isaac_Asimov">Asimov</a>: <em>“Los hombres que se acostumbran a preocuparse por las necesidades de unas máquinas, se vuelven insensibles respecto a las necesidades de los hombres”</em>, y hay veces que volverse insensible se ve, erróneamente, como una propuesta seductora. Hay gente que ahoga penas en alcohol, mucho más sano es ahogarlas matemáticas&#8230;</p>
<p>BTW, ya que tenía los datos armé un<a href="http://www.lucianobello.com.ar/blog/leibniz_principio.png"> plot de los primeros 1000 valores</a> de la serie para mostrar de forma gráfica la convergencia.</p>
<p>Ahora es momento de volver a la realidad, que buena o mala, irracional o racional (seguro que real al menos), inexacta o precisa, después de este recreo metal ya no se ve tan mal :-)</p>
<p><strong>UPDATE: Sat, 20 Sep 2008 22:18:18 -0300:</strong> La solución estaba realmente cerca (en mi misma ciudad) y se llama <a href="http://www.taniquetil.com.ar/plog/">Facundo</a>, quien dejó un <a href="http://www.lucianobello.com.ar/post/asimov-leibniz-pi-python-floats-y-evadirse-de-la-realidad/#comment-801">comentario</a>. Bah.. se llama <a href="http://docs.python.org/lib/module-decimal.html">decimal</a>, pero existe gracias a Facundo :). La <a href="http://docs.python.org/lib/module-decimal.html">biblioteca  decimal</a> permite manejar de forma exacta una cantidad arbitraria de decimales. La respuesta correcta es&#8230;&#8230;.. (redoblantes de suspenso) con <strong>n=(7497259+1)/2! aproxima a Π en 3.141592386825668744985771256 a solo 2.66764125 × 10<sup>-7</sup> del número irracional</strong>. El nuevo script.. <a href="http://www.lucianobello.com.ar/blog/asimov_decimal.py">aquí</a>.</p>
<p>Gracias Facundo, gracias decimal, gracias Asimov, gracias Leibniz&#8230;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/asimov-leibniz-pi-python-floats-y-evadirse-de-la-realidad/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>fútbol y matemática, unidos por cumpleaños en común</title>
		<link>http://www.lucianobello.com.ar/post/futbol-y-matematica-unidos-por-cumpleanos-en-comun/</link>
		<comments>http://www.lucianobello.com.ar/post/futbol-y-matematica-unidos-por-cumpleanos-en-comun/#comments</comments>
		<pubDate>Sat, 08 Mar 2008 07:41:00 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[books & reading]]></category>
		<category><![CDATA[favorites]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[probability & statistics]]></category>
		<category><![CDATA[procrastination]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=878</guid>
		<description><![CDATA[No, no me refiero a que el fútbol y la matemática cumplan años el mismo día. Vamos por partes. Antes que nada, una aclaración: aquellos que me conocen saben que a mí el fútbol, como cultura, me es tosco. No se por qué, tal vez algún prejuicio o trauma de la infancia, así que me [...]]]></description>
			<content:encoded><![CDATA[<p><img align=left src='http://www.mytestbook.com/images/Grade1/Math/127_1277_soccer_balls.jpg' />No, no me refiero a que el fútbol y la matemática cumplan años el mismo día. Vamos por partes.</p>
<p>Antes que nada, una aclaración: aquellos que me conocen saben que a mí el fútbol, como cultura, me es tosco. No se por qué, tal vez algún prejuicio o trauma de la infancia, así que me siento bastante tonto hablando del tema. La razón por la que el siguiente experimento tiene al fútbol de protagonista está justificada en la página 149 del libro <i>Matemática&#8230; estas ahí?</i> de Adrián Paenza (que puede bajarse <a href="http://mate.dm.uba.ar/~cepaenza/libro/matemati4.pdf">aquí</a> para uso personal).</p>
<p>En la página a la que me refiero el autor explica, con no mucho detalle, la mal llamada <b><a href="http://gaussianos.com/la-paradoja-del-cumpleanos/">Paradoja del Cumpleaños</a></b>. Para quien no suele hacer clicks sobre los links, una definición fugaz sobre qué es: <i>por más increíble que parezca, en un grupo de 23 personas existe el 50,73% de probabilidad de que dos personas cumplan años el mismo día del año.</i></p>
<p>En el mismo libro, Paenza propone:<br />
<center><i>Y si quieren poner esto a prueba, la próxima vez que participen de un partido de fútbol (once jugadores por equipo, un árbitro y dos jueces de línea), hagan el intento. Tienen más de 50% de posibilidades de que con las 25 personas haya dos que cumplan años el mismo día. Como esto es claramente antiintuitivo para muchos de los que participen del partido, quizás ustedes puedan ganar alguna apuesta.</i></center></p>
<p>Como últimamente juego poco al fútbol, decidí hacer la experiencia con los partidos del último torneo (<a href="http://www.clarin.com/deportes/primeraa/a2007/fixture.html">Apertura ‘07</a>) de la Liga Argentina. La idea es sencilla: tomar cada partido, averiguar qué jugadores fueron titulares, quién fue el árbitro y sus correspondiente fechas de nacimiento y ver si la teoría coincide con la práctica. Excluí de la experiencia a los <a href="http://es.wikipedia.org/wiki/%C3%81rbitro_asistente">jueces de línea</a>, ya que conseguir sus datos era muy complicado y, después de todo, alcanza con 23 para que la esperanza matemática esté de nuestro lado (además, estrictamente hablando, no están dentro de la cancha :P).</p>
<p>Después de algunos scripts para parsear el fixture y un poco de trabajo manual me hice de <a href="http://www.lucianobello.com.ar/paradoja_cumpleanios_apertura07/match/">una lista de partidos, con los jugadores y árbitros</a>. La parte más complicada fue obtener <a href="http://www.lucianobello.com.ar/paradoja_cumpleanios_apertura07/all">las fechas de nacimiento</a>. Estos últimos datos salieron de fuentes dispersas y no se que tan confiables, por lo que si algún lector friki encuentra algún error agradezco me lo haga saber.</p>
<p>Luego, con un poco de mi mediocre Python, escribí <a href="http://www.lucianobello.com.ar/paradoja_cumpleanios_apertura07/colision.py">algunas lineas</a> para ver en cuantas canchas del torneo coexistieron personas que pueden juntarse a festejar sus cumpleaños.</p>
<p>Los datos, los resultados y las conclusiones fueron:
<ul>
<li>En el torneo hubo <a href="http://www.clarin.com/deportes/primeraa/a2007/fixture.html">189 partidos</a>. Son 20 equipos que jugaron todos contra todos, a excepción de Gimnasia vs Arsenal.</p>
<li>Participaron 484 personas, entre jugadores y árbitros.
<li>Los nombres de pila más populares, en orden, son Juan, Pablo, Diego y Cristian.
<li>Las colisiones se dieron siempre de a pares. Es decir, no hubo 3 o más personas en el mismo partido que cumplan años el mismo día.
<li>En 11 partidos hubo dos pares de colisiones. Esto es curioso, porque se trata del 5,82% de los casos, cuando las probabilidades de que ocurran dos colisiones es del 22,5%.
<li>En 4 partidos hubo tres pares de colisiones. Esto también es curioso, porque se trata del 2,11% de los casos, cuando las probabilidades de que ocurran tres colisiones es del 8,52%. Una de estas colisiones fue el <a href="http://es.wikipedia.org/wiki/Supercl%C3%A1sico_del_f%C3%BAtbol_argentino">superclásico River vs  Boca</a>.
<li><b>La gran conclusión</b>: hubo colisiones de cumpleaños en 94 partidos, lo que representa <b>49,74% del total de partidos</b>.</ul>
<p>El detalle de los resultados puede verse <a href="http://www.lucianobello.com.ar/paradoja_cumpleanios_apertura07/result.txt">acá</a>.</p>
<p>Querido pragmático experimentófilo, no se trata de <a href="http://curiosoperoinutil.com/2007/09/19/la-tragedia-de-la-ciencia/">otra tragedia de la ciencia</a>. Afortunadamente, la matemática es la única ciencia donde la teoría siempre coincide con la práctica. Pero en el juego de las probabilidades, y si bajo la influencia de Paenza, hubiésemos apostado a todos los partidos del último campeonato, tal vez habríamos perdido algo de plata. Faltó un solo partido más con colisión para que la ganancia esté de nuestro lado&#8230; será el próximo campeonato.</p>
<p>El porcentaje 49,74% coincide casi a la perfección con la teoría. Es simpáticamente cercano (a 0,99 puntos) al número predicho, y es mucho más alto de lo que un simple mortal intuitivista podría haber arriesgado a primera vista :-).</p>
<p><center><small>Todos los archivos están codificados en utf-8. Las fechas están en formato día/mes/año</small></center></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/futbol-y-matematica-unidos-por-cumpleanos-en-comun/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>scrabbel looser</title>
		<link>http://www.lucianobello.com.ar/post/scrabbel-looser/</link>
		<comments>http://www.lucianobello.com.ar/post/scrabbel-looser/#comments</comments>
		<pubDate>Wed, 30 Jan 2008 03:07:00 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[procrastination]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=874</guid>
		<description><![CDATA[Cuando el hecho relevante de la semana es el descubrimiento de lo pésimo que soy en el scrabbel, es porque son días sin grandes sobresaltos. click para detalles Cuando se encuentra cualquier excusa para dejar de estudiar y jugar con gnuplot, es porque son días de grandes procrastinaciones. click para detalles Cuando scrabel se escribe [...]]]></description>
			<content:encoded><![CDATA[<p>Cuando el hecho relevante de la semana es el descubrimiento de lo pésimo que soy en el <a href="http://es.wikipedia.org/wiki/Scrabble">scrabbel</a>, es porque son días sin grandes sobresaltos.<br />
<center><a href="http://www.lucianobello.com.ar/blog/scrabel.jpg"><img src='http://www.lucianobello.com.ar/blog/scrabel1.jpg' /><br />click para detalles</a></center><br />
Cuando se encuentra cualquier excusa para dejar de estudiar y jugar con <a href="http://www.gnuplot.info/">gnuplot</a>, es porque son días de grandes <a href="http://es.wikipedia.org/wiki/Procrastinaci%C3%B3n">procrastinaciones</a>.<br />
<center><a href="http://www.lucianobello.com.ar/blog/studying.jpg"><img src='http://www.lucianobello.com.ar/blog/scrabel.png' /><br />click para detalles</a></center><br />
Cuando <i>scrabel</i> se escribe con una sola <i>b</i>, es porque se trata de industria argentina.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/scrabbel-looser/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>sudoku, algorítmos genéticos, la estrategia backtracking, programación lineal y R</title>
		<link>http://www.lucianobello.com.ar/post/sudoku-algoritmos-geneticos-la-estrategia-backtracking-programacion-lineal-y-r/</link>
		<comments>http://www.lucianobello.com.ar/post/sudoku-algoritmos-geneticos-la-estrategia-backtracking-programacion-lineal-y-r/#comments</comments>
		<pubDate>Wed, 16 May 2007 20:16:00 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[academy]]></category>
		<category><![CDATA[favorites]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[procrastination]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[university]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=845</guid>
		<description><![CDATA[/* Habiendo leído El curioso incidente del perro a medianoche le tomé cierto buen gusto a los títulos largos :-) */ Hace unas semanas, Mahoo me regaló un pequeño libro con un montón de sudokus para resolver. Si bien conocía el juego, nunca me atrajo particularmente. En esos días, yo estaba buscando algún tema original [...]]]></description>
			<content:encoded><![CDATA[<p>/* Habiendo leído <a href="http://www.ociojoven.com/article/articleview/948974/"><em>El curioso incidente del perro a medianoche</em></a> le tomé cierto buen gusto a los títulos largos :-) */</p>
<p><img src="http://farm1.static.flickr.com/228/498135954_f8dd8b4b08_m.jpg" alt="" align="right" />Hace unas semanas, <a href="http://www.asciigirl.com">Mahoo</a> me regaló un pequeño libro con un montón de <a href="http://www.sudoku.com/">sudokus</a> para resolver. Si bien conocía el juego, nunca me atrajo particularmente. En esos días, yo estaba buscando algún tema original para uno de los trabajos prácticos de <em>Inteligencia Artificial</em>. La consigna se refería al uso de <a href="http://es.wikipedia.org/wiki/Algoritmo_gen%C3%A9tico">algoritmos genéticos</a> para la resolución de algún problema. Lo importante no era el programa, sino el análisis de su comportamiento: estudiando, por ejemplo, qué <a href="http://en.wikipedia.org/wiki/Crossover_%28genetic_algorithm%29">método de cruzamiento</a> se aplica mejor o qué <a href="http://en.wikipedia.org/wiki/Fitness_function">función de aptitud</a> es más representativa.</p>
<p>Viendo como Mahoo se entretenía con alguno de ellos (práctica en la que también se iniciaba) se me ocurrió que un <em>resolver de sudokus</em> podría ser una linda propuesta para mi TP.</p>
<p><a href="http://www.genetic-programming.com/">Los algoritmos genéticos</a> intentan emular a la naturaleza, a base de prueba y error, favoreciendo a las soluciones más aptas y castigando a las que no lo son tanto. Suponiendo que el <em>cruzamiento</em> de las <em>buenas-soluciones</em> generan <em>aún-mejores-soluciones</em>. Se trata de la búsqueda probabilística, muy parecida a meter muchas soluciones en un <a href="http://images.google.com/images?q=cubilete">cubilete</a> gigante y agitarlas hasta encontrar algo útil.</p>
<p>Al tratarse de un problema determinístico, la solución dista muchísimo de ser óptima. De hecho, ni siquiera se asegura que vaya a haber una solución. Pero me pareció algo simpático de intentar.</p>
<p>El resultado, escrito en mi rústico <a href="http://www.python.org/">Python</a>, puede ser bajado de <a href="http://www.lucianobello.com.ar/miSudoku.tar.gz">aquí</a> (incluye instrucciones para correrlo en Windows). No, no esperen que funcione bien, advertidos están. Es uno de los peores métodos posibles para este tipo de problemas. Sólo llega a una solución cuando la cantidad de incógnitas es (muy) limitada. Se plantean soluciones a base de llenar de random cada uno de los casilleros vacíos y chequeando cuantos valores se repiten en cada fila, columna y región. Cuando este chequeo da 0, se llega a una solución. Bastante cavernícola como notarán.</p>
<p>Es natural pensar en cuál sería la forma correcta de llegar a una solución. Recordé las clases de <em>Investigación Operativa</em> y la utilización del <a href="http://www.phpsimplex.com/pages/teoria.htm">método simplex</a> para la solución a problemas con restricciones. De hecho, es una solución que <a href="http://www.google.com/search?q=simplex+sudoku+%22Linear+Programming%22">muchos proponen</a>. No se si alguno de ustedes lo ha intentado. Yo sí, durante las clases aburridas me senté a pensar como sería el conjunto de ecuaciones y me encontré con una demencial y frustrante cantidad de ecuaciones. <a href="ftp://ftp.math.tu-berlin.de/pub/Lehre/LinOpt/WS06/Uebung18.10.06/SudokuH.pdf">Acá</a> hay una linda explicación, la que resumo, haciendo énfasis en las complicaciones:<br />
Se necesitan variables binarias de la forma x<sub>ijk</sub> donde 1 significa que el símbolo <em>k</em> (de 1 a 9) va en la celda <em>(i,j)</em> de la solución. 0 significa que no está. Esto genera un total de <em>729 variables</em> (9<sup>3</sup>) lo que, como mínimo, asusta. Veamos las ecuaciones:<br />
<img src="http://www.lucianobello.com.ar/blog/sudokuSimplex.jpg" alt="" align="center" /><br />
<strong>(1)</strong> Para que cada celda <em>(i,j)</em> tenga un símbolo y éste sea único. Se necesitan 81 ecuaciones como éstas (una por cada celda).<br />
<strong>(2)</strong> Para que en la fila <em>i</em> cada símbolo esté una vez y que en todas las columnas sea distinto. Se necesitan 81 ecuaciones como éstas(una por cada columna y cada símbolo posible).<br />
<strong>(3)</strong> Para que en la columna <em>j</em> cada símbolo esté una vez y que en todas las filas sea distinto. Se necesitan 81 ecuaciones como éstas(una por cada fila y cada símbolo posible).<br />
<strong>(4)</strong> Para que en cada región cada símbolo esté una y solo una vez. Se necesitan 81 ecuaciones como éstas (una por cada región y cada símbolo posible).<br />
<strong>(5)</strong> Representa el enunciado, es decir, el problema a resolver. Por ejemplo, x<sub>115</sub>=1 significa que en la celda (1,1) hay un 5. Dependiendo cuantos casilleros vengan asignados es la cantidad de igualdades como estas que se necesitan; típicamente, ~30.<br />
<strong>(6)</strong> Restringe las variables al conjunto binario.</p>
<p>¡En total son <strong>más de 350 ecuaciones</strong>! Hay <a href="http://www.sudoku.com/forums/viewtopic.php?p=720&amp;sid=401c15a1aac8ef33e6056a968f0c1f7a">propuestas</a> con menos ecuaciones, pero siempre serán muchísimas. Evidentemente, ésta tampoco es la solución óptima (aunque es mucho mejor que los algoritmos genéticos). Y su problema radica en que, desde algún punto de vista, el método simplex no se ajusta al problema. Gráficamente, las ecuaciones representan semiplanos en un hiperespacio multidimencional (de 9 dimensiones?) cuya intersección es, en caso que haya una única solución, un único punto. /* Puede que le esté pifiando en esta conclusión final y cualquier ratificación o rectificación es bienvenida */</p>
<p>Simplex está pensado para restricciones de máximos y mínimos donde el objetivo es maximizar o minimizar y las variables binarias intentan ampliar el método para restricciones de este tipo. Da soluciones múltiples en forma de un polígono, donde a una o más se las llama <em>óptima</em>, porque maximiza o minimiza la función objetivo. Es claro que el problema del sudoku no usa sus ventajas y abusa de sus debilidades.</p>
<p>Curiosamente, cuando comenté este problema a un <a href="http://www.opensolaris.org//viewProfile.jspa?id=11967">reciente conocido</a>, surgió que también él tuvo que hacer un trabajo práctico que resolvía sudokus. En este caso, el TP giraba entorno a la gestión de la pila para recorrer árboles. Particularmente, árboles empleados en <a href="http://es.wikipedia.org/wiki/Vuelta_Atr%C3%A1s">la estrategia de backtracking</a>. Así pues, <a href="http://www.lucianobello.com.ar/sudokuBT.tar.gz">éste</a> es su programita, sencillo, simpático y rápido. Gracias Nacho :).</p>
<p>Los métodos basados en búsqueda combinatoria sobre árboles parecen ser particularmente buenas para el problema del sudoku. En la wikipedia figuran dos interesantes formas: <a href="http://es.wikipedia.org/wiki/Sudoku_backtracking">backtracking</a> y  <a href="http://es.wikipedia.org/wiki/Sudoku_ramificaci%C3%B3n_y_poda">ramificación y poda</a>.</p>
<p>Para terminar, una última casualidad: Por razones que no vienen al caso ahora y que seguramente provocarán un nuevo post en el futuro estoy aprendiendo un lenguaje para el procesamiento de señales llamado <a href="http://www.r-project.org/">R</a>. Estoy trabajando mucho con una biblioteca llamada <em><a href="http://cran.r-project.org/src/contrib/Descriptions/sound.html">sound</a></em>. Buscándola en el repositorio de bibliotecas, me encuentro con una llamada <em><a href="http://cran.r-project.org/src/contrib/Descriptions/sudoku.html">sudoku</a></em>. No resistí la tentación de probarla :). Un ejemplo de su uso:</p>
<pre>&gt; <strong>install.packages("sudoku")</strong>
&gt; <strong># es necesario instalar tcltk si se quiere la parte gráfica</strong>
&gt; <strong>install.packages("tcltk")</strong>
&gt; <strong>library(sudoku)</strong>
&gt; <strong>library(tcltk)</strong>
&gt; <strong>library(tkrplot)</strong>
&gt; <strong>miSudoku &lt;- generateSudoku(Nblank=50, print.it=TRUE)</strong>
  +-------+-------+-------+
  |   6   |   7   |   8 2 |
  | 4 8   |     1 | 7     |
  |       | 8 2   | 5     |
  +-------+-------+-------+
  |       | 1     | 9 7   |
  |       |     2 |   5 1 |
  | 5 1 6 |   9 7 |       |
  +-------+-------+-------+
  |       |   4 8 |       |
  | 6 5   | 7   9 | 8     |
  |       |       |   9 7 |
  +-------+-------+-------+
&gt; <strong># la variable miSudoku es una matriz</strong>
&gt; <strong>miSudoku</strong>
       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
 [1,]    0    6    0    0    7    0    0    8    2
 [2,]    4    8    0    0    0    1    7    0    0
 [3,]    0    0    0    8    2    0    5    0    0
 [4,]    0    0    0    1    0    0    9    7    0
 [5,]    0    0    0    0    0    2    0    5    1
 [6,]    5    1    6    0    9    7    0    0    0
 [7,]    0    0    0    0    4    8    0    0    0
 [8,]    6    5    0    7    0    9    8    0    0
 [9,]    0    0    0    0    0    0    0    9    7
&gt; <strong>#La biblioteca incluye una función para para solucionarlo</strong>
&gt; <strong>solveSudoku(miSudoku)</strong>
       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
 [1,]    1    6    5    9    7    3    4    8    2
 [2,]    4    8    2    5    6    1    7    3    9
 [3,]    3    7    9    8    2    4    5    1    6
 [4,]    2    4    8    1    5    6    9    7    3
 [5,]    7    9    3    4    8    2    6    5    1
 [6,]    5    1    6    3    9    7    2    4    8
 [7,]    9    3    7    2    4    8    1    6    5
 [8,]    6    5    1    7    3    9    8    2    4
 [9,]    8    2    4    6    1    5    3    9    7
&gt; <strong># Incluso trae soporte gráfico para resolverlo en una ventanita :)</strong>
&gt; <strong>playSudoku()</strong></pre>
<p>Así fue como, un simple regalo, un TP universitario y un montón de simpáticas casualidades tuvieron su punto de conexión. Y que divertido que resultó ser :). Ahora tengo que escribir el informe sobre los algoritmos genéticos en el sudoku. La semana que viene espero publicarlo <a href="http://www.lucianobello.com.ar/sudoku/">aquí</a>.</p>
<p><strong>UPDATE August 6th</strong>: El informe y los archivos relacionados <a href="http://www.lucianobello.com.ar/sudoku/">ya está publicados</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/sudoku-algoritmos-geneticos-la-estrategia-backtracking-programacion-lineal-y-r/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>mathematical beauty</title>
		<link>http://www.lucianobello.com.ar/post/mathematical-beauty/</link>
		<comments>http://www.lucianobello.com.ar/post/mathematical-beauty/#comments</comments>
		<pubDate>Mon, 06 Nov 2006 18:30:00 +0000</pubDate>
		<dc:creator>luciano</dc:creator>
				<category><![CDATA[books & reading]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[procrastination]]></category>

		<guid isPermaLink="false">http://www.lucianobello.com.ar/?p=828</guid>
		<description><![CDATA[Dado que esta semana tengo varios exámenes y que mi procrastinación me impidió estudiar, dediqué el fin de semana a la lectura. Leí La Matematica como una de las Bellas Artes de Pablo Amster. Un libro entretenido, corto e interesante, que por momentos peca de subestimar al lector cuando no profundiza en algunos temas por [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.tematika.com/articulo/detalleArticulo.jsp?idArticulo=395444"><img src="http://www.sigloxxieditores.com.mx/images/987-1105-91-4.jpg" alt="" align="left" /></a>Dado que esta semana tengo varios exámenes y que mi <a href="http://es.wikipedia.org/wiki/Procrastinaci%C3%B3n">procrastinación</a> me impidió estudiar, dediqué el fin de semana a la lectura.</p>
<p>Leí <em><a href="http://www.tematika.com/articulo/detalleArticulo.jsp?idArticulo=395444">La Matematica como una de las Bellas Artes</a></em> de <em>Pablo Amster</em>. Un libro entretenido, corto e interesante, que por momentos peca de subestimar al lector cuando no profundiza en algunos temas por tratarse &#8220;de cosas demasiado complejas&#8221;. Si bien se trata de un texto de divulgación (aka. &#8220;estimular al lector antes que espantarlo&#8221; (sic)) en algunos de sus párrafos los fundamentos y explicaciones tienen sabor a poco.</p>
<p>Si sos de esas personas que, como yo, describen al <a href="http://garciacapitan.auna.com/bella/htm/nueve.htm">Círculo de Euler</a> como <em>algo simpático</em>, este libro puede interesarte. Mucha anécdota, mucha rareza y mucha clasificación filosófica. Cientoveintitantas páginas bastante entretenidas que invitan a pensar sobre lo lindo de la matemática y la belleza de los teoremas.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucianobello.com.ar/post/mathematical-beauty/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

