<?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>RVBurke &#187; programación</title>
	<atom:link href="http://blog.rvburke.com/category/programacion/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.rvburke.com</link>
	<description>Arquitectura y técnica</description>
	<lastBuildDate>Fri, 08 Apr 2011 15:50:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Condensaciones 0.6</title>
		<link>http://blog.rvburke.com/2011/01/07/condensaciones-0-6/</link>
		<comments>http://blog.rvburke.com/2011/01/07/condensaciones-0-6/#comments</comments>
		<pubDate>Fri, 07 Jan 2011 16:43:57 +0000</pubDate>
		<dc:creator>pachi</dc:creator>
				<category><![CDATA[arquitectura]]></category>
		<category><![CDATA[castellano]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[software-libre]]></category>

		<guid isPermaLink="false">http://blog.rvburke.com/2011/01/07/condensaciones-0-6/</guid>
		<description><![CDATA[Para empezar el año con novedades, aquí va una nueva versión de Condensaciones, la aplicación de cálculo de parámetros higrotérmicos de cerramientos y que permite comprobar la existencia de condensaciones superficiales o intersticiales. Esta nueva versión 0.6 incluye como novedades principales: Mejora del rendimiento general para trabajar con mayor fluidez. Inclusión de una barra de [...]]]></description>
			<content:encoded><![CDATA[<p>Para empezar el año con novedades, aquí va una nueva versión de <a href="http://www.rvburke.com/condensaciones.html">Condensaciones</a>, la aplicación de <strong>cálculo de parámetros higrotérmicos</strong> de cerramientos y que permite <strong>comprobar la existencia de condensaciones</strong> <em>superficiales</em> o <em>intersticiales</em>.</p>
<p>Esta nueva <a href="https://bitbucket.org/pachi/condensaciones/downloads/condensaciones-0.6.0-setup.exe">versión 0.6</a> incluye como novedades principales:
<ul>
<li>Mejora del rendimiento general para trabajar con mayor fluidez.</li>
<li>Inclusión de una barra de condensaciones totales en la zona de información, con cantidades e indicación gráfica de la cantidad condensada en cada periodo.</li>
<li>El encabezado indica ahora la localidad y el periodo activo y se ha mejorado la indicación de condensaciones por el color de fondo (verde = sin condensaciones, anaranjado = condensaciones intersticiales o superficiales, rojo = condensaciones intersticiales y superficiales).</li>
<li>La gráfica de presiones y temperaturas muestra los resultados del periodo activo, que se puede cambiar en el diálogo de ambientes.</li>
<li>Se elimina la gráfica de presiones de vapor incluyendo su información en la de presiones y temperaturas.</li>
<li>El color asignado a un material se conserva al cambiar el orden de capas tanto en la lista de capas como en el gráfico de presiones y temperaturas.</li>
<li>El informe incluye un histograma de condensaciones acumuladas en cada periodo.</li>
<li>La ayuda en HTML está disponible desde el menú del sistema (win32).</li>
</ul>
<p>Como el aspecto general ha cambiado ligeramente aquí va un pantallazo de la versió 0.6:</p>
<div align="center"><img alt="Condensaciones - Diagrama de presiones y temperaturas" title="Condensaciones - Diagrama de presiones y temperaturas" style="max-width: 800px;" src="http://blog.rvburke.com/wp-content/uploads/2011/01/ui_04_pretemp1.png" height="50%" width="50%" /></div>
<p>La aplicación se puede descargar en la <a href="https://bitbucket.org/pachi/condensaciones/downloads">página de desarrollo del proyecto</a>.<br />La documentación, incluyendo manual del usuario y referencia de programación están disponibles <a href="http://www.rvburke.com/condensaciones/">aquí</a>.</p>
<p>¡Espero que la disfrutéis!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rvburke.com/2011/01/07/condensaciones-0-6/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Condensaciones &#8211; nueva versión 0.5.4</title>
		<link>http://blog.rvburke.com/2010/11/11/condensaciones-nueva-version-0-5-4/</link>
		<comments>http://blog.rvburke.com/2010/11/11/condensaciones-nueva-version-0-5-4/#comments</comments>
		<pubDate>Thu, 11 Nov 2010 20:58:52 +0000</pubDate>
		<dc:creator>pachi</dc:creator>
				<category><![CDATA[arquitectura]]></category>
		<category><![CDATA[castellano]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[software-libre]]></category>

		<guid isPermaLink="false">http://blog.rvburke.com/2010/11/11/condensaciones-nueva-version-0-5-4/</guid>
		<description><![CDATA[Hace ya unos días subí una nueva versión de la aplicación Condensaciones. Condensaciones es una aplicación que permite realizar el cálculo de los parámetros higrotérmicos de cerramientos y la comprobación de la existencia de condensaciones superficiales o intersticiales. Las novedades principales de la versión actual (0.5.4) respecto a la versión 0.4 son las siguientes: Nueva [...]]]></description>
			<content:encoded><![CDATA[<p>Hace ya unos días subí una nueva versión de la aplicación <a href="http://www.rvburke.com/condensaciones.html">Condensaciones</a>.</p>
<p><a href="http://www.rvburke.com/condensaciones.html"><strong>Condensaciones</strong> </a>es una aplicación que permite realizar el <strong>cálculo de los parámetros higrotérmicos</strong> de cerramientos y la <strong>comprobación de la existencia de condensaciones</strong> <em>superficiales</em> o <em>intersticiales</em>.</p>
<div align="center"><img alt="Condensaciones - Diagrama de presiones y temperaturas" title="Condensaciones - Diagrama de presiones y temperaturas" style="max-width: 800px;" src="http://blog.rvburke.com/wp-content/uploads/2010/11/ui_04_pretemp.png" height="50%" width="50%" /></div>
<p>Las novedades principales de la versión actual (0.5.4) respecto a la versión 0.4 son las siguientes:
<ul>
<li>Nueva base de datos de cerramientos en formato .ini.</li>
<li>Nueva base de datos de climas en formato .ini.</li>
<li>Base de datos de Materiales más compacta.</li>
<li>Nueva opción de entrada de climas exteriores según base de datos o manual.</li>
<li>Nombre y descripción de cerramientos editables.</li>
<li>Es posible añadir, eliminar y mover cerramientos en la base de datos.</li>
<li>Es posible guardar cerramientos de la sesión activa.</li>
<li>La aplicación se inicia con el primer cerramiento de la base de datos.</li>
<li>La lista de capas incluye el color del material que se usa en las gráficas.</li>
<li>Muestra localidad/mes seleccionado en encabezado e informe.</li>
<li>Indica condensaciones superficiales para el mes de enero s/CTE en el informe.</li>
<li>Indica condensaciones intersticiales para todos los meses en el informe.</li>
<li>Muestra índice de meses con condensaciones intersticiales en el informe.</li>
<li>Indica en amarillo si no se cumplen condiciones CTE en otros meses aunque se cumplan para las condiciones actuales.</li>
<li>Representa con relleno rojo la zona de condensaciones, en la gráfica P-T.</li>
<li>Salida de informe en navegador HTML.</li>
<li>Documentación inicial en HTML (disponible en la web).</li>
</ul>
<p>La aplicación se puede descargar en la <a href="https://bitbucket.org/pachi/condensaciones/downloads">página de desarrollo del proyecto</a>.<br />La documentación, incluyendo manual del usuario y referencia de programación están disponibles <a href="http://www.rvburke.com/condensaciones/">aquí</a>.</p>
<p>Todavía hay muchas cosas que me gustaría mejorar, pero esto avanza a ratos libres&#8230;</p>
<p>¡Espero que la disfrutéis!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rvburke.com/2010/11/11/condensaciones-nueva-version-0-5-4/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Diccionario visual da Construción do COAG</title>
		<link>http://blog.rvburke.com/2008/06/10/diccionario-visual-da-construcion-do-coag/</link>
		<comments>http://blog.rvburke.com/2008/06/10/diccionario-visual-da-construcion-do-coag/#comments</comments>
		<pubDate>Tue, 10 Jun 2008 10:32:15 +0000</pubDate>
		<dc:creator>pachi</dc:creator>
				<category><![CDATA[arquitectura]]></category>
		<category><![CDATA[castellano]]></category>
		<category><![CDATA[galego]]></category>
		<category><![CDATA[programación]]></category>

		<guid isPermaLink="false">http://blog.rvburke.com/?p=199</guid>
		<description><![CDATA[O Colexio Oficial de Arquitectos de Galicia (COAG) ten un excelente e útil Diccionario visual da Construción que, entre outras cousas, facilita a tradución dos termos máis habituais do mundo da construción e a arquitectura xa que permite facer buscas dende o galego ou o castelán e devolve os resultados relacionados coas equivalencias nos dous [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://flickr.com/photos/88903556@N00/119058236/'><img src="http://blog.rvburke.com/wp-content/uploads/2008/06/dict.jpg" alt="Dictionary by ElektraCute" title="Dictionary by ElektraCute" width="240" height="180" class="floatleft" /></a>O <a href="http://coag.es">Colexio Oficial de Arquitectos de Galicia (COAG)</a> ten un excelente e útil <a href="http://diccionario.coag.es">Diccionario visual da Construción</a> que, entre outras cousas, facilita a tradución dos termos máis habituais do mundo da construción e a arquitectura xa que permite facer buscas dende o galego ou o castelán e devolve os resultados relacionados coas equivalencias nos dous idiomas.</p>
<p>Xa que estes días ando a redactar as memorias duns proxectos de execución estou a botar man a miudo desa ferramenta, xa que son moitos os casos de dúbida e a documentación técnica en galego é, lamentablemente, moi escasa, polo que gran parte do traballo consiste en adaptar memorias escritas en castelán a unha versión en galego (máis algunhas adaptacións normativas, claro).</p>
<p>Para facilitar a tarefa, creei un buscador persoalizado que se pode engadir á barra de buscas do navegador <a href="http://www.mozilla.com/en-US/firefox/?from=getfirefox">Firefox</a> (e posiblemente tamén traballe noutros navegadores), de xeito que, a partires da súa instalación, podes usar a casiña de busca do navegador cun termo en castelán e devolve a páxina cos resultados relacionados, que inclúen a equivalencia en galego.</p>
<p><a href="" onclick="return window.sidebar.addSearchEngine('http://www.rvburke.com/datos/dvccoag/dvccoag.src', 'http://www.rvburke.com/datos/dvccoag/dvccoag.png', 'Diccionario COAG', 'Diccionarios');">Engade o buscador ó teu navegador</a>.</p>
<p>A creación dun buscador equivalente que faga a tradución inversa, do galego ó castelán, se fose necesaria, é moi sinxela, bastando editar o arquivo dvccoag.src e cambiando &#8220;castelán&#8221; por &#8220;galego&#8221;.</p>
<p>Unha instalación alternatva é obter os arquivos das <a href="http://www.rvburke.com/datos/dvccoag/dvccoag.src">fontes para o buscador Sherlock</a> e a <a href="http://www.rvburke.com/datos/dvccoag/dvccoag.png">icona do buscador</a> e instalalos no subdirectorio searchplugins do directorio do Firefox.</p>
<p>Unha <a href="http://www.rvburke.com/datos/dvccoag/dvccoag.xml">versión OpenSearch do mesmo buscador</a>. Ainda que non está probado o seu funcionamento, debería <a href="" onclick="return window.external.AddSearchProvider('http://www.rvburke.com/datos/dvccoag/dvccoag.xml');">instalarse eiquí</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rvburke.com/2008/06/10/diccionario-visual-da-construcion-do-coag/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple python calc addin example</title>
		<link>http://blog.rvburke.com/2008/05/06/simple-python-calc-addin-example/</link>
		<comments>http://blog.rvburke.com/2008/05/06/simple-python-calc-addin-example/#comments</comments>
		<pubDate>Tue, 06 May 2008 00:07:55 +0000</pubDate>
		<dc:creator>pachi</dc:creator>
				<category><![CDATA[english]]></category>
		<category><![CDATA[OpenOffice]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[software-libre]]></category>

		<guid isPermaLink="false">http://blog.rvburke.com/?p=190</guid>
		<description><![CDATA[The OpenOffice spreadsheet application, calc, can be extended through plugins to support new functions that can be as easily used in cell formulas as the built-in ones. Being able to do this using my favourite language, Python, is possible, but not very well documented, so I&#8217;ve experimented a bit with it and have come up [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.rvburke.com/wp-content/uploads/2008/05/oo-calc-shot.jpg" alt="OpenOffice calc spreadsheet screenshot" title="oo-calc-shot" width="250" height="190" class="floatleft size-full wp-image-191" />The <a href="http://www.openoffice.org">OpenOffice</a> spreadsheet application, calc, can be extended through plugins to support new functions that can be as easily used in cell formulas as the built-in ones.</p>
<p>Being able to do this using my favourite language, <a href="http://www.python.org">Python</a>, is possible, but not very well documented, so I&#8217;ve experimented a bit with it and have come up with a simple example that defines a bunch of new functions that take double and range arguments and return a single value or write back to a defined range. This example can be used as template to write your own plugins and is released under a GPL v2 or greater license.</p>
<p>The example has been developed using <a href="http://www.openoffice.org">OpenOffice 2.4</a> running on Vista. To build it, you need the OO 2.4 SDK and a MSys environment to comfortably use makefiles and get a decent shell.</p>
<p>The extension file has in it all the needed files to rebuild the example. As the <code>.oxt</code> files are just zipped files you can get them renaming the extension file so it gets a <code>.zip</code> extension and unzipping it.</p>
<p>The makefile has some variables that point to the SDK dir and <em>zip</em> utility that you need to tweak and has the <code>all</code> and <code>install </code>targets build and install the extension.</p>
<p>Addins are composed by:</p>
<ul>
<li>an .idl file to define the interfaces</li>
<li>a manifest.xml file to define the extension resources</li>
<li>an implementation file</li>
</ul>
<p>I hope this calc addin example is simple enough to get started. Enjoy!</p>
<p><a href="http://www.rvburke.com/datos/PachiAddin.oxt">Click here to download calc addin example: PachiAddin.oxt</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rvburke.com/2008/05/06/simple-python-calc-addin-example/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Postproceso de capas en planos de CypeCAD</title>
		<link>http://blog.rvburke.com/2008/04/25/postproceso-de-capas-en-planos-de-cypecad/</link>
		<comments>http://blog.rvburke.com/2008/04/25/postproceso-de-capas-en-planos-de-cypecad/#comments</comments>
		<pubDate>Fri, 25 Apr 2008 12:40:45 +0000</pubDate>
		<dc:creator>pachi</dc:creator>
				<category><![CDATA[castellano]]></category>
		<category><![CDATA[estructuras]]></category>
		<category><![CDATA[pascaline]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.rvburke.com/?p=185</guid>
		<description><![CDATA[El programa de cálculo de estructuras CypeCAD permite exportar los planos de las estructuras que calcula a archivos DXF para su manejo posteriore en programas de CAD. El programa usa una serie de capas que corresponden a distintos elementos como textos de armados, tipos de armado, etc. Esta separación es muy prolija y tiene la [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.rvburke.com/wp-content/uploads/2008/04/pilaresnd1.jpg" alt="Plano de despiece de pilares en estructura de hormigón armado" title="pilaresnd1" width="250" height="176" class="floatleft size-full wp-image-186" />El programa de cálculo de estructuras <a href="http://www.cype.es">CypeCAD</a> permite exportar los planos de las estructuras que calcula a archivos <a href="http://en.wikipedia.org/wiki/ASCII_Drawing_Interchange_file_format">DXF</a> para su manejo posteriore en programas de CAD.</p>
<p>El programa usa una serie de capas que corresponden a distintos elementos como textos de armados, tipos de armado, etc. Esta separación es muy prolija y tiene la ventaja de que permite diferenciar muy bien a posteriori a qué función estructural pertenece cada elemento de dibujo.</p>
<p>Sin embargo, la profusión de capas hace poco manejable el dibujo final y es necesario reducirlas a un subconjunto más reducido que, normalmente, se corresponderá también a un criterio personal de dibujo. </p>
<p>Este post explica cómo manejo el cambio de capas a partir de los planos generados en el <a href="http://www.cype.es">CypeCAD</a>, y otro día comentaré el criterio de capas de suelo utilizar, ya que lo he estado utilizando varios años y la <a href="http://www.mmn-arquitectos.com">gente que lo ha probado</a> lo ha adoptado como suyo <img src='http://blog.rvburke.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Volviendo a la gestión de capas de <a href="http://www.cype.es">CypeCAD</a>, si bien el programa permite definir a qué capas se deben traducir los distintos elementos, la interfaz para hacerlo es bastante engorrosa, ya que exige recorrer una a una las numerosas capas que incluye por defecto y esta configuración no se puede guardar para poder utilizarla en otra máquina o recuperarla al actualizar la aplicación.</p>
<p>Para automatizar la resolución del problema de unificación y estandarización de capas, genero los planos usando las capas por defecto de <a href="http://www.cype.es">CypeCAD</a> y luego utilizo un script que he escrito en <a href="http://www.python.org">Python</a> que traduce sus capas a otras personalizadas.</p>
<p>La traducción entre el nombre de capa original y el deseado se define en un archivo en formato de texto plano llamado <code>capas.txt</code> con una sintaxis muy sencilla:</p>
<p><code>CIM_COTAS|e.cotas<br />
CIM_CUADRO_ARRANQUE|e.1.gordas<br />
CIM_CUAD_VIG_ATA|e.1.gordas<br />
CIM_CUAD_VIG_CEN|e.1.gordas<br />
CIM_CUAD_ZAPATA|e.1.gordas<br />
CIM_DIB_ARMADOS|e.armado.gordo</code></p>
<p>Las capas sin la correspondiente capa &#8220;traducida&#8221; tras la barra vertical no cambian su nombre, por lo que las nuevas capas que puedan ir incorporando en nuevas versiones de la aplicación se mantienen intactas.</p>
<p>Para la ejecución del script es necesaria la instalación del intérprete de <a href="http://www.python.org">Python</a>, y el propio script ofrece información sobre los parámetros que acepta:</p>
<p><code>$python cambia_capas_cype.py</code></p>
<p>Quienes usen el programa AutoCAD de AutoDesk, pueden completar la estandarización de capas bien insertando el <a href="http://en.wikipedia.org/wiki/ASCII_Drawing_Interchange_file_format">DXF</a> en un dibjo nuevo iniciado con una plantilla en la que estén definidas las propiedades de las capas, o bien usando la función <code>LAYTRANS</code>. En un futuro es posible que amplie el script para definir las propiedades de las capas en el propio DXF procesado.</p>
<p><a href="http://www.rvburke.com/datos/cambia_capas_cype.zip">Descargar aplicación de cambio de capas para DXF de CypeCAD</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rvburke.com/2008/04/25/postproceso-de-capas-en-planos-de-cypecad/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Repository formats matter a lot in Mercurial</title>
		<link>http://blog.rvburke.com/2006/12/14/repository-formats-matter-a-lot-in-mercurial/</link>
		<comments>http://blog.rvburke.com/2006/12/14/repository-formats-matter-a-lot-in-mercurial/#comments</comments>
		<pubDate>Thu, 14 Dec 2006 16:00:48 +0000</pubDate>
		<dc:creator>pachi</dc:creator>
				<category><![CDATA[english]]></category>
		<category><![CDATA[mercurial]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[software-libre]]></category>

		<guid isPermaLink="false">http://blog.rvburke.com/2006/12/14/repository-formats-matter-a-lot-in-mercurial/</guid>
		<description><![CDATA[Keith Packard discusses why robust repository formats are important for any version control software. This is really an important point when evaluating the robustness of any version control system, as you want to avoid the corruption of all your data due to a disk failure and an unfortunate way to store the tracked information. One [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://keithp.com/blog/Repository_Formats_Matter.html">Keith Packard discusses</a> why robust repository formats are important for any version control software. This is really an important point when evaluating the robustness of any version control system, as you want to avoid the corruption of all your data due to a disk failure and an unfortunate way to store the tracked information.</p>
<p>One sad point, as he&#8217;s a person I certainly admire for his work on free software, is that, while praising the way <a href="http://git.or.cz/">git</a> faces that problem, he unfairly bashes <a href="http://selenic.com/mercurial">Mercurial</a> (besides other VCSs). The fact is that the comparison done is not correct. While the comparison used to measure store size is between packed git and standard Mercurial, the robustness of the repository format comparison uses the unpacked git and standard Mercurial.</p>
<p>I believe this is more of a handwaving issue than any real concern about how git or Mercurial are doing the job.<br />
<span id="more-114"></span></p>
<p>Mercurial uses a compact representation of data with separate revlog files for each tracked file, manifest and changelog, which are all append-only. Due to the append-only nature of those writes, the changes in each new revision don&#8217;t affect previous revisions. You are that way as safe as you can be in any other system with respect to writes and the space usage is very good.</p>
<p>To achieve similar space efficiency git needs to pack the repository data. This is done rewriting the repo, and the operation has to be done from time to time (repack).</p>
<p>IF the atomic append-only writes to the manifest and revlog files in Mercurial can be considered dangerous, then repacking is even more so, as it forces a rewrite of all the repo data, multiplying the chance of a failure. </p>
<p>So, if any corruption can happen on a faulty write it will hit git (unpacked) or Mercurial in the same way, but anytime you pack your repo in git you&#8217;re risking your data and the write fails you can corrupt its repository.</p>
<p>That said, one can meditate whether this unlikely situation of failure is of so high importance, as, in distributed systems, a lot of other repos will act as a full backup of the canonical repo. Furthermore, both use atomical operations and safety should be more than good enough.</p>
<p>A <a href="http://www.selenic.com/pipermail/mercurial/2006-November/011678.html">short reply</a> to Keith&#8217;s post has been written by Matt Mackal, <a href="http://selenic.com/mercurial">Mercurial</a>&#8216;s main author, and detailed information about the <a href="http://www.selenic.com/mercurial/wiki/index.cgi/Design">repository format and other design details for Mercurial</a> can be found on the project&#8217;s wiki.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rvburke.com/2006/12/14/repository-formats-matter-a-lot-in-mercurial/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Programación orientada a objetos en Python</title>
		<link>http://blog.rvburke.com/2006/11/22/programacion-orientada-a-objetos-en-python/</link>
		<comments>http://blog.rvburke.com/2006/11/22/programacion-orientada-a-objetos-en-python/#comments</comments>
		<pubDate>Wed, 22 Nov 2006 20:43:40 +0000</pubDate>
		<dc:creator>pachi</dc:creator>
				<category><![CDATA[castellano]]></category>
		<category><![CDATA[pascaline]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.rvburke.com/2006/11/22/programacion-orientada-a-objetos-en-python/</guid>
		<description><![CDATA[Introducción a la programación orientada a objetos Este artículo es una introducción a la programación orientada a objetos (POO, o OOP por sus siglas en inglés), uno de los paradigmas de programación estructurada más importante hoy en día. El artículo usa el lenguaje Python para los distintos ejemplos, y explica la implementación de la POO [...]]]></description>
			<content:encoded><![CDATA[<p><img class="floatleft" src="http://blog.rvburke.com/wp-content/uploads/2006/11/jerarquiaclases-thmb.png" alt="Logo programación orientada a objetos en python" /><br />
<h1>Introducción a la programación orientada a objetos</h1>
<p>Este artículo es una introducción a la programación orientada a objetos (POO, o OOP por sus siglas en inglés), uno de los paradigmas de programación estructurada más importante hoy en día.</p>
<p>El artículo usa el lenguaje <a href="http://www.python.org">Python</a> para los distintos ejemplos, y explica la implementación de la POO en ese lenguaje, aunque aborda conceptos generales que son fácilmente trasladables a otros lenguajes.</p>
<p>Los fragmentos de código se señalan usando un estilo de texto diferente (ancho fijo) y, cuando se utiliza el intérprete de python, se prefija cada línea con los símbolos &#8216;&gt;&gt;&gt;&#8217;.</p>
<p>Esta introducción presupone conocimientos básicos de programación y del lenguaje python.<br />
<span id="more-90"></span></p>
<h2>Formas de pensar: paradigmas de programación</h2>
<p>Uno de los elementos básicos a la hora de realizar un programa es la modelización del problema que pretende resolver. Es preciso localizar las variables y los aspectos relevantes, así como comprender los pasos necesarios para obtener el resultado a partir de los datos iniciales, etc. Es decir, abstraer el problema, reduciendo sus detalles de forma que podamos trabajar con pocos elementos cada vez.</p>
<p>La algoritmia plantea la forma óptima de resolver problemas concretos, tales como la ordenación de una lista de elementos, la búsqueda de un elemento en un conjunto, la manipulación de conjuntos de datos, etc. Sin embargo, no proporcionan un marco general, un enfoque, que nos permita plantear y formular las soluciones a un problema de forma coherente.</p>
<p>Los paradigmas de programación llenan ese hueco, proporcionando guías tanto sobre cómo realizar la abstracción de los datos como sobre el control de la ejecución. Es decir, <strong>los paradigmas de programación son herramientas conceptuales para analizar, representar y abordar los problemas, presentando sistematizaciones alternativas o complementarias para pasar del espacio de los problemas al de las implementaciones de una solución</strong>.</p>
<p>Es muy recomendable y productivo comprender el enfoque de distintos paradigmas, puesto que presentan estrategias alternativas, incrementando nuestras herramientas disponibles y haciéndono reflexionar sobre muchas de las tareas que realizamos al crear un programa. Además, a menudo ocurre que unos problemas se formulan de forma muy clara si se los analiza según una perspectiva determinada, mientras que producen una gran complejidad vistos de otra manera.</p>
<h2>Algunos paradigmas habituales</h2>
<p>Algunas de las formas de pensar los problemas que ha llegado a sistematizarse como paradigmas de programación son:</p>
<ul>
<li>La <strong>programación modular</strong>: Los programas se forman por partes separadas llamadas módulos. Estos funcionan de forma independiente entre sí, o se relacionan a través de interfaces bien definidas.</li>
<li>La <strong>programación procedural</strong>: Un programa se compone de procedimientos (subrutinas, métodos o funciones) que son fragmentos de código que pueden llamarse desde cualquier punto de la ejecución de un programa, incluídos otros procedimientos o él mismo. (ej. ALGOL)</li>
<li>La <strong>programación estructurada</strong>: Se puede expresar cualquier programa utilizando únicamente tres estructuras de control: secuencial, condicional e iterativa. Los programas se componen de partes menores con un único punto de entrada, y se trata de aislarlos para evitar la complejidad que introducen los efectos colaterales. (ej. Pascal, C, Ada)</li>
<li>La <strong>programación imperativa</strong>: Un programa se puede definir en términos de estado, y de instrucciones secuenciales que modifican dicho estado. (ej. C, BASIC)</li>
<li>La <strong>programación declarativa</strong>: Es posible expresar un programa a través de condiciones, proposiciones o restricciones, a partir de los que se obtiene la solución mediante reglas internas de control. (ej. PROLOG)</li>
<li>La <strong>programación funcional</strong>: Se puede expresar un programa como una secuencia de aplicación de funciones. Elude el concepto de estado del cómputo y no precisa de las estructuras de control de la programación estructurada. (ej. LISP, Haskell)</li>
<li>La <strong>programación orientada a objetos</strong>: Los programas se definen en términos de &#8220;clases de objetos&#8221; que se comunican entre sí mediante el envío de mensajes. Es una evolución de los paradigmas de la programación procedural, estructurada y modular, y se implementa en lenguajes como Java, Smalltalk, Python o C++.</li>
</ul>
<h2>Programación multiparadigma</h2>
<p>Los paradigmas de programación son idealizaciones, y, como tales, no siempre se presentan de forma totalmente &#8216;pura&#8217;, ni siempre resultan incompatibles entre sí. Cuando se entremezclan diversos paradigmas se produce lo que se conoce como <strong>programación multiparadigma</strong>.</p>
<p>El uso de distintos modelos, según se adapten mejor a las diversas partes de un problema o a nuestra forma de pensamiento, resulta también más natural y permite expresar de forma más clara y concisa nuestras ideas.</p>
<p>Algunos lenguajes, como <a href="http://haskell.org">Haskell</a> o <a href="http://pauillac.inria.fr/~diaz/gnu-prolog/">Prolog</a> están diseñados para encajar perfectamente en la visión de un paradigma particular, mientras que otros, como <a href="http://www.python.org">python</a>, se adaptan especialmente bien a la programación multiparadigma y dan gran libertad a la hora de resolver un problema, al no imponen un mismo patrón para todos los casos.</p>
<h2>Tipos de datos</h2>
<p>Una forma de almacenar y representar una fecha en un programa podría ser la siguiente:</p>
<p><code>
<pre>d = 14
m = "Noviembre"
a = 2006
def dime_fecha(dia, mes, anho):
    return "%i de %s de %i del calendario gregoriano" % (dia, mes, anho)
print dime_fecha(d, m, a)</pre>
<p></code></p>
<p>para obtener la siguiente salida:</p>
<p><code>"14 de Noviembre de 2006"</code></p>
<p>En este ejemplo, para representar y manipular lo que conceptualmente entendemos como una fecha, se utilizan las variables <code>d</code>, <code>m</code> y <code>a</code> como almacenes de datos, y un procedimiento o función, de nombre <code>dime_fecha</code>, para realizar la representación de la fecha almacenada.</p>
<p>Las variables permiten almacenar tipos de datos concretos como los enteros (<code>d</code> y <code>a</code>) o las cadenas de texto (<code>m</code>), y la función realiza su trabajo devolviendo otro tipo concreto, una cadena de texto.</p>
<p>Uno de los problemas de este enfoque es que no refleja demasiado bien el concepto fecha que usamos como modelo mental al implementarlo como un conjunto de tres variables no relacionadas entre sí (<code>d</code>, <code>m</code> y <code>a</code>). Es decir, las tres variables tienen una unidad conceptual en nuestra mente, que no se refleja en la forma de expresar el problema. De la misma manera, la función <code>dime_fecha</code> desconoce igualmente la relación entre sus parámetros, que podría ser totalmente arbitraria.</p>
<p>Esta situación, que puede parecer una cuestión de &#8216;estilo&#8217;, implica un riesgo de problemas de sincronización entre variables &#8216;relacionadas&#8217;, dispersión en distintas partes del código de manipulaciones que son relevantes al conjunto, pérdida del valor semántico de cada variable que puede dar lugar a errores al transformar el código&#8230;</p>
<p>Un ejemplo de desconexión semántica entre la implementación y el concepto es que <code>d</code> puede ser cualquier valor entero, mientras que un día tiene un valor situado entre 1 y 31, <code>m</code> es una cadena de texto dentro de un número limitado de opciones, o <code>a</code> no puede tomar valores negativos. Por supuesto que esto se podría solucionar con código que hiciese comprobaciones adicionales, pero en este caso queremos resaltar cómo un programa es un modelo aproximado a un problema y cómo sería preferible que la implementación pudiese representar de forma más ajustada el comportamiento del modelo elegido.</p>
<p>Una posible solución sería disponer de un tipo de datos que represente de forma más adecuada el concepto de fecha y que nos permita manipular fechas de la misma manera que manipulamos números enteros, números reales o cadenas de texto, independientemente de la implementación interna que los sustente.</p>
<h2>Clases y objetos</h2>
<p>Al enunciar algunos tipos de paradigmas hemos visto que la <strong>programación orientada a objetos define los programas en términos de &#8220;clases de objetos&#8221; que se comunican entre sí mediante el envío de mensajes</strong>. En este apartado aclararemos qué se entiende en ese contexto por clases y objetos.</p>
<p>Las clases surgen de la generalización de los tipos de datos y <strong> permiten una representación más directa de los conceptos necesarios para la modelización de un problema permitiendo definir nuevos tipos al usuario</strong>.</p>
<p><strong>Las clases permiten agrupar en un nuevo tipo los datos y las funcionalidades asociadas a dichos datos</strong>, favoreciendo la separación entre los detalles de la implementación de las propiedades esenciales para su uso. A esta cualidad, de no mostrar más que la información relevante, ocultando el estado y los métodos internos de la clase, es conocida como <strong>&#8220;encapsulación&#8221;</strong>, y es un principio heredado de la programación modular.</p>
<p>Un aspecto importante en el uso de clases es que no se manipulan directamente (salvo en lo que se conoce como <em>metaprogramación</em>), sino que sirven para la definición nuevos tipos. <strong>Una clase define propiedades y comportamiento que se muestran en los entes llamados <em>objetos</em></strong> (o <strong>instancias de una clase</strong>). La clase actúa como molde de un conjunto de objetos, de los que se dice que <strong>pertenecen</strong> a la clase.</p>
<p>Trasladando estos conceptos a los números enteros (tipo <em>int</em>), se puede decir que las variables que almacenan números enteros son objetos o instancias de la clase <em>int</em> o que <em>pertenecen</em> a la clase <em>int</em>.</p>
<p>En términos más abstractos, podemos pensar en las clases como definiciones y en los objetos como expresiones concretas de dichas definiciones.</p>
<h2>Fisonomía de una clase</h2>
<p>En python, el esquema para la definición de una clase es el siguiente:</p>
<p><code>
<pre>
class NombreClase:
  &lt;instrucción_1&gt;
  ...
  &lt;instrucción_n&gt;
</pre>
<p></code></p>
<p>en donde <strong>class</strong> es una palabra reservada que indica la declaración de una clase, <strong>NombreClase</strong> una etiqueta que da nombre a la clase y, los dos puntos, que señalan el inicio del bloque de instrucciones de la clase.</p>
<p>El cuerpo de instrucciones de la clase puede contener tanto asignaciones de datos como definiciones de funciones. Este bloque de instrucciones se encuentra en el nuevo espacio de nombres con el nombre de la clase, que se genera, a su vez, con la creación de cada objeto. En ambos casos, en el espacio de nombres de la clase y del objeto, es posible acceder a los elementos que lo integran usando el operador punto, como en el caso de los espacios de nombres de un módulo (e.j. <em>math.pi</em>, <em>objeto.dato</em>, <em>objeto.funcion()</em>).</p>
<p>Si la primera instrucción del cuerpo de la clase es una cadena de texto, ésta se usa como cadena de documentación de la clase.</p>
<p>Nuestro ejemplo podría reescribirse en términos de una clase así:</p>
<p><code>
<pre>class Fecha:
    "Ejemplo de clase para representar fechas"
    dia = 14
    mes = "Noviembre"
    anho = 2006
    def dime_fecha(self):
        return "%i de %s de %i" % (Fecha.dia, Fecha.mes, Fecha.anho)

mi_fecha = Fecha()
print mi_fecha.dia, mi_fecha.mes, mi_fecha.anho
print mi_fecha.dime_fecha()</pre>
<p></code></p>
<p>En el fragmento de código anterior definimos la clase <code>Fecha</code> y ella asignamos valores a las etiquetas <code>dia</code>, <code>mes</code> y <code>anho</code> (atributos de la clase), y definimos una función (un método de la clase), <code>dime_fecha</code>.</p>
<p>Fuera de la definición de la clase creamos (instanciamos) un objeto perteneciente a la clase <code>Fecha</code>. Esta instanciación se realiza utilizando la notación de llamada a función, y podemos entenderla como una llamada a una función que devuelve un objeto de la clase Fecha. El objeto obtenido es asignado a la etiqueta <code>mi_fecha</code>.</p>
<p>En la siguientes instrucciones mostramos por pantalla los valores de las propiedades <code>dia</code>, <code>mes</code> y <code>anho</code> y el resultado de la llamada al método <code>dime_fecha</code>, usando el operador punto para acceder a las propiedades y métodos del objeto <code>mi_fecha</code>, ya que, como hemos mencionado antes, forman parte del espacio de nombres del objeto.</p>
<p>La llamada al método <code>dime_fecha</code> no incluye ningún parámetro, pero podemos comprobar que, de forma contradictoria, la declaración del método indica uno, <code>self</code>. Este parámetro es añadido automáticamente por el intérprete en las llamadas a los métodos de una clase, y contiene una referencia al objeto que recibe la señal (el que recibe una llamada a un método). <code>self</code> permite acceder a las propiedades y métodos de un objeto concreto y aclararemos su significado y uso más adelante. Por ahora nos basta saber que <strong>es necesario incluir <code>self</code> como primer parámetro de los métodos definidos en una clase</strong> y que <strong>no es preciso incluir el parámetro implícito <code>self</code> al realizar llamadas a un método a través del objeto al que pertenece</strong></code>.</p>
<p>En realidad, en el ejemplo anterior, la llamada mi_fecha.dime_fecha() es una forma más cómoda de escribir (azúcar sintáctico) Fecha.dime_fecha(mi_fecha), lo que explica la presencia del parámetro.</p>
<h2>Un paseo entre objetos</h2>
<p>Hasta el momento hemos visto cómo las clases definen los datos (o estado) y comportamiento de los objetos a través de atributos (o propiedades) y métodos.</p>
<p>Ahora vamos a hacer un recorrido, utilizando una sesión interactiva del intérprete y las capacidades de introspección de python, para explicar el uso y el comportamiento de los objetos.</p>
<p>Veremos algunas <strong>características de los objetos</strong>:</p>
<ol>
<li><strong>Identidad</strong>. Los objetos se diferencian entre sí, de forma que dos objetos, creados a partir de la misma clase y con los mismos parámetros de inicialización, son entes distintos.</li>
<li>Definen su <strong>comportamiento</strong> (y operar sobre sus datos) a través de <strong>métodos</strong>, equivalentes a funciones.</li>
<li>Definen o reflejan su <strong>estado</strong> (datos) a través de <strong>propiedades o atributos</strong>, que pueden ser tipos concretos u otros objetos.</li>
</ol>
<p>Pasamos a ver una sesión interactiva del intérprete:</p>
<p><code><br />
&gt;&gt;&gt; mi_fecha = Fecha()<br />
&gt;&gt;&gt; mi_fecha_2 = Fecha()<br />
&gt;&gt;&gt; mi_fecha is mi_fecha_2<br />
False<br />
&gt;&gt;&gt; print mi_fecha<br />
<__main __.Fecha instance at 0x00B184B8><br />
&gt;&gt;&gt; print mi_fecha_2<br />
<__main __.Fecha instance at 0x00B18328><br />
</code></p>
<p>Vemos que tanto <code>mi_fecha</code> como <code>mi_fecha_2</code> son instancias de la clase <code>Fecha</code> (en el módulo <code>__main__</code>) y cada una tiene su propio espacio de memoria independiente.</p>
<p><code><br />
&gt;&gt;&gt; print mi_fecha.dime_fecha()<br />
14 de Noviembre de 2006<br />
&gt;&gt;&gt; print mi_fecha.dia<br />
14<br />
&gt;&gt;&gt; print mi_fecha_2.dia<br />
14<br />
&gt;&gt;&gt; Fecha.dia = 16<br />
&gt;&gt;&gt; print Fecha.dia<br />
16<br />
&gt;&gt;&gt; print mi_fecha.dia<br />
16<br />
&gt;&gt;&gt; print mi_fecha_2.dia<br />
16<br />
&gt;&gt;&gt; mi_fecha.dia = 30<br />
&gt;&gt;&gt; print Fecha.dia<br />
16<br />
&gt;&gt;&gt; print mi_fecha.dia<br />
30<br />
&gt;&gt;&gt; print mi_fecha_2.dia<br />
16<br />
</code></p>
<p>Este último experimento observamos cómo, pese a que <code>mi_fecha</code> y <code>mi_fecha_2</code> son dos instancias distintas de la clase <code>Fecha</code>, ambas hacen referencia a través de su atributo dia al mismo valor de la clase <code>Fecha.dia</code>. Sin embargo, cuando se produce una asignación a ese atributo (a esa etiqueta, en realidad) en uno de los objetos vemos cómo, a partir de entonces, ese objeto dispone de un valor 'individual' asociado al atributo.</p>
<p>Ese comportamiento revela la existencia de <strong>atributos (o estado) compartidos por todas las instancias de una clase</strong> y de <strong>atributos (o estado) ligados a una instancia particular</strong>. Los primeros se sitúan en el espacio de nombres de la clase, y vemos cómo se pueden hacer asignaciones en la sesión interactiva anterior, o lecturas, en el método <code>dime_fecha</code> del ejemplo anterior. Los segundos se sitúan en el espacio de nombres de cada objeto, y ahí es donde resulta útil el parámetro <code>self</code>.</p>
<p>Antes de proseguir, podemos escudriñar qué símbolos son accesibles y qué contienen los espacios de nombres de la clase Fecha y de los objetos <code>mi_fecha</code> y <code>mi_fecha_2</code>. Usamos la función <em>dir</em> para lo primero, y el atributo <code>__dict__</code> para lo segundo, ya que en python los espacios de nombres se implementan como <em>diccionarios</em></em>:</p>
<p><code><br />
&gt;&gt;&gt; dir(Fecha)<br />
['__doc__', '__module__', 'anho', 'dia', 'dime_fecha', 'mes']<br />
&gt;&gt;&gt; dir(fecha3)<br />
['__doc__', '__module__', 'anho', 'dia', 'dime_fecha', 'mes']<br />
&gt;&gt;&gt; dir(fecha4)<br />
['__doc__', '__module__', 'anho', 'dia', 'dime_fecha', 'mes']<br />
</code></p>
<p>En los tres podemos acceder a los mismos símbolos. Sin embargo...</p>
<p><code><br />
&gt;&gt;&gt; Fecha.__dict__<br />
{'__module__': '__main__', 'anho': 2006, 'dime_fecha': <function dime_fecha at 0<br />
x00B176F0>, 'dia': 14, 'mes': 'Noviembre', '__doc__': 'Ejemplo de clase para representar fechas'}<br />
&gt;&gt;&gt; mi_fecha_2.__dict__<br />
{}<br />
&gt;&gt;&gt; mi_fecha.__dict__<br />
{'dia': 30}<br />
</code></p>
<p>El espacio de nombres de la clase es el que alberga los nombres de los atributos y métodos indicados en la declaración de la clase, además de los atributos especiales <code>__doc__</code>, que contiene la cadena de documentación y <code>__module__</code>, que contiene el nombre del módulo al que pertenece la clase. Esos símbolos son accesibles también para los objetos pertenecientes a la clase (tal como nos indicaba <em>dir()</em>).</p>
<p>Podemos ver también que el espacio de nombres del objeto <code>mi_fecha_2</code> se encuentra vacío, mientras que el del objeto <code>mi_fecha</code> contiene el atributo <code>día</code>. Esto se debe a que anteriormente realizamos una asignación al atributo <code>dia</code> del objeto <code>mi_fecha</code> (dándole el valor 30). El espacio de nombres recoge esa versión particular del atributo, que no aparece en el otro objeto, puesto que accede al atributo de clase.</p>
<p>A los atributos compartidos por todos los objetos de una clase se los denomina <strong>atributos de clase</strong>, cuando se desea diferenciarlos de los atributos que pertenecen a cada instancia en particular.</p>
<h2>Acceso individualizado a objetos: self</h2>
<p>Ahora que hemos visto cómo usar atributos de clase para compartir datos entre todos los objetos de una misma clase, también nos interesa conocer cómo utilizar atributos comunes a una clase pero que puedan tomar valores distintos para cada uno de los objetos.</p>
<p>Retomamos ahora el misterioso parámetro <code>self</code> que vimos estaba presente como primer parámetro de todos los métodos de una clase. En su momento ya comentamos que <strong><code>self</code> contiene una referencia al objeto que recibe la señal</strong> (el objeto cuyo método es llamado), por lo que <strong>podemos usar esa referencia para acceder al espacio de nombres del objeto</strong>, es decir, a sus atributos individuales.</p>
<p><code></p>
<pre>
&gt;&gt;&gt; class F:
...     i = 5
...     def dime_i(self):
...             return F.i
...     def dime_mi_i(self):
...             return self.i
...
&gt;&gt;&gt; a = F()
&gt;&gt;&gt; a.dime_i()
5
&gt;&gt;&gt; a.dime_mi_i()
5
&gt;&gt;&gt; a.i = 6
&gt;&gt;&gt; a.dime_i()
5
&gt;&gt;&gt; a.dime_mi_i()
6
&gt;&gt;&gt; a.i
6
</pre>
<p></code></p>
<p>En este ejemplo el método <code>dime_i</code> usa el atributo de clase y retorna su valor, 5, mientras que el método <code>dime_mi_i</code> usa una referencia al objeto y devuelve el valor 6, el asignado al atributo del objeto <code>a</code>. Así accedemos selectivamente al atributo de clase <code>i</code> o al atributo de instancia <code>i</code>.</p>
<p>Algo que puede aclarar algo más la naturaleza del parámetro <code>self</code>, es recordar que, cuando hacemos una llamada a un método <code>un_metodo</code> de un objeto <code>un_objeto</code> perteneciente a la clase <code>UnaClase</code>, el intérprete traduce la expresión <code>un_objeto.un_metodo()</code> como <code>UnaClase.un_metodo(un_objeto)</code>.</p>
<p>El uso de <code>self</code> responde a la forma particular en que python implementa el soporte de objetos, aunque lenguajes como Java o C++ utilizan mecanismos similares con la palabra reservada <code>this</code>. En python <code>self</code> no es una palabra reservada y cualquier etiqueta usada como primer parámetro valdría igualmente, aunque se desaconseja totalmente el uso de otras etiquetas, por tratarse de una convención muy arraigada en el lenguaje que hace el código más legible, facilita el resaltado de sintaxis, etc.</p>
<h2>El método de inicialización __init__</h2>
<p>Hemos visto ya cómo definir y usar atributos de clase y de instancia. Pero en python no es necesaria la declaración de variables, por lo que cualquier atributo al que se realice una asignación en el código se convierte en un atributo de instancia:</p>
<p><code><br />
&gt;&gt;&gt; a = F()<br />
&gt;&gt;&gt; a.i = 6<br />
&gt;&gt;&gt; a.atr = 3<br />
&gt;&gt;&gt; print a.atr<br />
3<br />
&gt;&gt;&gt; a.__dict__<br />
{'i': 6, 'atr': 3}<br />
</code></p>
<p>Una funcionalidad muy conveniente que hemos visto en la declaración de atributos de clase es la de realizar su inicialización en el cuerpo de la clase. Para poder inicializar los atributos de una instancia existe un método <em>especial</em> que permite actuar sobre la inicialización del objeto. Dicho método se denomina <code>__init__</code> (con dos guiones bajos al principio y al final) y admite cualquier número de parámetros, siendo el primero la referencia al objeto que es incializado (<code>self</code>, por convención), que nos permite realizar las asignaciones a atributos de la instancia. Este método se ejecuta siempre que se crea un nuevo objeto de la clase, tras la asignación de memoria y con los atributos de clase inicializados, y se corresponde parcialmente con el concepto de <strong>constructor de la clase</strong> existente en otros lenguajes.</p>
<p>Con la referencia que nos proporciona <code>self</code> podemos inicializar atributos de instancia, con valores predeterminados si lo deseamos, como en cualquier definición de función:</p>
<p><code></p>
<pre>
class Clase:
    def __init__(self, x=2):
        self.x = x
        self.a = x**2
        self.b = x**3
        self.c = 999
    def dime_datos(self):
        return "Con x=%i obtenemos: a=%i, b=%i, c=%i" % (self.x, self.a, self.b, self.c)
a1 = Clase(2)
a1.dime_datos()
a2 = Clase(3)
a2.dime_datos()
</pre>
<p></code></p>
<p>Salida:</p>
<p><code><br />
Con x=2 obtenemos: a=4, b=8, c=999<br />
Con x=3 obtenemos: a=9, b=27, c=999<br />
</code></p>
<h2>Propiedades y Atributos</h2>
<p>Aunque en la terminología general de la programación orientada a objetos <em>atributo y propiedad</em> se pueden utilizar como sinómimos, en python se particulariza el uso de <strong>propiedades</strong> para un tipo especial de <strong>atributos cuyo acceso se produce a través de llamadas a funciones</strong>.</p>
<p><code></p>
<pre>
class ClaseC(object):
    def __init__(self):
        self.__b = 0
    def __get_b(self):
        return self.__b
    def __set_b(self, valor):
        if valor > 10:
            self.__b = 0
        else:
            self.__b = valor
    b = property(__get_b, __set_b, 'Propiedad b')

c1 = ClaseC()
print c1.b
# b es 0
c1.b = 5
print c1.b
# b es 5
c2 = ClaseC()
print c2.b
# b es 0
c2.b = 12
print c2.b
#b es 0
</pre>
<p></code></p>
<p>En este ejemplo se define la propiedad <code>b</code>, cuyo comportamiento es: cuando se realiza una asignación, toma el valor entregado si es menor que <em>10</em>, o <em>0</em> en caso contrario, y lo almacena en un atributo privado <code>__b</code>. Cuando se produce la lectura de <code>b</code>, devuelve el valor guardado en el atributo privado.</p>
<p>En Python, para poder usar propiedades en una clase es necesario hacerla derivar de la clase <code>object</code> de ahí que aparezca al lado del nombre de la clase <code>ClaseC</code>. En un apartado posterior se explicará en qué consiste la derivación de clases.</p>
<p>La signatura de la función <code>property</code>, que define una propiedad de la clase es la siguiente:<br />
<code>nombre_propiedad = property(get_f, set_f, del_f, doc)</code><br />
donde <code>get_f</code> es la función llamada cuando se produce la lectura del atributo; <code>set_f</code> la función llamada cuando se produce una asignación al atributo; <code>del_f</code> la función llamada cuando se elimina el atributo, y <code>doc</code> es una cadena de documentación de la propiedad.</p>
<p>Las propiedades resultan muy útiles para realizar la validación de los valores asignados, la transformación o cálculo de valores devueltos y, además, dotan de gran flexibilidad a la hora de escribir el código, puesto que es posible empezar usando atributos y luego sustituirlo por una propiedad que realice funciones adicionales, a medida que el código lo requiera y simplemente cambiando el código de la clase, sin afectar al código cliente de la clase.</p>
<h2>Herencia y derivación de clases</h2>
<p>Vemos que el uso de clases hace más adecuada la representación de conceptos en nuestros programas. Además, <strong>es posible generar una clase nueva a partir de otra, de la que recibe su comportamiento y estado (métodos y atributos), adaptándolos o ampliándolos según sea necesario</strong>.</p>
<p>De una clase que representase el concepto de vehículo podríamos derivar otras para representar automóviles, bicicletas, barcos o aviones, donde cada uno de ellos mantiene atributos y métodos comunes (peso, color, velocidad máxima, número de pasajeros), mientras que otros son exclusivos (número de ruedas, número de hélices, número de reactores, altitud máxima de vuelo...).</p>
<p>En términos matemáticos podemos expresarlo diciendo que es posible establecer relaciones de pertenencia entre clases. Si tenemos una clase A y de ella derivamos una clase B, podemos decir que "<em>B es una A</em>", o que "<em>B es una especialización de A</em>".</p>
<p>En la terminología de la POO se dice que "<em>B hereda de A</em>", "<em>B es una clase derivada de A</em>", "<em>A es la clase base de B</em>", "<em>A es superclase de B</em>" o "<em>A es clase madre de B</em>".</p>
<p>Esto facilita la reutilización del código, puesto que se pueden implementar los comportamientos y datos básicos en una clase base y especializarlos en las clases derivadas.</p>
<p>En un programa hipotético que trabajase con formas geométricas, podríamos tener una clase base <em>Forma</em> y clases derivadas de ella como <em>Triangulo</em>, <em>Cuadrado</em>, <em>Circulo</em>... En la clase base podríamos definir un método dibuja que representa la figura en pantalla, y un método area y otro perímetro que calculan el área y el perímetro, respectivamente.</p>
<p>En el lenguaje python, para expresar que una clase deriva, desciende o es heredera de otra u otras clases se añade tras el nombre, en la declaración de la clase, una tupla con los nombres de las clases base.</p>
<p>El siguiente ejemplo crea una <code>ClaseA</code> y de ella deriva una <code>ClaseB</code> que inicializa un atributo adicional, cambia el comportamiento de un método y hereda los atributos de la clase madre:</p>
<p><code></p>
<pre>
class ClaseA:
    def __init__(self, x):
        self.a = x
        self.b = 2 * x
    def muestra(self):
        print "a=%i, b=%i" % (self.a, self.b)

class ClaseB(ClaseA):
    def __init__(self, x, y):
        ClaseA.__init__(self, x)
        self.c = 3 * (x + y) + self.b
    def muestra(self):
        print "a=%i, b=%i, c=%i" % (self.a, self.b, self.c)

print "Objeto A"
a = ClaseA(2)
print a.__dict__
a.muestra()

print "ObjetoB"
b = ClaseB(2, 3)
print b.__dict__
b.muestra()
</pre>
<p></code></p>
<p>Este código al ejecutarse devuelve:</p>
<p><code><br />
Objeto A<br />
{'a': 2, 'b': 4}<br />
a=2, b=4<br />
ObjetoB<br />
{'a': 2, 'c': 19, 'b': 4}<br />
a=2, b=4, c=19<br />
</code></p>
<p>La clase <code>ClaseA</code> muestra funcionalidades que ya hemos ido viendo en esta introducción (atributos de instancia <code>a</code> y <code>b</code>, método <code>muestra</code>). La clase <code>ClaseB</code> se declara como descendiente de la <code>ClaseA</code>, por lo que hereda sus métodos y atributos y modifica algo el comportamiento de la clase madre. Por una parte, en su método de inicialización llama al método de la clase madre con los parámetros deseados, y, posteriomente, añade un nuevo atributo de instancia que no existe en la clase madre. Por otro lado, redefine un método existente en <code>ClaseA</code>, cambiando la implementación.</p>
<p>Esta última técnica, en la que un mismo nombre se asocia a comportamientos distintos se conoce como <strong>polimorfismo</strong>, y se habla de que el método se ha sobrecargado, es decir, se le asignan distintos significados en función de su contexto. El polimorfismo también alude a la posibilidad de utilizar, en un contexto en el que se espera una clase dada, cualquier clase derivada.</p>
<h3>La clase object</h3>
<p>Desde la versión <em>2.2</em> de <a href="http://www.python.org">python</a>, se ha establecido una clase base llamada <code>object</code> de la que se aconseja derivar todas las clases. Esto permite aprovechar una serie de características sólo existentes en las <em>"nuevas clases"</em> (como la definición de propiedades), que se describen en la documentación de python.</p>
<p>En el ejemplo sobre el uso de propiedades se introdujo la herencia sin explicarla, derivando la clase de <code>object</code>. Ahora debería estar más clara la razón <img src='http://blog.rvburke.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<h2>Jerarquías de clases</h2>
<p>La herencia permite establecer relaciones entre clases, y, estas relaciones de pertenencia pueden ser a varios niveles, y ramificarse en lo que se denominan <strong>jerarquías de clases</strong>.</p>
<p>Un ejemplo de clásico para visualizar las jerarquías de clases es el que podría servir para modelizar el conjunto de empleados de una empresa. En ella aparece una clase base <code>Empleado</code>, que dispone de los atributos <code>nombre</code> y <code>departamento</code>; de ella descienden las subclases <code>Gestor</code> (atributo adicional <code>informes</code>) y <code>Trabajador</code> (atributo adicional <code>proyectos</code>), y de esta última derivan las clases <code>Comercial</code> (atributo adicional <code>participación</code>) e <code>Ingeniero</code> (atributo original <code>area</code>).</p>
<p>Gráficamente podría representarse de la siguiente manera:</p>
<p><img src="http://blog.rvburke.com/wp-content/uploads/2006/11/jerarquiaclases.png" alt="Jerarquía de clases" /></p>
<p>En el diagrama se puede ver en negrita los atributos que implementa cada clase, y en gris los que hereda de clases madre. El código (básico de inicialización) de las clases podría ser el siguiente:</p>
<p><code></p>
<pre>
class Empleado:
    def __init__(self, nombre, departamento="general"):
        self.nombre = nombre
        self.departamento = departamento

class Gestor(Empleado):
    def __init__(self, nombre):
        Empleado.__init__(self, nombre)
        self.informes = []

class Trabajador(Empleado):
    def __init__(self, nombre):
        Empleado.__init__(self, nombre)
        self.proyectos = []

class Comercial(Trabajador):
    def __init__(self, nombre, participacion=0.1):
        Trabajador.__init__(self, nombre)
        self.departamento = "ventas"
        self.participacion = participacion

class Ingeniero(Trabajador):
    def __init__(self, nombre, area="mecánica"):
        Trabajador.__init__(self, nombre)
        self.departamento = "ingeniería"
        self.area = area
</pre>
<p></code></p>
<p>Naturalmente, cada una de las clases tendría sus propios métodos que definirían comportamientos propios de cada clase o subclase, que no se han detallado en el ejemplo.</p>
<p>Una alternativa a la herencia es la composición, en el que una clase se compone de otras clases internas, y que puede ser una mejor alternativa en muchos casos.</p>
<h2>Encapsulación y grados de privacidad</h2>
<p>Uno de los principios que guían la POO, heredados de la programación modular, es el de <strong>encapsulación</strong>. Hemos visto cómo se puede agrupar comportamiento y datos gracias al uso de objetos, pero hasta el momento, tanto los atributos como los métodos que se definen en las clases correspondientes se convierten en métodos y atributos visibles para los usuarios de la clase (la <em>API</em> de la clase).</p>
<p>Se dice que un método o atributo es <strong>público</strong> si es accesible desde el exterior de la clase, mientras que se denomina <strong>privado</strong> en caso contrario.</p>
<p>Es deseable poder señalar qué métodos y atributos no deben utilizarse fuera de la clase para evitar exponer excesivamente los detalles de la implementación de una clase o un objeto.</p>
<p>Python utiliza para ello convenciones a la hora de nombrar métodos y atributos, de forma que se señale su carácter privado, para su exclusión del espacio de nombres, o para indicar una función especial, normalmente asociada a funcionalidades estándar del lenguaje.</p>
<h3>_nombre</h3>
<p>Los nombres que comienzan con un único guión bajo indican de forma débil un uso interno. Además, estos nombres no se incorporan en el espacio de nombres de un módulo al importarlo con <em>"from ... import *"</em>.</p>
<h3>__nombre</h3>
<p>Los nombres que empiezan por dos guiones bajos indican su uso privado en la clase.</p>
<p>Por ejemplo, en la definición de clase siguiente:</p>
<p><code></p>
<pre>
class ClaseA:
    def __init__(self, a)
        self.__a = a
        self.x = self.__a**2 + 2
        self.y = self.__a**3 + 3
</pre>
<p></code></p>
<p>el atributo <code>__a</code> es de uso interno de la clase y no se exporta directamente. A continuación podemos ver cómo trata los atributos 'privados' python:</p>
<p><code><br />
&gt;&gt;&gt; a = ClaseA(2)<br />
&gt;&gt;&gt; dir(a)<br />
['_ClaseA__a', '__doc__', '__init__', '__module__', 'x', 'y']<br />
&gt;&gt;&gt; a.__dict__<br />
{'x':6, 'y':11, '_ClaseA__a':2}<br />
</code></p>
<p>Todavía es posible acceder a <code>__a</code>, pero el nombre es transformado a <code>'_ClaseA__a'</code>, que lo señala como un atributo de uso privado.</p>
<h3>__nombre__</h3>
<p>Los nombres que empiezan y acaban con dos guiones bajos indican atributos "mágicos", de uso especial y que residen en espacios de nombres que puede manipular el usuario. Solamente deben usarse en la manera que se describe en la documentación de python y debe evitarse la creación de nuevos atributos de este tipo.</p>
<p>Algunos ejemplos de nombres "singulares" de este tipo son:<br />
    <code>__init__</code>, método de inicialización de objetos<br />
    <code>__del__</code>, método de destrucción de objetos<br />
    <code>__doc__</code>, cadena de documentación de módulos, clases...<br />
    <code>__class__</code>, nombre de la clase<br />
    <code>__str__</code>, método que devuelve una descripción de la clase como cadena de texto<br />
    <code>__repr__</code>, método que devuelve una representación de la clase como cadena de texto<br />
    <code>__module__</code>, módulo al que pertenece la clase<br />
Se puede consultar la lista de atributos de este tipo y su descripción detallada en la documentación de python.</p>
<h2>Resúmen final</h2>
<p>La programación orientada a objetos enuncia la posibilidad de escribir un programa como un conjunto de clases de objetos capaces de almacenar su estado, y que interactúan entre sí a través del envío de mensajes.</p>
<p>Las técnicas más importantes utilizadas en la programación orientada a objetos son:</p>
<ul>
<li><strong>Abstracción</strong>: Los objetos pueden realizar tareas, interactuar con otros objetos, o modificar e informar sobre su estado sin necesidad de comunicar cómo se realizan dichas acciones.</li>
<li><strong>Encapsulación</strong> (u ocultación de la información): los objetos impiden la modificación de su estado interno o la llamada a métodos internos por parte de otros objetos, y solamente se relacionan a través de una interfaz clara que define cómo se relacionan con otros objetos.</li>
<li><strong>Polimorfismo</strong>: comportamientos distintos pueden estar asociados al mismo nombre</li>
<li><strong>Herencia</strong>: los objetos se relacionan con otros estableciendo jerarquías, y es posible que unos objetos hereden las propiedades y métodos de otros objetos, extendiendo su comportamiento y/o especializándolo. Los objetos se agrupan así en clases que forman jerarquías.</li>
</ul>
<p>Las clases definen el comportamiento y estado disponible que se concreta en los objetos.</p>
<p>Los objetos se caracterizan por:</p>
<ul>
<li>Tener <strong>identidad</strong>. Se diferencian entre sí.</li>
<li>Definir su <strong>comportamiento</strong> a través de <strong>métodos</strong>.</li>
<li>Definir o reflejar su <strong>estado</strong> a través de <strong>propiedades y atributos</strong>.</li>
</ul>
<blockquote><p>Gracias a la amable aportación de Óscar Carballal ahora es posible descargar una <a href="http://blog.rvburke.com/wp-content/uploads/2006/11/Introducción-a-la-programación-orientada-a-objetos.pdf">versión en PDF</a> del artículo</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.rvburke.com/2006/11/22/programacion-orientada-a-objetos-en-python/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Java y la GPL</title>
		<link>http://blog.rvburke.com/2006/11/14/java-y-la-gpl/</link>
		<comments>http://blog.rvburke.com/2006/11/14/java-y-la-gpl/#comments</comments>
		<pubDate>Tue, 14 Nov 2006 13:26:11 +0000</pubDate>
		<dc:creator>pachi</dc:creator>
				<category><![CDATA[castellano]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[software-libre]]></category>

		<guid isPermaLink="false">http://blog.rvburke.com/2006/11/14/java-y-la-gpl/</guid>
		<description><![CDATA[class FirstFreeJavaProg { public static void main(String args[]) { System.out.println("Java is getting Free as in GPL!"); } } Sun anunció ayer que publicará el código de la plataforma Java bajo la licencia GPL. Es una muy buena noticia para el mundo del software libre, ya que pronto será más fácil utilizar una de las formas [...]]]></description>
			<content:encoded><![CDATA[<p><img class="floatleft" src="http://blog.rvburke.com/wp-content/uploads/2006/11/open_source_java.jpg" alt="Open source Java" /><br />
<code>
<pre>class FirstFreeJavaProg
{
        public static void main(String args[])
        {
           System.out.println("Java is getting Free as in GPL!");
        }
}</pre>
<p></code><br />
<span id="more-94"></span><br />
Sun <a href="http://www.sun.com/2006-1113/feature/index.jsp">anunció</a> ayer que publicará el código de la <a href="https://openjdk.dev.java.net/">plataforma Java bajo la licencia GPL</a>. Es una muy buena noticia para el mundo del software libre, ya que pronto será más fácil utilizar una de las formas más comunes para expresar ideas en el ámbito de la computación <a href="http://www.gnu.org/philosophy/java-trap.es.html">sin comprometer tus libertades</a>.</p>
<p>Aunque me gusta más programar en <a href="http://www.python.org">python</a>, Java es un lenguaje bastante elegante, que puede compararse a un C++ más pulido, sin las cargas de mantener la compatibilidad con el lenguaje C. Java puede hacerle una buena competencia a la plataforma .NET (o su alternativa libre, <a href="http://www.mono-project.com/">Mono</a>) de Microsoft, por su gran implantación en el mundo empresarial y de las administraciones públicas o en el de los dispositivos electrónicos.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rvburke.com/2006/11/14/java-y-la-gpl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pascaline &#8211; cálculo de la presión de hundimiento en zapatas</title>
		<link>http://blog.rvburke.com/2006/11/06/pascaline-calculo-de-la-presion-de-hundimiento-en-zapatas/</link>
		<comments>http://blog.rvburke.com/2006/11/06/pascaline-calculo-de-la-presion-de-hundimiento-en-zapatas/#comments</comments>
		<pubDate>Sun, 05 Nov 2006 22:34:32 +0000</pubDate>
		<dc:creator>pachi</dc:creator>
				<category><![CDATA[castellano]]></category>
		<category><![CDATA[estructuras]]></category>
		<category><![CDATA[pascaline]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[software-libre]]></category>

		<guid isPermaLink="false">http://blog.rvburke.com/2006/11/06/pascaline-calculo-de-la-presion-de-hundimiento-en-zapatas/</guid>
		<description><![CDATA[Pascaline, el proyecto que quiere llevar el software libre al cálculo de estructuras, ha avanzado un pequeño paso más estos días con la incorporación de un programa para el cálculo de la presión de hundimiento en zapatas siguiendo la formulación del CTE DB-SE-C. El 24 de octubre, Alfredo Rodríguez Viescas, &#8216;Fredo&#8217;, envió la implementación inicial [...]]]></description>
			<content:encoded><![CDATA[<p><img class="floatleft" src="http://blog.rvburke.com/wp-content/uploads/2006/11/zapata.gif" alt="cálculo de la presión hundimiento zapata - CTE" /><a href="http://www.rvburke.com/pascaline.html">Pascaline</a>, el proyecto que quiere llevar el software libre al cálculo de estructuras, ha avanzado un pequeño paso más estos días con la incorporación de un programa para el cálculo de la presión de hundimiento en zapatas siguiendo la formulación del CTE DB-SE-C.</p>
<p>El 24 de octubre, Alfredo Rodríguez Viescas, &#8216;Fredo&#8217;, envió la <a href="http://pascaline.rvburke.com/private.cgi/pascaline-rvburke.com/attachments/20061024/3a5c9700/phundimiento.ksh">implementación inicial</a> a la lista de correo de Pascaline y anteayer subí una <a href="http://hg.rvburke.com/pascaline/pachi/?f=31eee74e1a50;file=phundimiento.py">versión corregida</a> al <a href="http://hg.rvburke.com/pascaline/pachi/">repositorio del proyecto</a>.<br />
<span id="more-93"></span><br />
El programa phundimiento permite el cálculo de la presión de hundimiento de zapatas rectangulares tanto en condiciones drenadas como no drenadas, y para todos los casos que contempla la formulación del código técnico en su DB-SE-C, salvo el caso de zapatas circulares , y los casos en los que las cargas están inclinadas respecto a la vertical, o cuando se ha de tener en cuenta la presencia de taludes próximos.</p>
<p>En la versión del repositorio se ha desacoplado la interfaz de texto de las funciones que podrían formar parte de una librería de cálculos geotécnicos; se han renombrado las variables y funciones procurando que el código se autodocumente y no precise de aclaraciones en línea; se ha unificado el estilo siguiendo el PEP-8; se ha unificado la API; se ha tratado de que cada función realice tareas específicas y reciba únicamente los parámetros necesarios para ello; también se han separado las funciones que podrían llegar a ser útiles en una librería&#8230;</p>
<p>Los casos pendientes de resolución en la versión actual no presentan gran complejidad, puesto que se trata de incorporar un par de coeficientes adicionales o de señalizar el tipo de geometría de la zapata, pero todavía es necesario pensar cómo queremos modelar la API de programa.</p>
<p>Todavía es preciso abstraer más la interfaz de las funciones generales, para evitar la profusión de parámetros que únicamente responden a la casuística del problema. Seguramente, nos ayudará en esta tarea la generalización de las acciones y del terreno en clases que encapsulen la variedad existente, y permitan que las funciones principales tengan una API más uniforme. Es preferible que la lógica de selección del caso apropiado se encuentre en el propio código, por ejemplo usando el patrón estrategia, y no recaiga en la selección previa de la función adecuada por parte del usuario/a.</p>
<p>Idealmente, se trataría de pasar una zapata, un terreno y unas acciones, y de obtener de ellos la presión de hundimiento&#8230; así que no deberíamos exigir mucho más que eso&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rvburke.com/2006/11/06/pascaline-calculo-de-la-presion-de-hundimiento-en-zapatas/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>HTML 4.01 Entities Reference</title>
		<link>http://blog.rvburke.com/2006/10/22/html-401-entities-reference/</link>
		<comments>http://blog.rvburke.com/2006/10/22/html-401-entities-reference/#comments</comments>
		<pubDate>Sun, 22 Oct 2006 17:29:39 +0000</pubDate>
		<dc:creator>pachi</dc:creator>
				<category><![CDATA[english]]></category>
		<category><![CDATA[programación]]></category>

		<guid isPermaLink="false">http://blog.rvburke.com/2006/10/22/html-401-entities-reference/</guid>
		<description><![CDATA[It&#8217;s quite common to find myself searching the web for HTML entity names when writing webpages. They&#8217;re very useful to avoid encoding problems with those symbols that don&#8217;t fit belong to those defined with ASCII codes. I&#8217;ve posted a reference here to have them at hand next time. The following table has been extracted from [...]]]></description>
			<content:encoded><![CDATA[<p><img class="floatleft" src="http://blog.rvburke.com/wp-content/uploads/2006/10/circuito_impreso-by-nc-nd.thumbnail.jpg" alt="circuito impreso luz" />It&#8217;s quite common to find myself searching the web for HTML entity names when writing webpages. They&#8217;re very useful to avoid encoding problems with those symbols that don&#8217;t fit belong to those defined with ASCII codes.</p>
<p>I&#8217;ve posted a reference here to have them at hand next time.<br />
<span id="more-70"></span><br />
The following table has been extracted from information found at <a href="http://www.w3schools.com/tags/ref_entities.asp">www.w3schools.com</a>:</p>
<p><strong>Note</strong>: entity names are case sensitive.</p>
<h2>ASCII Entities with new Entity Names</h2>
<table class="ex" cellspacing="0" border="1" width="100%">
<tbody>
<tr>
<th align="left">Result</th>
<th align="left">Description</th>
<th align="left">Entity Name</th>
<th align="left">Entity Number</th>
</tr>
<tr>
<td>&#8220;</td>
<td>quotation mark</td>
<td>&amp;quot;</td>
<td>&amp;#34;</td>
</tr>
<tr>
<td>&amp;</td>
<td>ampersand</td>
<td>&amp;amp;</td>
<td>&amp;#38;</td>
</tr>
<tr>
<td>&lt;</td>
<td>less-than</td>
<td>&amp;lt;</td>
<td>&amp;#60;</td>
</tr>
<tr>
<td>&gt;</td>
<td>greater-than</td>
<td>&amp;gt;</td>
<td>&amp;#62;</td>
</tr>
</tbody>
</table>
<h2>ISO 8859-1 Symbol Entities</h2>
<table class="ex" cellspacing="0" border="1" width="100%">
<tbody>
<tr>
<th align="left">Result</th>
<th align="left">Description</th>
<th align="left">Entity Name</th>
<th align="left">Entity Number</th>
</tr>
<tr>
<td> </td>
<td>non-breaking space</td>
<td>&amp;nbsp;</td>
<td>&amp;#160;</td>
</tr>
<tr>
<td>¡</td>
<td>inverted exclamation mark</td>
<td>&amp;iexcl;</td>
<td>&amp;#161;</td>
</tr>
<tr>
<td>¤</td>
<td>currency</td>
<td>&amp;curren;</td>
<td>&amp;#164;</td>
</tr>
<tr>
<td>¢</td>
<td>cent</td>
<td>&amp;cent;</td>
<td>&amp;#162;</td>
</tr>
<tr>
<td>£</td>
<td>pound</td>
<td>&amp;pound;</td>
<td>&amp;#163;</td>
</tr>
<tr>
<td>¥</td>
<td>yen</td>
<td>&amp;yen;</td>
<td>&amp;#165;</td>
</tr>
<tr>
<td>¦</td>
<td>broken vertical bar</td>
<td>&amp;brvbar;</td>
<td>&amp;#166;</td>
</tr>
<tr>
<td>§</td>
<td>section</td>
<td>&amp;sect;</td>
<td>&amp;#167;</td>
</tr>
<tr>
<td>¨</td>
<td>spacing diaeresis</td>
<td>&amp;uml;</td>
<td>&amp;#168;</td>
</tr>
<tr>
<td>©</td>
<td>copyright</td>
<td>&amp;copy;</td>
<td>&amp;#169;</td>
</tr>
<tr>
<td>ª</td>
<td>feminine ordinal indicator</td>
<td>&amp;ordf;</td>
<td>&amp;#170;</td>
</tr>
<tr>
<td>«</td>
<td>angle quotation mark (left)</td>
<td>&amp;laquo;</td>
<td>&amp;#171;</td>
</tr>
<tr>
<td>¬</td>
<td>negation</td>
<td>&amp;not;</td>
<td>&amp;#172;</td>
</tr>
<tr>
<td>­</td>
<td>soft hyphen</td>
<td>&amp;shy;</td>
<td>&amp;#173;</td>
</tr>
<tr>
<td>®</td>
<td>registered trademark</td>
<td>&amp;reg;</td>
<td>&amp;#174;</td>
</tr>
<tr>
<td>&#8482;</td>
<td>trademark</td>
<td>&amp;trade;</td>
<td> </td>
</tr>
<tr>
<td>¯</td>
<td>spacing macron</td>
<td>&amp;macr;</td>
<td>&amp;#175;</td>
</tr>
<tr>
<td>°</td>
<td>degree</td>
<td>&amp;deg;</td>
<td>&amp;#176;</td>
</tr>
<tr>
<td>±</td>
<td>plus-or-minus </td>
<td>&amp;plusmn;</td>
<td>&amp;#177;</td>
</tr>
<tr>
<td>²</td>
<td>superscript 2</td>
<td>&amp;sup2;</td>
<td>&amp;#178;</td>
</tr>
<tr>
<td>³</td>
<td>superscript 3</td>
<td>&amp;sup3;</td>
<td>&amp;#179;</td>
</tr>
<tr>
<td>´</td>
<td>spacing acute</td>
<td>&amp;acute;</td>
<td>&amp;#180;</td>
</tr>
<tr>
<td>µ</td>
<td>micro</td>
<td>&amp;micro;</td>
<td>&amp;#181;</td>
</tr>
<tr>
<td>¶</td>
<td>paragraph</td>
<td>&amp;para;</td>
<td>&amp;#182;</td>
</tr>
<tr>
<td>·</td>
<td>middle dot</td>
<td>&amp;middot;</td>
<td>&amp;#183;</td>
</tr>
<tr>
<td>¸</td>
<td>spacing cedilla</td>
<td>&amp;cedil;</td>
<td>&amp;#184;</td>
</tr>
<tr>
<td>¹</td>
<td>superscript 1</td>
<td>&amp;sup1;</td>
<td>&amp;#185;</td>
</tr>
<tr>
<td>º</td>
<td>masculine ordinal indicator</td>
<td>&amp;ordm;</td>
<td>&amp;#186;</td>
</tr>
<tr>
<td>»</td>
<td>angle quotation mark (right)</td>
<td>&amp;raquo;</td>
<td>&amp;#187;</td>
</tr>
<tr>
<td>¼</td>
<td>fraction 1/4</td>
<td>&amp;frac14;</td>
<td>&amp;#188;</td>
</tr>
<tr>
<td>½</td>
<td>fraction 1/2</td>
<td>&amp;frac12;</td>
<td>&amp;#189;</td>
</tr>
<tr>
<td>¾</td>
<td>fraction 3/4</td>
<td>&amp;frac34;</td>
<td>&amp;#190;</td>
</tr>
<tr>
<td>¿</td>
<td>inverted question mark</td>
<td>&amp;iquest;</td>
<td>&amp;#191;</td>
</tr>
<tr>
<td>×</td>
<td>multiplication</td>
<td>&amp;times;</td>
<td>&amp;#215;</td>
</tr>
<tr>
<td>÷</td>
<td>division</td>
<td>&amp;divide;</td>
<td>&amp;#247;</td>
</tr>
</tbody>
</table>
<h2>ISO 8859-1 Character Entities</h2>
<table class="ex" cellspacing="0" border="1" width="100%">
<tbody>
<tr>
<th align="left">Result</th>
<th align="left">Description</th>
<th align="left">Entity Name</th>
<th align="left">Entity Number</th>
</tr>
<tr>
<td>À</td>
<td>capital a, grave accent</td>
<td>&amp;Agrave;</td>
<td>&amp;#192;</td>
</tr>
<tr>
<td>Á</td>
<td>capital a, acute accent</td>
<td>&amp;Aacute;</td>
<td>&amp;#193;</td>
</tr>
<tr>
<td>Â</td>
<td>capital a, circumflex accent</td>
<td>&amp;Acirc;</td>
<td>&amp;#194;</td>
</tr>
<tr>
<td>Ã</td>
<td>capital a, tilde</td>
<td>&amp;Atilde;</td>
<td>&amp;#195;</td>
</tr>
<tr>
<td>Ä</td>
<td>capital a, umlaut mark</td>
<td>&amp;Auml;</td>
<td>&amp;#196;</td>
</tr>
<tr>
<td>Å</td>
<td>capital a, ring</td>
<td>&amp;Aring;</td>
<td>&amp;#197;</td>
</tr>
<tr>
<td>Æ</td>
<td>capital ae</td>
<td>&amp;AElig;</td>
<td>&amp;#198;</td>
</tr>
<tr>
<td>Ç</td>
<td>capital c, cedilla</td>
<td>&amp;Ccedil;</td>
<td>&amp;#199;</td>
</tr>
<tr>
<td>È</td>
<td>capital e, grave accent</td>
<td>&amp;Egrave;</td>
<td>&amp;#200;</td>
</tr>
<tr>
<td>É</td>
<td>capital e, acute accent</td>
<td>&amp;Eacute;</td>
<td>&amp;#201;</td>
</tr>
<tr>
<td>Ê</td>
<td>capital e, circumflex accent</td>
<td>&amp;Ecirc;</td>
<td>&amp;#202;</td>
</tr>
<tr>
<td>Ë</td>
<td>capital e, umlaut mark</td>
<td>&amp;Euml;</td>
<td>&amp;#203;</td>
</tr>
<tr>
<td>Ì</td>
<td>capital i, grave accent</td>
<td>&amp;Igrave;</td>
<td>&amp;#204;</td>
</tr>
<tr>
<td>Í</td>
<td>capital i, acute accent</td>
<td>&amp;Iacute;</td>
<td>&amp;#205;</td>
</tr>
<tr>
<td>Î</td>
<td>capital i, circumflex accent</td>
<td>&amp;Icirc;</td>
<td>&amp;#206;</td>
</tr>
<tr>
<td>Ï</td>
<td>capital i, umlaut mark</td>
<td>&amp;Iuml;</td>
<td>&amp;#207;</td>
</tr>
<tr>
<td>Ð</td>
<td>capital eth, Icelandic</td>
<td>&amp;ETH;</td>
<td>&amp;#208;</td>
</tr>
<tr>
<td>Ñ</td>
<td>capital n, tilde</td>
<td>&amp;Ntilde;</td>
<td>&amp;#209;</td>
</tr>
<tr>
<td>Ò</td>
<td>capital o, grave accent</td>
<td>&amp;Ograve;</td>
<td>&amp;#210;</td>
</tr>
<tr>
<td>Ó</td>
<td>capital o, acute accent</td>
<td>&amp;Oacute;</td>
<td>&amp;#211;</td>
</tr>
<tr>
<td>Ô</td>
<td>capital o, circumflex accent</td>
<td>&amp;Ocirc;</td>
<td>&amp;#212;</td>
</tr>
<tr>
<td>Õ</td>
<td>capital o, tilde</td>
<td>&amp;Otilde;</td>
<td>&amp;#213;</td>
</tr>
<tr>
<td>Ö</td>
<td>capital o, umlaut mark</td>
<td>&amp;Ouml;</td>
<td>&amp;#214;</td>
</tr>
<tr>
<td>Ø</td>
<td>capital o, slash</td>
<td>&amp;Oslash;</td>
<td>&amp;#216;</td>
</tr>
<tr>
<td>Ù</td>
<td>capital u, grave accent</td>
<td>&amp;Ugrave;</td>
<td>&amp;#217;</td>
</tr>
<tr>
<td>Ú</td>
<td>capital u, acute accent</td>
<td>&amp;Uacute;</td>
<td>&amp;#218;</td>
</tr>
<tr>
<td>Û</td>
<td>capital u, circumflex accent</td>
<td>&amp;Ucirc;</td>
<td>&amp;#219;</td>
</tr>
<tr>
<td>Ü</td>
<td>capital u, umlaut mark</td>
<td>&amp;Uuml;</td>
<td>&amp;#220;</td>
</tr>
<tr>
<td>Ý</td>
<td>capital y, acute accent</td>
<td>&amp;Yacute;</td>
<td>&amp;#221;</td>
</tr>
<tr>
<td>Þ</td>
<td>capital THORN, Icelandic</td>
<td>&amp;THORN;</td>
<td>&amp;#222;</td>
</tr>
<tr>
<td>ß</td>
<td>small sharp s, German</td>
<td>&amp;szlig;</td>
<td>&amp;#223;</td>
</tr>
<tr>
<td>à</td>
<td>small a, grave accent</td>
<td>&amp;agrave;</td>
<td>&amp;#224;</td>
</tr>
<tr>
<td>á</td>
<td>small a, acute accent</td>
<td>&amp;aacute;</td>
<td>&amp;#225;</td>
</tr>
<tr>
<td>â</td>
<td>small a, circumflex accent</td>
<td>&amp;acirc;</td>
<td>&amp;#226;</td>
</tr>
<tr>
<td>ã</td>
<td>small a, tilde</td>
<td>&amp;atilde;</td>
<td>&amp;#227;</td>
</tr>
<tr>
<td>ä</td>
<td>small a, umlaut mark</td>
<td>&amp;auml;</td>
<td>&amp;#228;</td>
</tr>
<tr>
<td>å</td>
<td>small a, ring</td>
<td>&amp;aring;</td>
<td>&amp;#229;</td>
</tr>
<tr>
<td>æ</td>
<td>small ae</td>
<td>&amp;aelig;</td>
<td>&amp;#230;</td>
</tr>
<tr>
<td>ç</td>
<td>small c, cedilla</td>
<td>&amp;ccedil;</td>
<td>&amp;#231;</td>
</tr>
<tr>
<td>è</td>
<td>small e, grave accent</td>
<td>&amp;egrave;</td>
<td>&amp;#232;</td>
</tr>
<tr>
<td>é</td>
<td>small e, acute accent</td>
<td>&amp;eacute;</td>
<td>&amp;#233;</td>
</tr>
<tr>
<td>ê</td>
<td>small e, circumflex accent</td>
<td>&amp;ecirc;</td>
<td>&amp;#234;</td>
</tr>
<tr>
<td>ë</td>
<td>small e, umlaut mark</td>
<td>&amp;euml;</td>
<td>&amp;#235;</td>
</tr>
<tr>
<td>ì</td>
<td>small i, grave accent</td>
<td>&amp;igrave;</td>
<td>&amp;#236;</td>
</tr>
<tr>
<td>í</td>
<td>small i, acute accent</td>
<td>&amp;iacute;</td>
<td>&amp;#237;</td>
</tr>
<tr>
<td>î</td>
<td>small i, circumflex accent</td>
<td>&amp;icirc;</td>
<td>&amp;#238;</td>
</tr>
<tr>
<td>ï</td>
<td>small i, umlaut mark</td>
<td>&amp;iuml;</td>
<td>&amp;#239;</td>
</tr>
<tr>
<td>ð</td>
<td>small eth, Icelandic</td>
<td>&amp;eth;</td>
<td>&amp;#240;</td>
</tr>
<tr>
<td>ñ</td>
<td>small n, tilde</td>
<td>&amp;ntilde;</td>
<td>&amp;#241;</td>
</tr>
<tr>
<td>ò</td>
<td>small o, grave accent</td>
<td>&amp;ograve;</td>
<td>&amp;#242;</td>
</tr>
<tr>
<td>ó</td>
<td>small o, acute accent</td>
<td>&amp;oacute;</td>
<td>&amp;#243;</td>
</tr>
<tr>
<td>ô</td>
<td>small o, circumflex accent</td>
<td>&amp;ocirc;</td>
<td>&amp;#244;</td>
</tr>
<tr>
<td>õ</td>
<td>small o, tilde</td>
<td>&amp;otilde;</td>
<td>&amp;#245;</td>
</tr>
<tr>
<td>ö</td>
<td>small o, umlaut mark</td>
<td>&amp;ouml;</td>
<td>&amp;#246;</td>
</tr>
<tr>
<td>ø</td>
<td>small o, slash</td>
<td>&amp;oslash;</td>
<td>&amp;#248;</td>
</tr>
<tr>
<td>ù</td>
<td>small u, grave accent</td>
<td>&amp;ugrave;</td>
<td>&amp;#249;</td>
</tr>
<tr>
<td>ú</td>
<td>small u, acute accent</td>
<td>&amp;uacute;</td>
<td>&amp;#250;</td>
</tr>
<tr>
<td>û</td>
<td>small u, circumflex accent</td>
<td>&amp;ucirc;</td>
<td>&amp;#251;</td>
</tr>
<tr>
<td>ü</td>
<td>small u, umlaut mark</td>
<td>&amp;uuml;</td>
<td>&amp;#252;</td>
</tr>
<tr>
<td>ý</td>
<td>small y, acute accent</td>
<td>&amp;yacute;</td>
<td>&amp;#253;</td>
</tr>
<tr>
<td>þ</td>
<td>small thorn, Icelandic</td>
<td>&amp;thorn;</td>
<td>&amp;#254;</td>
</tr>
<tr>
<td>ÿ</td>
<td>small y, umlaut mark</td>
<td>&amp;yuml;</td>
<td>&amp;#255;</td>
</tr>
</tbody>
</table>
<h2>Some Other Entities supported by HTML</h2>
<table class="ex" cellspacing="0" border="1" width="100%">
<tbody>
<tr>
<th align="left">Result</th>
<th align="left">Description</th>
<th align="left">Entity Name</th>
<th align="left">Entity Number</th>
</tr>
<tr>
<td>&#338;</td>
<td>capital ligature OE</td>
<td>&amp;OElig;</td>
<td>&amp;#338;</td>
</tr>
<tr>
<td>&#339;</td>
<td>small ligature oe</td>
<td>&amp;oelig;</td>
<td>&amp;#339;</td>
</tr>
<tr>
<td>&#352;</td>
<td>capital S with caron</td>
<td>&amp;Scaron;</td>
<td>&amp;#352;</td>
</tr>
<tr>
<td>&#353;</td>
<td>small S with caron</td>
<td>&amp;scaron;</td>
<td>&amp;#353;</td>
</tr>
<tr>
<td>&#376;</td>
<td>capital Y with diaeres</td>
<td>&amp;Yuml;</td>
<td>&amp;#376;</td>
</tr>
<tr>
<td>&#710;</td>
<td>modifier letter circumflex accent</td>
<td>&amp;circ;</td>
<td>&amp;#710;</td>
</tr>
<tr>
<td>&#732;</td>
<td>small tilde</td>
<td>&amp;tilde;</td>
<td>&amp;#732;</td>
</tr>
<tr>
<td>&#8194;</td>
<td>en space</td>
<td>&amp;ensp;</td>
<td>&amp;#8194;</td>
</tr>
<tr>
<td>&#8195;</td>
<td>em space</td>
<td>&amp;emsp;</td>
<td>&amp;#8195;</td>
</tr>
<tr>
<td>&#8201;</td>
<td>thin space</td>
<td>&amp;thinsp;</td>
<td>&amp;#8201;</td>
</tr>
<tr>
<td>&#8204;</td>
<td>zero width non-joiner</td>
<td>&amp;zwnj;</td>
<td>&amp;#8204;</td>
</tr>
<tr>
<td>&#8205;</td>
<td>zero width joiner</td>
<td>&amp;zwj;</td>
<td>&amp;#8205;</td>
</tr>
<tr>
<td>&#8206;</td>
<td>left-to-right mark</td>
<td>&amp;lrm;</td>
<td>&amp;#8206;</td>
</tr>
<tr>
<td>&#8207;</td>
<td>right-to-left mark</td>
<td>&amp;rlm;</td>
<td>&amp;#8207;</td>
</tr>
<tr>
<td>&#8211;</td>
<td>en dash</td>
<td>&amp;ndash;</td>
<td>&amp;#8211;</td>
</tr>
<tr>
<td>&#8212;</td>
<td>em dash</td>
<td>&amp;mdash;</td>
<td>&amp;#8212;</td>
</tr>
<tr>
<td>&#8216;</td>
<td>left single quotation mark</td>
<td>&amp;lsquo;</td>
<td>&amp;#8216;</td>
</tr>
<tr>
<td>&#8217;</td>
<td>right single quotation mark</td>
<td>&amp;rsquo;</td>
<td>&amp;#8217;</td>
</tr>
<tr>
<td>&#8218;</td>
<td>single low-9 quotation mark</td>
<td>&amp;sbquo;</td>
<td>&amp;#8218;</td>
</tr>
<tr>
<td>&#8220;</td>
<td>left double quotation mark</td>
<td>&amp;ldquo;</td>
<td>&amp;#8220;</td>
</tr>
<tr>
<td>&#8221;</td>
<td>right double quotation mark</td>
<td>&amp;rdquo;</td>
<td>&amp;#8221;</td>
</tr>
<tr>
<td>&#8222;</td>
<td>double low-9 quotation mark</td>
<td>&amp;bdquo;</td>
<td>&amp;#8222;</td>
</tr>
<tr>
<td>&#8224;</td>
<td>dagger</td>
<td>&amp;dagger;</td>
<td>&amp;#8224;</td>
</tr>
<tr>
<td>&#8225;</td>
<td>double dagger</td>
<td>&amp;Dagger;</td>
<td>&amp;#8225;</td>
</tr>
<tr>
<td>&#8230;</td>
<td>horizontal ellipsis</td>
<td>&amp;hellip;</td>
<td>&amp;#8230;</td>
</tr>
<tr>
<td>&#8240;</td>
<td>per mille </td>
<td>&amp;permil;</td>
<td>&amp;#8240;</td>
</tr>
<tr>
<td>&#8249;</td>
<td>single left-pointing angle quotation</td>
<td>&amp;lsaquo;</td>
<td>&amp;#8249;</td>
</tr>
<tr>
<td>&#8250;</td>
<td>single right-pointing angle quotation</td>
<td>&amp;rsaquo;</td>
<td>&amp;#8250;</td>
</tr>
<tr>
<td>&#8364;</td>
<td>euro</td>
<td>&amp;euro;</td>
<td>&amp;#8364;</td>
</tr>
<tr>
<td>&#8482;</td>
<td>trademark</td>
<td> </td>
<td>&amp;#8482;</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://blog.rvburke.com/2006/10/22/html-401-entities-reference/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

