<?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; pascaline</title>
	<atom:link href="http://blog.rvburke.com/category/pascaline/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>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>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>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>Participación en comunidades de software libre</title>
		<link>http://blog.rvburke.com/2006/10/10/participacion-en-comunidades-de-software-libre/</link>
		<comments>http://blog.rvburke.com/2006/10/10/participacion-en-comunidades-de-software-libre/#comments</comments>
		<pubDate>Tue, 10 Oct 2006 11:33:04 +0000</pubDate>
		<dc:creator>pachi</dc:creator>
				<category><![CDATA[castellano]]></category>
		<category><![CDATA[pascaline]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[software-libre]]></category>

		<guid isPermaLink="false">http://blog.rvburke.com/2006/10/10/participacion-en-comunidades-de-software-libre/</guid>
		<description><![CDATA[Comentando con Ramón y Coya acerca de la gente suscrita a la lista de correo de Pascaline siempre sale a relucir la escasa participación general. Personalmente, ya contaba con una bajísima participación, puesto que es la norma en los proyectos en los que participo, pero a raíz de la lectura de algunas reflexiones al respecto, [...]]]></description>
			<content:encoded><![CDATA[<p><img class="floatleft" src="http://blog.rvburke.com/wp-content/uploads/2006/10/open-source-diagram.png" alt="Open source diagram" />Comentando con <a href="http://www.demecanica.com">Ramón</a> y Coya acerca de la gente suscrita a la <a href="http://pascaline.rvburke.com/listinfo.cgi/pascaline-rvburke.com">lista de correo</a> de <a href="http://rvburke.com/pascaline.html">Pascaline</a> siempre sale a relucir la escasa participación general.</p>
<p>Personalmente, ya contaba con una bajísima participación, puesto que es la norma en los proyectos en los que participo, pero a raíz de la lectura de algunas <a href="http://agiletesting.blogspot.com/2006/10/90-9-1-rule-and-building-open-source.html">reflexiones al respecto</a>, he pensado que estaría bien exponer aquí algunas de las informaciones que he ido encontrando en la red.</p>
<p>En un artículo de la serie <a href="http://www.useit.com/alertbox/">AlertBox</a>, <a href="http://es.wikipedia.org/wiki/Jakob_Nielsen">Jakob Nielsen</a> trata la <a href="http://www.useit.com/alertbox/participation_inequality.html">participación en proyectos online</a> y cómo es posible facilitar la colaboración en ellos.<br />
<span id="more-62"></span><br />
Las conclusiones principales de ambos artículos son:</p>
<ul>
<li><strong>La participación en los proyectos se estratifica de forma muy desigual</strong>:
<ul>
<li>El 90% de la gente son mirones. Siguen el proyecto pero no participan.</li>
<li>El 9% de la gente hacen aportaciones ocasionales.</li>
<li>El 1% de la gente es la que hace el grueso de aportaciones.</li>
</ul>
</li>
<li>Los <strong>problemas potenciales de la participación desigual</strong> son:
<ul>
<li>Falta de realimentación por parte de los usuarios.</li>
<li>Falta de representatividad de las aportaciones respecto a los intereses de la población general.</li>
<li>Tendencia de las posiciones extremas a adquirir mayor visibilidad.</li>
<li>El exceso de ruido respecto al contenido interesante, puede desmotivar la participación de las personas con menos disponibilidad de tiempo.</li>
<li>El contenido indexado responde a los intereses de las personas que participan y no al de la mayoría.</li>
</ul>
</li>
<li>Es necesario <strong>asumir este comportamiento</strong> desigual, pero es posible <strong>propiciar una mayor y mejor participación</strong>:
<ul>
<li>Haciendo que sea muy sencillo participar.</li>
<li>Convirtiendo la participación en un efecto secundario, de manera que participar exija esfuerzo nulo.</li>
<li>Favorece la edición sobre la creación. Es más sencilla la participación modificando o mejorando algo ya existente que creando desde cero.</li>
<li>Premiando a la gente que participa, pero no en exceso.</li>
<li>Promoviendo a la gente que hace aportaciones de calidad, por ejemplo, favoreciendo su reputación en el proyecto.</li>
</ul>
</li>
<li>Algunas <strong>recomendaciones para crear una comunidad</strong> son:
<ul>
<li>Blog, blog, blog (comunicación en la red)</li>
<li>Enviar mensajes relacionados con el tema del proyecto a la lista de correo.</li>
<li>Escribir mucha documentación y facilitar que la gente se una al proyecto.</li>
<li>Crear un repositorio de código</li>
<li>Conseguir ayuda de los primeros usuarios, implicándolos en el proyecto.</li>
</ul>
</li>
<li>Y <strong>recomendaciones parar sostener una comunidad</strong>:
<ul>
<li>Blog, blog, blog (comunicación en la red)</li>
<li>Enviar mensajes a gente que puede tener interés en participar.</li>
<li>Reconocer las aportaciones.</li>
<li>Responder con rapidez a las cuestiones de la lista de correo.</li>
<li>Mostrar la utilidad del proyecto, a los participantes y a las organizaciones que se puedan implicar.</li>
<li>Promocionar el proyecto incansablemente.</li>
</ul>
</li>
</ul>
<p>En resúmen&#8230; gran parte del esfuerzo para lograr una participación efectiva parece estar en una <strong>estrategia de comunicación efectiva</strong>.<br />
Otro <a href="http://www.docdroppers.org/wiki/index.php?title=Running_A_Successful_Open_Source_Project">artículo</a> que leí hace unos meses da otras claves interesantes y más concretas sobre cómo gestionar un proyecto de software libre, incluído cómo, cuándo y con qué hacer un lanzamiento de una nueva versión de un programa, la forma y el momento de publicitarlo, cómo establecer objetivos&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rvburke.com/2006/10/10/participacion-en-comunidades-de-software-libre/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Curso para el trabajo con parches</title>
		<link>http://blog.rvburke.com/2006/08/10/pequeno-curso-para-el-trabajo-con-parches/</link>
		<comments>http://blog.rvburke.com/2006/08/10/pequeno-curso-para-el-trabajo-con-parches/#comments</comments>
		<pubDate>Thu, 10 Aug 2006 18:07:22 +0000</pubDate>
		<dc:creator>pachi</dc:creator>
				<category><![CDATA[castellano]]></category>
		<category><![CDATA[pascaline]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[software-libre]]></category>

		<guid isPermaLink="false">http://blog.rvburke.com/2006/08/10/pequeno-curso-para-el-trabajo-con-parches/</guid>
		<description><![CDATA[Ahora que vamos avanzando en el proyecto Pascaline se ve la necesidad de mandar correcciones al código a la lista y formas más eficientes de enviarnos la información. Para aprender a manejarse con los parches he escrito un pequeño cursito. Introducción En los proyectos de software, es común la continua realización de cambios al código [...]]]></description>
			<content:encoded><![CDATA[<p><img class="floatright" src="http://blog.rvburke.com/wp-content/uploads/2006/08/codigo-fuente.jpg" alt="Código Fuente" />Ahora que vamos avanzando en el proyecto Pascaline se ve la necesidad de mandar correcciones al código a la lista y formas más eficientes de enviarnos la información. Para aprender a manejarse con los parches he escrito un pequeño cursito.</p>
<p><span id="more-13"></span></p>
<p></p>
<h1>Introducción</h1>
<p>En los proyectos de software, es común la continua realización de cambios al código y la documentación para hacer mejoras o corregir fallos. El uso de parches es un método muy eficaz para transmitir y mostrar dichos cambios, y en este curso se explica cómo trabajar con ellos.</p>
<blockquote class="nota"><p><strong>NOTA:</strong><br />
En las rutas de archivos y en la línea de comandos se utiliza la convención Unix, con &#8220;$&#8221; como símbolo de la línea de comandos y &#8220;/&#8221; como separador de directorios dentro de una ruta, que equivalen al símbolo &#8220;&gt;&#8221; y &#8220;\&#8221; de Windows. (p.e. &#8220;$ dir&#8221; -&gt; &#8220;&gt; dir&#8221; y &#8220;programa/a.txt&#8221; -&gt; &#8220;programa\a.txt&#8221;)</p></blockquote>
<h1>Qué es un parche y para qué sirve</h1>
<p>Un parche es un archivo que recoge los cambios necesarios para pasar de un archivo &#8220;original&#8221; y un archivo &#8220;modificado&#8221;.</p>
<p>Por ejemplo:</p>
<blockquote><p><code>original/a.txt (original):<br />
linea 0<br />
linea A<br />
linea B</code></p>
<p><code>modificaciones/b.txt (modificado):<br />
linea 0<br />
linea B<br />
linea C<br />
linea D</code>
</p></blockquote>
<p>el parche que recoge los cambios que convierten a.txt en b.txt es:</p>
<blockquote><p>
<code>--- original/a.txt       2006-08-10 13:51:46.000000000 +0200<br />
+++ modificaciones/b.txt 2006-08-10 13:51:55.000000000 +0200<br />
@@ -1,3 +1,4 @@<br />
linea 0<br />
-linea A<br />
linea B<br />
+linea C<br />
+linea D</code></p></blockquote>
<p>Más adelante explicaremos qué significa cada una de las partes de este parche.</p>
<p>Con un poco de práctica, el uso de parches hace más sencillo el intercambio y la revisión de modificaciones, además de dar una idea más acertada que la simple inspección visual de la magnitud de los cambios que se producen entre las diferentes versiones de un archivo.</p>
<p>También facilita la separación de los cambios en conjuntos coherentes y &#8220;ortogonales&#8221;. Un parche puede corregir una errata, otro añadir una nueva funcionalidad, otro arreglar un fallo concreto, etc&#8230; de forma que se puede decidir aplicarlos todos (uno tras otro), aplicar solamente alguno de ellos, descartar alguno por incorrecto, etc. La utilización de parches &#8220;pequeños&#8221; que actúen sobre problemas específicos es una buena práctica que dificulta la introducción de errores de forma inadvertida.</p>
<h1>Herramientas para generar y aplicar parches</h1>
<p>Algunas herramientas, como &#8216;diff&#8217; y &#8216;patch&#8217;, permiten generar y aplicar parches de forma automática, de manera que se evita el tedio de localizar manualmente los cambios y trasladarlos de una versión a otra.</p>
<p>La instalación de &#8216;diff&#8217; y &#8216;patch&#8217; es trivial en cualquier sistema GNU/Linux con las herramientas habituales (apt, rpm, synaptics&#8230;). Los paquetes relevantes son &#8216;diffutils&#8217; y &#8216;patch&#8217;, aunque es probable que ya se encuentren instalados por defecto.</p>
<p>En Windows se pueden descargar binarios [1][2] compilados para esa plataforma, que se usan desde la línea de comandos. Es conveniente incluir la ruta de estos programas en la ruta por defecto del sistema (variable PATH) para evitar tener que escribir continuamente la ruta completa cada vez que se usan.</p>
<p>El proyecto Mingw [3] incluye muchas de estas aplicaciones empaquetadas conjuntamente con otras del entrono de desarrollo de GNU/Linux.</p>
<p>[1] <a title="binario de patch para win32" href="http://gnuwin32.sourceforge.net/packages/patch.htm">http://gnuwin32.sourceforge.net/packages/patch.htm</a><br />
[2] <a title="Binario de diff para win32" href="http://gnuwin32.sourceforge.net/packages/diffutils.htm">http://gnuwin32.sourceforge.net/packages/diffutils.htm</a><br />
[3] <a title="Proyecto MinGW - herramientas GNU para win32" href="http://www.mingw.org/">http://www.mingw.org/</a></p>
<p>Ahora que hemos visto cómo instalar en nuestro sistema las herramientas necesarias, veremos cómo utilizarlas y para qué sirven.</p>
<h2>diff</h2>
<p>La aplicación &#8216;diff&#8217; muestra las diferencias entre el archivo &#8220;original&#8221; y el &#8220;modificado&#8221;. Admite opciones que permiten hacer más legible el registro de cambios, por ejemplo, incorporando algo de contexto a los cambios (la opción más habitual es -u (formato unificado), pero depende de las políticas de cada proyecto).</p>
<p>Para generar el parche anterior se ejecutó en la línea de comandos:</p>
<blockquote><p><code>$ diff -u a.txt b.txt</code></p></blockquote>
<p>que produce la siguiente salida:</p>
<blockquote><p><code>--- original/a.txt       2006-08-10 13:51:46.000000000 +0200<br />
+++ modificaciones/b.txt 2006-08-10 13:51:55.000000000 +0200<br />
@@ -1,3 +1,4 @@<br />
linea 0<br />
-linea A<br />
linea B<br />
+linea C<br />
+linea D</code></p></blockquote>
<p>Si redirigirmos la salida a un archivo ya tenemos un parche con los cambios (cambios.diff):</p>
<blockquote><p><code>$ diff -u original/a.txt modificaciones/b.txt &gt; cambios.diff</code></p></blockquote>
<h1>Información contenida en un parche</h1>
<p>Hemos visto que la herramienta diff incluye algunos datos que no se encontraban en los archivos que compara:</p>
<blockquote><p><code>--- original/a.txt       2006-08-10 13:51:46.000000000 +0200<br />
+++ modificaciones/b.txt 2006-08-10 13:51:55.000000000 +0200<br />
@@ -1,3 +1,4 @@<br />
linea 0<br />
-linea A<br />
linea B<br />
+linea C<br />
+linea D</code></p></blockquote>
<p>Esa información adicional aporta metadatos sobre los cambios, útiles para conocer el contexto, la procedencia de los datos y la localiza<br />
Las primeras dos líneas de la salida que produce diff indican la ruta relativa (desde donde se hace el parche) y el nombre de los archivos que se comparan, y otros datos como la fecha de modificación, hora&#8230;</p>
<p>Ha de advertirse que, para las obtención de diferencias entre archivos, es significativo el órden. No es idéntica la diferencia entre a.txt y b.txt que la diferencia entre b.txt y a.txt.</p>
<p>La tercera línea encabeza un conjunto de cambios e informa acerca del fragmento (en a.txt y b.txt) en el que se han encontrado cambios, y se muestran a continuación en el parche. En nuestro ejemplo se indica que las líneas afectadas son las líneas 1 a 3 del archivo a.txt y las líneas 1 a 4 del archivo b.txt. Pueden aparecer varios de estos fragmentos en un mismo parche, con su encabezado correspondiente.</p>
<p>Dentro de cada uno de estos fragmentos, y a continuación del encabezado,  se prefijan con un &#8216;-&#8217; las líneas eliminadas de a.txt (que no aparecen en b.txt) y se prefijan con un &#8216;+&#8217; las líneas insertadas en b.txt (que no aparecen en a.txt).</p>
<blockquote><p><code>-linea A</code> &lt; &#8212; se elimina (-) esta línea<br />
<code>+linea C</code> &lt; &#8212; se añade (+) esta línea<br />
<code>+linea D</code> &lt; &#8212; se añade (+) esta línea</p></blockquote>
<p>Las líneas sin prefijo simplemente muestran parte del contexto de los cambios, para facilitar la lectura del parche. Estas líneas no representan cambios en los archivos, sino simplemente partes comunes que rodean las zonas de cambio.</p>
<p>Ya sabemos, pues, cómo se genera y qué significa el contenido de un parche.</p>
<h1>Aplicación y reversión de cambios</h1>
<p>Una vez guardada en un parche la información de los cambios parar transformar un archivo a.txt en otro b.txt, ¿qué hacemos con esa información?.</p>
<p>Puesto que en el parche se dispone de la información necesaria, es posible generar b.txt a partir de a.txt y el parche. Para ello se usa otra herramienta llamada &#8216;patch&#8217; (es la que ha dado nombre a los parches=patches).</p>
<h2>patch</h2>
<p> La aplicación &#8216;patch&#8217; aplica un conjunto de cambios generado por diff a un archivo para obtener el archivo modificado.</p>
<p>Simplemente se le debe enviar por la entrada estándar el archivo que contiene los cambios (el parche).</p>
<p>En nuestro ejemplo:</p>
<blockquote><p><code>$ patch &lt; cambios.diff</code></p></blockquote>
<p>Con esta simple acción patch localiza a.txt (tiene en la cabecera la ruta) y aplica los cambios, dejando el archivo como b.txt. Hay que aclarar que el archivo a.txt no se renombra, sino que simplemente contiene lo mismo que contenía b.txt.</p>
<p>Hay que tener en cuenta que se debe aplicar el parche en el mismo nivel de directorio que se usó para generar el parche (es posible modificar esto con la opción -p, pero es más sencillo así). Normalmente se usa el directorio raíz del proyecto para generar y aplicar los parches y así no tener que consultar la posición del archivo y la ruta del parche.</p>
<p>Otra operación útil es la reversión de los cambios que produce un parche (es decir, volver de b.txt a a.txt deshaciendo los cambios indicados en el parche). Para ello simplemente se usa la opción -R de &#8216;patch&#8217;.</p>
<blockquote><p><code>$ patch -R &lt; cambios.diff</code></p></blockquote>
<h1>Trabajo con parches</h1>
<p>En los proyectos de software libre es habitual la comunicación mediante listas de correo en las que se comenta y revisa el código entre las distintas personas que participan en el proyecto.</p>
<p>Se deben señalar algunas buenas prácticas para colaborar de esa manera:</p>
<ul>
<li>El asunto del correo debe corresponder al contenido del mensaje</li>
<li>Cuando se quiera comentar el contenido de otro correo se debe responder al mismo en el cliente de correo (no crear un correo nuevo con el mismo tema) de forma que se pueda seguir el hilo en los clientes que soporten la visualización de conversaciones.</li>
<li>El código se comenta en línea (pegando el código) aunque se adjuntan parches para cada uno de las cuestiones tratadas que sean conceptualmente distintas. Así, si se deciden integrar dichos cambios, se puede elegir cuáles son relevantes, cuáles necesitan más trabajo, o dejar algunos sin aplicar.</li>
</ul>
<h1>Otros recursos en la red</h1>
<p><a title="Manual de diff y patch" href="http://www.gnu.org/software/diffutils/manual/html_mono/diff.html"> http://www.gnu.org/software/diffutils/manual/html_mono/diff.html</a><br />
<a title="Ejemplos diff y patch" href="http://www.infres.enst.fr/~blanch/howto/DiffPatch.html"> http://www.infres.enst.fr/~blanch/howto/DiffPatch.html</a><br />
<a title="Diff, Patch, and Friends" href="http://www.linuxjournal.com/article/1237"> http://www.linuxjournal.com/article/1237</a></p>
<p><em>Copyright ©, Rafael Villar Burke, agosto 2006<br />
Se permite la distribución, copia y modificación del texto, siempre y cuando se conserve el copyright y esta nota.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rvburke.com/2006/08/10/pequeno-curso-para-el-trabajo-con-parches/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Proyecto Pascaline</title>
		<link>http://blog.rvburke.com/2006/08/01/proyecto-pascaline/</link>
		<comments>http://blog.rvburke.com/2006/08/01/proyecto-pascaline/#comments</comments>
		<pubDate>Tue, 01 Aug 2006 17:29:57 +0000</pubDate>
		<dc:creator>pachi</dc:creator>
				<category><![CDATA[arquitectura]]></category>
		<category><![CDATA[castellano]]></category>
		<category><![CDATA[estructuras]]></category>
		<category><![CDATA[pascaline]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[software-libre]]></category>

		<guid isPermaLink="false">http://blog.rvburke.com/2006/08/10/proyecto-pascaline/</guid>
		<description><![CDATA[Es llamativa la falta de programas de software libre para la oficina técnica, y más concretamente para CAD o el cálculo de estructuras. Por ello, desde hace tiempo decidí ir haciendo algo al respecto en mis ratos libres. Para no abordar todos los frentes de una sola vez, y tras participar en algunos proyectos esporádicamente, [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.rvburke.com/wp-content/uploads/2006/08/pascaline-peq.jpg" alt="Máquina de calcular Pascaline" style="float:right"/><br />
Es llamativa la falta de programas de software libre para la oficina técnica, y más concretamente para CAD o el <a href="http://www.rvburke.com/estructuras.html">cálculo de estructuras</a>. Por ello, desde hace tiempo decidí ir haciendo algo al respecto en mis ratos libres.</p>
<p>Para no abordar todos los frentes de una sola vez, y tras participar en algunos proyectos esporádicamente, comencé a programar una versión libre del <a title="Prontuario informático del hormigón" href="http://www.ieca.es/publicaciones2.php?IdLibreria=31">&#8220;Prontuario informático del Hormigón&#8221;</a>, que iría generando a su vez librerías y utilidades para otros proyectos posteriores.</p>
<p><span id="more-12"></span></p>
<p>Hasta el momento he avanzado bastante, con una interfaz gráfica hecha con  <a title="PyGTK - Python bindings for GTK+" href="http://www.pygtk.org/">PyGTK</a>, cálculo de las propiedades reológicas y mecánicas del hormigón, propiedades geométricas de las secciones y alguna cosa más que no hace el Prontuario original&#8230; Pensaba publicar el resultado en cuanto tuviese algo un poco completo, para ver si se generaba una comunidad a su alrededor (siempre es más fácil esto con una aplicación completa que con un prototipo).</p>
<div style="text-align: center"><img alt="Prontuario - pantallazos 2" id="image11" src="http://blog.rvburke.com/wp-content/uploads/2006/08/prontuario-02.jpg" /><br />
<img alt="Prontuario - pantallazos 1" id="image10" src="http://blog.rvburke.com/wp-content/uploads/2006/08/prontuario-01.jpg" /><br />
<em>Pantallazos de la interfaz actual del programa tipo &#8220;Prontuario&#8221;</em>
</div>
<p></p>
<p>Algo que me sorprendió es que, en la excelente web dedicada al campo de las estructuras <a title="De Mecánica - Web sobre Estructuras" href="http://demecanica.com/">demecanica.com</a>, hacían un llamamiento para crear conjuntamente un software libre, el proyecto <a href="http://www.rvburke.com/pascaline.html">Pascaline</a>, para el cálculo, diseño, enseñanza de las estructuras de edificación. En ese momento decidí mandar un mensaje al foro del proyecto y un mail a Ramón Gesto (el hombre detrás del proyecto demecanica.com) para unir esfuerzos&#8230;</p>
<div style="text-align: center"><img src="http://blog.rvburke.com/wp-content/uploads/2006/08/maq_pascaline.jpg" alt="Pascaline - Máquina de calcular" /><br />
<em>Pascaline, primera calculadora mecánica de la historia</em>
</div>
<p>Ahora voy a dedicar mis esfuerzos al proyecto Pascaline.</p>
<p>Esta puede ser la oportunidad para que unos cuantos nos juntemos e intentemos llevar algo adelante, ya que no se ha visto ningún fruto de este tipo ni desde las universidades u otras instituciones con carácter investigador o docente.</p>
<p>Antes del verano aprovechamos Ramón y yo para reunirnos en La Latina y charlar sobre las expectativas que cada uno depositaba en el proyecto y cómo lo veíamos. Creo que ambos quedamos ilusionados con lo que podía surgir y en este tiempo ya hemos creado una lista de correo a la que se han ido incorporando más personas, aunque hasta el momento solamente Ramón, Coya y yo hemos participado activamente. Esperemos que más gente se anime en breve.Algo que tendremos que ver es dónde alojamos el proyecto para la publicación de versiones, si en mi dominio, en sourceforge, o en el recién estrenado lugar para proyectos de software libre de google. Lo mismo pasa con el sistema de control de versiones, que preferiría que fuese Mercurial, aunque subversion probablemente tiene herramientas más integradas y fáciles de usar para principiantes en Windows, y parece que esa es la plataforma mayoritaria en el equipo.</p>
<p>Por ahora, y puesto que parece que soy el que más experiencia tiene en el campo de la programación, trataré de ir mandando código y documentación para que todo el mundo se vaya poniendo en marcha, aprendiendo a usar el entorno elegido (hasta ahora python) y poder ir elaborando una base sobre la que trabajar. Esta primera parte me temo que será la más complicada, hasta que nos acompasemos y se establezca una rutina.</p>
<p>Inicialmente nos hemos puesto a hacer un módulo de geotecnia y una interfaz en modo texto del mismo.</p>
<p>Ya iré comentando sobre los avances que vayamos haciendo&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rvburke.com/2006/08/01/proyecto-pascaline/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

