<?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>Hyperreals *R</title>
	<atom:link href="http://ch3m4.org/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://ch3m4.org/blog</link>
	<description>quarks, bits y otras criaturas infinitesimales</description>
	<lastBuildDate>Tue, 07 Feb 2012 13:22:47 +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>Estudio función factorial en scala &#8211; Revisión funcional</title>
		<link>http://ch3m4.org/blog/2012/02/07/estudio-funcion-factorial-en-scala-revision-funcional/</link>
		<comments>http://ch3m4.org/blog/2012/02/07/estudio-funcion-factorial-en-scala-revision-funcional/#comments</comments>
		<pubDate>Tue, 07 Feb 2012 12:41:32 +0000</pubDate>
		<dc:creator>Chema Cortés</dc:creator>
				<category><![CDATA[Scala]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[factorial]]></category>

		<guid isPermaLink="false">http://ch3m4.org/blog/?p=382</guid>
		<description><![CDATA[Como programador de python que todavía anda algo despistado estudiando scala, ahora empiezo a captar la filosófía que hay detrás de este lenguaje de programación. Mientras que python empienza a erradicar poco a poco la programación funcional, en scala su influencia es cada vez mayor hasta el extremo de considerar precindibles la mayoría de los <a href='http://ch3m4.org/blog/2012/02/07/estudio-funcion-factorial-en-scala-revision-funcional/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Como programador de python que todavía anda algo despistado estudiando scala, ahora empiezo a captar la filosófía que hay detrás de este lenguaje de programación. Mientras que python empienza a erradicar poco a poco la programación funcional, en scala su influencia es cada vez mayor hasta el extremo de considerar precindibles la mayoría de los bucles. Aún asi, ambos lenguajes soportan la <em>&#8220;compresión de listas&#8221;</em> como técnica a medio camino entre funcional y bucle estándar, aunque esta técnica está más orientada a obtener listas a partir de otras listas, y no para realizar cálculos sobre un conjunto de números.</p>

<p>Voy a completar el anterior artículo que trataba del <a href="http://ch3m4.org/blog/2011/10/17/estudio-funcion-factorial-en-scala/">&#8220;Estudio función factorial en scala&#8221;</a> con algunas formas más <em>&#8220;funcionales&#8221;</em> de definir el factorial:</p>

<p>La forma más simple de definir la función factorial:</p>

<div class="codecolorer-container scala default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> fact<span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span>Int<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #F78811;">&#40;</span><span style="color: #F78811;">1</span> to n<span style="color: #F78811;">&#41;</span>.<span style="color: #000000;">product</span></div></div>

<p>En realidad, <code>1 to n</code> no es un elemento sintáctico del lenguaje, si no más bien la forma <em>alternativa</em> de escribir la invocación del método <code>1.to(n)</code>. Este método nos genera una secuencia de números desde el 1 al n (equivalente en python a range(1,n+1)).</p>

<p>Curiosamente, también está definido <code>fact(0)</code> gracias a que <code>product</code> da como resultado el elemento neutro <code>1</code> en secuencias vacías <sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>.</p>

<p>Esta forma concisa de calcular el producto es común a todas las secuencias en scala. Faltaría, tan sólo, que operara con BigInts para que fuera perfecta:</p>

<div class="codecolorer-container scala default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> fact<span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span>Int<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #F78811;">&#40;</span>BigInt<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">1</span><span style="color: #F78811;">&#41;</span> to n<span style="color: #F78811;">&#41;</span>.<span style="color: #000000;">product</span></div></div>

<p>No es necesario indicar el tipo devuelto por la función puesto que el compilador es capaz de inferirlo de la expresión.</p>

<p>Otra forma funcional sería usando el método <code>reduce</code>, donde se indica <em>explícitamente</em> la operación binaria a realizar entre pares de elementos:</p>

<div class="codecolorer-container scala default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> fact<span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span>Int<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #F78811;">&#40;</span>BigInt<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">1</span><span style="color: #F78811;">&#41;</span> to n<span style="color: #F78811;">&#41;</span>.<span style="color: #000000;">reduce</span><span style="color: #F78811;">&#40;</span><span style="color: #000080;">_*_</span><span style="color: #F78811;">&#41;</span></div></div>

<p>Como operación se pone una especie de <em>plantilla</em> (<em>pattern</em>) que representa la operación binaria de multiplicación. Por comparar, en python se puede hacer algo así:</p>

<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">operator</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #0000cd;">__mul__</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> fact<span style="color: black;">&#40;</span>n<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp;<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">reduce</span><span style="color: black;">&#40;</span><span style="color: #0000cd;">__mul__</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">xrange</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span>n+<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></div></div>

<p>Lamentablemente, el operador funcional <code>'reduce'</code> está desapareciendo de python por considerarlo complejo de entender en su funcionamiento <sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup>.</p>

<p>Por último, aún existe otra forma funcional de expresar el factorial en scala. Son los <em>&#8220;plegados&#8221;</em> (<em>folds</em>), similar en funcionamiento a <code>reduce</code>, pero con control sobre la dirección del recorrido y la posibilidad de dar un valor inicial:</p>

<div class="codecolorer-container scala default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> fact<span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span>Int<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #F78811;">&#40;</span><span style="color: #F78811;">1</span> to n<span style="color: #F78811;">&#41;</span>.<span style="color: #000000;">foldLeft</span><span style="color: #F78811;">&#40;</span>BigInt<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">1</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#40;</span><span style="color: #000080;">_*_</span><span style="color: #F78811;">&#41;</span></div></div>

<p>Seguro que pronto se me ocurrirán más formas.</p>

<div class="footnotes">
<hr />
<ol>

<li id="fn:1">
<p>En el caso del método <code>sum</code> daría el elemento neutro para la suma, o sea, el <code>0</code>.&#160;<a href="#fnref:1" rev="footnote">&#8617;</a></p>
</li>

<li id="fn:2">
<p>Personalmente, considero que la desaparición de la programación funcional se debe más a la corta visión de quién sólo ve un encadenamiento de sentencias, en lugar de ver <em>&#8220;actores&#8221;</em> interaccionando en libre concurrencia.&#160;<a href="#fnref:2" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://ch3m4.org/blog/2012/02/07/estudio-funcion-factorial-en-scala-revision-funcional/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Codificando en binario</title>
		<link>http://ch3m4.org/blog/2012/01/26/condificando-en-binario/</link>
		<comments>http://ch3m4.org/blog/2012/01/26/condificando-en-binario/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 19:24:23 +0000</pubDate>
		<dc:creator>Chema Cortés</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[tip]]></category>
		<category><![CDATA[unicode]]></category>

		<guid isPermaLink="false">http://ch3m4.org/blog/?p=375</guid>
		<description><![CDATA[A raiz de la consulta de un colega, me ha llamado la atención el módulo binascii. Este módulo se encarga de la codificación y decodificación de cadenas binarias para su transmisión en mensajes de texto. Lo habitual es que sea usado por otros módulos como uu, base64 o binhex, por lo que no es nada <a href='http://ch3m4.org/blog/2012/01/26/condificando-en-binario/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>A raiz de la consulta de un colega, me ha llamado la atención el módulo <code>binascii</code>. Este módulo se encarga de la codificación y decodificación de cadenas binarias para su transmisión en mensajes de texto. Lo habitual es que sea usado por otros módulos como <code>uu</code>, <code>base64</code> o <code>binhex</code>, por lo que no es nada frecuente ver su uso directo en una aplicación.</p>

<p>Sin embargo, <code>binascii</code> posee algunas funciones que pueden sernos bastante útiles a la hora de simplificar el empaquetado de datos que requieren determinadas APIs, en lugar de usar estructuras más complejas como <code>array</code> o <code>struct</code>. También se revela muy útil a la hora de crear batería de tests donde necesitemos chequear valores binarios.</p>

<h2>Estructuras array y struct</h2>

<p>Por ejemplo, imaginemos que nuestra API nos pide que empaquetemos un número entero como cuatro bytes. Antes de python3 no existía una forma para controlar el tamaño en bytes de un objeto sin tener que recurrir a alguna estructura especializada. Por ejemplo:</p>

<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">array</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">array</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> numpack<span style="color: black;">&#40;</span>num<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; a<span style="color: #66cc66;">=</span><span style="color: #dc143c;">array</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'L'</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; a.<span style="color: black;">append</span><span style="color: black;">&#40;</span>num<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> a.<span style="color: black;">tostring</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>::-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><br />
<br />
n<span style="color: #66cc66;">=</span>numpack<span style="color: black;">&#40;</span><span style="color: #ff4500;">0xffeeddcc</span><span style="color: black;">&#41;</span> &nbsp;<span style="color: #808080; font-style: italic;"># res: \xff\xee\xdd\xcc</span></div></div>

<p>En el resultado final ha hecho falta invertir el orden de los bytes debido a que nos estaba usando un orden <em>&#8220;little-endian&#8221;</em> para su codificación. El orden puede depender del sistema donde estemos trabajando, con lo que no es nada seguro usar este método. Es preferible el uso más especializado de <code>struct</code> donde tendremos algo más de control sobre éste y muchos otros aspectos:</p>

<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">struct</span> <span style="color: #ff7700;font-weight:bold;">import</span> pack<br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> numpack<span style="color: black;">&#40;</span>num<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> pack<span style="color: black;">&#40;</span><span style="color: #483d8b;">'!L'</span><span style="color: #66cc66;">,</span> num<span style="color: black;">&#41;</span><br />
<br />
n<span style="color: #66cc66;">=</span>numpack<span style="color: black;">&#40;</span><span style="color: #ff4500;">0xffeeddcc</span><span style="color: black;">&#41;</span> &nbsp;<span style="color: #808080; font-style: italic;"># res: \xff\xee\xdd\xcc</span></div></div>

<p>Nota que en la cadena de formato que se pasa a <code>pack()</code> tiene un indicador <code>'!'</code> al principio, con el que indicamos que queremos una ordenación <em>&#8220;network (=big-endian)&#8221;</em>.</p>

<p>El proceso inverso es tan fácil como usar la función complementaria <code>unpack</code>:</p>

<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">unpack<span style="color: black;">&#40;</span><span style="color: #483d8b;">'!L'</span><span style="color: #66cc66;">,</span> n<span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span></div></div>

<h2>Codificando mensajes</h2>

<p>Lo visto hasta ahora funciona bien cuando tenemos que interaccionar con una API que use tamaños fijos para los datos. Pero, ¿qué pasa cuando los datos son de longitud variable, por ejemplo, un mensaje largo de decenas de bytes? En el mejor de los casos, tendríamos que ir byte a byte, tal vez apoyándonos en <code>array</code> o <code>struct</code> para realizar las conversiones, algo a todas luces resulta bastante tedioso.</p>

<p>Como ya adelanté, el módulo <code>binascii</code> nos va a ayudar en este cometido, en concreto la función <code>b2a_hex</code> y su contraparte <code>a2b_hex</code>.</p>

<p>Por ejemplo, nos envían en un mensaje un entero codificado en multibyte. No sabemos si son 2, 4 u 8 bytes, o incluso podrían ser más bytes de tratarse de un <code>BigInt</code> (entero muy largo). Con <code>binascii</code> podríamos resolverlo así:</p>

<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">binascii</span> <span style="color: #ff7700;font-weight:bold;">import</span> b2a_hex<span style="color: #66cc66;">,</span> a2b_hex<br />
<br />
num <span style="color: #66cc66;">=</span> <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>b2a_hex<span style="color: black;">&#40;</span>msg<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span></div></div>

<p>Para el proceso contrario, codificar un entero en una cadena binaria, usaríamos <code>a2b_hex</code>:</p>

<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">h <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;%x&quot;</span>%num<br />
<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>h<span style="color: black;">&#41;</span>%<span style="color: #ff4500;">2</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">1</span>:<br />
&nbsp; &nbsp; h <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;0&quot;</span> + h<br />
<br />
msg <span style="color: #66cc66;">=</span> a2b_hex<span style="color: black;">&#40;</span>h<span style="color: black;">&#41;</span></div></div>

<p>Hemos tenido cuidado de que la cadena hexadecimal tenga longitud par ya que <code>a2b_hex</code> codifica siempre cada byte a partir de una pareja de dígitos hexadecimales.</p>

<h2>Estudio codificaciones unicode</h2>

<p>También es posible usar <code>binascii</code> para estudiar las codificaciones de cadenas unicode, lo que hace más sencillo crear tests automáticos para funciones que empleen unicode. Sin muchos adornos, haríamos algo así:</p>

<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">#-*- coding: utf-8 -*-</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">binascii</span> <span style="color: #ff7700;font-weight:bold;">import</span> b2a_hex<span style="color: #66cc66;">,</span> a2b_hex<br />
<br />
cadena <span style="color: #66cc66;">=</span> u<span style="color: #483d8b;">&quot;Peón <span style="color: #000099; font-weight: bold;">\N</span>{BLACK CHESS PAWN}&quot;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">print</span> b2a_hex<span style="color: black;">&#40;</span>cadena.<span style="color: black;">encode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'utf-8'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;">#res: 5065c3b36e20e2999f</span></div></div>

<p>Comparando el resultado obtenido con la cadena unicode, vemos que la <em>ó</em> acentuada se codifica en &#8216;utf-8&#8242; como <code>0xc3b3</code>, o que la figura de peón negro se codifica como <code>0xe2999f</code>.</p>

<p>Si cambiamos la codificación por &#8216;utf-16&#8242; obtenermos como resultado <code>fffe50006500f3006e0020005f26</code>. Además de ser más larga, vemos que se añade al principio <code>fffe</code>, que es lo que se denomina <abbr title="Byte Order Mark">BOM</abbr>, y que nos indica qué ordenación de bytes se ha usado en la codificación (<code>'FEFF'</code> para <em>Big Endian</em> / <code>'FFFE'</code> para <em>Little Endian</em>). Con <code>fffe</code> nos indica concretamente que se ha usado la codificación &#8216;UTF-16 Little Endian&#8217;, con lo que tenemos los bytes invertidos para cada caracter codificado (ver más info en el <a href="http://es.wikipedia.org/wiki/Marca_de_orden_de_bytes_(BOM)">artículo sobre <abbr title="Byte Order Mark">BOM</abbr></a> de la wikipedia).</p>

<p>De no desear que se nos añada la marca <abbr title="Byte Order Mark">BOM</abbr>, podríamos haber forzado la codificación mediante <code>'utf-16be'</code> ó <code>'utf-16le'</code> para <em>Big Endian</em> y <em>Little Endian</em>, respectivamente.</p>
]]></content:encoded>
			<wfw:commentRss>http://ch3m4.org/blog/2012/01/26/condificando-en-binario/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>web2py, con pilas incluidas</title>
		<link>http://ch3m4.org/blog/2011/12/01/web2py-con-pilas-incluidas/</link>
		<comments>http://ch3m4.org/blog/2011/12/01/web2py-con-pilas-incluidas/#comments</comments>
		<pubDate>Thu, 01 Dec 2011 18:34:12 +0000</pubDate>
		<dc:creator>Chema Cortés</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[web2py]]></category>
		<category><![CDATA[webdev]]></category>

		<guid isPermaLink="false">http://ch3m4.org/blog/2011/12/01/web2py-con-pilas-incluidas/</guid>
		<description><![CDATA[He estado últimamente trabajando en varios proyectos que me han hecho descuidar un poco el blog. En próximos días espero publicar algunos artículos relacionados que creo serán de interés. Lo último que estoy haciendo es un desarrollo de aplicación de escritorio con web2py, a pesar de tratarse de un framework para crear aplicaciones web. Corre <a href='http://ch3m4.org/blog/2011/12/01/web2py-con-pilas-incluidas/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>He estado últimamente trabajando en varios proyectos que me han hecho descuidar un poco el blog. En próximos días espero publicar algunos artículos relacionados que creo serán de interés.</p>

<p>Lo último que estoy haciendo es un desarrollo de aplicación de escritorio con <a href="http://www.web2py.com">web2py</a>, a pesar de tratarse de un framework para crear aplicaciones web. Corre desde un navegador cualquiera, interaccionando con [jQuery] para la presentación, y con python corriendo por debajo para dar soporte a la capas de datos y lógica de negocio.</p>

<h2>¿Por qué web2py?</h2>

<p>Como indico en el título, web2py lleva las <em>&#8220;pilas incluidas&#8221;</em>, que tratándose de python significa que incluye todo lo puedas necesitar. ¡Y no exagero! La selección de <a href="http://www.web2py.com/book/default/chapter/04#Libraries">librerías</a> que incluye es extensa, permitiendo desarrollar casi cualquier aplicación web que necesites, con herramientas administrativas tanto para el modelo de datos como para editar los ficheros vistas y controladores. Vamos, que con descomprimir el fichero con web2py y un navegador ya tienes todo lo necesario para desarrollar la aplicación, desde una simple aplicación estática, hasta una completa aplicación que funcione en el Google AppEngine. Además posee un sistema de plugins que permite cambiar fácilmente el diseño de la web o añadir funcionalidades.</p>

<p>Hasta ahora, había probado algunos GUIs graficos como pyqt o wxpython que incluyeran algún <em>widget</em> html para renderizar páginas webs y poder controlarlas desde el programa python, algo bastante costoso de programar y con serias incompatibilidades a la hora de presentar la página web. Con web2py, la aplicación de escritorio se orienta a una aplicación web con el servidor web corriendo directamente en el cliente. Web2py permite abstraer algunas facilidades ajax y jquery habituales, aunque no resulta difícil usar el resto de funcionalidades de jquery en las aplicaciones sin tener que ser un experto en programación javascript.</p>

<p>Uno de los problemas que también había tenido hasta ahora era en la distribución de aplicaciones python para windows. Habitualmente, hace falta instalar varias herramientas en el sistema, desde el intérprete python hasta todas las librerías necesarias, algunas complicadas de hacerlas funcionar. Bien es cierto que existen formas de empaquetar una aplicación usando py2exe (py2app en MacOS), pero casi siempre hay alguna cosa que no funciona bien del todo. Web2py viene con todo empaquetado para su uso en windows y macOS, incluyendo el intérprete python y resto de librerías necesarias. Basta descomprimir el fichero y, sin intalación, ejecutar el servidor web y abrir un navegador. Las aplicaciones web son carpetas que podemos copiar de una instalación a otra o, aún más sencillo, usar el interface administrativo para empaquetar e instalar aplicaciones (al estilo <em>tomcat</em>).</p>

<p>Échale un vistazo, y no te dejes las <a href="http://www.web2py.com/book/default/chapter/04#Libraries">&#8220;pilas&#8221;</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://ch3m4.org/blog/2011/12/01/web2py-con-pilas-incluidas/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Estudio función factorial en scala</title>
		<link>http://ch3m4.org/blog/2011/10/17/estudio-funcion-factorial-en-scala/</link>
		<comments>http://ch3m4.org/blog/2011/10/17/estudio-funcion-factorial-en-scala/#comments</comments>
		<pubDate>Mon, 17 Oct 2011 19:49:15 +0000</pubDate>
		<dc:creator>Chema Cortés</dc:creator>
				<category><![CDATA[Scala]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[factorial]]></category>

		<guid isPermaLink="false">http://ch3m4.org/blog/?p=356</guid>
		<description><![CDATA[Como continuación al artículo que dediqué al estudio del factorial, voy a explicar cómo se haría este famoso algoritmo usando scala. Tengo que añadir que tan sólo llevo una semana con el lenguaje scala, por lo que es muy probable que haya algún aspecto de este lenguaje que me haya dejado por el camino. Versión <a href='http://ch3m4.org/blog/2011/10/17/estudio-funcion-factorial-en-scala/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Como continuación al artículo que dediqué al <a href="http://ch3m4.org/blog/2011/06/06/estudio-funcion-factorial/">estudio del factorial</a>, voy a explicar cómo se haría este famoso algoritmo usando <a href="http://scala-lang.org" title="Scala programming language">scala</a>. Tengo que añadir que tan sólo llevo una semana con el lenguaje scala, por lo que es muy probable que haya algún aspecto de este lenguaje que me haya dejado por el camino.</p>

<h2>Versión recursiva (y <em>one-line</em>)</h2>

<p>La forma básica de la función sería:</p>

<div class="codecolorer-container scala default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> fact<span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span>Int<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span>BigInt <span style="color: #000080;">=</span><br />
&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">if</span></a> <span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">==</span><span style="color: #F78811;">0</span><span style="color: #F78811;">&#41;</span> <span style="color: #F78811;">1</span><br />
&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">else</span></a> n<span style="color: #000080;">*</span>fact<span style="color: #F78811;">&#40;</span>n-<span style="color: #F78811;">1</span><span style="color: #F78811;">&#41;</span></div></div>

<p>Si se compara con la función recursiva en python, no parece que haya mucha diferencia, con excepción de que en scala existe el tipado de datos.</p>

<p>Esta función es en realidad una sóla línea, por lo que podíamos haberla escrito de esta manera:</p>

<div class="codecolorer-container scala default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> fact<span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span>Int<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span>BigInt <span style="color: #000080;">=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">if</span></a> <span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">==</span><span style="color: #F78811;">0</span><span style="color: #F78811;">&#41;</span> <span style="color: #F78811;">1</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">else</span></a> n<span style="color: #000080;">*</span>fact<span style="color: #F78811;">&#40;</span>n-<span style="color: #F78811;">1</span><span style="color: #F78811;">&#41;</span></div></div>

<p>Es una clara señal de la orientación funcional que tiene scala.</p>

<p>Al igual que python, esta función recursiva se corta cuando se sobrepasa un cierto límite de llamadas recursivas para proteger la memoria del sistema.</p>

<p>El compilador de Scala posee una optimización especial denominda de <em>&#8220;LLamada Terminal&#8221;</em> (<a href="http://en.wikipedia.org/wiki/Tail_call" title="Tail Call">Tail Call</a>)<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> (optimización que no existe en JVM). Este tipo de optimizaciones son posibles cuando la última línea a ejecutar de la función es únicamente la llamada recursiva a sí misma, con lo cuál hace innecesario guardar el stack de ejecución puesto que no quedarían más líneas para ejecutar.</p>

<p>Para que sea posible aplicar esta optimización de &#8220;llamada terminal&#8221;, tenemos que reescribir nuestra función de modo que la última línea sea una llamada a sí misma. Para ello usaremos una función acumuladora que se encargue de realizar la multiplicación previamente a la llamada. Casi mejor si vemos el código:</p>

<div class="codecolorer-container scala default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> fact<span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span>Int<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span>BigInt <span style="color: #000080;">=</span> <span style="color: #F78811;">&#123;</span><br />
&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> factAcc<span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span>Int, acc<span style="color: #000080;">:</span>BigInt<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span>BigInt <span style="color: #000080;">=</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">if</span></a> <span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">&lt;=</span><span style="color: #F78811;">1</span><span style="color: #F78811;">&#41;</span> acc <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">else</span></a> factAcc<span style="color: #F78811;">&#40;</span>n-<span style="color: #F78811;">1</span>, n<span style="color: #000080;">*</span>acc<span style="color: #F78811;">&#41;</span><br />
<br />
&nbsp; &nbsp; factAcc<span style="color: #F78811;">&#40;</span>n,<span style="color: #F78811;">1</span><span style="color: #F78811;">&#41;</span><br />
<span style="color: #F78811;">&#125;</span></div></div>

<p>En las últimas versiones de scala existe una <em>&#8220;anotación&#8221;</em> especial para indicar al compilador de scala que intente aplicar la optimización de &#8220;LLamada Terminal&#8221;, o que nos dé un aviso de no poder hacerlo. Finalmente, así quedaría el código de nuestra función recursiva:</p>

<div class="codecolorer-container scala default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">import</span></a> scala.<span style="color: #000000;">annotation</span>.<span style="color: #000000;">tailrec</span><br />
<br />
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> fact<span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span>Int<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span>BigInt <span style="color: #000080;">=</span> <span style="color: #F78811;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000080;">@</span>tailrec<br />
&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> factAcc<span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span>Int, acc<span style="color: #000080;">:</span>BigInt<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span>BigInt<span style="color: #000080;">=</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">if</span></a> <span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">&lt;=</span><span style="color: #F78811;">1</span><span style="color: #F78811;">&#41;</span> acc <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">else</span></a> factAcc<span style="color: #F78811;">&#40;</span>n-<span style="color: #F78811;">1</span>, n<span style="color: #000080;">*</span>acc<span style="color: #F78811;">&#41;</span><br />
<br />
&nbsp; &nbsp; factAcc<span style="color: #F78811;">&#40;</span>n,<span style="color: #F78811;">1</span><span style="color: #F78811;">&#41;</span><br />
<span style="color: #F78811;">&#125;</span></div></div>

<h2>Versión iterativa</h2>

<p>Es la versión más sencilla:</p>

<div class="codecolorer-container scala default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> fact<span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span>Int<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span>BigInt <span style="color: #000080;">=</span> <span style="color: #F78811;">&#123;</span><br />
&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">var</span></a> res<span style="color: #000080;">=</span>BigInt<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">1</span><span style="color: #F78811;">&#41;</span><br />
&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">for</span></a> <span style="color: #F78811;">&#40;</span>i <span style="color: #000080;">&lt;</span>- <span style="color: #F78811;">1</span> to n<span style="color: #F78811;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; res<span style="color: #000080;">*=</span>i<br />
&nbsp; &nbsp; res<br />
<span style="color: #F78811;">&#125;</span></div></div>

<h2>Fórmula de Stirling</h2>

<p>Para completar el estudio, podemos ver cómo sería la función de Stiling en Scala, bastante similar, como puede verse, a su versión en python:</p>

<div class="codecolorer-container scala default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">import</span></a> math.<span style="color: #000080;">_</span><br />
<br />
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> fact<span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span>Int<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span>Double <span style="color: #000080;">=</span><br />
&nbsp; &nbsp; sqrt<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">2</span><span style="color: #000080;">*</span>Pi<span style="color: #000080;">*</span>n<span style="color: #F78811;">&#41;</span><span style="color: #000080;">*</span>pow<span style="color: #F78811;">&#40;</span>n/E,n<span style="color: #F78811;">&#41;</span></div></div>

<div class="footnotes">
<hr />
<ol>

<li id="fn:1">
<p>Existe algún intento para implementar esta optimización de &#8220;Tail Call&#8221; en python, con algunos decoradores más o menos funcionales. Si quieres ver motivos en contra, visita el artículo que escribió Guido sobre el tema: <a href="http://neopythonic.blogspot.com/2009/04/tail-recursion-elimination.html">http://neopythonic.blogspot.com/2009/04/tail-recursion-elimination.html</a>&#160;<a href="#fnref:1" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://ch3m4.org/blog/2011/10/17/estudio-funcion-factorial-en-scala/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Rentrée (nueva temporada)</title>
		<link>http://ch3m4.org/blog/2011/10/08/rentree-nueva-temporada/</link>
		<comments>http://ch3m4.org/blog/2011/10/08/rentree-nueva-temporada/#comments</comments>
		<pubDate>Sat, 08 Oct 2011 17:22:33 +0000</pubDate>
		<dc:creator>Chema Cortés</dc:creator>
				<category><![CDATA[Pensamientos]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jvm]]></category>
		<category><![CDATA[pyday]]></category>
		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://ch3m4.org/blog/2011/10/08/rentree-nueva-temporada/</guid>
		<description><![CDATA[Desconectado de mis tareas habituales depués de algunas semanas viajando por Francia, veo que me quedaron varios proyectos y artículos en dique seco que pretendo recuperar. Con la &#8220;reentrada&#8221; (o, como dirían los franceses, &#8220;rentrée&#8221;) me he propuesto algunas metas para esta nueva temporada (por llamarla de algún modo) que ahora empiezo. Junto a los <a href='http://ch3m4.org/blog/2011/10/08/rentree-nueva-temporada/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Desconectado de mis tareas habituales depués de algunas semanas viajando por Francia, veo que me quedaron varios proyectos y artículos en dique seco que pretendo recuperar. Con la <em>&#8220;reentrada&#8221;</em> (o, como dirían los franceses, <em>&#8220;rentrée&#8221;</em>) me he propuesto algunas metas para esta nueva <em>temporada</em> (por llamarla de algún modo) que ahora empiezo.</p>

<p>Junto a los artículos que tengo previstos, intentaré incorporar al blog más comentarios sobre temas técnicos que me vayan surgiendo en el día a día, preferiblemente relacionados con la programación. Sin llegar a la extensión de un artículo, espero que sirvan como gérmen de desarrollos posteriores más extensos.</p>

<p>Como primeras ideas para esta <em>rentrée</em>, he tomados dos decisiones: centrar mis desarrollos en la <a href="http://es.wikipedia.org/wiki/Máquina_virtual_Java">máquina virtual java</a> (plataforma <abbr title="Java Virtual Machine">JVM</abbr>) y aprender a programar con <a href="http://www.scala-lang.org/" title="Lenguaje Scala">scala</a>.</p>

<h2>Máquina Virtual Java (<abbr title="Java Virtual Machine">JVM</abbr>)</h2>

<p>Hoy en día, la <abbr title="Java Virtual Machine">JVM</abbr> está omnipresente para casi cualquier dispositivo y sistema operativo. Su uso empresarial es muy extendido, tanto para desarrollo en el lado servidor como para clientes móviles. Librerías y paquetes suficientemente robustos y probados completan una gran plataforma donde desarrollar cualquier tipo de aplicativo que podamos pensar.</p>

<p>Al evaluar la robustez de las librerías java, hay que tener en cuenta que java y su <abbr title="Java Virtual Machine">JVM</abbr> están en constante evolución. El paso de Java5 a Java6 sido muy lento debido a las pocas ventajas que ofrecía el cambio frente al coste de tener que adaptar el código; pero con Java7 se incorpora a la máquina virtual el poder trabajar con tipos dinámicos de datos, lo que mejorará bastante el rendimiento de los lenguajes de scripting como jython, jruby ó groovy, por poner algunos ejemplos. Este cambio parece independizar el desarrollo de la <abbr title="Java Virtual Machine">JVM</abbr> del lenguaje java para pasar a ser una plataforma común para la ejecución de aplicaciones, sea cual sea el lenguaje que se haya usado (objetivo similar a lo que tenía que haber sido .Net).</p>

<p>En lo personal, desde hace mucho tiempo que estoy programando en jython, tal como comenté en otro <a href="http://ch3m4.org/blog/2011/05/30/porque-uso-jython/">artículo</a>. La llegada de los dispositivos android hace aún más interesante la programación para <abbr title="Java Virtual Machine">JVM</abbr>, así como que las numerosas herramientas de software libre que estoy usando estén para esta plataforma. No quiero decir con ésto que renuncie a utilizar la CPython, la máquina virtual <em>&#8220;nativa&#8221;</em> que lleva python, siempre que sea necesario. Tan sólo priorizo la plataforma, <abbr title="Java Virtual Machine">JVM</abbr>, frente a las últimas implementaciones del lenguaje python. Espero que el proyecto <a href="http://pypy.org/">PyPy</a> facilite un único camino para el desarrollo del lenguaje, independiente de la máquina virtual empleada.</p>

<h2>Lenguaje Scala</h2>

<p>Poco conozco de este lenguaje, la verdad. En el índice [tiobe] de septiembre de 2011 figura en la posición 50, la última posición que entra en valoración. Pero los comentarios que he leído sobre este lenguaje me han picado tanto la curiosidad que he decidido darle un vistazo. Si quieres un consejo: no te limites a un sólo lenguaje de programación. Sólo comparando con otros lenguajes descubrirás las virtudes y limitaciones de los lenguajes que uses. Sobre todo, intenta aprender algún lenguaje <em>&#8220;exótico&#8221;</em>, si por exótico se entiende aquél que no se ve en los estudios oficiales de informática. Siempre que te pidan mostrar tus conocimientos de programador, saber programar en un lenguaje &#8220;exótico&#8221; será visto como que te entusiasma la programación y que tienes capacidad para aprender cosas nuevas por tu cuenta (Python sigue siendo un excelente ejemplo de lenguaje para estas demostraciones).</p>

<p>Algunas características interesantes de Scala:</p>

<ul>
<li>Lenguaje funcional orientado a objeto similar a java, pero superando a éste en simplicidad. Incorpora clausuras y tipado perezoso de datos.</li>
<li>Escalable (como indica su nombre: <strong>sca</strong>lable <strong>la</strong>nguage)</li>
<li>Emplea la <abbr title="Java Virtual Machine">JVM</abbr>, aunque también hay versión para .Net. Puede usarse en cualquier sitio que se use java como, por ejemplo, para programación en android.</li>
<li>Preparado para la programación concurrente. Sigue el modelo &#8220;Actor&#8221;, o lo que es lo mismo, todos los objetos son &#8220;actores&#8221; con su propio entorno de ejecución.</li>
</ul>

<h2>Asociacionismo en torno a python</h2>

<p>Tangencialmente, he empezado a meterme en la organización de un evento relacionado con python. Creo importante que todos retomemos los contactos personales e intentar hacer reflotar las ilusiones perdidas por esta crisis que estamos viviendo. Si todo va bien, espero vernos en el <a href="http://python-hispano.org/DiaPythonZGZ">Día Python 2011</a> en Zaragoza dentro de la LSWC&#8217;11.</p>
]]></content:encoded>
			<wfw:commentRss>http://ch3m4.org/blog/2011/10/08/rentree-nueva-temporada/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Bitbucket soporta también git</title>
		<link>http://ch3m4.org/blog/2011/10/04/bitbucket-soporta-tambien-git/</link>
		<comments>http://ch3m4.org/blog/2011/10/04/bitbucket-soporta-tambien-git/#comments</comments>
		<pubDate>Tue, 04 Oct 2011 01:38:08 +0000</pubDate>
		<dc:creator>Chema Cortés</dc:creator>
				<category><![CDATA[Novedad]]></category>
		<category><![CDATA[bitbucket]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[mercurial]]></category>

		<guid isPermaLink="false">http://ch3m4.org/blog/?p=345</guid>
		<description><![CDATA[Relacionado con el anterior artículo en el que contaba cómo usar mercurial para acceder a repositorios git, la noticia de hoy es que bitbucket soporta también git (además de mercurial). Unido a las herramientas para importar cualquier proyecto de github, SourceForge, Google Code y Codeplex convierten a bitbucket en el lugar ideal para alojar nuestros <a href='http://ch3m4.org/blog/2011/10/04/bitbucket-soporta-tambien-git/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Relacionado con el <a href="http://ch3m4.org/blog/2011/08/30/mercurial-como-cliente-dcvs-universal/">anterior artículo</a> en el que contaba cómo usar mercurial para acceder a repositorios git, la noticia de hoy es que <a href="http://bitbucket.org">bitbucket</a> soporta también git (además de mercurial). Unido a las herramientas para importar cualquier proyecto de github, SourceForge, Google Code y Codeplex convierten a <a href="http://bitbucket.org">bitbucket</a> en el lugar ideal para alojar nuestros proyectos, usando cualquier DCVS que elijamos.</p>

<p>Noticia en el blog de bitbucket: <a href="http://blog.bitbucket.org/2011/10/03/bitbucket-now-rocks-git/">http://blog.bitbucket.org/2011/10/03/bitbucket-now-rocks-git/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://ch3m4.org/blog/2011/10/04/bitbucket-soporta-tambien-git/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mercurial como cliente DCVS universal</title>
		<link>http://ch3m4.org/blog/2011/08/30/mercurial-como-cliente-dcvs-universal/</link>
		<comments>http://ch3m4.org/blog/2011/08/30/mercurial-como-cliente-dcvs-universal/#comments</comments>
		<pubDate>Tue, 30 Aug 2011 12:14:13 +0000</pubDate>
		<dc:creator>Chema Cortés</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[bitbucket]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[mercurial]]></category>

		<guid isPermaLink="false">http://ch3m4.org/blog/?p=341</guid>
		<description><![CDATA[Uso de mercurial como cliente para acceso a repositorios git.]]></description>
			<content:encoded><![CDATA[<h2>Introducción</h2>

<p>Con la llegada de los <a href="http://en.wikipedia.org/wiki/Distributed_Concurrent_Versions_System" title="Distributed Concurrent Versions System">DCVS</a> (<em>Distributed Concurrent Versions System</em>), se ha convertido en habitual el uso de un sistema de control de versiones en todo desarrollo. La popularización de sitios webs basados en estos sistemas como <a href="http://github.com">github</a>, <a href="http://gitorious.org/">gitorious</a>, <a href="http://bitbucket.org">bitbucket</a> o <a href="http://code.google.com/">googlecode</a> como foros públicos donde compartir código entre programadores hasta el punto de convertirse en auténticas <em>redes sociales</em>, ha hecho de estos sistemas una necesidad para todo desarrollador que se precio, con el consabido dilema de cuál de los sistemas elegir.</p>

<p>Gracias a las extensiones que podemos añadir, cada día es menos transcendente la elección de un DCVS, pudiendo usar cualquier cliente con cualquier otro servidor.</p>

<h2>Comparando git y mercurial</h2>

<p>Sin entrar en mucho detalle, podemos comparar estos dos sistemas DCVS populares para hacernos una idea:</p>

<h3>git</h3>

<ul>
<li><span style="text-decoration: line-through;">Desarrollado en</span> <em>Depende de</em> perl y está pensado para linux (mal soporte en windows)</li>
<li>Velocidad: muy rápido</li>
<li>Comandos: algo complejo</li>
<li>Interface gráfico: no tiene</li>
<li>Popularidad muy alta</li>
<li>Repositorio público <em>estrella</em>: <a href="http://github.com">github</a></li>
</ul>

<h3>mercurial (hg)</h3>

<ul>
<li>Desarrollado en python, con versiones para linux, windows y mac</li>
<li>Velocidad: rápido</li>
<li>Comandos: sencillo (similar a subversion)</li>
<li>Interface gráfico: <a href="http://tortoisehg.bitbucket.org/">tortoiseHG</a> para gnome y windows</li>
<li>Popularidad alta</li>
<li>Repositorio público <em>estrella</em>: <a href="http://bitbucket.org">bitbucket</a></li>
</ul>

<p>Éstos son algunos apuntes rápidos. Evidentemente, hay algunos interfaces gráficos para git y es posible emplear git en windows, pero en mi opinión tiene algunos problemas que necesitan pulirse. Por otro lado, existen varios IDEs como netbeans o eclipse que pueden usar cualquiera de estos DCVS, abstrayendo su uso interno a través de un interface común.</p>

<p>Para un programador de <strong>python</strong>, la elección debería ser clara: <strong>mercurial</strong>. Realizado en python y con numerosas extensiones, también desarrolladas en python, parece sin duda la mejor elección. Además, es el sistema de control de versiones más utilizado en proyectos python, incluyendo el desarrollo del lenguaje en si, por lo que se uso es casi obligado si queremos colaborar con otros desarrolladores python.</p>

<p>Pero no hace falta renunciar a nada: desde mercurial también se puede usar repositorios git o subversion. Basta con añadir la extensión adecuada.</p>

<p>En el resto del articulo, me centreré sólo en la extensión <a href="http://hg-git.github.com/">hg-git</a>, con la que se posibilita el uso de repositorios git desde mercurial, sin necesidad de instalar ningún cliente de git adicional (no existen dependecias con ningún ejecutable <code>git</code>).</p>

<h2>hg-git</h2>

<h3>Instalación</h3>

<p>La última versión de mercurial a la hora de escribir este artículo es la 1.9. Como la versión <em>&#8220;estable</em>&#8221; de hg-git tiene problemas con esta versión en concreto de mercurial, voy a explicar aquí lo que sería el método <em>manual</em> de instalación, bastante más seguro.</p>

<p>Suponemos que tenemos ya instalado <code>mercurial</code> por lo medios habituales (autoinstalador en windows/instalador de paquetes en linux). Nos será de gran ayuda tener instalado <a href="http://tortoisehg.bitbucket.org/">tortoiseHG</a> como interface gráfico para manejar los repositorios. Para windows, la instalación de <a href="http://tortoisehg.bitbucket.org/">tortoiseHG</a> incluye todo lo necesario al empotrar un intérprete de python, mercurial y varias extensiones, algunas de ellas necesarias para transformar rutas y nombres de ficheros codificados en MBCS. Los siguientes pasos a ejecutar con mercurial serán más fáciles de aplicar desde la interface de tortoiseHG.</p>

<p>En el emplazamiento que queramos, empezamos por clonar un repositorio con <strong>hg-git</strong> desde mercurial:</p>

<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">$ </span>hg clone http:<span style="color: #000000; font-weight: bold;">//</span>bitbucket.org<span style="color: #000000; font-weight: bold;">/</span>durin42<span style="color: #000000; font-weight: bold;">/</span>hg-git hg-git</div></div>

<p>Normalmente, yo suelo usar un mismo directorio para agrupas todos los repositorios clonados. Ése podría ser el lugar adecuado para guardar este repositorio.</p>

<p>Añadimos esta extensión a la configuración de mercurial. Normalmente, se hace en el fichero <code>mercurial.ini</code> (windows) o en <code>~/.hgrc</code> (linux). Si usamos tortoiseHG, desde las <code>"opciones globales"</code> podemos editar directamente este fichero.</p>

<p>Para añadir la extensión:</p>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">[extensions]<br />
hggit = &lt;ruta-al-repositorio&gt;\hg-git\hggit</div></div>

<p>Como anotación, en alguna documentación se recomienda añadir también la extensión <em>opcional</em> <code>bookmarks</code> a la configuración; pero a partir de la versión 1.8 de mercurial, el comando <code>bookmark</code> es parte propia de los comandos de mercurial, por lo tanto este paso ya no es necesario.</p>

<p>Como dependencia, hace falta instalar el módulo de python <code>dulwich</code> para manejo de repositorios git con python. En windows ya viene incluído en tortoiseHG, por lo que no hay que hacer nada más. En linux, viene como paquete instalable (<code>python-dulwich</code> en ubuntu), pero también se podría haber instalado mediante <code>easy_install</code> sin mayor problema. Lo que sí hay que tener cuidado es en asegurarnos que no tenemos instalado el paquete <code>python-git</code> para que no interfiera con el módulo <code>hg-git</code> que estamos configurando.</p>

<p>Como lista final, estas serían las versiones probadas:</p>

<ul>
<li>mercurial (hg) <code>1.9</code></li>
<li>hg-git <code>0.2.4</code></li>
<li>dulwich <code>0.6.1</code></li>
</ul>

<h2>Utilización</h2>

<p>Con hg-git instalado ya podemos acceder, por ejemplo, a los repositorios de github directamente desde mercurial. Basta con especificar que se trata de un repositorio git:</p>

<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">$ </span>hg clone git:<span style="color: #000000; font-weight: bold;">//</span>github.com<span style="color: #000000; font-weight: bold;">/</span>django<span style="color: #000000; font-weight: bold;">/</span>django.git django.git</div></div>

<p>Para realizar un <code>push</code> a github con conexión codificada con SSH:</p>

<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">$ </span>hg push <span style="color: #c20cb9; font-weight: bold;">git</span>+ssh:<span style="color: #000000; font-weight: bold;">//</span>user<span style="color: #000000; font-weight: bold;">@</span>github.com<span style="color: #000000; font-weight: bold;">/</span>user<span style="color: #000000; font-weight: bold;">/</span>myrep.git</div></div>

<p>Así mismo, si partimos de un repositorio mercurial también podemos <em>&#8220;convertirlo&#8221;</em> para su uso en git con el siguiente proceso:</p>

<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ <span style="color: #7a0874; font-weight: bold;">cd</span> myrep <span style="color: #666666; font-style: italic;"># (dentro del repositorio mercurial)</span><br />
$ hg bookmark <span style="color: #660033;">-r</span> default master <span style="color: #666666; font-style: italic;"># marcamos 'default' como 'master'</span><br />
$ hg push <span style="color: #c20cb9; font-weight: bold;">git</span>+ssh:<span style="color: #000000; font-weight: bold;">//</span>user<span style="color: #000000; font-weight: bold;">@</span>github.com<span style="color: #000000; font-weight: bold;">/</span>user<span style="color: #000000; font-weight: bold;">/</span>myrep.git<br />
$ hg push</div></div>

<p>Al marcar con el nombre <code>master</code> a <code>default</code> facilitamos la conversión de los datos de mercurial a objetos git. Este proceso sólo es necesario hacerlo la primera vez.</p>

<h2>github o bitbucket</h2>

<p>En cuanto a elegir entre github o bitbucket, es más una cuestión de gustos. <strong>github</strong> se ha posicionado como el sistema predilecto para darse a conocer, sobre todo como referencia en los <em>curriculo</em> a la hora de solicitar empleo. En cambio, <strong>bitbucket</strong> permite el uso de repositorios privados, muy útil para pequeños grupos de trabajo y para colaboraciones en la <em>&#8220;nube&#8221;</em> (dispositivos móviles).</p>

<p>Ambos son gratuitos, por lo que no debes dejar de probarlos tan sólo por lo que haya podido decir aquí. Es una nueva forma de conocer y darse a conocer entre programadores, algo que sin duda hace de nuestro pequeño mundo algo mucho más grande.</p>
]]></content:encoded>
			<wfw:commentRss>http://ch3m4.org/blog/2011/08/30/mercurial-como-cliente-dcvs-universal/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>iconv en python</title>
		<link>http://ch3m4.org/blog/2011/08/04/iconv-en-python/</link>
		<comments>http://ch3m4.org/blog/2011/08/04/iconv-en-python/#comments</comments>
		<pubDate>Thu, 04 Aug 2011 17:38:21 +0000</pubDate>
		<dc:creator>Chema Cortés</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[tip]]></category>

		<guid isPermaLink="false">http://ch3m4.org/blog/?p=332</guid>
		<description><![CDATA[Últimamente he necesitado pasar algunos ficheros de una web a codificación utf-8, codificación de caracteres más acorde con lo que se lleva hoy en día. En sistemas linux es una labor que se puede hacer fácilmente con la utilidad iconv: $ iconv -f cp850 -t utf8 &#60;fichero_entrada.txt &#62;fichero_salida.txt Pero hay veces que es necesario realizar <a href='http://ch3m4.org/blog/2011/08/04/iconv-en-python/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Últimamente he necesitado pasar algunos ficheros de una web a codificación <code>utf-8</code>, codificación de caracteres más acorde con lo que se lleva hoy en día. En sistemas linux es una labor que se puede hacer fácilmente con la utilidad <code>iconv</code>:</p>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ iconv -f cp850 -t utf8 &lt;fichero_entrada.txt &gt;fichero_salida.txt</div></div>

<p>Pero hay veces que es necesario realizar esta conversión en windows. Si tenemos instalado <code>python</code>, una forma rápida de hacerlo sería:</p>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ python -c &quot;import sys,codecs;codecs.EncodedFile(sys.stdout,'latin-1','utf-8').writelines(sys.stdin)&quot; &lt;fichero_entrada.txt &gt;fichero_salida.txt</div></div>

<p>&#8230;¡y todo en una sóla línea!<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup></p>

<p>Tan sólo puntualizar que esta conversión emplea <em>iteradores</em>, por lo que no tiene que ser un problema el tamaño del fichero de texto a convertir.</p>

<div class="footnotes">
<hr />
<ol>

<li id="fn:1">
<p>Para ver más ejemplos de <em>&#8220;one-liners&#8221;</em> os recomiendo este <a href="http://joedicastro.com/python-one-liners-potencia-en-una-sola-linea.html">artículo</a>  de Joe di Castro&#160;<a href="#fnref:1" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://ch3m4.org/blog/2011/08/04/iconv-en-python/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Evento Python Madrid 2011</title>
		<link>http://ch3m4.org/blog/2011/07/06/evento-python-madrid-2011/</link>
		<comments>http://ch3m4.org/blog/2011/07/06/evento-python-madrid-2011/#comments</comments>
		<pubDate>Wed, 06 Jul 2011 08:08:36 +0000</pubDate>
		<dc:creator>Chema Cortés</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[evento]]></category>

		<guid isPermaLink="false">http://ch3m4.org/blog/?p=328</guid>
		<description><![CDATA[El grupo Python-Madrid y el Grupo de Usuarios de Linux de la Universidad Carlos III de Madrid, celebrarán el próximo día 15 de Julio de 10:00 a 18:00 el evento Python Madrid 2011. El evento tendrá lugar en la Universidad Carlos III de Madrid, en su campus de Leganés. Se trataran temas como Python, Django, <a href='http://ch3m4.org/blog/2011/07/06/evento-python-madrid-2011/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>El grupo <a href="http://python-hispano.org/PythonMadrid" title="Python-Madrid">Python-Madrid</a> y el <a href="http://www.gul.uc3m.es/" title="GUL de la UC3M">Grupo de Usuarios de Linux de la Universidad Carlos III de Madrid</a>, celebrarán el próximo día 15 de Julio de 10:00 a 18:00 el evento Python Madrid 2011. El evento tendrá lugar en la <a href="http://www.uc3m.es/" title="UC3M">Universidad Carlos III</a> de Madrid, en su campus de Leganés. Se trataran temas como Python, Django, PyGame y mucho más. Toda la información en <a href="http://www.espython.org">www.espython.org</a></p>
]]></content:encoded>
			<wfw:commentRss>http://ch3m4.org/blog/2011/07/06/evento-python-madrid-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Método __getattribute__</title>
		<link>http://ch3m4.org/blog/2011/06/26/metodo-__getattribute__/</link>
		<comments>http://ch3m4.org/blog/2011/06/26/metodo-__getattribute__/#comments</comments>
		<pubDate>Sun, 26 Jun 2011 17:59:06 +0000</pubDate>
		<dc:creator>Chema Cortés</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[técnicas dinámicas]]></category>

		<guid isPermaLink="false">http://ch3m4.org/blog/2011/06/26/metodo-__getattribute__/</guid>
		<description><![CDATA[Con el método especial "<strong>getattribute</strong>", lo primero que piensa es que se va a producir una autorecursividad puesto que en el acceso al método <strong>getattribute</strong> se debería invocar el propio método <strong>getattribute</strong> y así indefinidamente.

Si embargo, cuando se prueba se ve que funciona tal y como se espera.]]></description>
			<content:encoded><![CDATA[<p>Si has seguido hasta ahora la serie de <a href="http://ch3m4.org/blog/tag/descriptor/" title="Artículos sobre descriptores">artículos sobre descriptores</a>, habrás visto que buena parte de la <em>magia</em> de los objetos en python se debe al método <code>__getattribute__</code> que todo objeto adquiere de su antecesor común, la clase <code>object</code>.</p>

<p>En el último artículo, donde hablaba de las <a href="http://ch3m4.org/blog/2011/06/24/optimizaciones-con-los-metodos-especiales/" title="Optimizaciones con los Métodos Especiales">optimizaciones de los métodos especiales</a>, también comentaba algunas optimizaciones que tenían qué ver con el método <code>__getattribute__</code> y proponía un ejercicio:</p>

<blockquote>
  <p>¿Sabrías qué es lo que pasa en el siguiente caso? ¿Se invoca el método <strong>getattribute</strong> en algún momento? ¿Sería una llamada implícita o explícita?</p>

<pre><code>   obj.__getattribute__("__getattribute__")
</code></pre>
</blockquote>

<p>Quien se enfrenta a este código por primera vez, lo primero que piensa es que se va a producir una <em>autorecursividad</em> puesto que en el acceso al método <code>__getattribute__</code> se debería invocar el propio método <code>__getattribute__</code> y así indefinidamente.</p>

<p>Si embargo, cuando se prueba se ve que funciona tal y como se espera. Entonces, ¿cómo se evita la recursividad?</p>

<p>En el artículo de <a href="http://ch3m4.org/blog/2011/06/24/optimizaciones-con-los-metodos-especiales/" title="Optimizaciones con los Métodos Especiales">optimizaciones de los métodos especiales</a> hablábamos de dos optimizaciones (<em>atajos</em>) de las llamadas <em>implícitas</em> a métodos especiales:</p>

<ol>
<li><p>Implícitamente, sólo se buscará métodos especiales en la clase, <strong><em>nunca</em></strong> en el diccionario del objeto.</p></li>
<li><p>Implícitamente, <strong><em>nunca</em></strong> se accederá a un método especial a través de <code>__getattribute__</code></p></li>
</ol>

<p>La intuición nos dice que aquí está la respuesta de que no tengamos <em>autorecursividad</em>.</p>

<p>Antes de analizar lo que está pasando, señalar que en el acceso a atributos se usa el operador &#8216;<code>.</code>&#8216; (<em>punto</em>) que, como cualquier otro operador, está sujeto a las mismas optimizaciones que hemos apuntado. Para su labor, el operador <code>.</code> empleará el método especial <code>__getattribute__</code>.</p>

<p>La invocación <code>obj.__getattribute__("atributo")</code> se produce en dos pasos:</p>

<ol>
<li><em>Implícitamente</em>, el operador &#8216;<code>.</code>&#8216; accede directamente al método <code>__getattribute__</code>, aplicando las optimizaciones.</li>
<li>Se invoca <em>explícitamente</em> a <code>__getattribute__</code> para que retorne el valor del <code>"atributo"</code></li>
</ol>

<p>Así pues, el resultado final consiste en la combinación de una llamada implícita y otra explícita.</p>

<p>Como corolario, se puede afirmar que &#8220;Nunca se invocará a <code>__getattribute__</code> para acceder a <code>__getattribute__</code>&#8220;. No será la primera vez que alguien lo haya intentado.</p>
]]></content:encoded>
			<wfw:commentRss>http://ch3m4.org/blog/2011/06/26/metodo-__getattribute__/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

