<?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>(code segment) &#187; net</title>
	<atom:link href="http://oldblog.ideseg.com/category/net/feed" rel="self" type="application/rss+xml" />
	<link>http://oldblog.ideseg.com</link>
	<description>se acabarón las espinacas</description>
	<lastBuildDate>Thu, 26 Jan 2012 17:27:41 +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>PolarShow 0.70</title>
		<link>http://oldblog.ideseg.com/2010/polarshow-0-70</link>
		<comments>http://oldblog.ideseg.com/2010/polarshow-0-70#comments</comments>
		<pubDate>Fri, 29 Jan 2010 23:29:00 +0000</pubDate>
		<dc:creator>cseg</dc:creator>
				<category><![CDATA[net]]></category>

		<guid isPermaLink="false">/post/PolarShow-070.aspx</guid>
		<description><![CDATA[Mi pequeño proyecto PolarShow ha tomado un poquito más de cuerpo, estoy ya en la versión 0.70 y prácticamente tiene ya todas las características que se pueden encontrar en polarpersonaltrainer.com En esta versión hay un calendario con un resumen semanal de las sesiones de entrenamiento También he ajustado algunos de los gráficos para que se [...]]]></description>
			<content:encoded><![CDATA[<p>Mi pequeño proyecto <strong>PolarShow </strong>ha tomado un poquito más de cuerpo, estoy ya en la versión 0.70 y prácticamente tiene ya todas las características que se pueden encontrar en polarpersonaltrainer.com</p>
<p>En esta versión hay un calendario con un resumen semanal de las sesiones de entrenamiento</p>
<p style="text-align: center;"><img src="http://oldblog.ideseg.com/content/polar_070_1.png" alt="" width="650" /></p>
<p>También he ajustado algunos de los gráficos para que se muestren más claramente, el gráfico de sesiones por defecto muestra las 10 últimas sesiones salvo que se seleccionen otras</p>
<p style="text-align: center;"><img src="http://oldblog.ideseg.com/content/polar_070_2.png" alt="" width="650" /></p>
<p>Una cosa interesante es la agregación, en el momento que hemos seleccionado un conjunto de sesiones podemos ver agregados los resultados, mostrando el total de Km, el total de entrenamiento y las medias de velocidad y pulsaciones,</p>
<p style="text-align: center;"><img src="http://oldblog.ideseg.com/content/polar_070_3.png" alt="" width="650" /></p>
<p>Las “Auto Laps” quedan agregadas de modo que podemos ver un gráfico completo por ejemplo de una semana completa.</p>
<p>Una cosa interesante es que ahora se pueden editar los archivos xml que hemos extraído del reloj pudiendo añadir notas, una clasificación de cómo te has sentido en el entrenamiento y una url (por ejemplo a GPSSies) con la ruta que has seguido.</p>
<p style="text-align: center;"><img src="http://oldblog.ideseg.com/content/polar_070_5.png" alt="" /></p>
<p>También como no he solucionado un montonazo de bugs…</p>
<p>Podeís descargar esta versión desde <a href="/software">aquí</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://oldblog.ideseg.com/2010/polarshow-0-70/feed</wfw:commentRss>
		<slash:comments>524</slash:comments>
		</item>
		<item>
		<title>Fuzzy Logic y expresiones lambda</title>
		<link>http://oldblog.ideseg.com/2010/fuzzy-logic-y-expresiones-lambda</link>
		<comments>http://oldblog.ideseg.com/2010/fuzzy-logic-y-expresiones-lambda#comments</comments>
		<pubDate>Sat, 16 Jan 2010 01:33:00 +0000</pubDate>
		<dc:creator>cseg</dc:creator>
				<category><![CDATA[net]]></category>

		<guid isPermaLink="false">/post/Fuzzy-Logic-y-expresiones-lambda.aspx</guid>
		<description><![CDATA[Para un proyecto que estoy realizando, he realizado una prueba de concepto probado a aplicar l&#243;gica difusa con el fin de realizar ciertas acciones a partir de una serie de datos imprecisos. A la hora de expresar las reglas encargadas de modelar nuestro sistema de l&#243;gica difusa, (IF-THEN) la mayor&#237;a de los sistemas que he [...]]]></description>
			<content:encoded><![CDATA[<p>Para un proyecto que estoy realizando, he realizado una prueba de concepto probado a aplicar l&oacute;gica difusa con el fin de realizar ciertas acciones a partir de una serie de datos imprecisos.</p>
<p>A la hora de expresar las reglas encargadas de modelar nuestro sistema de l&oacute;gica difusa, (IF-THEN) la mayor&iacute;a de los sistemas que he visto requer&iacute;an de un peque&ntilde;o y simple analizador sint&aacute;ctico para interpretar las reglas, en este punto me he preguntado si en vez de un analizador sint&aacute;ctico, podr&iacute;amos usar expresiones lambda y una interfaz fluida.</p>
<p><strong>FuzzySystem (improvisado)</strong></p>
<p>De modo que he construido un peque&ntilde;o motor de l&oacute;gica difusa que tiene la particularidad de usar expresiones lambda y una interfaz fluida para definir el conjunto de reglas.<br />Este peque&ntilde;o motor incorpora un par de funciones miembro, una de tipo Trapezoide y otra Triangular, b&aacute;sicamente su uso es el siguiente.<br />Definimos el sistema, a&ntilde;adimos las variables con sus estados y funciones miembro&hellip;</p>
<pre class="brush: c-sharp;">    public class FuzzyTest
    {
        private readonly FuzzySystem _engine = new FuzzySystem();

        public FuzzyTest()
        {
            FuzzyVariable varA = new FuzzyVariable("A");
            varA.Memberships.Add(new TrapezoidMembership("Cerrado", 0, 0, 5, 5));
            varA.Memberships.Add(new TrapezoidMembership("Medio", 4, 4, 6, 6));
            varA.Memberships.Add(new TrapezoidMembership("Abierto", 7, 7, 9, 9));
            _engine.Variables.Add(varA);

            FuzzyVariable varB = new FuzzyVariable("B");
            varB.Memberships.Add(new TrapezoidMembership("Cerrado", 0, 0, 5, 5));
            varB.Memberships.Add(new TrapezoidMembership("Medio", 4, 4, 6, 6));
            varB.Memberships.Add(new TrapezoidMembership("Abierto", 7, 7, 9, 9));
            _engine.Variables.Add(varB);

            FuzzyVariable varR = new FuzzyVariable("R");
            varR.Memberships.Add(new TrapezoidMembership("Frio", 0, 0, 3, 3));
            varR.Memberships.Add(new TrapezoidMembership("Templado", 3, 3, 6, 6));
            varR.Memberships.Add(new TrapezoidMembership("Caliente", 7, 7, 9, 9));
            _engine.Variables.Add(varR);</pre>
<p>&nbsp;</p>
<p><strong>La definici&oacute;n de reglas mediante expresiones Lambda</strong></p>
<p>El beneficio en este punto es que el sistema no requiere del analizador sint&aacute;ctico para evaluar las expresiones si no que ser&aacute; el CLR quien se encargue de ello.<br />Para llevar a cabo esta evaluaci&oacute;n de las reglas he definido una clase <em>FuzzyExpresion </em>que tiene definidos&nbsp; los operadores &amp;&amp; y || para as&iacute; como el true y el false para poder evaluar las reglas en consecuencia.</p>
<pre class="brush: c-sharp;">    public class FuzzyExpression
    {
        private readonly FuzzyVariable _variable;
        private string _state;
        private double? _value;

        public double Value
        {
            get
            {
                if (_value.HasValue)
                    return _value.Value;
                _value = _variable.Fuzzify(State);
                return _value.Value;
            }
        }

        public string State
        {
            get { return _state; }
        }

        public FuzzyExpression(FuzzySystem engine, string literal)
        {
            _variable = engine.Variables[literal];

            if (_variable == null)
            {
                throw new FuzzyException("variable not found.");
            }
        }

        public FuzzyExpression(double value)
        {
            _value = value;
        }

        public FuzzyExpression Is(string state)
        {
            _state = state;
            _value = _variable.Fuzzify(_state);
            return this;
        }

        public FuzzyExpression Set(string newState)
        {
            _state = newState;
            return this;
        }

        public static FuzzyExpression operator |(FuzzyExpression a, FuzzyExpression b)
        {
            return new FuzzyExpression(Math.Max(a.Value, b.Value));
        }

        public static FuzzyExpression operator &amp;(FuzzyExpression a, FuzzyExpression b)
        {
            return new FuzzyExpression(Math.Min(a.Value, b.Value));
        }

        public static bool operator false(FuzzyExpression a)
        {
            return 0 &gt; a.Value;
        }

        public static bool operator true(FuzzyExpression a)
        {
            return a.Value &gt; 0;
        }
    }</pre>
<p>&nbsp;</p>
<p>Las reglas en la l&oacute;gica difusa sirven para combinar las distintas proposiciones, no son reglas excesivamente complicadas, y son del tipo IF-THEN, b&aacute;sicamente hay 4 reglas (Implicaci&oacute;n Conjunci&oacute;n, Disyunci&oacute;n&nbsp; y negaci&oacute;n) que se corresponden con:</p>
<p>-&nbsp;&nbsp;&nbsp; Implicaci&oacute;n IF variable==estado THEN variable = estado<br />-&nbsp;&nbsp;&nbsp; Conjunci&oacute;n, equivalente al AND, si dos proposiciones son ciertas simult&aacute;neamente <br />-&nbsp;&nbsp;&nbsp; Disyunci&oacute;n, cualquiera de las dos proposiciones es cierta OR<br />-&nbsp;&nbsp;&nbsp; Negaci&oacute;n, invierte la proposici&oacute;n</p>
<p>Finalmente podemos definir las reglas de este modo</p>
<pre class="brush: c-sharp;">            _engine.AddRule(x =&gt;
                            x.Variable("A").Is("Abierto") &amp;&amp;
                            x.Variable("B").Is("Abierto"))
                            .Then(x =&gt; x.Variable("R").Set("Caliente"));

            _engine.AddRule(x =&gt;
                            x.Variable("A").Is("Abierto") &amp;&amp;
                            (x.Variable("B").Is("Cerrado") || x.Variable("B").Is("Medio")))
                            .Then(x =&gt; x.Variable("R").Set("Templado"));

            _engine.AddRule(x =&gt;
                            x.Variable("B").Is("Abierto") &amp;&amp;
                            (x.Variable("A").Is("Cerrado") || x.Variable("A").Is("Medio")))
                            .Then(x =&gt; x.Variable("R").Set("Templado"));

            _engine.AddRule(x =&gt;
                            x.Variable("A").Is("Cerrado") &amp;&amp;
                            x.Variable("B").Is("Cerrado"))
                            .Then(x =&gt; x.Variable("R").Set("Frio"));</pre>
<p><strong>&iquest;C&oacute;mo funciona?</strong></p>
<p>Una regla tiene una condici&oacute;n (IF) y una consecuencia (THEN), la condici&oacute;n es una funci&oacute;n que recibe el sistema y debe devolver una FuzzyExpresion, (<em>Func&lt;FuzzySystem,FuzzyExpression&gt;</em>), esto es parte de la magia ya que una expresi&oacute;n condicional es siempre reducida a una &uacute;nica expresi&oacute;n y finalmente a un &uacute;nico valor.<br />Y curiosamente la consecuencia de la regla, es exactamente igual, solo que en este caso la expresi&oacute;n no devuelve nada porque la consecuencia es una acci&oacute;n, aqu&iacute; hay otro peque&ntilde;o truco que es que la propia regla contiene los dos elementos separados (condici&oacute;n y consecuencia) fijaros en que:</p>
<pre class="brush: c-sharp;">   _engine.AddRule(x =&gt;
                        x.Variable("A").Is("Abierto") &amp;&amp;
                        x.Variable("B").Is("Abierto"))</pre>
<p>Est&aacute; devolviendo una regla y el m&eacute;todo <em>Then</em> es aplicado sobre la regla, y cuando se eval&uacute;a la regla si la condici&oacute;n es cierta se eval&uacute;a la consecuencia, que lo que hace es &uacute;nicamente cambiar el estado (ver el m&eacute;todo <em>Set </em>de <em>FuzzyExpression</em>)</p>
<pre class="brush: c-sharp;">    public class FuzzyRule
    {
        private readonly FuzzySystem _engine;
        private readonly Func _condition;
        private Func _then;

        public double Value { get; set; }

        public FuzzySystem Engine
        {
            get { return _engine; }
        }

        public FuzzyRule(FuzzySystem engine, Func condition)
        {
            _engine = engine;
            _condition = condition;
        }

        public FuzzyExpression Eval()
        {
            Value = _condition(Engine).Value;

            if (Value &gt; 0)
            {
                return _then(Engine);
            }

            return null;
        }

        public void Then(Func then)
        {
            _then = then;
        }
    }</pre>
<p><strong>Defuzzyficando</strong></p>
<p>Para evaluar nuestro sistema ..</p>
<p>&nbsp;</p>
<pre class="brush: c-sharp;">            for (int a = 0; a &lt; 10; a++)
            {
                for (int b = 0; b &lt; 10; b++)
                {
                    _engine.Variables["A"].InputValue = a;
                    _engine.Variables["B"].InputValue = b;
                    _engine.Consecuent = "R";

                    var r = _engine.Defuzzy();

                    Console.WriteLine(string.Format("A {0} - B {1} = {2,-6} [{3,-10}][{4,-10}] = {5}",
                        a,
                        b,
                        r,
                        _engine.GetVariableState("A",a),
                        _engine.GetVariableState("B",b),
                        _engine.GetVariableState("R", r)));
                }
            }
        }</pre>
<p><strong>Mejoras de dise&ntilde;o </strong></p>
<p>Hay una cosa que no me gusta mucho y es el hecho de que mi clase FuzzyExpression, tiene tanto el m&eacute;todo Is como el m&eacute;todo Set y esto habr&iacute;a que dividirlo en dos para no llevar a errores a la hora de la usar la interfaz fluida.</p>
<p><strong>Errores de dise&ntilde;o </strong></p>
<p>Pero no todo es de color de rosa, cuando planifique el sistema, pens&eacute; en la posibilidad de guardar las expresiones lambda como texto y despu&eacute;s compilarlas usando CodeDom, bien tengo que deciros que cuando me he puesto a ello me he llevado la desagradable sorpresa de que CodeDom no soporta expresiones lambda, de modo que mi gozo en un pozo.</p>
<p>Y digo esto porque es de vital importancia el poder mantener las reglas fuera del c&oacute;digo, bien un archivo de configuraci&oacute;n, un archivo XML, lo que sea&hellip; de este modo podemos realizar ajustes sin tener que recompilar todo &hellip; <br /><strong></strong></p>
<p><strong>Para una futura versi&oacute;n </strong></p>
<p>Completar estas cositas &hellip;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://oldblog.ideseg.com/2010/fuzzy-logic-y-expresiones-lambda/feed</wfw:commentRss>
		<slash:comments>243</slash:comments>
		</item>
		<item>
		<title>Polar Rs300x &#8211; GUI</title>
		<link>http://oldblog.ideseg.com/2010/polar-rs300x-gui</link>
		<comments>http://oldblog.ideseg.com/2010/polar-rs300x-gui#comments</comments>
		<pubDate>Fri, 08 Jan 2010 14:34:00 +0000</pubDate>
		<dc:creator>cseg</dc:creator>
				<category><![CDATA[miscelanea]]></category>
		<category><![CDATA[net]]></category>

		<guid isPermaLink="false">/post/Polar-Rs300x-GUI.aspx</guid>
		<description><![CDATA[Estas navidades el Olentzero, Santa Claus, Papa Noel &#243; uno mismo, vaya ud. a saber &#8230; me dejo un pulsometro Polar RS300x, uno de esos aparatitos que te miden las pulsaciones (para evitar que a los que nos vamos haciendo mayores nos d&#233; un chunguito) La verdad es que no est&#225; nada mal, viene con [...]]]></description>
			<content:encoded><![CDATA[<p>Estas navidades el Olentzero, Santa Claus, Papa Noel &oacute; uno mismo, vaya ud. a saber &hellip; me dejo un pulsometro Polar RS300x, uno de esos aparatitos que te miden las pulsaciones (para evitar que a los que nos vamos haciendo mayores nos d&eacute; un chunguito)</p>
<p><a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/csegura/RS300X_5F00_blk_5F00_front_5F00_240x298.jpg"><img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/csegura/RS300X_5F00_blk_5F00_front_5F00_240x298.jpg" border="0" alt="" /></a><a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/csegura/FlowLink_5F00_front_5F00_115x115.jpg"><img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/csegura/FlowLink_5F00_front_5F00_115x115.jpg" border="0" alt="" /></a><a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/csegura/s1_5F00_115x115.jpg"><img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/csegura/s1_5F00_115x115.jpg" border="0" alt="" /></a><a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/csegura/wearlink_2B005F00_31coded_5F00_front_5F00_115x115.jpg"><img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/csegura/wearlink_2B005F00_31coded_5F00_front_5F00_115x115.jpg" border="0" alt="" /></a></p>
<p>La verdad es que no est&aacute; nada mal, viene con el transmisor WearLink que es la cinta que te atas en el pecho que se encarga de enviar la frecuencia cardiaca al reloj, con un sensor S1 que es un pod&oacute;metro que te pones en la zapatilla y una vez calibrado, mide la distancia y la velocidad, y finalmente con el FlowLink que es un dispositivo USB a trav&eacute;s del cual puedes enviar la informaci&oacute;n a una web para (www.polarpersonaltrainer.com) para mantener un hist&oacute;rico de las sesiones de entrenamiento.</p>
<p>El domingo d&iacute;a 3 calibre el sensor S1 recorriendo una distancia de 1km y despu&eacute;s prob&eacute; por los alrededores de mi casa a correr una distancia conocida y me quede impresionado, tan solo medio metro de diferencia. Una maravilla.</p>
<p>El lunes d&iacute;a 4 realice una sesi&oacute;n de entrenamiento y despu&eacute;s sub&iacute; los datos la web, usando el FlowLink y el software de sincronizaci&oacute;n que viene con el aparato.</p>
<p>Bueno, no es que este mal del todo, pero no se puede decir que la web sea una pasada. La cosa es que me pico el gusanito ese &ldquo;f-geek&rdquo; (freak-geek) que llevo dentro ..</p>
<p>De modo que me puse a buscar todo tipo de informaci&oacute;n acerca de c&oacute;mo sacar los datos del dichoso relojito &hellip; y no encontr&eacute; absolutamente nada (y mira que ha sido f&aacute;cil) </p>
<p>Revisando el software de sincronizaci&oacute;n di con unas .dlls curiosas .. Polar.Transport.dll y Polar.Monitor.dll &hellip; que curiosamente est&aacute;n en .Net &hellip; tambi&eacute;n hay una biblioteca de m&aacute;s bajo nivel llamada libpolar.dll a la que las otras dos hacen refencia (Interop) .. </p>
<p>Bueno tras una revisi&oacute;n con el reflector encontr&eacute; muchas, muchas cosas interesantes .. lo mejor es que me pod&iacute;a conectar al relojito y obtener los datos de las sesiones, de modo que en un primer paso realice un sencillo programita para exportar los datos a XML </p>
<p>Que bonito &hellip; en poco m&aacute;s de una hora ten&iacute;a los datos &hellip; </p>
<p>B&aacute;sicamente basta con crear un proyecto en VS y referenciar Polar.Monitor.dll (como internamente usa libpolar.dll) deb&eacute;is aseguraros que libpolar.dll est&aacute; tambi&eacute;n localizable.</p>
<p>Pero para no perder detalle aqu&iacute; os dejo un video de c&oacute;mo hacerlo&hellip;</p>
<p>
<object width="580" height="360"><param name="movie" value="http://www.youtube.com/v/pztlLRI9koA&amp;hl=es_ES&amp;fs=1&amp;rel=0&amp;color1=0x3a3a3a&amp;color2=0x999999&amp;border=1" /><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><embed type="application/x-shockwave-flash" width="580" height="360" src="http://www.youtube.com/v/pztlLRI9koA&amp;hl=es_ES&amp;fs=1&amp;rel=0&amp;color1=0x3a3a3a&amp;color2=0x999999&amp;border=1" allowscriptaccess="always"></embed></object></p>
<p>La cosa es que me he liado un poco (&iquest;C&oacute;mo no?) y me he metido a hacer un GUI que por el momento tiene este aspecto.</p>
<p>Permite ver un resumen de las sesiones</p>
<p><a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/csegura/polar0.png"><img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/csegura/polar0.png" border="0" alt="" /></a></p>
<p>Permite analizar cada sesi&oacute;n (yo le he activado el modo Auto Lap, de modo que el pulsometro toma datos a cada KM) me muestra el tiempo empleado, la velocidad, la FC Max, y la FC Media. Adem&aacute;s emparejo cada dato de FC con la Zona de trabajo. </p>
<p><a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/csegura/Polar1.png"><img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/csegura/Polar1.png" border="0" alt="" /></a></p>
<p>En el gr&aacute;fico, se puede ver la FC , la FC Max (puntitos rojos) y ambas dentro de sus zonas correspondientes. En el gr&aacute;fico de velocidad, se puede ver la velocidad en Km/h y en min/km adem&aacute;s la vuelta m&aacute;s r&aacute;pida queda en verde y la m&aacute;s lenta en rojo.</p>
<p><a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/csegura/Polar2.png"><img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/csegura/Polar2.png" border="0" alt="" /></a></p>
<p>Por &uacute;ltimo el gr&aacute;fico de las Zonas, con el tiempo empleado en cada una de ellas en la sesi&oacute;n de entrenamiento.</p>
<p><a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/csegura/Polar3.png"><img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/csegura/Polar3.png" border="0" alt="" /></a></p>
<p>Os dejo otro bonito video del programita &hellip; (que me he emocionaooo &#8230;)</p>
<p>
<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/OThHSK1R_18&amp;hl=es_ES&amp;fs=1&amp;rel=0" /><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><embed type="application/x-shockwave-flash" width="425" height="344" src="http://www.youtube.com/v/OThHSK1R_18&amp;hl=es_ES&amp;fs=1&amp;rel=0" allowscriptaccess="always"></embed></object>
</p>
<p>Ya sabes si eres un f-geek de los ordenadores que adem&aacute;s te gusta el running el Rs300x es una magnifica opci&oacute;n</p>
]]></content:encoded>
			<wfw:commentRss>http://oldblog.ideseg.com/2010/polar-rs300x-gui/feed</wfw:commentRss>
		<slash:comments>229</slash:comments>
		</item>
		<item>
		<title>ASP.NET Mvc Delete Link usando DELETE method</title>
		<link>http://oldblog.ideseg.com/2009/asp-net-mvc-delete-link-usando-delete-method</link>
		<comments>http://oldblog.ideseg.com/2009/asp-net-mvc-delete-link-usando-delete-method#comments</comments>
		<pubDate>Sun, 01 Nov 2009 11:53:19 +0000</pubDate>
		<dc:creator>cseg</dc:creator>
				<category><![CDATA[net]]></category>

		<guid isPermaLink="false">/post/ASPNET-Mvc-Delete-Link-usando-DELETE-method.aspx</guid>
		<description><![CDATA[Realmente he llegado tarde (seguro que estaba haciendo alguna que otra mala cosa) al MVC de ASP.Net, lo digo porque aunque había jugueteado un poco no me había tenido que poner a hacer cosas un poco serias. Bueno, la verdad es que estoy encantado ya voy haciendo mis pinitos poco a poco … una de [...]]]></description>
			<content:encoded><![CDATA[<p>Realmente he llegado tarde (seguro que estaba haciendo alguna que otra mala cosa) al MVC de ASP.Net, lo digo porque aunque había jugueteado un poco no me había tenido que poner a hacer cosas un poco serias.</p>
<p>Bueno, la verdad es que estoy encantado ya voy haciendo mis pinitos poco a poco … una de las cosas con las que estaba más a disgusto ha sido el tema de hacer las eliminaciones vía POST (cosas de los que hemos jugado con Ruby)</p>
<p><a href="http://stephenwalther.com">Sthephen Walter</a> (autor de ASP.NET MVC Framework Unleashed) tiene un post en su blog con una <a href="http://stephenwalther.com/blog/archive/2009/01/21/asp.net-mvc-tip-46-ndash-donrsquot-use-delete-links-because.aspx">muy buena descripción del problema</a> en su blog.  Resumo.</p>
<ul>
<li>Realizar un borrado mediante HTTP GET es un error de seguridad como la copa de un pino.</li>
<li>Realizar un borrado usando Ajax y HTTP DELETE es dependiente del JavaScript.</li>
<li>Realizar un borrado usando HTTP POST, según Sthephen es la manera más idónea para no ser dependiente de JavaScript.</li>
</ul>
<blockquote>
<blockquote>
<ul>
<li>Problema, un link no puede hacer un HTTP POST</li>
<li>Tenemos que usar una imagen o un botó</li>
</ul>
</blockquote>
</blockquote>
<ul>
<li>Propone una solución para realizar la eliminación mediante AJAX y java script (demasiado dependiente)</li>
</ul>
<p>Mi problema (y seguro que el de otros) &#8211; Requisitos</p>
<ul>
<li>Quiero realizar un borrado</li>
<li> Quiero hacerlo usando un link</li>
<li>Quiero que sea seguro</li>
<li>Quiero que use HTTP DELETE</li>
<li> Quiero poder validar “¿Esta Ud. Seguro?”</li>
<li> Quiero poder personalizar el mensaje</li>
<li> Quiero que tras borrar pueda dirigirme a una página concreta</li>
<li> Quiero controlar los errores</li>
<li>Quiero que sea versátil y no tener que escribir JavaScript cada vez</li>
</ul>
<p>Extendiendo jQuery</p>
<p>Ya está más que dicho, pero jQuery es grande, muy grande. Y una de las cosas que más me gustan es la facilidad con que puede extenderse, básicamente hay dos formas de hacerlo, una añadiendo nuevos métodos que son aplicables a los elementos (jQuery.fn.extend) y otra a través de la cual se pueden añadir nuevos métodos a  jQuery (jQuery.extend).</p>
<p>En este caso, vamos a extender jQuery añadiéndole un nuevo método, un método llamado mvcDelete que podremos usar desde el onclick de un link.</p>
<p>He preferido la este modo de extensión para poder escribir un sencillo HtmlHelper que me ayude a no tener que escribir prácticamente nada de JavaScript cada vez que quiero poner un link para eliminar un elemento.</p>
<p>&lt;%= Html.DeleteLink(“Delete”, new { action=”Delete”, controller=”Page”, id=Model.Id, redirectToController=”Page”}, null) %&gt;</p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span>jQuery.extend({</pre>
<pre><span class="lnum">   2:  </span>        mvcDelete: <span class="kwrd">function</span>(options) {</pre>
<pre class="alt"><span class="lnum">   3:  </span>            var defaults = {</pre>
<pre><span class="lnum">   4:  </span>                controller: <span class="str">""</span>,</pre>
<pre class="alt"><span class="lnum">   5:  </span>                action: <span class="str">"delete"</span>,</pre>
<pre><span class="lnum">   6:  </span>                onComplete: <span class="kwrd">function</span>(xhr, status) { },</pre>
<pre class="alt"><span class="lnum">   7:  </span>                onSuccess: <span class="kwrd">function</span>(data) { },</pre>
<pre><span class="lnum">   8:  </span>                onError: <span class="kwrd">function</span>(xhr, status) { alert(<span class="str">"Error"</span>); },</pre>
<pre class="alt"><span class="lnum">   9:  </span>                message: <span class="str">"Are you sure you wish to delete this item?"</span>,</pre>
<pre><span class="lnum">  10:  </span>                confirmAlert: <span class="kwrd">true</span>,</pre>
<pre class="alt"><span class="lnum">  11:  </span>                id: 0,</pre>
<pre><span class="lnum">  12:  </span>                redirectToController: <span class="str">""</span>,</pre>
<pre class="alt"><span class="lnum">  13:  </span>                redirectToAction: <span class="str">"index"</span></pre>
<pre><span class="lnum">  14:  </span>            }</pre>
<pre class="alt"><span class="lnum">  15:  </span>            var ajaxError = <span class="kwrd">false</span>;</pre>
<pre><span class="lnum">  16:  </span>            var opt = $.extend(defaults, options);</pre>
<pre class="alt"><span class="lnum">  17:  </span>            var deleteRequest = <span class="kwrd">function</span>() {</pre>
<pre><span class="lnum">  18:  </span>                var deleteUrl = <span class="rem">'/' + opt.controller + '/' + opt.action + '/' + opt.id;</span></pre>
<pre class="alt"><span class="lnum">  19:  </span>                $.ajax({</pre>
<pre><span class="lnum">  20:  </span>                    type: <span class="str">"DELETE"</span>,</pre>
<pre class="alt"><span class="lnum">  21:  </span>                    url: deleteUrl,</pre>
<pre><span class="lnum">  22:  </span>                    async: <span class="kwrd">false</span>,</pre>
<pre class="alt"><span class="lnum">  23:  </span>                    success: opt.onSuccess(data),</pre>
<pre><span class="lnum">  24:  </span>                    complete: opt.onComplete(xhr,status),</pre>
<pre class="alt"><span class="lnum">  25:  </span>                    <span class="kwrd">error</span>: <span class="kwrd">function</span>(xhr, status) { opt.onError(xhr, status); ajaxError = <span class="kwrd">true</span>; }</pre>
<pre><span class="lnum">  26:  </span>                });</pre>
<pre class="alt"><span class="lnum">  27:  </span>            };</pre>
<pre><span class="lnum">  28:  </span></pre>
<pre class="alt"><span class="lnum">  29:  </span>            <span class="kwrd">if</span> (opt.controller.length &gt; 0 &amp;&amp; opt.id &gt; 0) {</pre>
<pre><span class="lnum">  30:  </span>                <span class="kwrd">if</span> (opt.confirmAlert) {</pre>
<pre class="alt"><span class="lnum">  31:  </span>                    <span class="kwrd">if</span> (confirm(opt.message))</pre>
<pre><span class="lnum">  32:  </span>                        deleteRequest();</pre>
<pre class="alt"><span class="lnum">  33:  </span>                    <span class="kwrd">else</span></pre>
<pre><span class="lnum">  34:  </span>                        <span class="kwrd">return</span> <span class="kwrd">false</span>;</pre>
<pre class="alt"><span class="lnum">  35:  </span>                } <span class="kwrd">else</span></pre>
<pre><span class="lnum">  36:  </span>                    deleteRequest();</pre>
<pre class="alt"><span class="lnum">  37:  </span></pre>
<pre><span class="lnum">  38:  </span>                <span class="kwrd">if</span> (!ajaxError &amp;&amp; opt.redirectToController.length &gt; 0) {</pre>
<pre class="alt"><span class="lnum">  39:  </span>                    var redirect = <span class="rem">'/' + opt.redirectToController + '/' + opt.redirectToAction;</span></pre>
<pre><span class="lnum">  40:  </span>                    window.location.replace(redirect);</pre>
<pre class="alt"><span class="lnum">  41:  </span>                }</pre>
<pre><span class="lnum">  42:  </span>            }</pre>
<pre class="alt"><span class="lnum">  43:  </span>            <span class="kwrd">return</span> <span class="kwrd">false</span>;</pre>
<pre><span class="lnum">  44:  </span>        }</pre>
<pre class="alt"><span class="lnum">  45:  </span></pre>
<pre><span class="lnum">  46:  </span>    });</pre>
</div>
<p>En donde vamos a poder pasar:</p>
<p><em>controller </em>-&gt; controlador de la acción de borrado (requerido)<br />
<em>action </em>-&gt; acción de borrado, por defecto delete<br />
<em>id </em>-&gt; elemento a borrar (requerido)<br />
<em>onComplete </em>-&gt; una función a realizar tras completarse el borrado<br />
<em>onError </em>-&gt; una función a realizar si se producen errores<br />
<em>confirmAlert </em>-&gt; si se mostrará o no el mensaje de advertencia<br />
<em>message </em>-&gt; el mensaje de seguridad<br />
<em>redirectToController </em>-&gt; el controlador de salida (por defecto el mismo que de entrada)<br />
<em>redirectToAction </em>-&gt; la acción de la salida por defecto (Index)</p>
<p>Después el helper que se encargará de realizar el link será</p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">string</span> DeleteLink(<span class="kwrd">this</span> HtmlHelper helper,</pre>
<pre><span class="lnum">   2:  </span>                                <span class="kwrd">string</span> text,</pre>
<pre class="alt"><span class="lnum">   3:  </span>                                <span class="kwrd">object</span> deleteOptions,</pre>
<pre><span class="lnum">   4:  </span>                                <span class="kwrd">object</span> linkHtmlAttributes)</pre>
<pre class="alt"><span class="lnum">   5:  </span>{</pre>
<pre><span class="lnum">   6:  </span>    var linkTagBuilder = <span class="kwrd">new</span> TagBuilder(<span class="str">"a"</span>);</pre>
<pre class="alt"><span class="lnum">   7:  </span></pre>
<pre><span class="lnum">   8:  </span>    linkTagBuilder.Attributes.Add(<span class="str">"href"</span>, <span class="str">"#"</span>);</pre>
<pre class="alt"><span class="lnum">   9:  </span>    linkTagBuilder.SetInnerText(text);</pre>
<pre><span class="lnum">  10:  </span></pre>
<pre class="alt"><span class="lnum">  11:  </span>    var serializer = <span class="kwrd">new</span> JavaScriptSerializer();</pre>
<pre><span class="lnum">  12:  </span>    var mvcDeleteOptions = serializer.Serialize(deleteOptions);</pre>
<pre class="alt"><span class="lnum">  13:  </span></pre>
<pre><span class="lnum">  14:  </span>    linkTagBuilder.MergeAttribute(<span class="str">"onclick"</span>,</pre>
<pre class="alt"><span class="lnum">  15:  </span>                                  <span class="kwrd">string</span>.Format(<span class="str">"$.mvcDelete({0}); return false;"</span>, mvcDeleteOptions));</pre>
<pre><span class="lnum">  16:  </span>    linkTagBuilder.MergeAttributes(<span class="kwrd">new</span> RouteValueDictionary(linkHtmlAttributes));</pre>
<pre class="alt"><span class="lnum">  17:  </span></pre>
<pre><span class="lnum">  18:  </span>    <span class="kwrd">return</span> linkTagBuilder.ToString();</pre>
<pre class="alt"><span class="lnum">  19:  </span>}</pre>
</div>
<p>Aquí lo más destacable es como pasamos las opciones a nuestro plugin, usando un método anónimo, convertimos el objeto usando el serializador de javascript de este modo nuestro plugin, recibe los parámetros.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://oldblog.ideseg.com/2009/asp-net-mvc-delete-link-usando-delete-method/feed</wfw:commentRss>
		<slash:comments>217</slash:comments>
		</item>
		<item>
		<title>YACAMLQT (Yet another CAML query tool) Redux (3) in CodePlex</title>
		<link>http://oldblog.ideseg.com/2009/yacamlqt-yet-another-caml-query-tool-redux-3-in-codeplex</link>
		<comments>http://oldblog.ideseg.com/2009/yacamlqt-yet-another-caml-query-tool-redux-3-in-codeplex#comments</comments>
		<pubDate>Tue, 26 May 2009 23:47:39 +0000</pubDate>
		<dc:creator>cseg</dc:creator>
				<category><![CDATA[caml]]></category>
		<category><![CDATA[net]]></category>
		<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">/post/YACAMLQT-(Yet-another-CAML-query-tool)-Redux-(3)-in-CodePlex.aspx</guid>
		<description><![CDATA[Bueno, esta es la última entrega a partir de hoy el proyecto se encuentra en CodePlex (yacamlqt.codeplex.com).En esta última parte solo unas pequeñas notas para el usuario final.Bien, para usar YACAMLQT, dentro de tus proyectos, solo hay que referenciar la dll (IdeSeg.SharePoint.Caml.QueryParser.dll)&#160; y el uso sería el siguiente: 1: try 2: { 3: var parser [...]]]></description>
			<content:encoded><![CDATA[<p>Bueno, esta es la última entrega a partir de hoy el proyecto se encuentra en CodePlex (<FONT color=#ff0000><B><A href="http://yacamlqt.codeplex.com/">yacamlqt.codeplex.com</A></B></FONT>).<BR><BR>En esta última parte solo unas pequeñas notas para el usuario final.<BR><BR>Bien, para usar YACAMLQT, dentro de tus proyectos, solo hay que referenciar la dll (<B>IdeSeg.SharePoint.Caml.QueryParser.dll</B>)&nbsp; y el uso sería el siguiente:<BR><BR><BR><br />
<P></P><!-- code formatted by http://manoli.net/csharpformat/ --><br />
<DIV class=csharpcode><PRE class=alt><SPAN class=lnum>   1:  </SPAN>            <SPAN class=kwrd>try</SPAN></PRE><PRE><SPAN class=lnum>   2:  </SPAN>            {</PRE><PRE class=alt><SPAN class=lnum>   3:  </SPAN>                var parser = <SPAN class=kwrd>new</SPAN> NParser(textTSql, <SPAN class=kwrd>new</SPAN> ASTNodeCAMLFactory());</PRE><PRE><SPAN class=lnum>   4:  </SPAN>                var generator = <SPAN class=kwrd>new</SPAN> CodeGenerator(parser.Parse());</PRE><PRE class=alt><SPAN class=lnum>   5:  </SPAN>                generator.Generate();</PRE><PRE><SPAN class=lnum>   6:  </SPAN>                <SPAN class=kwrd>return</SPAN> _formatTools.FormatXml(generator.Code);</PRE><PRE class=alt><SPAN class=lnum>   7:  </SPAN>            }</PRE><PRE><SPAN class=lnum>   8:  </SPAN>            <SPAN class=kwrd>catch</SPAN> (ParserException ex)</PRE><PRE class=alt><SPAN class=lnum>   9:  </SPAN>            {</PRE><PRE><SPAN class=lnum>  10:  </SPAN>                _view.Status = ex.Message;</PRE><PRE class=alt><SPAN class=lnum>  11:  </SPAN>            }</PRE><PRE><SPAN class=lnum>  12:  </SPAN>            <SPAN class=kwrd>catch</SPAN> (ScannerException ex)</PRE><PRE class=alt><SPAN class=lnum>  13:  </SPAN>            {</PRE><PRE><SPAN class=lnum>  14:  </SPAN>                _view.Status = ex.Message;</PRE><PRE class=alt><SPAN class=lnum>  15:  </SPAN>            }</PRE></DIV><br />
<P>Instanciamos el Parser (<B>NParser</B>), le pasamos la consulta en TSQL (<B>textSql</B>) y la factoría correspondiente a lo que queremos generar, por el momento solo está disponible la de <B>CAML</B>, en breve completaré la de <B>CAML.Net</B>; Por último inyectamos el Parser en el Generador de código, llamamos al método <B>Generate</B> y recogemos la consulta en CAML en <B>generator.Code</B>.</P><br />
<P><BR>Las posibles excepciones tanto del Parser como del generador de código se pueden atrapar con <B>ParserException</B> y <B>ScannerException</B>.</P><br />
<P><BR>En el proyecto se incluye un pequeño subproyecto con una interfaz WinForms (no es que se me de especialmente bien)<BR><BR></P><br />
<DIV align=center><IMG src="http://oldblog.ideseg.com/content//YACAMLQT_Sample_Gui.PNG" border=0><BR><BR><B><A href="http://www.ideseg.com/YACAMLQTYetAnotherCAMLQueryToolRedux2.aspx">Parte 2 http://www.ideseg.com/YACAMLQTYetAnotherCAMLQueryToolRedux2.aspx</A></B><BR><B><A href="http://www.ideseg.com/YACAMLQTYetAnotherCAMLQueryToolRedux1.aspx">Parte 1 http://www.ideseg.com/YACAMLQTYetAnotherCAMLQueryToolRedux1.aspx</A></B><BR></DIV></p>
]]></content:encoded>
			<wfw:commentRss>http://oldblog.ideseg.com/2009/yacamlqt-yet-another-caml-query-tool-redux-3-in-codeplex/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>¿Por qué son importantes los patrones? &#8211; Libros de Referencia</title>
		<link>http://oldblog.ideseg.com/2009/por-que-son-importantes-los-patrones-libros-de-referencia</link>
		<comments>http://oldblog.ideseg.com/2009/por-que-son-importantes-los-patrones-libros-de-referencia#comments</comments>
		<pubDate>Fri, 22 May 2009 13:49:40 +0000</pubDate>
		<dc:creator>cseg</dc:creator>
				<category><![CDATA[miscelanea]]></category>
		<category><![CDATA[net]]></category>

		<guid isPermaLink="false">/post/c2bfPor-que-son-importantes-los-patrones-Libros-de-Referencia.aspx</guid>
		<description><![CDATA[A estas alturas… todavía me encuentro con aplicaciones donde es imposible comprender el diseño e interpretar las intenciones del desarrollador. Básicamente, pienso que hablan por sí solos, es decir, revelan la intención del diseño, son un lenguaje común; cuando en un equipo de desarrollo se habla en términos de patrones de código, se está hablando [...]]]></description>
			<content:encoded><![CDATA[<p>A estas alturas… todavía me encuentro con aplicaciones donde es imposible<br />
comprender el diseño e interpretar las intenciones del desarrollador. </p>
<p>Básicamente, pienso que hablan por sí solos, es decir, revelan la intención del<br />
diseño, son un lenguaje común; cuando en un equipo de desarrollo se habla en<br />
términos de patrones de código, se está hablando de las características,<br />
cualidades y restricciones que el patrón representa. Hablamos simplificando los<br />
problemas y partes del diseño de nuestras aplicaciones.
</p>
<p>Prácticamente no hay API ó Framework (<a href="http://www.ideseg.com/CenandoBuenasPracticasHistoriaDeTerror.aspx"><u><b>la de SharePoint es una excepción</b></u></a>) donde<br />
no se haga uso de patrones, esto hace que el uso y comprensión así como las<br />
extensiones que realicemos sea mucho más sencillo.
</p>
<p>“Cada patrón describe un problema que ocurre una y otra vez en nuestro ambiente<br />
y describe el corazón de la solución del problema, de esta manera podemos usar<br />
esta solución una y otra vez sin hacerlo de la misma manera dos veces”<br />
Christopher Alexander [AIS+77, page x] 
</p>
<p>Los patrones nos dicen como estructurar clases y objetos para resolver<br />
problemas, y es nuestro trabajo adaptarlos a nuestros diseños.
</p>
<p>Y esto es lo más grande, porque esa adaptación a un problema particular no<br />
oculta las intenciones del programador, viendo que patrón se ha adaptado nos<br />
permite vislumbrar en que ha pensado a la hora de tomar decisiones.
</p>
<p>En fin, para todos aquellos que comienzan, y para algunos que todavía… os dejo<br />
una lista de libros que son (no todos) de obligada lectura.</p>
<p align="center"><img src="http://oldblog.ideseg.com/content//patterns_books.gif" border="0">
</p>
<p>De arriba abajo:</p>
<p><iframe src="http://rcm.amazon.com/e/cm?t=codesegm-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0201633612&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=FFFFFF&amp;bg1=FFFFFF&amp;f=ifr&amp;npa=1" style="width: 120px; height: 240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0"></iframe></p>
<p><iframe src="http://rcm.amazon.com/e/cm?t=codesegm-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0201895420&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=FFFFFF&amp;bg1=FFFFFF&amp;f=ifr&amp;npa=1" style="width: 120px; height: 240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0"></iframe></p>
<p><iframe src="http://rcm.amazon.com/e/cm?t=codesegm-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0131857258&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=FFFFFF&amp;bg1=FFFFFF&amp;f=ifr&amp;npa=1" style="width: 120px; height: 240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0"></iframe></p>
<p><iframe src="http://rcm.amazon.com/e/cm?t=codesegm-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0321127420&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=FFFFFF&amp;bg1=FFFFFF&amp;f=ifr&amp;npa=1" style="width: 120px; height: 240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0"></iframe></p>
<p><iframe src="http://rcm.amazon.com/e/cm?t=codesegm-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0321213351&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=FFFFFF&amp;bg1=FFFFFF&amp;f=ifr&amp;npa=1" style="width: 120px; height: 240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0"></iframe></p>
<p><iframe src="http://rcm.amazon.com/e/cm?t=codesegm-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0321413091&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=FFFFFF&amp;bg1=FFFFFF&amp;f=ifr&amp;npa=1" style="width: 120px; height: 240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0"></iframe></p>
<p><iframe src="http://rcm.amazon.com/e/cm?t=codesegm-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=059652773X&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=FFFFFF&amp;bg1=FFFFFF&amp;f=ifr&amp;npa=1" style="width: 120px; height: 240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0"></iframe></p>
<p><iframe src="http://rcm.amazon.com/e/cm?t=codesegm-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0201844532&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=FFFFFF&amp;bg1=FFFFFF&amp;f=ifr&amp;npa=1" style="width: 120px; height: 240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0"></iframe></p>
<p><iframe src="http://rcm.amazon.com/e/cm?t=codesegm-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0131495054&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=FFFFFF&amp;bg1=FFFFFF&amp;f=ifr&amp;npa=1" style="width: 120px; height: 240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0"></iframe></p>
<p><iframe src="http://rcm.amazon.com/e/cm?t=codesegm-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0321490452&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=FFFFFF&amp;bg1=FFFFFF&amp;f=ifr&amp;npa=1" style="width: 120px; height: 240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0"></iframe></p>
<p>* Patrones de diseño, edición en castellano de<br />
<a href="http://www.amazon.com/dp/0201633612?tag=codesegm-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=0201633612&amp;adid=11B3BTMQPJRR9ZJR01FA&amp;"><br />
Design Patterns</a> &#8211; <span style="color: rgb(255, 0, 0);"><strong>Lectura obligatoria</strong></span><br />
*<br />
<a href="http://www.amazon.com/dp/0201633612?tag=codesegm-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=0201633612&amp;adid=11B3BTMQPJRR9ZJR01FA&amp;"><br />
Design Patters</a> (GOF Book) &#8211; <span style="color: rgb(255, 0, 0);"><strong>Lectura obligatoria</strong></span><br />
*<br />
<a href="http://www.amazon.com/dp/0201895420?tag=codesegm-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=0201895420&amp;adid=10K4QWCT5K84XRV3YHNF&amp;"><br />
Analysis Patterns</a> &#8211; Es un libro más profundo, sobre todo orientado al<br />
análisis y diseño de aplicaciones, con ejemplos (sin código) del diseño de<br />
aplicaciones de negocio y de aplicación de patrones en el diseño -<br />
<span style="color: rgb(255, 0, 0);"><strong>Lectura Recomendada</strong></span><br />
* <a href="http://www.amazon.com/dp/0131857258?tag=codesegm-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=0131857258&amp;adid=1AT1S5GRY9R1QVGDBMDM&amp;"><br />
AAgile Principles, Patterns and Practices in C#</a> &#8211; Para mi uno de los mejores<br />
libros que he leído, no solo hace hincapié en los principios de diseño más<br />
básicos, sino que también añade una completa referencia de los patrones más<br />
usados. &#8211; <span style="color: rgb(255, 0, 0);"><strong>Lectura Muy Recomendada.</strong></span><br />
* <a href="http://www.amazon.com/dp/0321127420?tag=codesegm-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=0321127420&amp;adid=114DFAY63EWB8EB37GNS&amp;"><br />
Patterns of Enterprise Application Architecture</a>  &#8211; Fantástico, aquí se<br />
incluyen muchos de los patrones más usados que no se encuentran en el GOF Book,<br />
desde Active Record, Lazy Load, Unit Of Work &#8230; aproximadamente 50 patrones<br />
menos conocidos, pero ampliamente usados. &#8211; <span style="color: rgb(255, 0, 0);"><strong>Lectura<br />
Obligatoria.</strong></span><br />
* <a href="http://www.amazon.com/dp/0321213351?tag=codesegm-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=0321213351&amp;adid=1RW62VM2FNMBTP4179WV&amp;"><br />
Refactoring to Patterns</a>,, un pedazo de libro, que es como el eslabón que une<br />
refactorizaciones y patrones, perfectamente explicado, realmente impresionante<br />
como une el libro de Design Patterns, con el de<a href="https://www.amazon.com/dp/0201485672?tag=codesegm-20&amp;camp=0&amp;creative=0&amp;linkCode=as1&amp;creativeASIN=0201485672&amp;adid=12V0NKY1F1DRMDDSJZFV&amp;"><br />
Refactoring</a>&nbsp; (Fowler) &#8211; <span style="color: rgb(255, 0, 0);"><strong>Lectura Muy<br />
Recomendada.</strong></span><br />
* <a href="http://www.amazon.com/dp/0321413091?tag=codesegm-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=0321413091&amp;adid=1FEHGRXBWSCBEKW5ZFPT&amp;"><br />
Implementation Patterns</a>  &#8211; Un libro que realmente habla más del estilo de<br />
código que de patrones, un poco flojo, recomiendo leer<br />
<a href="https://www.amazon.com/dp/0132350882?tag=codesegm-20&amp;camp=0&amp;creative=0&amp;linkCode=as1&amp;creativeASIN=0132350882&amp;adid=14YYGQV3FEZZDNJW29P7&amp;"><br />
Clean Code</a> de Robert C. Martin. &#8211; <span style="color: rgb(255, 0, 0);"><strong>Lectura Medio<br />
Recomendada.</strong></span><br />
* <a href="http://www.amazon.com/dp/059652773X?tag=codesegm-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=059652773X&amp;adid=1YMRHP3J2ZJ6FN462QYT&amp;">C# 3.0 Design Patterns</a> &#8211; Un libro con ejemplos de patrones (GOF) en C# 3.0<br />
sin más. &#8211; <span style="color: rgb(255, 0, 0);"><strong>Lectura Medio Recomendada.</strong></span><br />
* <a href="http://www.amazon.com/dp/0201844532?tag=codesegm-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=0201844532&amp;adid=07TKRSQX91ZS59KV38Z2&amp;">C# Design Patterns</a>, los GOF con ejemplos en C#, <span style="color: rgb(255, 0, 0);"><br />
<strong>Libro recomendado para los que comienzan con C#.</strong></span><br />
* <a href="http://www.amazon.com/dp/0131495054?tag=codesegm-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=0131495054&amp;adid=18AXVS8JFNPDWJF24J4K&amp;">xUnit Test Patterns</a> &#8211; Si haces pruebas ó TDD es imprescindible.<br />
<span style="color: rgb(255, 0, 0);"><strong>Lectura Muy Recomendada</strong></span>.<br />
* <a href="http://www.amazon.com/dp/0321490452?tag=codesegm-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=0321490452&amp;adid=0DF0H7MDQNF64Y363EY1&amp;"><br />
Design Patterns in Ruby</a>  &#8211; Si eres un salsas, como yo, no esta de más ver<br />
como se implementan los GOF en Ruby, muy entretenido.<span style="color: rgb(255, 0, 0);"><strong><br />
Lectura Pasatiempo.</strong></span></p>
<p>Por último tengo un librito que aunque parece que esta en chino, no es así, esta<br />
en ingles, pero es una edición Design Patterns para China, a mi me gusta para<br />
llevarlo en la maleta cuando doy charlas o cursos.</p>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://oldblog.ideseg.com/2009/por-que-son-importantes-los-patrones-libros-de-referencia/feed</wfw:commentRss>
		<slash:comments>234</slash:comments>
		</item>
		<item>
		<title>YACAMLQT (Yet another CAML query tool) Redux (2)</title>
		<link>http://oldblog.ideseg.com/2009/yacamlqt-yet-another-caml-query-tool-redux-2</link>
		<comments>http://oldblog.ideseg.com/2009/yacamlqt-yet-another-caml-query-tool-redux-2#comments</comments>
		<pubDate>Fri, 22 May 2009 09:50:52 +0000</pubDate>
		<dc:creator>cseg</dc:creator>
				<category><![CDATA[caml]]></category>
		<category><![CDATA[net]]></category>
		<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">/post/YACAMLQT-(Yet-another-CAML-query-tool)-Redux-(2).aspx</guid>
		<description><![CDATA[Continuando con la explicación del código de YACAMLQT. Habíamos visto la parte relacionada con el Lexer el analizador morfológico. Como es obvio detrás debe haber un analizador sintáctico y semántico el Parser. El analizador sintáctico y semántico (NParser) se ha implementado siguiendo el patrón interpeter, (seguramente sea uno de los que menos se ven), el [...]]]></description>
			<content:encoded><![CDATA[<p>Continuando con la <a href="http://www.ideseg.com/YACAMLQTYetAnotherCAMLQueryToolRedux1.aspx">explicación del código de YACAMLQT</a>.</p>
<p>Habíamos visto la parte relacionada con el Lexer el analizador morfológico. Como es obvio detrás debe haber un analizador sintáctico y semántico el <a href="http://en.wikipedia.org/wiki/Parsing">Parser</a>.</p>
<p>El analizador sintáctico y semántico (<b>NParser</b>) se ha implementado siguiendo el patrón interpeter, (<i>seguramente sea uno de los que menos se ven</i>), el objetivo es obtener los distintos Tokens desde el Scanner y montar un árbol sintáctico (<a href="http://en.wikipedia.org/wiki/Abstract_syntax_tree">AST</a>) este árbol contiene Nodos (<b>ASTNodeBase</b>) y estos nodos representan de manera abstracta y simplificada la estructura sintáctica de la consulta en SQL.</p>
<p>(diagrama NParser)
<div align="center"><img src="http://oldblog.ideseg.com/content//yacamlqt_nparser.gif" border="0" width="467" height="445"></div>
<p>A la clase <b>NParser </b>se le puede inyectar una factoria (<b>ASTNodeFactoryBase</b>) en función del código que queramos generar, por el momento solo esta implementado el CAML, pero se puede extender sencillamente para generar <a href="http://www.codeplex.com/camldotnet">CAML.Net</a>.</p>
<p>Partiendo de un nodo abstracto (<b>ASTNodeBase</b>) podemos definir las distintas unidades sintácticas, por medio de la herencia. Estos nodos abstractos (heredados de <b>ASTNodeBase </b>) conforman las distintas expresiones que se usan en el analizador sintáctico y semántico (<b>NParser</b>), para ello se ha definido una clase para cada uno de los Tokens a modo de plantilla (template),&nbsp; y estas clases son a su vez son las distintas expresiones abstractas, que se usan en&nbsp; el patrón interpreter implementado en el parser. (<b>NParser</b>).</p>
<p>Todos estos nodos que forman las expresiones abstractas al fin al cabo son plantillas (templates), y podrían a su vez ser clases abstractas, yo opte por una implementarlas como clases normales. Ya que algunos de los nodos son terminales y otros intermedios y no tienen por qué ser heredados, de este modo la factoria base (<b>ASTNodeFactoryBase</b>) usa miembros virtuales parar crear dichos nodos.</p>
<p>(diagrama parcial de ASTNodeBase)
<div align="center"><img src="http://oldblog.ideseg.com/content//yacamlqt_ast.gif" border="0"></div>
<p>Para crear todos estas expresiones abstractas existe una factoría abstracta (<b>ASTNodeFactoryBase </b>) a través de la cual creamos los distintos nodos. Como puede verse, para añadir una variante como <a href="http://www.codeplex.com/camldotnet">CAML.Net</a>, solamente hay que añadir las expresiones abstractas heredando de las ya existentes e implementando <b>PreCode()</b> y <b>PostCode()</b>. </p>
<p>Todos estos nodos que forman las expresiones abstractas al fin al cabo son plantillas (templates), y podrían a su vez ser clases abstractas, yo opte por una implementarlas como clases normales, debido a que algunos de los nodos son terminales y otros intermedios y no tienen por qué ser heredados, de este modo la factoria base (<b>ASTNodeFactoryBase</b>) usa miembros virtuales parar crear dichos nodos terminales e intermedios.</p>
<p>Después para poder inyectar en el parser dichas expresiones debemos crear una nueva factoría heredada de la factoría base (ASTNodeFactoryBase).</p>
<p>(diagrama ASTNodeFactoryBase)
<div align="center"><img src="http://oldblog.ideseg.com/content//yacamlqt_nodefactory.gif" border="0"></div>
<p>Para generar CAML lo que he hecho es heredar de cada plantilla ó expresión abstracta definida, una nueva clase que redefine los métodos virtuales <b>PreCode()</b> y <b>PostCode()</b> que son los encargados de sustituir cada nodo del árbol sintáctico en CAML.</p>
<p>Y crear una factoría (<b>ASTNodeCAMLFactory</b>) que se encarga de crear las expresiones.</p>
]]></content:encoded>
			<wfw:commentRss>http://oldblog.ideseg.com/2009/yacamlqt-yet-another-caml-query-tool-redux-2/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>YACAMLQT (Yet another CAML query tool) Redux (1)</title>
		<link>http://oldblog.ideseg.com/2009/yacamlqt-yet-another-caml-query-tool-redux-1</link>
		<comments>http://oldblog.ideseg.com/2009/yacamlqt-yet-another-caml-query-tool-redux-1#comments</comments>
		<pubDate>Mon, 27 Apr 2009 13:26:05 +0000</pubDate>
		<dc:creator>cseg</dc:creator>
				<category><![CDATA[caml]]></category>
		<category><![CDATA[net]]></category>
		<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">/post/YACAMLQT-(Yet-another-CAML-query-tool)-Redux-(1).aspx</guid>
		<description><![CDATA[Hace un mes, John Holliday, me pidió a ver si podíamos integrar su CAML.net con mi YACAMLQT, a la vez que ampliar mi herramienta para soportar otro tipo de consultas como adds y updates. YACAMLQT, es una utilidad que convierte una sentencia SQL en CAML, el lenguaje de consulta de Sharepoint. (Véase YACAMLQT, YACAMLQT2 y [...]]]></description>
			<content:encoded><![CDATA[<p>Hace un mes, <a href="http://www.johnholliday.net/">John Holliday</a>, me pidió a ver si podíamos integrar su <a href="http://www.codeplex.com/camldotnet">CAML.net</a> con mi <b><a href="http://www.ideseg.com/SharePointYetAnotherCAMLQueryTool2.aspx">YACAMLQT</a></b>, a la vez que ampliar mi herramienta para soportar otro tipo de consultas como adds y updates.</p>
<p>YACAMLQT, es una utilidad que convierte una sentencia SQL en CAML, el lenguaje de consulta de Sharepoint. (Véase <a href="http://www.ideseg.com/SharePointYetAnotherCAMLQueryToolAlaSQL.aspx">YACAMLQT</a>, <a href="http://www.ideseg.com/SharePointYetAnotherCAMLQueryTool2.aspx">YACAMLQT</a>2 y <a href="http://www.ideseg.com/SharePointCAMLNetGenial.aspx">YACAMLQT-CAML.Net</a>)</p>
<p>Estos días entre rato bueno y rato malo, he reescrito totalmente el código de YACAMLQT, para hacerlo más sencillo (por supuesto usando TDD), en principio el objetivo ha sido emular el antiguo YACAMLQT, pero dotándolo de un diseño más sencillo y ampliable.</p>
<p>YACAMLQT, es un programa que convierte una sintaxis tipo SQL en CAML (el lenguaje de consulta de SharePoint).</p>
<p>Es decir esto: 
<p class="style1"><font face="Courier New"><font size="2"><font color="#000080"><strong><span class="style2">WHERE</span> </strong>((Column1 = &#8220;Value1&#8243;) <span class="style2"><strong>AND</strong></span> (Column2 = &#8220;Value2&#8243;)) <span class="style2"><strong>OR</strong></span> ((Column3 = 10) <br /></font></font></font><font face="Courier New"><font size="2"><font color="#000080"><span class="style2"><strong>AND</strong></span> (Column3 &lt;&gt; NULL)) <span class="style2"><strong>GROUPBY</strong></span> Column1 <span class="style2"><strong>ORDERBY</strong></span> Column1, Column2 <span class="style2"><strong>ASC</strong></span>, Column3 <span class="style2"><strong>DESC</strong></span></font></font></font></p>
<p>En esto:</p>
<div class="csharpcode">
<pre class="alt"><span class="kwrd">&lt;</span><span class="html">Query</span><span class="kwrd">&gt;</span></pre>
<pre>  <span class="kwrd">&lt;</span><span class="html">Where</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">    <span class="kwrd">&lt;</span><span class="html">Or</span><span class="kwrd">&gt;</span></pre>
<pre>      <span class="kwrd">&lt;</span><span class="html">And</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">        <span class="kwrd">&lt;</span><span class="html">Eq</span><span class="kwrd">&gt;</span></pre>
<pre>          <span class="kwrd">&lt;</span><span class="html">FieldRef</span> <span class="attr">Name</span><span class="kwrd">="Column1"</span> <span class="kwrd">/&gt;</span></pre>
<pre class="alt">          <span class="kwrd">&lt;</span><span class="html">Value</span> <span class="attr">Type</span><span class="kwrd">="Text"</span><span class="kwrd">&gt;</span>Value1<span class="kwrd">&lt;/</span><span class="html">Value</span><span class="kwrd">&gt;</span></pre>
<pre>        <span class="kwrd">&lt;/</span><span class="html">Eq</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">        <span class="kwrd">&lt;</span><span class="html">Eq</span><span class="kwrd">&gt;</span></pre>
<pre>          <span class="kwrd">&lt;</span><span class="html">FieldRef</span> <span class="attr">Name</span><span class="kwrd">="Column2"</span> <span class="kwrd">/&gt;</span></pre>
<pre class="alt">          <span class="kwrd">&lt;</span><span class="html">Value</span> <span class="attr">Type</span><span class="kwrd">="Text"</span><span class="kwrd">&gt;</span>Value2<span class="kwrd">&lt;/</span><span class="html">Value</span><span class="kwrd">&gt;</span></pre>
<pre>        <span class="kwrd">&lt;/</span><span class="html">Eq</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">      <span class="kwrd">&lt;/</span><span class="html">And</span><span class="kwrd">&gt;</span></pre>
<pre>      <span class="kwrd">&lt;</span><span class="html">And</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">        <span class="kwrd">&lt;</span><span class="html">Eq</span><span class="kwrd">&gt;</span></pre>
<pre>          <span class="kwrd">&lt;</span><span class="html">FieldRef</span> <span class="attr">Name</span><span class="kwrd">="Column3"</span> <span class="kwrd">/&gt;</span></pre>
<pre class="alt">          <span class="kwrd">&lt;</span><span class="html">Value</span> <span class="attr">Type</span><span class="kwrd">="Integer"</span><span class="kwrd">&gt;</span>10<span class="kwrd">&lt;/</span><span class="html">Value</span><span class="kwrd">&gt;</span></pre>
<pre>        <span class="kwrd">&lt;/</span><span class="html">Eq</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">        <span class="kwrd">&lt;</span><span class="html">IsNotNull</span><span class="kwrd">&gt;</span></pre>
<pre>          <span class="kwrd">&lt;</span><span class="html">FieldRef</span> <span class="attr">Name</span><span class="kwrd">="Column3"</span> <span class="kwrd">/&gt;</span></pre>
<pre class="alt">        <span class="kwrd">&lt;/</span><span class="html">IsNotNull</span><span class="kwrd">&gt;</span></pre>
<pre>      <span class="kwrd">&lt;/</span><span class="html">And</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">    <span class="kwrd">&lt;/</span><span class="html">Or</span><span class="kwrd">&gt;</span></pre>
<pre>  <span class="kwrd">&lt;/</span><span class="html">Where</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">  <span class="kwrd">&lt;</span><span class="html">GroupBy</span><span class="kwrd">&gt;</span></pre>
<pre>    <span class="kwrd">&lt;</span><span class="html">FieldRef</span> <span class="attr">Name</span><span class="kwrd">="Column1"</span> <span class="kwrd">/&gt;</span></pre>
<pre class="alt">  <span class="kwrd">&lt;/</span><span class="html">GroupBy</span><span class="kwrd">&gt;</span></pre>
<pre>  <span class="kwrd">&lt;</span><span class="html">OrderBy</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">    <span class="kwrd">&lt;</span><span class="html">FieldRef</span> <span class="attr">Name</span><span class="kwrd">="Column1"</span> <span class="kwrd">/&gt;</span></pre>
<pre>    <span class="kwrd">&lt;</span><span class="html">FieldRef</span> <span class="attr">Name</span><span class="kwrd">="Column2"</span> <span class="attr">Ascending</span><span class="kwrd">="True"</span> <span class="kwrd">/&gt;</span></pre>
<pre class="alt">    <span class="kwrd">&lt;</span><span class="html">FieldRef</span> <span class="attr">Name</span><span class="kwrd">="Column3"</span> <span class="attr">Ascending</span><span class="kwrd">="False"</span> <span class="kwrd">/&gt;</span></pre>
<pre>  <span class="kwrd">&lt;/</span><span class="html">OrderBy</span><span class="kwrd">&gt;</span></pre>
<pre class="alt"><span class="kwrd">&lt;/</span><span class="html">Query</span><span class="kwrd">&gt;</span></pre>
</div>
<p>El proyecto completo lo subiré a <b>CodePlex</b> en unos días, con su código fuente que poco a poco y con ayuda espero ir ampliando.</p>
<p>Por si alguien quiere echar una mano en el proyecto, voy a contar alguno de los entresijos del diseño de la aplicación.</p>
<p>Lo primero que he diseñado es el analizador morfológico (<i>lexer</i>) que se encarga de identificar dentro de un string, las distintas unidades sintácticas (<i>tokens</i>) con las que construiremos un analizador sintáctico y semántico (<i>parser</i>) con el cual construiremos un árbol sintáctico (<i>AST</i>) que por último recorreremos para transformar el SQL en CAML u otra variante como CAML.Net.</p>
<p>El lexer, está compuesto por una clase base, <b>ScannerBase </b>que contiene las partes más básicas del lexer, he extraído esta clase base una vez que tenía el analizador morfológico completo ya que de esta manera podemos realizar otro tipo de analizadores. </p>
<p><img src="http://oldblog.ideseg.com/content//yacamlqt_lexer.gif" border="0"></p>
<p>Las funciones básicas como comerse los espacios (<b>EatSpaces</b>()), detectar si es el final de línea (<b>EndOfLine</b>()) , saltar caracteres (<b>SkipChar</b>()) son parte de ScannerBase. Lo más importante de esta clase es la propiedad <b>CurrentChar </b>que devuelve el último carácter leído y el método <b>GetCharMoveNext</b>(), que obtiene un carácter y se mueve a la siguiente posición.</p>
<p>Para los que habéis usado el unix <a href="http://es.wikipedia.org/wiki/Herramienta_de_programaci%C3%B3n_lex">flex</a>, <b>GetCharMoveNext</b>() es similar a <b>input</b>().</p>
<p>Esta clase <b>ScannerBase </b>utiliza internamente una clase <b>ScannerState </b>que mantiene el estado para poder releer un token ó unidad sintáctica. </p>
<p>Los tokens en el caso de YACAMLQT, consisten en las palabras reservadas propias de SQL, así como los distintos operadores, los campos y los valores (<i>cadena, fecha, lógico y numérico</i>). </p>
<p>A diferencia del unix <a href="http://es.wikipedia.org/wiki/Herramienta_de_programaci%C3%B3n_lex">flex</a>, esto no se trata de un <b>unput</b>(), ya que mediante este volveríamos al carácter anterior. En este caso, como lo importante del analizador es obtener una unidad sintáctica, o token, lo que he hecho es implementar un método llamado <b>BackToken</b>() que lo que hace es posicionar el lexer justo al comienzo del último token obtenido, de modo que <b>GetToken</b>() volverá a devolvernos el mismo token.</p>
<p>La clase <b>Scanner</b>, hereda como es de suponer de <b>ScannerBase</b>, e implementa <b>GetToken</b>(), el responsable de de devolver un token, y <b>CheckCorrectBracketsAndQuotes</b>() que es el responsable de comprobar que los paréntesis y las comillas están correctamente.</p>
<p>Dentro de la clase <b>Scanner</b>, el método <b>GetToken</b>() es el responsable de identificar cada uno de los tokens, para lo cual he realizado un método para identificar cada uno de los distintos tokens. <b>GetToken</b>() usa los métodos <b>ScanDate</b>(), <b>ScanString</b>(), <b>ScanOperator</b>(), <b>ScanNumber</b>() y <b>ScanReservedWordOrSymbol</b>().</p>
<p><b>ScanOperator</b>() y <b>ScanReservedWordOrSymbol</b>() usan un diccionario para identificar los distintos operadores y palabras reservadas. En el caso de <b>ScanReservedWordOrSymbol</b>(), si el token leído no se encuentra en el diccionario de palabras reservadas estaremos identificando un símbolo ó identificador.</p>
<p>Para terminar con esta primera parte, y siguiendo el principio de responsabilidad única, se ha implementado la clase <b>Token </b>como un contenedor y <b>TokenFactory </b>como una factória encargada de crear los distintos tipos de tokens ó unidades sintácticas. La clase<b> Scanner</b> es la que usa la factória para crear los distintos Tokens.</p>
<p><img src="http://oldblog.ideseg.com/content//yacamlqt_token.gif" border="0"></p>
<p>La clase <b>Token</b>, puede contener los distintos tipos de tokens, en principio todos aunque pueden ser de diferentes tipos, mantendrán su valor como un string. El resto de propiedades para identificar el tipo de token (<b>TType</b>) ó el tipo de valor (<b>ValueType</b>) son una enumeración.</p>
]]></content:encoded>
			<wfw:commentRss>http://oldblog.ideseg.com/2009/yacamlqt-yet-another-caml-query-tool-redux-1/feed</wfw:commentRss>
		<slash:comments>355</slash:comments>
		</item>
		<item>
		<title>Mi particular visión del Test Driven Development (TDD)</title>
		<link>http://oldblog.ideseg.com/2009/mi-particular-vision-del-test-driven-development-tdd</link>
		<comments>http://oldblog.ideseg.com/2009/mi-particular-vision-del-test-driven-development-tdd#comments</comments>
		<pubDate>Sun, 19 Apr 2009 19:06:23 +0000</pubDate>
		<dc:creator>cseg</dc:creator>
				<category><![CDATA[net]]></category>

		<guid isPermaLink="false">/post/Mi-particular-vision-del-Test-Driven-Development-(TDD).aspx</guid>
		<description><![CDATA[Cuando nos enfrentamos al diseño de un programa sea el que sea, partimos de un estado que podemos llamar “A” problema, y como es obvio un estado “B” en el que tenemos resuelto el problema, por medio de un programa. Si la programación fuera como las matemáticas, cosa que “no es” aunque&#160; se fundamente en [...]]]></description>
			<content:encoded><![CDATA[<p>Cuando nos enfrentamos al diseño de un programa sea el que sea, partimos de un estado que podemos llamar “A” problema, y como es obvio un estado “B” en el que tenemos resuelto el problema, por medio de un programa.</p>
<p>Si la programación fuera como las matemáticas, cosa que “no es” aunque&nbsp; se fundamente en ello; la solución ideal sería la <b>línea recta</b>. Una línea recta que nos lleva del punto “A” al punto “B”, directamente, sin rodeos. </p>
<p>Es la solución más ELEGANTE, por qué es la solución más CLARA y BREVE que se puede dar. </p>
<p>Hay partes de la programación en donde existen uno o varios algoritmos que podemos usar y que son como la línea recta es decir ya están optimizados y no hay manera de mejorar (algoritmos de ordenación, búsqueda, etc..) pero cuando hablamos de un sistema de mayor tamaño, donde se ven involucrados más componentes la cosa cambia.</p>
<p>Existen miles de maneras de llegar de “A” a “B”, podemos hacer tirabuzones, hipérbolas, curvas mágicas y un sinfín de figuras geométricas que nos llevarán también de “A” a “B”. <b>Los programadores somos capaces de crear miles y miles de esas formas mágicas. (Es nuestra naturaleza, como le dijo el escorpión a la rana)</b></p>
<p>De modo que nos enfrentamos a un problema doble, llegar del punto “A”, problema, al punto “B”, programa&nbsp; sin morir en el intento. Y hacerlo de la manera más ELEGANTE.</p>
<p>No hace mucho, hablaba Rodrigo, del “<a href="http://geeks.ms/blogs/rcorral/archive/2009/03/23/ya-ya-keep-it-simple-stupid-191-pero-c-243-mo.aspx">Principio KISS</a>” y del “Divide y Vencerás”, este último es sin duda la práctica que seguimos todos los programadores desde que tenemos conocimiento de nosotros mismos, es decir de que somos eso “<a href="http://www.ideseg.com/VenenoEnLosDedos.aspx">Programadores</a>”. <br />&nbsp;<br />Debemos resolver un problema, es decir crear un programa “B”, que resuelva “A”, y hay miles de soluciones ó caminos posibles que nos llevarán de “A” a “B”. </p>
<p>Nosotros no disponemos de un algoritmo determinado, de una solución magistral como la ecuación de la recta que pasa por dos puntos, <b>cada programador es un mundo</b> y su percepción tanto del problema como del modo de llegar a la solución (diseño) podemos decir que es casi única, cuya aproximación es inversamente proporcional a la complejidad del problema.</p>
<p>A un problema más sencillo, hay más posibilidades de que dos programadores sigan el mismo camino, a un problema más complejo la desviación entre las soluciones tiende a distar más.</p>
<p>No existe la certeza de que nuestra solución sea la más optima, clara y concisa y lo que es peor tampoco podemos medir desviación alguna, puesto que cuanto más complejo es el programa más variantes tiene y por ende para poder medir dicha desviación, deberíamos conocer la línea recta, cosa que a priori es imposible.</p>
<p>Partiendo como base de que la línea recta sería la solución “perfecta” del problema, tenemos una complicada tarea.</p>
<p>Pero por otro lado una línea no es más que una sucesión de puntos, de modo, que podemos interpretar cada punto como una parte de la solución, y aquí volvemos al “Divide y Vencerás”.</p>
<p>Gracias a que tenemos técnicas como el TDD o ATDD, podemos ir punto por punto trazando nuestra línea. </p>
<p><b>“Solo escribimos el código necesario para pasar la prueba”, esta frase que resume en esencia que es “Test Driven Development”, también es la mejor manera que conozco de ir<u> punto por punto</u> trazando la solución de “A” a “B”, siguiendo esa imaginaría línea recta que sería la solución más ELEGANTE, CLARA y BREVE que se puede dar.<br /></b></p>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://oldblog.ideseg.com/2009/mi-particular-vision-del-test-driven-development-tdd/feed</wfw:commentRss>
		<slash:comments>508</slash:comments>
		</item>
		<item>
		<title>Veneno en los dedos</title>
		<link>http://oldblog.ideseg.com/2009/veneno-en-los-dedos</link>
		<comments>http://oldblog.ideseg.com/2009/veneno-en-los-dedos#comments</comments>
		<pubDate>Thu, 16 Apr 2009 22:33:09 +0000</pubDate>
		<dc:creator>cseg</dc:creator>
				<category><![CDATA[miscelanea]]></category>
		<category><![CDATA[net]]></category>

		<guid isPermaLink="false">/post/Veneno-en-los-dedos.aspx</guid>
		<description><![CDATA[En la vida de todo programador hay un “día especial”, algunos tendréis que hacer memoria, otros mucha memoria y algunos no lo recordareis pero es el día en que uno toma conciencia de sí mismo y se da cuenta de que es un “PROGRAMADOR”. (¡Qué fea palabra!… léase “CODER” please) No estoy hablando de ser [...]]]></description>
			<content:encoded><![CDATA[<p>En la vida de todo programador hay un “día especial”, algunos tendréis que hacer memoria, otros mucha memoria y algunos no lo recordareis pero es el día en que uno toma conciencia de sí mismo y se da cuenta de que es un “PROGRAMADOR”. (¡Qué fea palabra!… léase “CODER” please)</p>
<p>No estoy hablando de ser “programador”, si no de ser “PROGRAMADOR”. Me refiero al momento en que te das cuenta de que el código es importante, que eres una máquina de tirar líneas que buscas mejorar día a día y de que el veneno de los 1s y los 0s está dentro de ti, del momento en que te das cuenta que todo es programable, de que a la silla de ruedas de tu abuelo se le puede poner un motor y programarlo, de que la gameboy de tu primo lleva un Z80 y seguro que hay alguna forma de meterle mano y…..en fin, te das cuenta de que el teclado es una extensión de tus dedos. </p>
<p>Os contaré como fue mi momento. </p>
<p>Yo cacharreaba con ordenadores como muchos de vosotros, que si un ZX81, un Commodore 64, etc…,etc… Allá por el año 1989 (yo tenía 19 años), un amigo de mi cuadrilla (Iñaki) me propuso hacer un programa para la empresa en que trabajaba su padre, era una empresa de excavaciones pequeña, CAMES, que hacía cosas generalmente para empresas más grandes.</p>
<p>El programa demandado consistía en llevar un control de los partes de los empleados y las máquinas; había que controlar el número de horas que se empleaba en cada obra. Tuvimos algunas reuniones en la oficina de la empresa y me explicaron con todo detalle cómo se llevaban los partes manualmente y los controles que se debían hacer semanalmente y mensualmente, así como los trabajos que había que re-facturar a terceros. <br />Durante las reuniones tome un montón de notas tratando de no perder detalle de lo que querían que el programa hiciera exactamente.<br />Por aquel entonces, había aprendido algunos leguajes de programación, como Basic, Pascal, C, algo de Lisp y Prolog, y dBase3, para el asunto me decante por dBase3, no por nada especial, pero las librerías btreeve que usaba entonces en Basic y en C, daban bastante guerra. También pensé en la comodidad de que dBase contaba con campos de entrada que admitían validaciones sin mucho esfuerzo, así como poder examinar las tablas y ver cualquier detalle de los datos. Otro de los factores importantes en la decisión fueron los listados, ya que hacer listados con dBase era coser y cantar. En fin dBase era perfecto para hacerlo todo sin demasiado esfuerzo.</p>
<p>De modo que me encerré en casa e hice el programa; unos días más tarde recibí en mi casa (la de mis padres en realidad y en mi habitación más concretamente) a las personas a las que debía enseñar el programa. Estuvimos toda la tarde revisando las especificaciones y surgieron varias cosas. Al terminar, yo no estaba del todo satisfecho con el programa a pesar de que cumplía con las especificaciones salvo en algún pequeño detalle que surgió durante la demo.</p>
<p>Un amigo me hablo de Clipper el compilador de dBase, me dejo un manual y me dijo que sería mucho más profesional hacerlo con Clipper (87). Así que rehíce el programa completamente desde cero. </p>
<p>Finalmente entregué el programa y cobre 60.000 pesetas (un dineral en el año 89) y muy agradecido asesoré a la empresa también acerca del ordenador y la impresora que debían comprar. </p>
<p>Los primeros viernes de cada semana, momento en que se pagaban las horas extras a los empleados, yo tenía que bajar a la empresa exclusivamente por si surgía algún problema o alguno de los cálculos no salían correctamente. El argumento de “Benito”, el encargado,&nbsp; era que los empleados (tíos muy curtidos de la obra y con carácter más bien duro) sabían mejor que nadie cuanto debían cobrar de modo que, por si acaso, sería mejor que yo estuviese allí en caso de que no coincidieran las cifras.</p>
<div align="center"><img src="http://oldblog.ideseg.com/content//CAMES1.gif" border="0"></div>
<p>Lo estuvimos haciendo aproximadamente durante un mes hasta que lo dieron por válido, ya que, los cálculos siempre salían correctamente si se habían introducido bien los datos.</p>
<p>Ese fue mi primer programa de ordenador, y mis primeros ingresos como “programador”. </p>
<p><b>Aún así, todavía no era un programador.</b></p>
<p>Tiempo después, mientras estudiaba FP por las mañanas, entre a trabajar por las tardes en una empresa de programación. Ellos programaban en Clipper pero no muy bien, de modo que, les di algunas lecciones, suena chulesco lo sé, pero lo mejor de todo es que mi profesor de COBOL de FP, trabajaba allí por las tardes, de modo que, él por la mañana me daba COBOL y yo por la tarde le daba Clipper a él. Cosas de la vida.</p>
<p>Bueno, estando allí hice multitud de programas, facturaciones, contabilidad,&nbsp; etc…etc … </p>
<div align="center"><img src="http://oldblog.ideseg.com/content//CLIPPER2.gif" border="0"></div>
<p><b>Aún así, no er</b><b>a un pro</b><b>gramador</b> de los que hablaba al principio, pero el momento llegó y lo recuerdo perfectamente. </p>
<p>No estaba satisfecho con algunas de las cosas repetitivas que hacíamos programando, así que, cree un meta lenguaje que nos ahorraba horas y horas de programación de esa repetitiva, lo hice en casa por las noches e incluso hice un manual para que todo el mundo en la empresa pudiese usarlo. Ese fue el momento que arruinó mi vida <img src='http://oldblog.ideseg.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . </p>
<p>Ese momento en que no te basta con lo que los lenguajes te dan, cuando empiezas a crear bibliotecas de código, a optimizar en ensamblador rutinas lentas, cuando creas un sistema que es capaz de ahorrar multitud de horas de programación, cuando los días y las noches se funden en la pantalla tirando líneas de código, leyendo programas de otros para aprender más y más, cuando no puedes pasar sin programar algo, lo que sea aunque sea solo por auténtico ocio, por ver si eres capaz de hacerlo o por la razón que sea, que seguro que es lo suficientemente buena como excusa para teclear.</p>
<p><b>¿Cómo te entro a ti el veneno?</b></p>
]]></content:encoded>
			<wfw:commentRss>http://oldblog.ideseg.com/2009/veneno-en-los-dedos/feed</wfw:commentRss>
		<slash:comments>542</slash:comments>
		</item>
	</channel>
</rss>

