<?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>Calcifer &#187; code</title>
	<atom:link href="http://blog.calcifer.com.ar/tag/code/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.calcifer.com.ar</link>
	<description></description>
	<lastBuildDate>Sat, 02 Oct 2010 05:32:38 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Vim scripting con Python</title>
		<link>http://blog.calcifer.com.ar/2010/02/vim-scripting-con-python/</link>
		<comments>http://blog.calcifer.com.ar/2010/02/vim-scripting-con-python/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 01:20:00 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/?p=549</guid>
		<description><![CDATA[Vim permite agregar funcionalidades mediante varios lenguajes externos, entre ellos Perl, Python, Ruby y Tcl. Para poder hacer uso de esta característica es necesario haber compilado Vim con el soporte para el lenguaje necesario (con el flag-python, para soporte python). En debian existe un paquete llamado vim-nox (no X) que contiene una versión compilada con [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.vim.org/" title="Vim the editor" class="external">Vim</a> permite agregar funcionalidades mediante varios lenguajes externos, entre ellos Perl, Python, Ruby y Tcl. Para poder hacer uso de esta característica es necesario haber compilado Vim con el soporte para el lenguaje necesario (con el flag<code>-python</code>, para soporte python). En debian existe un paquete llamado <a href="http://packages.debian.org/stable/vim-nox" title="Debian Package: vim-nox" class="external">vim-nox</a> (no X) que contiene una versión compilada con soporte para los cuatro lenguajes mencionados:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">sudo apt-get install vim-nox</div></div>
<p>Para comprobar que efectivamente se encuentre habilitado el soporte para Python ejecutar Vim y en modo comando escribir:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:echo has(&quot;python&quot;)</div></div>
<p>Un 1 indica que Vim interpreta Python ;)</p>
<p>Es muy recomendable leer la ayuda en línea:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:help python</div></div>
<p>También se puede acceder vía web desde <a href="http://vimdoc.sourceforge.net/htmldoc/if_pyth.html" title="Vim documentation: if_pyth" class="external">http://vimdoc.sourceforge.net/htmldoc/if_pyth.html</a></p>
<h3>Ejecución de código Python</h3>
<p>La ejecución de una línea de código Python se realiza según la sintaxis:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:[range]py[thon] {stmt}</div></div>
<p>Ejemplo:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:python print &quot;hello world&quot;</div></div>
<p>Aquí el prompt mostrará el mensaje &#8220;hello world&#8221;.</p>
<p>En cambio para escribir código en varias líneas hay que usar la siguiente forma:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">[range]:py[thon] &lt;&lt; {endmarker}<br />
{script}<br />
{endmarker}</div></div>
<p>Ejemplo:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:python &lt;&lt; EOF<br />
def get_user():<br />
&nbsp; import os<br />
&nbsp; return os.getenv('USER')<br />
EOF</div></div>
<p>De esta manera la función queda guardada en la memoria de la sesión actual. Luego su uso podría ser el siguiente:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py user = get_user()</div></div>
<p>Tambien es posible cargar y/o ejecutar código desde un archivo externo. La sintaxis es:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:[range]pyf[ile] {file}</div></div>
<p>Ejemplo:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:pyfile myscript.py</div></div>
<p>Si<code>myscript.py</code>necesitara parámetros la forma de pasárselos es la siguiente:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py import sys<br />
:py sys.argv = ['foo', 'bar']<br />
:pyf myscript.py</div></div>
<h3>El módulo vim</h3>
<p>La comunicación entre Python y Vim se realiza a través del módulo vim, el cual hay que importar antes de usar:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:python import vim</div></div>
<p>Como indica la ayuda de Vim, el módulo implementa dos métodos (<code>vim.command(str)</code>y<code>vim.eval(str)</code>), tres constantes (<code>vim.buffers</code>,<code>vim.windows</code>y<code>vim.current</code>) y un objeto error (<code>vim.error</code>). Las tres constantes mencionadas no son realmente constantes sino variables que pueden ser reasignadas pero, como dice también la ayuda, esto sería absurdo ya que se perdería acceso a los objetos de Vim que referencian. Por otra parte cabe recordar que no existen constantes en Python. Como cita el libro &#8220;<a href="http://www.gulic.org/almacen/diveintopython-5.4-es/object_oriented_framework/class_attributes.html" title="Capítulo 5.8. - Presentación de los atributos de clase" class="external">Inmersión en Python</a>&#8220;:</p>
<blockquote><p>Todo puede cambiar si lo intenta con ahínco. Esto se ajusta a uno de los principios básicos de Python: los comportamientos inadecuados sólo deben desaconsejarse, no prohibirse.</p></blockquote>
<p><span id="more-549"></span><br />
A continuación transcribo un detalle de cada una de las constantes mencionadas:</p>
<dl>
<dt>vim.buffers</dt>
<dd>
Objeto de tipo secuencia que provee acceso al listado de buffers actuales. El objeto soporta las siguiente operaciones:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py b = vim.buffers[i] &nbsp; &nbsp; # Indexación (Read-Only)<br />
:py b in vim.buffers &nbsp; &nbsp; &nbsp; # Prueba de existencia<br />
:py n = len(vim.buffers) &nbsp; # Número de elementos<br />
:py for b in vim.buffers: &nbsp;# Acceso secuencial</div></div>
</dd>
<dt>vim.windows</dt>
<dd>
Objeto de tipo secuencia que provee acceso al listado de ventanas actuales. El objeto soporta las mismas operaciones que vim.buffers:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py w = vim.windows[i] &nbsp; &nbsp; # Indexación (RO)<br />
:py w in vim.windows &nbsp; &nbsp; &nbsp; # Prueba de existencia<br />
:py n = len(vim.windows) &nbsp; # Número de elementos<br />
:py for w in vim.windows: &nbsp;# Acceso secuencial</div></div>
</dd>
<dt>vim.current</dt>
<dd>
Objeto que provee acceso (vía atributos específicos) a distintos objetos actuales:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">vim.current.line &nbsp; &nbsp;# (RW) String<br />
vim.current.buffer &nbsp;# (RO) Buffer<br />
vim.current.window &nbsp;# (RO) Window<br />
vim.current.range &nbsp; # (RO) Range</div></div>
</dd>
</dl>
<h3>Ejemplos básicos de uso del módulo vim</h3>
<p>Usando<code>vim.current.line</code>:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py from string import upper<br />
:py vim.current.line = upper(vim.current.line)</div></div>
<p>Usando<code>vim.current.buffer</code>:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py b = vim.current.buffer &nbsp; &nbsp; &nbsp;# obtiene buffer actual<br />
:py name = b.name &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # nombre de archivo del buffer actual<br />
:py num = len(b) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# total de líneas en el buffer<br />
:py line = b[n] &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # obtiene la línea n+1<br />
:py lines = b[n:m] &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# obtiene una lista de líneas<br />
:py b[n] = str &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# reemplaza la línea n+1<br />
:py b[n:m] = [str1, str2, str3] # reemplaza varias líneas a la vez<br />
:py b[0:0] = [&quot;hola mundo&quot;] &nbsp; &nbsp; # inserta una línea al comienzo<br />
:py b.append(&quot;fin&quot;) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # inserta una línea al final<br />
:py del b[n] &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# borra la línea n+1<br />
:py del b[n:m] &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# borra varias líneas a la vez<br />
:py b[:] = None &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # borra el buffer completo</div></div>
<p>Usando<code>vim.current.window</code>:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py cw = vim.current.window &nbsp; &nbsp; &nbsp;# obtiene la ventana actual<br />
:py cw.height = 30 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # setea el alto de la ventana<br />
:py cw.width = 80 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# setea el ancho<br />
:py pos = cw.cursor &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# posicion del cursor (row, col)</div></div>
<h3>Script para subrayado de títulos</h3>
<p>El siguiente script (<a href="http://blog.calcifer.com.ar/uploads/2010/02/heading.vim" title="">heading.vim</a>) lo escribí para no tener que, manualmente, subrayar títulos y delimitar bloques de texto. Especialmente quería que reconociera cuando se tratara de texto dentro de comentarios de código fuente y que respetara los caracteres especiales al comienzo (y final) de los mismos.</p>
<p>El script tiene una función que decora la línea actual colocando él o los caracteres decoradores tanto arriba como debajo de la misma (comportamiento por defecto). El largo (también por defecto) es el largo de la línea, pero se puede fijar un límite (ejemplo 80 columnas) y pedirle que ocupe todo el espacio disponible. Esta opción funciona bien sólamente cuando el indentado es con espacios. La opción uppercase funciona como se espera.</p>
<p>El código es el siguiente:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px;height:500px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br /></div></td><td><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">&quot; ============================================================================<br />
&quot; File: &nbsp; &nbsp; &nbsp; &nbsp;heading.vim<br />
&quot; Version: &nbsp; &nbsp; 0.1<br />
&quot; Description: vim global plugin that provides a way to create headings.<br />
&quot; Maintainer: &nbsp;Leonardo Vidarte &lt;lvidarte at gmail dot com&gt;<br />
&quot; Last Change: 21 February, 2010<br />
&quot; ============================================================================<br />
if has('python')<br />
python &lt;&lt; EOF<br />
def heading(decorator='=', top=True, bottom=True, limit=0, uppercase=False):<br />
<br />
&nbsp; &nbsp; import vim<br />
&nbsp; &nbsp; from string import upper, rstrip, lstrip<br />
<br />
&nbsp; &nbsp; if not top and not bottom:<br />
&nbsp; &nbsp; &nbsp; &nbsp; return None # nothing to do<br />
<br />
&nbsp; &nbsp; (row, col) = vim.current.window.cursor<br />
&nbsp; &nbsp; line = vim.current.buffer[row-1].rstrip()<br />
&nbsp; &nbsp; line_length = len(line.decode('utf8'))<br />
&nbsp; &nbsp; title = line.lstrip()<br />
&nbsp; &nbsp; word_length = len(title.decode('utf8'))<br />
&nbsp; &nbsp; whitespace = line[0:line_length - word_length]<br />
<br />
&nbsp; &nbsp; if limit &gt; 0:<br />
&nbsp; &nbsp; &nbsp; &nbsp; decorator *= limit<br />
&nbsp; &nbsp; &nbsp; &nbsp; total_length = limit<br />
&nbsp; &nbsp; else:<br />
&nbsp; &nbsp; &nbsp; &nbsp; decorator *= word_length<br />
&nbsp; &nbsp; &nbsp; &nbsp; total_length = line_length<br />
<br />
&nbsp; &nbsp; if title[0:3] in ('// ', '/* ', '-- '):<br />
&nbsp; &nbsp; &nbsp; &nbsp; decoline = whitespace + title[0:3] + decorator<br />
&nbsp; &nbsp; elif title[0:2] in ('//', '/*', '--', '# ', '* ', '&quot; '):<br />
&nbsp; &nbsp; &nbsp; &nbsp; decoline = whitespace + title[0:2] + decorator<br />
&nbsp; &nbsp; elif title[0:1] in ('#', '*', '&quot;'):<br />
&nbsp; &nbsp; &nbsp; &nbsp; decoline = whitespace + title[0:1] + decorator<br />
&nbsp; &nbsp; else:<br />
&nbsp; &nbsp; &nbsp; &nbsp; decoline = whitespace + decorator<br />
<br />
&nbsp; &nbsp; # Special case: comments like C /* hello world */<br />
&nbsp; &nbsp; cend = ''<br />
&nbsp; &nbsp; if title[0:2] == '/*':<br />
&nbsp; &nbsp; &nbsp; &nbsp; if title[-3:] == ' */':<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cend = ' */'<br />
&nbsp; &nbsp; &nbsp; &nbsp; elif title[-2:] == '*/':<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cend = '*/'<br />
<br />
&nbsp; &nbsp; decoline = decoline[0:total_length - len(cend)] + cend<br />
&nbsp; &nbsp; final_heading = []<br />
<br />
&nbsp; &nbsp; if top:<br />
&nbsp; &nbsp; &nbsp; &nbsp; final_heading.append(decoline)<br />
<br />
&nbsp; &nbsp; if uppercase:<br />
&nbsp; &nbsp; &nbsp; &nbsp; final_heading.append(line.upper())<br />
&nbsp; &nbsp; else:<br />
&nbsp; &nbsp; &nbsp; &nbsp; final_heading.append(line)<br />
<br />
&nbsp; &nbsp; if bottom:<br />
&nbsp; &nbsp; &nbsp; &nbsp; final_heading.append(decoline)<br />
<br />
&nbsp; &nbsp; del vim.current.buffer[row-1]<br />
&nbsp; &nbsp; vim.current.buffer[row-1:0] = final_heading<br />
<br />
&nbsp; &nbsp; # Set final cursor position<br />
&nbsp; &nbsp; if top and bottom:<br />
&nbsp; &nbsp; &nbsp; &nbsp; vim.current.window.cursor = (row + 2, 0)<br />
&nbsp; &nbsp; else:<br />
&nbsp; &nbsp; &nbsp; &nbsp; vim.current.window.cursor = (row + 1, 0)<br />
<br />
H = heading # shortcut<br />
EOF<br />
<br />
&quot; ============================================================================<br />
&quot; Vim maps (see :help leader)<br />
&quot; ============================================================================<br />
nnoremap &lt;silent&gt; &lt;Leader&gt;hh :python heading()&lt;CR&gt;<br />
<br />
nnoremap &lt;silent&gt; &lt;Leader&gt;h1 :python heading('#', uppercase=True)&lt;CR&gt;<br />
nnoremap &lt;silent&gt; &lt;Leader&gt;h2 :python heading('*', uppercase=True)&lt;CR&gt;<br />
nnoremap &lt;silent&gt; &lt;Leader&gt;h3 :python heading('=')&lt;CR&gt;<br />
nnoremap &lt;silent&gt; &lt;Leader&gt;h4 :python heading('-')&lt;CR&gt;<br />
nnoremap &lt;silent&gt; &lt;Leader&gt;h5 :python heading('~', top=False)&lt;CR&gt;<br />
<br />
nnoremap &lt;silent&gt; &lt;Leader&gt;HH :python heading(limit=78)&lt;CR&gt;<br />
nnoremap &lt;silent&gt; &lt;Leader&gt;Hb :python heading(limit=78, top=False)&lt;CR&gt;<br />
nnoremap &lt;silent&gt; &lt;Leader&gt;Ht :python heading(limit=78, bottom=False)&lt;CR&gt;<br />
<br />
endif</div></td></tr></tbody></table></div>
<p>Para usarlo hay que colocar el archivo <a href="http://blog.calcifer.com.ar/uploads/2010/02/heading.vim" title="">heading.vim</a> en el directorio<code>~/.vim/plugins</code>.</p>
<h4>Ejemplos de uso</h4>
<p>1. Texto normal</p>
<pre>Título</pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py H()</div></div>
<pre>======
Título
======</pre>
<p>2. Comentario en línea (Python, Bash, Perl, PHP, Ruby)</p>
<pre>    # Comment</pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py H()</div></div>
<pre>    # =======
    # Comment
    # =======</pre>
<p>3. Comentario en bloque, estilo javadoc (C, C++, Java, Javascript, CSS, PHP, SQL)</p>
<pre>    /**
     * Comment
     */</pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py H('#', uppercase=True)</div></div>
<pre>    /**
     * #######
     * COMMENT
     * #######
     */</pre>
<p>4. Comentario en línea (C, C++, Java, Javascript, CSS, PHP, SQL)</p>
<pre>/* Comment */</pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py H('~+')</div></div>
<pre>/* ~+~+~+~ */
/* Comment */
/* ~+~+~+~ */</pre>
<p>5. Comentario en línea (C, Java, Javascript, PHP)</p>
<pre>// Comment</pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py H(limit=40)</div></div>
<pre>// =====================================
// Comment
// =====================================</pre>
<p>6. Comentario en línea (Vim script)</p>
<pre>" Comment</pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py H(top=None)</div></div>
<pre>" Comment
" ======</pre>
<p>7. Comentario en línea (Lua, SQL)</p>
<pre>-- Comment</pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py H()</div></div>
<pre>-- =======
-- Comment
-- =======</pre>
<h4>Atajos de teclado</h4>
<p>El script también define algunos atajos en modo normal para Vim. Para los mismos se usa la tecla especial<code>&lt;Leader&gt;</code>que es definida por la variable<code>mapleader</code>y que generealmente es el caracter<code>\</code>.</p>
<table>
<tr>
<th>Atajo</th>
<th>Comando</th>
</tr>
<tr>
<td>\hh</td>
<td>:python heading()</td>
</tr>
<tr>
<td>\h1</td>
<td>:python heading(&#8216;#&#8217;, uppercase=True)</td>
</tr>
<tr>
<td>\h2</td>
<td>:python heading(&#8216;*&#8217;, uppercase=True)</td>
</tr>
<tr>
<td>\h3</td>
<td>:python heading(&#8216;=&#8217;)</td>
</tr>
<tr>
<td>\h4</td>
<td>:python heading(&#8216;-&#8217;)</td>
</tr>
<tr>
<td>\h5</td>
<td>:python heading(&#8216;~&#8217;, top=False)</td>
</tr>
<tr>
<td>\HH</td>
<td>:python heading(limit=78)</td>
</tr>
<tr>
<td>\Hb</td>
<td>:python heading(limit=78, top=False)</td>
</tr>
<tr>
<td>\Ht</td>
<td>:python heading(limit=78, bottom=False)</td>
</tr>
</table>
<h3>Lectura adicional</h3>
<ul>
<li><a href="http://www.builderau.com.au/program/python/soa/Extending-Vim-with-Python/0,2000064084,339283181,00.htm">Extending Vim with Python</a></li>
<li><a href="http://www.tummy.com/Community/Presentations/vimpython-20070225/vim.html">Python and vim: Two great tastes that go great together</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2010/02/vim-scripting-con-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Humor en comentarios de códigos fuente</title>
		<link>http://blog.calcifer.com.ar/2009/07/humor-en-comentarios-de-codigos-fuente/</link>
		<comments>http://blog.calcifer.com.ar/2009/07/humor-en-comentarios-de-codigos-fuente/#comments</comments>
		<pubDate>Fri, 24 Jul 2009 21:48:46 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[humor]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/?p=443</guid>
		<description><![CDATA[Visto en stackoverflow.com
Algunos de ellos:
// sometimes I believe compiler ignores
// all my comments
// When I wrote this, only God and I understood
// what I was doing. Now, God only knows
if &#40;/*you*/ $_GET&#91;'action'&#93;&#41; &#123; //celebrate
// 
// Dear maintainer:
// 
// Once you are done trying to 'optimize'
// this routine, and have realized what
// a terrible mistake that [...]]]></description>
			<content:encoded><![CDATA[<p class="from">Visto en <a href="http://stackoverflow.com/questions/184618" class="external">stackoverflow.com</a></p>
<p>Algunos de ellos:</p>
<div class="codecolorer-container c " style="overflow:auto;white-space:nowrap;width:435px"><div class="c codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co1">// sometimes I believe compiler ignores</span><br />
<span class="co1">// all my comments</span></div></div>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">// When I wrote this, only God and I understood<br />
// what I was doing. Now, God only knows</div></div>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:435px"><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">if</span> <span class="br0">&#40;</span><span class="coMULTI">/*you*/</span> <span class="re0">$_GET</span><span class="br0">&#91;</span><span class="st_h">'action'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="co1">//celebrate</span></div></div>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">// <br />
// Dear maintainer:<br />
// <br />
// Once you are done trying to 'optimize'<br />
// this routine, and have realized what<br />
// a terrible mistake that was, please<br />
// increment the following counter as a<br />
// warning to the next guy:<br />
// <br />
// total_hours_wasted_here = 16<br />
//</div></div>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">// I'm sorry.</div></div>
<div class="codecolorer-container c " style="overflow:auto;white-space:nowrap;width:435px"><div class="c codecolorer" style="font-family:Monaco,Lucida Console,monospace">virgin <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span> <span class="coMULTI">/* you're not a virgin anymore, sweety */</span></div></div>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:435px"><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sy0">...</span> or <a href="http://www.php.net/die"><span class="kw3">die</span></a> <span class="co1">// bitch</span></div></div>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">// This is crap code but it's 3 a.m. and<br />
// I need to get this working.</div></div>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">// Hard to explain</div></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2009/07/humor-en-comentarios-de-codigos-fuente/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Calculadora de notación polaca inversa en C</title>
		<link>http://blog.calcifer.com.ar/2009/04/calculadora-de-notacion-polaca-inversa-en-c/</link>
		<comments>http://blog.calcifer.com.ar/2009/04/calculadora-de-notacion-polaca-inversa-en-c/#comments</comments>
		<pubDate>Wed, 15 Apr 2009 18:16:13 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[code]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/?p=419</guid>
		<description><![CDATA[La Notación Polaca Inversa (RPN en inglés, Reverse Polish Notation) es un método de introducción de datos alternativo al algebráico. Fue creada en 1920 por el matemático polaco Jan Lukasiewicz como una forma de escribir expresiones matemáticas sin tener que utilizar paréntesis y corchetes.
En la notación polaca inversa los operadores suceden a sus operandos. Por [...]]]></description>
			<content:encoded><![CDATA[<p>La Notación Polaca Inversa (RPN en inglés, Reverse Polish Notation) es un método de introducción de datos alternativo al algebráico. Fue creada en 1920 por el matemático polaco Jan Lukasiewicz como una forma de escribir expresiones matemáticas sin tener que utilizar paréntesis y corchetes.</p>
<p>En la notación polaca inversa los operadores suceden a sus operandos. Por ejemplo, la expresión algebráica<code>5+((1+2)*4)-3</code>se traduce a la notación polaca inversa como<code>5 1 2 + 4 * + 3 -</code>.</p>
<p>Su principio es el de evaluar los datos directamente cuando se introducen y manejarlos dentro de una estructura LIFO (Last In First Out), lo que optimiza los procesos a la hora de programar.</p>
<p>El siguiente programa es una implementación en C de una calculadora que funciona con notación polaca inversa. El programa es una versión modificada del que figura en el libro &#8220;<a href="http://en.wikipedia.org/wiki/The_C_Programming_Language_(book)" class="external">El lenguaje de programación C</a>&#8221; de Kernighan y Ritchie.</p>
<div class="codecolorer-container c blackboard" style="overflow:auto;white-space:nowrap;width:435px;height:500px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br /></div></td><td><div class="c codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co2">## ************</span><br />
<span class="co2">## @file calc.c</span><br />
<span class="co2">## ************</span><br />
<br />
<span class="co2">#include &lt;stdio.h&gt;</span><br />
<span class="co2">#include &lt;stdlib.h&gt;</span><br />
<br />
<span class="co2">#define MAXVAL 100</span><br />
<span class="co2">#define NUMBER '0'</span><br />
<br />
<span class="coMULTI">/**<br />
&nbsp;* &nbsp;Variables<br />
&nbsp;*/</span><br />
<span class="kw4">int</span> verbose<span class="sy0">;</span><br />
<span class="kw4">int</span> sp <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span><br />
<span class="kw4">double</span> val<span class="br0">&#91;</span>MAXVAL<span class="br0">&#93;</span><span class="sy0">;</span><br />
<br />
<span class="coMULTI">/**<br />
&nbsp;* &nbsp;Prototypes<br />
&nbsp;*/</span><br />
<span class="kw4">int</span> toi <span class="br0">&#40;</span><span class="kw4">char</span> <span class="kw4">const</span> <span class="sy0">*</span>s<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw4">void</span> push <span class="br0">&#40;</span><span class="kw4">double</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw4">double</span> pop <span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="coMULTI">/**<br />
&nbsp;* &nbsp;Main<br />
&nbsp;*/</span><br />
<span class="kw4">int</span> main <span class="br0">&#40;</span><span class="kw4">int</span> argc<span class="sy0">,</span> <span class="kw4">char</span> <span class="kw4">const</span> <span class="sy0">*</span>argv<span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="kw4">int</span> offset<span class="sy0">,</span> i<span class="sy0">;</span><br />
&nbsp; <span class="kw4">double</span> op2<span class="sy0">;</span><br />
<br />
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>argc <span class="sy0">&lt;</span> <span class="nu0">2</span><span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; fprintf <span class="br0">&#40;</span>stderr<span class="sy0">,</span> <br />
&nbsp; &nbsp; &nbsp; <span class="st0">&quot;Usage: %s [-v] EXP<span class="es1">\n</span>&quot;</span><span class="sy0">,</span> argv<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">1</span><span class="sy0">;</span><br />
&nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; verbose <span class="sy0">=</span> offset <span class="sy0">=</span> <br />
&nbsp; &nbsp; <span class="br0">&#40;</span>strcmp <span class="br0">&#40;</span>argv<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="st0">&quot;-v&quot;</span><span class="br0">&#41;</span> <span class="sy0">==</span> <span class="nu0">0</span><span class="br0">&#41;</span> <span class="sy0">?</span> <span class="nu0">1</span> <span class="sy0">:</span> <span class="nu0">0</span><span class="sy0">;</span><br />
&nbsp; <br />
&nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span>i <span class="sy0">=</span> <span class="nu0">1</span> <span class="sy0">+</span> offset<span class="sy0">;</span> i <span class="sy0">&lt;</span> argc<span class="sy0">;</span> i<span class="sy0">++</span><span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">switch</span> <span class="br0">&#40;</span>toi <span class="br0">&#40;</span>argv<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="st0">'+'</span> <span class="sy0">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>verbose<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a> <span class="br0">&#40;</span><span class="st0">&quot;operator +<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; push <span class="br0">&#40;</span>pop<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">+</span> pop<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">break</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="st0">'-'</span> <span class="sy0">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>verbose<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a> <span class="br0">&#40;</span><span class="st0">&quot;operator -<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; op2 <span class="sy0">=</span> pop<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; push <span class="br0">&#40;</span>pop<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">-</span> op2<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">break</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="st0">'*'</span> <span class="sy0">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>verbose<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a> <span class="br0">&#40;</span><span class="st0">&quot;operator *<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; push <span class="br0">&#40;</span>pop<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">*</span> pop<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">break</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="st0">'/'</span> <span class="sy0">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>verbose<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a> <span class="br0">&#40;</span><span class="st0">&quot;operator /<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; op2 <span class="sy0">=</span> pop<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>op2 <span class="sy0">!=</span> <span class="nu16">0.0</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; push <span class="br0">&#40;</span>pop<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">/</span> op2<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fprintf <span class="br0">&#40;</span>stderr<span class="sy0">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;Error: division by zero<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">break</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">case</span> NUMBER <span class="sy0">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; push <span class="br0">&#40;</span>atof <span class="br0">&#40;</span>argv<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">break</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">default</span> <span class="sy0">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; fprintf <span class="br0">&#40;</span>stderr<span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;Error: unknown operator %s<span class="es1">\n</span>&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; argv<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">break</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; <span class="co1">// Result</span><br />
&nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a> <span class="br0">&#40;</span><span class="st0">&quot;%f<span class="es1">\n</span>&quot;</span><span class="sy0">,</span> val<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; <span class="kw1">return</span> <span class="nu0">0</span><span class="sy0">;</span><br />
<br />
<span class="br0">&#125;</span><br />
<br />
<span class="coMULTI">/**<br />
&nbsp;* &nbsp;Toi<br />
&nbsp;*/</span><br />
<span class="kw4">int</span> toi <span class="br0">&#40;</span><span class="kw4">char</span> <span class="kw4">const</span> <span class="sy0">*</span>s<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="kw1">return</span> <span class="br0">&#40;</span>isdigit<span class="br0">&#40;</span>s<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">?</span> <br />
&nbsp; &nbsp; NUMBER <span class="sy0">:</span> <span class="br0">&#40;</span><span class="kw4">int</span><span class="br0">&#41;</span> s<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="coMULTI">/**<br />
&nbsp;* &nbsp;Push<br />
&nbsp;*/</span><br />
<span class="kw4">void</span> push <span class="br0">&#40;</span><span class="kw4">double</span> e<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>sp <span class="sy0">&lt;</span> MAXVAL<span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>verbose<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a> <span class="br0">&#40;</span><span class="st0">&quot;push %f in %d<span class="es1">\n</span>&quot;</span><span class="sy0">,</span> e<span class="sy0">,</span> sp<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; val<span class="br0">&#91;</span>sp<span class="sy0">++</span><span class="br0">&#93;</span> <span class="sy0">=</span> e<span class="sy0">;</span><br />
&nbsp; <span class="br0">&#125;</span><br />
&nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; fprintf <span class="br0">&#40;</span>stderr<span class="sy0">,</span> <span class="st0">&quot;Error: full stack<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="coMULTI">/**<br />
&nbsp;* &nbsp;Pop<br />
&nbsp;*/</span><br />
<span class="kw4">double</span> pop <span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>sp <span class="sy0">&gt;</span> <span class="nu0">0</span><span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="sy0">--</span>sp<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>verbose<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a> <span class="br0">&#40;</span><span class="st0">&quot;pop %f from %d<span class="es1">\n</span>&quot;</span><span class="sy0">,</span> val<span class="br0">&#91;</span>sp<span class="br0">&#93;</span><span class="sy0">,</span> sp<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> val<span class="br0">&#91;</span>sp<span class="br0">&#93;</span><span class="sy0">;</span><br />
&nbsp; <span class="br0">&#125;</span><br />
&nbsp; <span class="kw1">else</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; fprintf <span class="br0">&#40;</span>stderr<span class="sy0">,</span> <span class="st0">&quot;Error: empty stack<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu16">0.0</span><span class="sy0">;</span><br />
&nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div></td></tr></tbody></table></div>
<p>Para compilarlo ejecutamos</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">$ <span class="kw2">gcc</span> <span class="re5">-o</span> calc calc.c</div></div>
<p>A diferencia del programa original publicado en el libro de C, aquí se utiliza el array<code>argv[]</code>como fuente de operandos y operadores. Esto permite que podamos llamar al programa desde línea de comandos de la siguiente manera:</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">$ .<span class="sy0">/</span>calc <span class="nu0">5</span> <span class="nu0">1</span> <span class="nu0">2</span> + <span class="nu0">4</span> \<span class="sy0">*</span> + <span class="nu0">3</span> -</div></div>
<p>Notar que para el caso especial del operador multiplicación, debemos <i>escaparlo</i> para evitar la expansión propia de bash antes de la llamada efectiva al programa.</p>
<p>El programa admite la opción<code>-v</code>(verbose), que muestra información acerca de uno de los pasos realizados.</p>
<h4>Ejemplo I</h4>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;width:435px;height:300px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">$ ./calc -v 5 1 2 + 4 \* + 3 -<br />
push 5.000000 in 0<br />
push 1.000000 in 1<br />
push 2.000000 in 2<br />
operator +<br />
pop 2.000000 from 2<br />
pop 1.000000 from 1<br />
push 3.000000 in 1<br />
push 4.000000 in 2<br />
operator *<br />
pop 4.000000 from 2<br />
pop 3.000000 from 1<br />
push 12.000000 in 1<br />
operator +<br />
pop 12.000000 from 1<br />
pop 5.000000 from 0<br />
push 17.000000 in 0<br />
push 3.000000 in 1<br />
operator -<br />
pop 3.000000 from 1<br />
pop 17.000000 from 0<br />
push 14.000000 in 0<br />
14.000000</div></div>
<p><span id="more-419"></span></p>
<h4>Ejemplo II</h4>
<p>La expresión algebráica (de resultado -3)</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">(3 * 9 / ((4 - 1) * 3)) - 6</div></div>
<p>Tiene la siguiente notación polaca inversa</p>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;width:435px;height:300px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">$ ./calc -v 3 9 \* 4 1 - 3 \* / 6 -<br />
push 3.000000 in 0<br />
push 9.000000 in 1<br />
operator *<br />
pop 9.000000 from 1<br />
pop 3.000000 from 0<br />
push 27.000000 in 0<br />
push 4.000000 in 1<br />
push 1.000000 in 2<br />
operator -<br />
pop 1.000000 from 2<br />
pop 4.000000 from 1<br />
push 3.000000 in 1<br />
push 3.000000 in 2<br />
operator *<br />
pop 3.000000 from 2<br />
pop 3.000000 from 1<br />
push 9.000000 in 1<br />
operator /<br />
pop 9.000000 from 1<br />
pop 27.000000 from 0<br />
push 3.000000 in 0<br />
push 6.000000 in 1<br />
operator -<br />
pop 6.000000 from 1<br />
pop 3.000000 from 0<br />
push -3.000000 in 0<br />
-3.000000</div></div>
<h4>Referencias</h4>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Polish_notation" class="external">Polish notation</a></li>
<li><a href="http://en.wikipedia.org/wiki/Reverse_Polish_notation" class="external">Reverse Polish notation</a></li>
<li><a href="http://h41111.www4.hp.com/calculators/es/es/articles/rpn.html" class="external">RPN: Introducción a la notación polaca inversa</a></li>
<li><a href="http://codigomaldito.blogspot.com/2008/04/calculadora-con-notacin-polaca-inversa.html" class="external">Calculadora con notación polaca inversa en C</a><br />(código original publicado en libro de C)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2009/04/calculadora-de-notacion-polaca-inversa-en-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Accediendo a MySQL con Python y MySQLdb</title>
		<link>http://blog.calcifer.com.ar/2009/03/accediendo-a-mysql-con-python-y-mysqldb/</link>
		<comments>http://blog.calcifer.com.ar/2009/03/accediendo-a-mysql-con-python-y-mysqldb/#comments</comments>
		<pubDate>Thu, 26 Mar 2009 15:00:27 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/?p=330</guid>
		<description><![CDATA[MySQLdb es un módulo que implementa la API estándar (PEP249) para manejo de bases de datos, en este caso MySQL. MySQLdb es en realidad un wrapper del módulo _mysql que provee Python, el cual implementa la mayoría de las funciones definidas en la API C de MySQL. La idea de definir una API estándar es [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://sourceforge.net/projects/mysql-python" class="external">MySQLdb</a> es un módulo que implementa la <a href="http://www.python.org/dev/peps/pep-0249/">API estándar (PEP249)</a> para manejo de bases de datos, en este caso <a href="http://www.mysql.com" class="external">MySQL</a>. MySQLdb es en realidad un wrapper del módulo _mysql que provee Python, el cual implementa la mayoría de las funciones definidas en la <a href="http://mysql-python.sourceforge.net/MySQLdb.html#mysql-c-api-function-mapping">API C de MySQL</a>. La idea de definir una API estándar es que uno debería poder cambiar a otra base de datos sin modificar demasiado el código.</p>
<blockquote title="python.org"><p>This API has been defined to encourage similarity between the Python modules that are used to access databases.</p></blockquote>
<h3>Instalación MySQLdb</h3>
<p>El paquete que nos provee el módulo se llama python-mysqldb. Podemos comprobar que lo tenemos instalado mediante</p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">dpkg</span> <span class="re5">--get-selections</span> <span class="sy0">|</span> <span class="kw2">grep</span> python-mysqldb</div></div>
<p>Si no existe lo instalamos</p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">sudo</span> <span class="kw2">apt-get</span> <span class="kw2">install</span> python-mysqldb</div></div>
<p>Para comprobar que efectivamente tenemos el módulo disponible y funcionando llamamos al <a href="http://docs.python.org/tutorial/interpreter.html" class="external">intérprete de Python</a> y escribimos</p>
<div class="codecolorer-container python " style="overflow:auto;white-space:nowrap;width:435px"><div class="python codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sy0">&gt;&gt;&gt;</span> <span class="kw1">import</span> MySQLdb</div></div>
<p>Un silencioso retorno de carro indica que podemos <a href="http://xkcd.com/353/" class="external">el módulo ha sido cargado</a>. Salimos del intérprete con<code>C-d</code>.</p>
<h3>Creación de una DB de pruebas</h3>
<p>Para nuestro ejemplo crearemos una base de datos con una única tabla. Entramos a la <a href="http://dev.mysql.com/doc/refman/5.1/en/mysql.html" class="external">consola de MySQL</a> y escribimos</p>
<div class="codecolorer-container mysql " style="overflow:auto;white-space:nowrap;width:435px"><div class="mysql codecolorer" style="font-family:Monaco,Lucida Console,monospace">mysql<span class="sy1">&gt;</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=CREATE&amp;lr=lang_en"><span class="kw1">CREATE</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=DATABASE&amp;lr=lang_en"><span class="kw2">database</span></a> test<span class="sy2">;</span><br />
Query OK<span class="sy2">,</span> <span class="nu0">1</span> row affected <span class="br0">&#40;</span><span class="nu0">0.01</span> sec<span class="br0">&#41;</span><br />
<br />
mysql<span class="sy1">&gt;</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=USE&amp;lr=lang_en"><span class="kw1">USE</span></a> test<span class="sy2">;</span><br />
<a href="http://search.mysql.com/search?site=refman-51&amp;q=DATABASE&amp;lr=lang_en"><span class="kw2">Database</span></a> changed<br />
mysql<span class="sy1">&gt;</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=CREATE&amp;lr=lang_en"><span class="kw1">CREATE</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=TABLE&amp;lr=lang_en"><span class="kw1">TABLE</span></a> users <span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="sy1">-&gt;</span> id <a href="http://search.mysql.com/search?site=refman-51&amp;q=INT&amp;lr=lang_en"><span class="kw4">INT</span></a> <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span class="kw10">NOT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=NULL&amp;lr=lang_en"><span class="kw3">NULL</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=AUTO_INCREMENT&amp;lr=lang_en"><span class="kw6">AUTO_INCREMENT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=PRIMARY%20KEY&amp;lr=lang_en"><span class="kw1">PRIMARY KEY</span></a><span class="sy2">,</span><br />
&nbsp; &nbsp; <span class="sy1">-&gt;</span> name <a href="http://search.mysql.com/search?site=refman-51&amp;q=VARCHAR&amp;lr=lang_en"><span class="kw4">VARCHAR</span></a><span class="br0">&#40;</span><span class="nu0">100</span><span class="br0">&#41;</span><span class="sy2">,</span><br />
&nbsp; &nbsp; <span class="sy1">-&gt;</span> lastname <a href="http://search.mysql.com/search?site=refman-51&amp;q=VARCHAR&amp;lr=lang_en"><span class="kw4">VARCHAR</span></a><span class="br0">&#40;</span><span class="nu0">100</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="sy1">-&gt;</span> <span class="br0">&#41;</span><span class="sy2">;</span><br />
Query OK<span class="sy2">,</span> <span class="nu0">0</span> rows affected <span class="br0">&#40;</span><span class="nu0">0.01</span> sec<span class="br0">&#41;</span><br />
<br />
mysql<span class="sy1">&gt;</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=INSERT&amp;lr=lang_en"><span class="kw2">INSERT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=INTO&amp;lr=lang_en"><span class="kw1">INTO</span></a> users <span class="br0">&#40;</span>name<span class="sy2">,</span> lastname<span class="br0">&#41;</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=VALUES&amp;lr=lang_en"><span class="kw1">VALUES</span></a><br />
&nbsp; &nbsp; <span class="sy1">-&gt;</span> <span class="br0">&#40;</span><span class="st0">'Juan'</span><span class="sy2">,</span> <span class="st0">'Perez'</span><span class="br0">&#41;</span><span class="sy2">,</span><br />
&nbsp; &nbsp; <span class="sy1">-&gt;</span> <span class="br0">&#40;</span><span class="st0">'Ana Maria'</span><span class="sy2">,</span> <span class="st0">'Lopez'</span><span class="br0">&#41;</span><span class="sy2">,</span><br />
&nbsp; &nbsp; <span class="sy1">-&gt;</span> <span class="br0">&#40;</span><span class="st0">'Carlos L.'</span><span class="sy2">,</span> <span class="st0">'Gutierrez'</span><span class="br0">&#41;</span><span class="sy2">;</span><br />
Query OK<span class="sy2">,</span> <span class="nu0">3</span> rows affected <span class="br0">&#40;</span><span class="nu0">0.00</span> sec<span class="br0">&#41;</span><br />
Records: <span class="nu0">3</span> &nbsp;Duplicates: <span class="nu0">0</span> &nbsp;<a href="http://search.mysql.com/search?site=refman-51&amp;q=WARNINGS&amp;lr=lang_en"><span class="kw1">Warnings</span></a>: <span class="nu0">0</span></div></div>
<p>Nuestra tabla users quedó entonces</p>
<div class="codecolorer-container mysql " style="overflow:auto;white-space:nowrap;width:435px"><div class="mysql codecolorer" style="font-family:Monaco,Lucida Console,monospace">mysql<span class="sy1">&gt;</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=SELECT&amp;lr=lang_en"><span class="kw1">SELECT</span></a> <span class="sy1">*</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=FROM&amp;lr=lang_en"><span class="kw1">FROM</span></a> users<span class="sy2">;</span><br />
<span class="sy1">+----+-----------+-----------+</span><br />
<span class="sy1">|</span> id <span class="sy1">|</span> name &nbsp; &nbsp; &nbsp;<span class="sy1">|</span> lastname &nbsp;<span class="sy1">|</span><br />
<span class="sy1">+----+-----------+-----------+</span><br />
<span class="sy1">|</span> &nbsp;<span class="nu0">1</span> <span class="sy1">|</span> Juan &nbsp; &nbsp; &nbsp;<span class="sy1">|</span> Perez &nbsp; &nbsp; <span class="sy1">|</span> <br />
<span class="sy1">|</span> &nbsp;<span class="nu0">2</span> <span class="sy1">|</span> Ana Maria <span class="sy1">|</span> Lopez &nbsp; &nbsp; <span class="sy1">|</span> <br />
<span class="sy1">|</span> &nbsp;<span class="nu0">3</span> <span class="sy1">|</span> Carlos L. <span class="sy1">|</span> Gutierrez <span class="sy1">|</span> <br />
<span class="sy1">+----+-----------+-----------+</span><br />
<span class="nu0">3</span> rows <a href="http://search.mysql.com/search?site=refman-51&amp;q=IN&amp;lr=lang_en"><span class="kw2">in</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=SET&amp;lr=lang_en"><span class="kw1">set</span></a> <span class="br0">&#40;</span><span class="nu0">0.00</span> sec<span class="br0">&#41;</span></div></div>
<h3>Creación del script mysqldb.py</h3>
<p>Creamos el siguiente script que se conectará a la base de datos test y traerá todos los datos de los usuarios cargados en la tabla users. En el script es necesario reemplazar &lt;user&gt; y &lt;pass&gt; por los datos requeridos para acceder a tu DB.</p>
<div class="codecolorer-container python " style="overflow:auto;white-space:nowrap;width:435px;height:300px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br /></div></td><td><div class="python codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co1">#!/usr/bin/python</span><br />
<span class="kw1">import</span> MySQLdb<br />
<br />
<span class="co1"># Conexion a la base de datos</span><br />
conn = MySQLdb.<span class="me1">connect</span> <span class="br0">&#40;</span>host=<span class="st0">&quot;localhost&quot;</span>,<br />
&nbsp; &nbsp; <span class="kw3">user</span>=<span class="st0">&quot;&lt;user&gt;&quot;</span>, passwd=<span class="st0">&quot;&lt;pass&gt;&quot;</span>, db=<span class="st0">&quot;test&quot;</span><span class="br0">&#41;</span><br />
<br />
<span class="co1"># Creacion cursor</span><br />
cursor = conn.<span class="me1">cursor</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<br />
<span class="co1"># Ejecucion query</span><br />
cursor.<span class="me1">execute</span><span class="br0">&#40;</span><span class="st0">&quot;SELECT * FROM users&quot;</span><span class="br0">&#41;</span><br />
<br />
<span class="co1"># Manejo de datos devueltos por la consulta</span><br />
<span class="kw1">while</span> <span class="kw2">True</span>:<br />
&nbsp; &nbsp; row = cursor.<span class="me1">fetchone</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> row <span class="kw1">is</span> <span class="kw2">None</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><br />
&nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;id: %s<span class="es0">\t</span>name: %s %s&quot;</span> <span class="sy0">%</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>row<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>, row<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>, row<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span><span class="br0">&#41;</span><br />
<br />
<span class="co1"># Finalizado cursor y objeto conexion</span><br />
cursor.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
conn.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div></td></tr></tbody></table></div>
<p>La salida debería ser</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">id: 1 &nbsp; name: Juan Perez<br />
id: 2 &nbsp; name: Ana Maria Lopez<br />
id: 3 &nbsp; name: Carlos L. Gutierrez</div></div>
<h4>Links recomendados para ampliar conocimientos</h4>
<ul>
<li><a href="http://mysql-python.sourceforge.net/MySQLdb.html" class="external">MySQLdb User&#8217;s Guide</a></li>
<li><a href="http://www.kitebird.com/articles/pydbapi.html" class="external">Writing MySQL Scripts with Python DB-API</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2009/03/accediendo-a-mysql-con-python-y-mysqldb/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>GNU gettext con php5</title>
		<link>http://blog.calcifer.com.ar/2009/03/gnu-gettext-con-php5/</link>
		<comments>http://blog.calcifer.com.ar/2009/03/gnu-gettext-con-php5/#comments</comments>
		<pubDate>Sat, 21 Mar 2009 17:55:06 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[gnu/linux]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/?p=226</guid>
		<description><![CDATA[
GNU gettext es la biblioteca GNU de internacionalización (i18n) y es usada para escribir programas con interfaz en múltiples idiomas.
wikipedia
La internacionalización es el proceso de diseñar software de manera tal que pueda adaptarse a diferentes idiomas y regiones sin necesidad de cambios de ingeniería ni de código. La localización es el proceso de adaptar el [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.calcifer.com.ar/uploads/2009/03/gnu-head-sm.jpg" alt="gnu-head-sm" title="gnu-head-sm" width="129" height="122" class="alignright size-full wp-image-231" /></p>
<p><a href="http://www.gnu.org/software/gettext/gettext.html" class="wikipedia">GNU gettext</a> es la biblioteca <a href="http://es.wikipedia.org/wiki/GNU" class="wikipedia">GNU</a> de <a href="http://es.wikipedia.org/wiki/Internacionalizaci%C3%B3n_(computaci%C3%B3n)" class="wikipedia">internacionalización</a> (i18n) y es usada para escribir programas con interfaz en múltiples idiomas.</p>
<p><a href="http://es.wikipedia.org/wiki/Internacionalizaci%C3%B3n_(computaci%C3%B3n)" class="wikipedia">wikipedia</a></p>
<blockquote title="wikipedia.org"><p>La internacionalización es el proceso de diseñar software de manera tal que pueda adaptarse a diferentes idiomas y regiones sin necesidad de cambios de ingeniería ni de código. La localización es el proceso de adaptar el software para una región específica mediante la adición de componentes específicos de un locale y la traducción de los textos, por lo que también se le puede denominar regionalización.<br />
&#8230;<br />
Es una práctica común en el idioma inglés (sobre todo en el ámbito de la computación), abreviar internationalization como &#8220;i18n&#8221;. Ello se debe a que entre la primera i y la última n de dicha palabra hay 18 letras. Lo mismo sucede con localization, que se abrevia &#8220;L10n&#8221;.
</p></blockquote>
<h3>gettext en PHP</h3>
<p>Existen dos formas de usar gettext en PHP: mediante la <a href="http://ar2.php.net/manual/en/book.gettext.php" class="external">extensión gettext nativa de PHP</a> o utilizando la librería <a href="http://savannah.nongnu.org/projects/php-gettext/" class="external">PHP-gettext</a>, escrita en PHP, que no necesita ninguna extensión.</p>
<p>La forma de usar gettext es</p>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:435px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"># @file: index.php<br />
<span class="kw2">&lt;?php</span><br />
<a href="http://www.php.net/print"><span class="kw3">print</span></a> <a href="http://www.php.net/_"><span class="kw3">_</span></a><span class="br0">&#40;</span><span class="st0">&quot;hello world&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span></div></td></tr></tbody></table></div>
<p>La función<code>_()</code>, alias de<code>gettext()</code>, devolverá la cadena &#8220;hello world&#8221; en el lenguaje correspondiente, de acuerdo al <a href="http://en.wikipedia.org/wiki/Locale" class="wikipedia">locale</a> que hayamos seleccionado.</p>
<p>Si ejecutamos el script obtendremos &#8220;hello world&#8221; como salida, puesto que no hemos indicado ningún locale, ni creado ningún catálogo de traducción. Necesitamos crear el archivo<code>comments.po</code>con la traducción de la cadena &#8220;hello world&#8221;. Esto puede hacerse mediante el comando<code>xgettext</code>, o mediante un editor gráfico como <a href="http://www.poedit.net/" class="external">poEdit</a>.</p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">apt-get</span> <span class="kw2">install</span> poedit</div></div>
<h3>Creación del catálogo con poEdit</h3>
<p>Ante todo debemos saber que la estructura de directorios para guardar los distintos catálogos tiene forma determinada. Por cada traducción se utiliza un directorio. Este generalmente se nombra usando dos letras minúsculas para el idioma, un guión bajo y dos mayúsculas para el país (es_AR, para español de Argentina). Dentro de este directorio debe existir otro con el nombre LC_MESSAGES, el cual será finalmente el directorio que contendrá el catálogo.</p>
<p>La estructura de nuestro ejemplo será</p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">.<br />
<span class="sy0">|</span>-- locale<br />
<span class="sy0">|</span> &nbsp; <span class="sy0">`</span>-- es_AR<br />
<span class="sy0">|</span> &nbsp; &nbsp; &nbsp; <span class="sy0">`</span>-- LC_MESSAGES<br />
<span class="sy0">|</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">|</span>-- messages.mo<br />
<span class="sy0">|</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">`</span>-- messages.po<br />
<span class="sy0">`</span>-- index.php</div></div>
<p>El archivo<code>messages.mo</code>es la versión compilada de<code>messages.po</code>y el que usará PHP para obtener la traducción.</p>
<p>Iniciemos poEdit. La primera vez nos preguntará por nuestro nombre y correo electrónico. Estos datos servirán para saber quién fue el último traductor que modificó el catálogo. Una vez en la ventana principal vamos a File -> New catalog. Seleccionamos el idioma (Español en este caso), el país y el código de caracteres tanto para el catálogo como para la fuente de datos desde la que obtendremos el listado de cadenas que requieren traducción. En la solapa Paths debemos colocar en &#8216;Base path&#8217; la ruta completa al directorio base de archivos php (conteniendo las cadenas mencionadas anteriormente) y, debajo, en el cuadro &#8216;Paths&#8217; agregar una entrada con &#8216;.&#8217; indicando que se debe utilizar el directorio ingresado anteriormente. Al hacer click en OK aparecerá un cuadro de diálogo para guardar el nuevo catálogo. Navegamos hasta el directorio LC_MESSAGES y guardamos el archivo como messages.po. poEdit escaneará el directorio ingresado en Paths y extraerá todos las cadenas gettext. Ahora queda simplemente realizar la traducción y guardar el archivo. Al guardarlo, poEdit lo compilará y generará el .mo que finalmente usará PHP.</p>
<p>Ahora, modificaremos index.php para setear el locale</p>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:435px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"># @file: index.php<br />
<span class="kw2">&lt;?php</span><br />
<span class="re0">$language</span> <span class="sy0">=</span> <span class="st_h">'es_AR.UTF-8'</span><span class="sy0">;</span><br />
<a href="http://www.php.net/putenv"><span class="kw3">putenv</span></a><span class="br0">&#40;</span><span class="st0">&quot;LANG=<span class="es4">$language</span>&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span> <br />
<a href="http://www.php.net/setlocale"><span class="kw3">setlocale</span></a><span class="br0">&#40;</span>LC_ALL<span class="sy0">,</span> <span class="st0">&quot;&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="re0">$domain</span> <span class="sy0">=</span> <span class="st0">&quot;messages&quot;</span><span class="sy0">;</span><br />
<a href="http://www.php.net/bindtextdomain"><span class="kw3">bindtextdomain</span></a><span class="br0">&#40;</span><span class="re0">$domain</span><span class="sy0">,</span> <span class="st0">&quot;./locale&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<a href="http://www.php.net/bind_textdomain_codeset"><span class="kw3">bind_textdomain_codeset</span></a><span class="br0">&#40;</span><span class="re0">$domain</span><span class="sy0">,</span> <span class="st_h">'UTF-8'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<a href="http://www.php.net/textdomain"><span class="kw3">textdomain</span></a><span class="br0">&#40;</span><span class="re0">$domain</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<a href="http://www.php.net/print"><span class="kw3">print</span></a> <a href="http://www.php.net/_"><span class="kw3">_</span></a><span class="br0">&#40;</span><span class="st0">&quot;hello world&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span></div></td></tr></tbody></table></div>
<p>Aun nos queda un paso y es comprobar que tengamos dicho locale habilitado en nuestro sistema. Esto lo hacemos mirando la salida de</p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">locale <span class="re5">-a</span></div></div>
<p>Si no tenemos habilitado el charset es_AR.UTF8, ejecutamos</p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">locale-gen es_AR.UTF-<span class="nu0">8</span></div></div>
<p>En este punto la salida del script debería ser la traducción que hicimos al español.</p>
<h3>Tip</h3>
<p>Para casos en que la cadena a traducir contenga variables, podemos utilizar esta función:</p>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:435px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">function</span> __<span class="br0">&#40;</span><span class="re0">$string</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="re0">$arg</span> <span class="sy0">=</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">for</span><span class="br0">&#40;</span><span class="re0">$i</span> <span class="sy0">=</span> <span class="nu0">1</span> <span class="sy0">;</span> <span class="re0">$i</span> <span class="sy0">&lt;</span> <a href="http://www.php.net/func_num_args"><span class="kw3">func_num_args</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">++</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$arg</span><span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="sy0">=</span> <a href="http://www.php.net/func_get_arg"><span class="kw3">func_get_arg</span></a><span class="br0">&#40;</span><span class="re0">$i</span><span class="br0">&#41;</span><span class="sy0">;</span> <br />
&nbsp; &nbsp; <span class="kw1">return</span> <a href="http://www.php.net/vsprintf"><span class="kw3">vsprintf</span></a><span class="br0">&#40;</span><a href="http://www.php.net/gettext"><span class="kw3">gettext</span></a><span class="br0">&#40;</span><span class="re0">$string</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="re0">$arg</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="re0">$total</span> <span class="sy0">=</span> <span class="nu0">400</span><span class="sy0">;</span><br />
<a href="http://www.php.net/print"><span class="kw3">print</span></a> __<span class="br0">&#40;</span><span class="st0">&quot;results <span class="es6">%d</span> - <span class="es6">%d</span> of about <span class="es6">%d</span>&quot;</span><span class="sy0">,</span> <span class="nu0">1</span><span class="sy0">,</span> <span class="nu0">20</span><span class="sy0">,</span> <span class="re0">$total</span><span class="br0">&#41;</span><span class="sy0">;</span></div></td></tr></tbody></table></div>
<p>La traducción podría quedar</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">resultados %d - %d de aproximadamente %d</div></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2009/03/gnu-gettext-con-php5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code Golf &#8211; Saving Time</title>
		<link>http://blog.calcifer.com.ar/2009/02/code-golf-saving-time/</link>
		<comments>http://blog.calcifer.com.ar/2009/02/code-golf-saving-time/#comments</comments>
		<pubDate>Mon, 09 Feb 2009 19:08:36 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/?p=187</guid>
		<description><![CDATA[Code Golf es un sitio donde se juega a resolver problemas informáticos en la menor cantidad posible de pulsaciones de tecla. Para ello pueden utilizarse lenguajes como Perl, PHP, Python y Ruby. Quien resuelva el desafío en menor cantidad de keystrokes es quien tendrá mayor puntaje.
Me anoté en uno llamado Saving Time y llegué al [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://codegolf.com" class="external">Code Golf</a> es un sitio donde se juega a resolver problemas informáticos en la menor cantidad posible de pulsaciones de tecla. Para ello pueden utilizarse lenguajes como Perl, PHP, Python y Ruby. Quien resuelva el desafío en menor cantidad de <em>keystrokes</em> es quien tendrá mayor puntaje.</p>
<p>Me anoté en uno llamado <a href="http://codegolf.com/saving-time" class="external">Saving Time</a> y llegué al <a href="http://codegolf.com/leaderboard/competition/saving-time/php" class="external">puesto 20 de PHP</a>, con 245 keystrokes. (<strong>2009-03-27: Aunque ahora me encuentro en el 22, malditos nerds!</strong>)</p>
<p>El desafío consiste en crear la cara de un reloj analógico partiendo de una hora dada en formato<code>hh:mm</code>. Algunas de las reglas son</p>
<ul>
<li>La hora dada en hh:mm se representa con una &#8216;h&#8217; minúscula.</li>
<li>La hora que indica los minutos dados en hh:mm se representa con una &#8216;m&#8217; minúscula.</li>
<li>Cuando hora y minutos coinciden en la misma posición se representa con una &#8216;x&#8217; minúscula.</li>
<li>El resto de las horas se representan con una &#8216;o&#8217; minúscula.</li>
<li>Los minutos deben redondearse al múltiplo de 5 más cercano (23 se convierte en 20, 39 en 35, etc.)</li>
</ul>
<h3>Salida del programa</h3>
<p><iframe src="/devel/code-golf/saving_time.php" width="400" height="270" frameborder="0"></iframe></p>
<h3>Código</h3>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sy1">&lt;?</span><span class="re0">$f</span><span class="sy0">=</span><span class="st0">&quot;874D1F0D1748110202020201&quot;</span><span class="sy0">;</span><br />
<a href="http://www.php.net/list"><span class="kw3">list</span></a><span class="br0">&#40;</span><span class="re0">$h</span><span class="sy0">,</span><span class="re0">$m</span><span class="br0">&#41;</span><span class="sy0">=</span><a href="http://www.php.net/split"><span class="kw3">split</span></a><span class="br0">&#40;</span><span class="st_h">':'</span><span class="sy0">,</span><a href="http://www.php.net/fgets"><span class="kw3">fgets</span></a><span class="br0">&#40;</span>STDIN<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$h</span><span class="sy0">&gt;=</span><span class="nu0">12</span><span class="br0">&#41;</span><span class="re0">$h</span><span class="sy0">-=</span><span class="nu0">12</span><span class="sy0">;</span><br />
<span class="re0">$m</span><span class="sy0">=</span><a href="http://www.php.net/floor"><span class="kw3">floor</span></a><span class="br0">&#40;</span><span class="re0">$m</span><span class="sy0">/</span><span class="nu0">5</span><span class="br0">&#41;</span><span class="sy0">;</span><span class="re0">$a</span><span class="sy0">=</span><span class="re0">$i</span><span class="sy0">=</span><span class="nu0">12</span><span class="sy0">;</span><br />
<span class="kw1">while</span><span class="br0">&#40;</span><span class="re0">$i</span><span class="br0">&#41;</span><span class="br0">&#123;</span><span class="re0">$a</span><span class="sy0">+=</span><span class="re0">$i</span><span class="sy0">%</span><span class="nu19">2</span>?<span class="re0">$i</span><span class="sy0">:-</span><span class="re0">$i</span><span class="sy0">;</span><br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <a href="http://www.php.net/str_pad"><span class="kw3">str_pad</span></a><span class="br0">&#40;</span><span class="st0">&quot;&quot;</span><span class="sy0">,</span><a href="http://www.php.net/hexdec"><span class="kw3">hexdec</span></a><span class="br0">&#40;</span><span class="re0">$f</span><span class="br0">&#123;</span><span class="sy0">--</span><span class="re0">$i</span><span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">.</span><br />
<span class="br0">&#40;</span><span class="br0">&#40;</span><span class="re0">$a</span><span class="sy0">==</span><span class="re0">$h</span><span class="br0">&#41;</span>?<span class="br0">&#40;</span><span class="re0">$h</span><span class="sy0">==</span><span class="re0">$m</span>?<span class="st_h">'x'</span><span class="sy0">:</span><span class="st_h">'h'</span><span class="br0">&#41;</span><span class="sy0">:</span><span class="br0">&#40;</span><span class="re0">$a</span><span class="sy0">==</span><span class="re0">$m</span>?<span class="st_h">'m'</span><span class="sy0">:</span><span class="st_h">'o'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">.</span><br />
<a href="http://www.php.net/str_repeat"><span class="kw3">str_repeat</span></a><span class="br0">&#40;</span><span class="st0">&quot;<span class="es1">\n</span>&quot;</span><span class="sy0">,</span><span class="re0">$f</span><span class="br0">&#123;</span><span class="re0">$i</span><span class="sy0">+</span><span class="nu0">12</span><span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span><span class="br0">&#125;</span><span class="sy1">?&gt;</span></div></div>
<p>El string hexadecimal $f contiene el formato necesario para &#8220;dibujar&#8221; el reloj. Para interpretarlo es necesario dividirlo en dos mitades. La primera mitad contiene, en cada caracter hexadecimal, la distancia a la que se encuentra respecto de su elemento anterior, que puede ser el número de la izquierda o un salto de línea. De aquí surge el por qué de haber usado el sistema hexadecimal: el espacio mayor a representar es 15. En la segunda mitad cada caracter representa la cantidad de saltos de línea que preceden al caracter.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2009/02/code-golf-saving-time/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pattern Singleton en PHP4</title>
		<link>http://blog.calcifer.com.ar/2007/07/pattern-singleton-en-php4/</link>
		<comments>http://blog.calcifer.com.ar/2007/07/pattern-singleton-en-php4/#comments</comments>
		<pubDate>Mon, 30 Jul 2007 12:44:51 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/2007/07/30/pattern-singleton-en-php4/</guid>
		<description><![CDATA[A pesar de sus limitaciones en cuanto a orientación a objetos, PHP4 permite implementar un pattern del tipo Singleton.
Por defecto, en PHP4 (y a diferencia de PHP5) los objetos se devuelven/asignan por valor (una copia), por ello es necesario indicar expresamente que deseamos devolver/asignar una referencia del objeto en cuestión.
Una de las formas más elegantes [...]]]></description>
			<content:encoded><![CDATA[<p>A pesar de sus limitaciones en cuanto a orientación a objetos, PHP4 permite implementar un pattern del tipo Singleton.</p>
<p>Por defecto, en PHP4 (y a diferencia de PHP5) los objetos se devuelven/asignan por valor (una copia), por ello es necesario indicar expresamente que deseamos devolver/asignar una referencia del objeto en cuestión.</p>
<p>Una de las formas más elegantes de implemetar este pattern es:</p>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:435px;height:600px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br /></div></td><td><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co1">// Clase de la cual deseamos que exista</span><br />
<span class="co1">// una única instancia en todo el programa</span><br />
<span class="kw2">class</span> Config<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw2">var</span> <span class="re0">$message</span> <span class="sy0">=</span> <span class="kw2">null</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp;<span class="kw2">function</span> set<span class="br0">&#40;</span><span class="re0">$message</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">message</span> <span class="sy0">=</span> <span class="re0">$message</span><span class="sy0">;</span><br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp;<span class="kw2">function</span> get<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">message</span><span class="sy0">;</span><br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="co1">// Pattern que se ocupará de devolver</span><br />
<span class="co1">// la única instancia de la clase Config</span><br />
<span class="kw2">class</span> Singleton<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="co1">// Método que devuelve una referencia al objeto</span><br />
&nbsp; &nbsp;<span class="kw2">function</span> <span class="sy0">&amp;</span>get<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span> &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; <a href="http://www.php.net/static"><span class="kw3">static</span></a> <span class="re0">$instance</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="sy0">!</span> <a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">&#40;</span><span class="re0">$instance</span><span class="br0">&#41;</span> <span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re0">$instance</span> <span class="sy0">=</span> <span class="kw2">new</span> Config<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<a href="http://www.php.net/print"><span class="kw3">print</span></a> <span class="st0">&quot;instancia creada.<span class="es1">\n</span>&quot;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$instance</span><span class="sy0">;</span> &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="co1">// Forma de uso</span><br />
<span class="re0">$config</span> <span class="sy0">=&amp;</span> Singleton<span class="sy0">::</span><span class="me2">get</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$config</span><span class="sy0">-&gt;</span><span class="me1">set</span><span class="br0">&#40;</span><span class="st_h">'hello world.'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<a href="http://www.php.net/printf"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">&quot;<span class="es6">%s</span><span class="es1">\n</span>&quot;</span><span class="sy0">,</span> <span class="re0">$config</span><span class="sy0">-&gt;</span><span class="me1">get</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="re0">$config</span> <span class="sy0">=&amp;</span> Singleton<span class="sy0">::</span><span class="me2">get</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<a href="http://www.php.net/printf"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">&quot;<span class="es6">%s</span><span class="es1">\n</span>&quot;</span><span class="sy0">,</span> <span class="re0">$config</span><span class="sy0">-&gt;</span><span class="me1">get</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></td></tr></tbody></table></div>
<p>Salida del programa</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">instancia creada.<br />
hello world.<br />
hello world.</div></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2007/07/pattern-singleton-en-php4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Javascript no intrusivo</title>
		<link>http://blog.calcifer.com.ar/2007/07/javascript-no-intrusivo/</link>
		<comments>http://blog.calcifer.com.ar/2007/07/javascript-no-intrusivo/#comments</comments>
		<pubDate>Tue, 17 Jul 2007 19:10:21 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[xhtml]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/2007/07/17/javascript-no-intrusivo/</guid>
		<description><![CDATA[Forma de usar Javascript fuera del flujo HTML:
123456789101112&#60;head&#62;
&#160; &#60;script type=&#34;text/javascript&#34;&#62;
&#160; &#160; window.onload = function&#40;&#41; &#123;
&#160; &#160; &#160; var reloj = document.getElementById&#40;&#34;reloj&#34;&#41;;
&#160; &#160; &#160; var fecha = &#40;new Date&#40;&#41;&#41;.toLocaleString&#40;&#41;;
&#160; &#160; &#160; reloj.innerHTML = fecha;
&#160; &#160; &#125;
&#160; &#60;/script&#62;
&#60;/head&#62;
&#60;body&#62;
&#160; &#60;div id=&#34;reloj&#34;&#62;No te puedo mostrar la hora&#60;/div&#62;
&#60;/body&#62;
]]></description>
			<content:encoded><![CDATA[<p>Forma de usar Javascript fuera del flujo HTML:</p>
<div class="codecolorer-container javascript " style="overflow:auto;white-space:nowrap;width:435px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="javascript codecolorer" style="font-family:Monaco,Lucida Console,monospace">&lt;head&gt;<br />
&nbsp; <span class="sy0">&lt;</span>script type<span class="sy0">=</span><span class="st0">&quot;text/javascript&quot;</span><span class="sy0">&gt;</span><br />
&nbsp; &nbsp; window.<span class="kw3">onload</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw2">var</span> reloj <span class="sy0">=</span> document.<span class="me1">getElementById</span><span class="br0">&#40;</span><span class="st0">&quot;reloj&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw2">var</span> fecha <span class="sy0">=</span> <span class="br0">&#40;</span><span class="kw2">new</span> Date<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>.<span class="me1">toLocaleString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; reloj.<span class="me1">innerHTML</span> <span class="sy0">=</span> fecha<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; <span class="sy0">&lt;/</span>script<span class="sy0">&gt;</span><br />
&lt;/head&gt;<br />
&lt;body&gt;<br />
&nbsp; &lt;div id=&quot;reloj&quot;&gt;No te puedo mostrar la hora&lt;/div&gt;<br />
&lt;/body&gt;</div></td></tr></tbody></table></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2007/07/javascript-no-intrusivo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Webserver en Java</title>
		<link>http://blog.calcifer.com.ar/2007/03/webserver-en-java/</link>
		<comments>http://blog.calcifer.com.ar/2007/03/webserver-en-java/#comments</comments>
		<pubDate>Sat, 17 Mar 2007 22:30:14 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/2007/03/17/webserver-en-java/</guid>
		<description><![CDATA[Se trata de un sencillo servidor web que hice recientemente, en Java. Sus características son:

Maneja Theads, lo que le permite atender peticiones simultáneas
Sirve los siguientes tipos de archivos: html, xml, css, js, txt, ico, png, gif, jpg y pdf
Implementa los dos errores más comunes: 404 y 403
Lleva un registro de logs al estilo combined de [...]]]></description>
			<content:encoded><![CDATA[<p>Se trata de un sencillo servidor web que hice recientemente, en Java. Sus características son:</p>
<ul>
<li>Maneja Theads, lo que le permite atender peticiones simultáneas</li>
<li>Sirve los siguientes tipos de archivos: html, xml, css, js, txt, ico, png, gif, jpg y pdf</li>
<li>Implementa los dos errores más comunes: 404 y 403</li>
<li>Lleva un registro de logs al estilo combined de Apache</li>
<li>Tiene una salida por consola de cada petición hecha, con los mensajes enviados durante el Request</li>
</ul>
<p>Código fuente: <a href='http://blog.calcifer.com.ar/devel/webserver-java/webserver-java.tar.gz'>webserver-java.tar.gz</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2007/03/webserver-en-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Generando Captchas con PHP</title>
		<link>http://blog.calcifer.com.ar/2006/10/generando-captchas-con-php/</link>
		<comments>http://blog.calcifer.com.ar/2006/10/generando-captchas-con-php/#comments</comments>
		<pubDate>Fri, 06 Oct 2006 04:12:28 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/2006/10/06/generando-captchas-con-php/</guid>
		<description><![CDATA[Captcha es el acrónimo de Completely Automated Public Turing test to tell Computers and Humans Apart (Prueba de Turing pública y automática para diferenciar a máquinas y humanos).
Se trata de una prueba desafío-respuesta utilizada en computación para determinar cuándo el usuario es o no humano. Como el test es controlado por una máquina en lugar [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Captcha</strong> es el acrónimo de <em><strong>C</strong>ompletely <strong>A</strong>utomated <strong>P</strong>ublic <a href="http://es.wikipedia.org/wiki/Prueba_de_Turing" title="Prueba de Turing en Wikipedia" class="linkwikipedia"><strong>T</strong>uring test</a> to tell <strong>C</strong>omputers and <strong>H</strong>umans <strong>A</strong>part</em> (Prueba de Turing pública y automática para diferenciar a máquinas y humanos).</p>
<p>Se trata de una prueba desafío-respuesta utilizada en computación para determinar cuándo el usuario es o no humano. Como el test es controlado por una máquina en lugar de un humano como en la prueba de turing, también se denomina Prueba de Turing inversa.</p>
<h2>Clase Captcha</h2>
<p>Esta es una clase que hice para <a href="http://www.lamarchaperonista.com.ar/pedidos" title="" class="linkexternal">www.lamarchaperonista.com.ar</a> que genera captchas usando fuentes True Type (.ttf). La clase tiene varios métodos para personalizar el captcha, generar el código y seteralo en una variable de sesión de PHP.</p>
<p>La forma de usarla es realmente simple. Sólo hay que crear un script que contenga la clase y devuelva el captcha. Este mismo script será el encargado de generar el código y guardarlo en una variable de sesión:</p>
<pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px;height:300px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">// File: getCaptcha.php<br />
requiere_once('Capcha.php');<br />
session_start();<br />
<br />
// Creo un captcha de 150 x 50 px<br />
$captcha = new Captcha(150, 50);<br />
<br />
// Creo y seteo en $_SESSION el código de 4 caracteres<br />
$captcha-&gt;setSessionVar(4);<br />
<br />
// Seteo la fuente TTF a usar<br />
if ($captcha-&gt;setFontFile('ArsleGothic.ttf')) {<br />
<br />
&nbsp; &nbsp;// Seteo el tamaño de la tipografía<br />
&nbsp; &nbsp;$captcha-&gt;setFontSize(24);<br />
<br />
&nbsp; &nbsp;// El color<br />
&nbsp; &nbsp;$captcha-&gt;setFontColorWeb('716052');<br />
<br />
&nbsp; &nbsp;// Envío la imagen<br />
&nbsp; &nbsp;$captcha-&gt;sendCaptcha();<br />
<br />
}</div></div>
</pre>
<p>Al ser llamado desde otra página (como esta), mediante</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">&amp;lt;img scr=&quot;getCapcha.php&quot;/&amp;gt;</div></div>
<p>, el script generará un captcha como el siguiente:</p>
<p class="center"><img src="http://blog.calcifer.com.ar/devel/captcha/getCaptcha.php?id=1" alt="Captcha generado con la clase Captcha.php" name="captcha1"/><br />
<a href="javascript:;" onclick="document.images.captcha1.src='http://blog.calcifer.com.ar/devel/captcha/getCaptcha.php?id=1&amp;date='+(new Date()).getTime()">generar nuevo</a></p>
<p>Luego, en el script que controla los datos que vienen del formulario (en el que el captcha fue mostrado), hacemos algo como esto:</p>
<pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">// File: checkForm.php<br />
requiere_once('Capcha.php');<br />
session_start();<br />
<br />
// Creo una instancia de Captcha, pero sin pasarle parámetros,<br />
// ya que no voy a generar ninguna imagen.<br />
$captcha = new Captcha();<br />
<br />
// Traigo el código del captcha (seteado en $_SESSION)<br />
// y lo comparo con el que me vino del formulario<br />
if ( $_POST['codeCaptcha'] == $captcha-&gt;getCode() ) {<br />
<br />
&nbsp; &nbsp;// lo que haré en caso de coincidir los códigos.<br />
<br />
}<br />
else {<br />
<br />
&nbsp; &nbsp;// lo que haré en caso de NO coincidir los códigos.<br />
<br />
}</div></div>
</pre>
<h2>Otro ejemplo</h2>
<p>La clase tiene varios métodos más para setear las distintas propiedades del captcha, como el color de fondo, la densidad del ruido (las lineas que aparecen detras del texto) y el color del mismo.</p>
<p class="center"><img src="http://blog.calcifer.com.ar/devel/captcha/getCaptcha.php?id=2" alt="Captcha generado con la clase Captcha.php" name="captcha2"/><br />
<a href="javascript:;" onclick="document.images.captcha2.src='http://blog.calcifer.com.ar/devel/captcha/getCaptcha.php?id=2&amp;date='+(new Date()).getTime()">generar nuevo</a></p>
<pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">$captcha = new Captcha(280, 70);<br />
$captcha-&gt;setSessionVar(6);<br />
if ($captcha-&gt;setFontFile('BagadBold.ttf')) {<br />
&nbsp; &nbsp;$captcha-&gt;setFontSize(32);<br />
&nbsp; &nbsp;$captcha-&gt;setFontColorWeb('00497B');<br />
&nbsp; &nbsp;$captcha-&gt;setBgColorWeb('5C9FCC');<br />
&nbsp; &nbsp;$captcha-&gt;setNoiseColorWeb('0069B0');<br />
&nbsp; &nbsp;$captcha-&gt;setNoiseFactor(70);<br />
&nbsp; &nbsp;$captcha-&gt;sendCaptcha();<br />
}</div></div>
</pre>
<p>Existen métodos para setear los colores pasando el código hexadecimal, ej.</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">setFontColorWeb(&quot;FF0033&quot;)</div></div>
<p>, y para setearlos pasando los valores por cada canal, ej.</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">setFontColor(255,0,51)</div></div>
<p>.</p>
<h2>Archivos y documentación</h2>
<p>El código junto con la documentación pueden bajarse desde aquí: <a href="http://blog.calcifer.com.ar/devel/captcha/Captcha.tar.gz" title="" class="linkcompressfile">Captcha.tar.gz</a><br />
La documentación también puede verse en línea en <a href="http://blog.calcifer.com.ar/devel/captcha/doc" title="" class="linkexternal">http://blog.calcifer.com.ar/devel/captcha/doc</a><br />
Un buen sitio para bajar fuentes TrueType es <a href="http://www.creamundo.com/" title="" class="linkexternal">http://www.creamundo.com/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2006/10/generando-captchas-con-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

