<?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>Snippets Tricks</title> <atom:link href="http://snippets-tricks.org/feed/" rel="self" type="application/rss+xml" /><link>http://snippets-tricks.org</link> <description>Blog de Programación &#38; Unix</description> <lastBuildDate>Thu, 04 Mar 2010 01:03:41 +0000</lastBuildDate> <generator>http://wordpress.org/?v=2.9.2</generator> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <item><title>Las tuberías de Unix</title><link>http://snippets-tricks.org/tubos-unix/</link> <comments>http://snippets-tricks.org/tubos-unix/#comments</comments> <pubDate>Thu, 04 Mar 2010 01:03:41 +0000</pubDate> <dc:creator>Alberto</dc:creator> <category><![CDATA[Unix]]></category> <category><![CDATA[Tutorial]]></category><guid
isPermaLink="false">http://snippets-tricks.org/?p=2178</guid> <description><![CDATA[En los sistemas Unix encontramos el concepto de Tubos. Estos permiten que la salida (stdout) de un comando sea la entrada (stdin) de otro comando.
Dicho de otro modo; los tubos de Unix son comandos anidados.
Se emplean con el caracter &#124; de acuerdo con la siguiente sintaxis:
orden1 &#124; orden2 &#124; orden3 &#124; ... &#124; ordenNEjemplo: Mostrar [...]]]></description> <content:encoded><![CDATA[<p>En los sistemas Unix encontramos el concepto de <em>Tubos</em>. Estos permiten que la salida <em>(stdout)</em> de un comando sea la entrada <em>(stdin)</em> de otro comando.</p><p>Dicho de otro modo; los tubos de Unix son comandos anidados.</p><p>Se emplean con el caracter <code>|</code> de acuerdo con la siguiente sintaxis:</p><p><code>orden1 | orden2 | orden3 | ... | ordenN</code><br
/> <span
id="more-2178"></span></p><h3>Ejemplo: Mostrar el contenido de un directorio página por página</h3><p>Veamos un ejemple simple: Es necesario visualizar completamente la carpeta <code>sbin</code>, para esto debemos ejecutar el comando <code>ls -l</code>, pero este comando muestra la lista completa sin dejar visualizar los primeros directorios o archivos ya que su contenido es bastante para visualizarlo en una sola pantalla.</p><pre><strong>$ ls -l /sbin/</strong>
total 15824
-rwxr-x--- 1 root root     22324 2009-10-23 19:33 acpid
-rwxr-xr-x 1 root root      1754 2010-02-23 18:46 activate_dm_linear
-rwxr-xr-x 1 root root     39048 2009-10-21 15:04 adjtimex
-rwxr-xr-x 1 root root     18540 2009-10-21 15:04 agetty
-rwxr-xr-x 1 root root    754308 2009-10-24 08:05 apparmor_parser
-rwxr-xr-x 1 root root     48864 2009-10-19 10:36 arp
-rwxr-xr-x 1 root root     18100 2009-10-23 19:37 arping
-rwxr-x--- 1 root root     96152 2009-10-23 19:22 audispd
-rwxr-x--- 1 root root    116576 2009-10-23 19:22 auditctl
-rwxr-x--- 1 root root    174284 2009-10-23 19:22 auditd
.
.
.
$
</pre><p>Este problema se puede resolver con <code>tuberías</code> y el comando <code>more</code> de la siguiente manera:</p><pre><strong>$ ls -l /sbin/ | more</strong>
total 15824
-rwxr-x--- 1 root root     22324 2009-10-23 19:33 acpid
-rwxr-xr-x 1 root root      1754 2010-02-23 18:46 activate_dm_linear
-rwxr-xr-x 1 root root     39048 2009-10-21 15:04 adjtimex
-rwxr-xr-x 1 root root     18540 2009-10-21 15:04 agetty
-rwxr-xr-x 1 root root    754308 2009-10-24 08:05 apparmor_parser
-rwxr-xr-x 1 root root     48864 2009-10-19 10:36 arp
-rwxr-xr-x 1 root root     18100 2009-10-23 19:37 arping
-rwxr-x--- 1 root root     96152 2009-10-23 19:22 audispd
-rwxr-x--- 1 root root    116576 2009-10-23 19:22 auditctl
-rwxr-x--- 1 root root    174284 2009-10-23 19:22 auditd
.
.
.
<strong>--More--</strong>
.
.
.
-rwxr-xr-x 1 root root     82600 2009-10-19 10:47 debugfs
-rwxr-xr-x 1 root root    227384 2009-10-19 10:59 debugreiserfs
-rwxr-xr-x 1 root root     67976 2009-10-23 19:32 depmod
-rwxr-xr-x 1 root root     13912 2009-10-23 19:24 detectups
-rwxr-xr-x 1 root root    453124 2009-12-17 18:45 dhclient
-rwx------ 1 root root     12564 2009-12-17 18:45 dhclient-script
-rwxr-xr-x 1 root root     72248 2010-01-24 18:05 dhcpcd
-rwxr-xr-x 1 root root     14040 2009-10-21 15:01 dm_dso_reg_tool
-r-xr-xr-x 1 root root     26636 2009-10-23 19:25 dmeventd
-rwxr-xr-x 1 root root    235320 2009-10-21 15:01 dmraid
<strong>--More--</strong>
.
.
.
$
</pre><p>Su funcionamiento es simple: la salida del comando <code>ls -l</code> es enviada al comando <code>more</code> que se encarga de mostrar el contenido página por página.</p><h3>Ejemplo: man 2 PDF</h3><p>Con el comando <code>man</code> visualizamos la documentación de los comandos que especifiquemos, por ejemplo:</p><pre><strong>$ man tar</strong>
.
.
.
NAME
       tar - The GNU version of the tar archiving utility

SYNOPSIS
       tar [OPTION...] [FILE]...
.
.
.</pre><p>Pero&#8230; tal vez no sea muy cómodo leerlo en el Shell, entonces lo enviamos a un archivo PDF:</p><pre><strong>man -t tar | ps2pdfwr -> tar.pdf</strong></pre><p>También lo podemos enviar a la impresora:</p><pre><strong>man -t tar | lpr</strong></pre><p>Simple, ¿No?&#8230;</p> ]]></content:encoded> <wfw:commentRss>http://snippets-tricks.org/tubos-unix/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Introducción a las Intefaces en Java</title><link>http://snippets-tricks.org/introduccion-intefaces-java/</link> <comments>http://snippets-tricks.org/introduccion-intefaces-java/#comments</comments> <pubDate>Sun, 28 Feb 2010 21:25:14 +0000</pubDate> <dc:creator>Alberto</dc:creator> <category><![CDATA[Java]]></category> <category><![CDATA[Freebies]]></category> <category><![CDATA[Tutorial]]></category><guid
isPermaLink="false">http://snippets-tricks.org/?p=2174</guid> <description><![CDATA[Una interfaz es un tipo de clase que solo declara métodos abstractos y variables estáticas. Su tarea es indicarnos lo que deben hacer las clases que la implementan, sin especificar como deben hacerlo.
Las clases pueden implementar mas de una interfaz. Y debemos seguir una sola regla: Todos los métodos declarados en la interfaz deben estar [...]]]></description> <content:encoded><![CDATA[<p>Una <em>interfaz</em> es un tipo de clase que solo declara <em>métodos abstractos</em> y <em>variables estáticas</em>. Su tarea es indicarnos <em>lo que</em> deben hacer las clases que la implementan, sin especificar <em>como</em> deben hacerlo.</p><p>Las clases pueden implementar mas de una interfaz. Y debemos seguir una sola regla: Todos los métodos declarados en la interfaz deben estar implementados en las clases que implementan la interfaz.<br
/> <span
id="more-2174"></span><br
/> <img
class="aligncenter size-full wp-image-2175" title="Interfaces-1" src="http://snippets-tricks.org/wp-content/uploads/2010/02/Interfaces-1.png" alt="" width="506" height="184" /></p><p>Es recomendable crear una interfaz en un archivo distinto. Y al igual que las clases, el nombre del archivo debe ser el mismo que el de la interfaz; en este caso el archivo se llama <code>Geometria.java</code>.</p><p>La interfaz Geometria será implementada por las clases <code>Circulo</code> y <code>Cuadrado</code>.</p><p><img
src="http://snippets-tricks.org/wp-content/uploads/2010/02/Interfaces-2.png" alt="" title="Interfaces-2" width="513" height="240" class="aligncenter size-full wp-image-2177" /></p><p>Como mencioné al inicio; una interfaz nos indica lo que deben hacer las clases pero no como hacerlo. En esta caso la interfaz <code>Geometria</code> nos indica que las clases <code>Circulo</code> y <code>Cuadrado</code> realizarán los cálculos para obtener el área, perímetro y el nombre de las figuras; pero no nos especifica como hacerlo ya que los calculos para ambas figuras son distintos, al igual que el nombre.</p><p>El código completo queda de la siguiente forma con los cuatro archivos respectivamente: <code>Geometria.java</code>, <code>Circulo.java</code>, <code>Cuadrado.java</code> y <code>Test.java</code>.<br
/> Código para el archivo Geometria.java</p><pre class="brush: java">package org.snippetstricks.oop;

public interface Geometria {

	public static final double PI = 3.14159265;
	public double area();
	public double perimetro();
	public String nombre();

}</pre><p>Código para el archivo Circulo.java</p><pre class="brush: java">package org.snippetstricks.oop;

public class Circulo implements Geometria {

	private double radio = 0;

	public Circulo(double r) {
		this.radio = r;
	}

	public double area() {
		return PI * radio * radio;
	}

	public double perimetro() {
		return 2.0 * PI * radio;
	}

	public String nombre() {
		return "Circulo";
	}

}
</pre><p>Código para el archivo Cuadrado.java</p><pre class="brush: java">package org.snippetstricks.oop;

public class Cuadrado implements Geometria {

	private double lado = 0;

	public Cuadrado(double l) {
		this.lado = l;
	}

	public double area() {
		return lado * lado;
	}

	public double perimetro() {
		return 4.0 * lado;
	}

	public String nombre() {
		return "Cuadrado";
	}

}
</pre><p>Código para el archivo Test.java</p><pre class="brush: java">package org.snippetstricks.oop;

public class Test {

	static void resultados(Geometria figura) {
		System.out.printf("Los datos de la figura %s son:%n", figura.nombre());
		System.out.printf("El perimetro es: %f%n", figura.area());
		System.out.printf("El area es: %f%n", figura.perimetro());
	}

	public static void main(String[] args) {

		Circulo circulo = new Circulo(10);
		Cuadrado cuadrado = new Cuadrado(20);

		resultados(circulo);
		resultados(cuadrado);
	}

}</pre><p>Para probar el ejemplo creamos el archivo <code>Test.java</code> donde declaramos el método <code>resultados</code> que tiene como argumento la interfaz <code>Geometria</code> con el nombre figura. Este argumento utiliza los métodos <code>perimetro()</code>, <code>area()</code> y <code>nombre()</code> de las clases <code>Circulo</code> y <code>Cuadrado</code>.</p><p>Ahora compilemos y ejecutemos el ejemplo.</p><pre>> javac -d . *.java
> java org.snippetstricks.oop.Test
Los datos de la figura Circulo son:
El perimetro es: 314.159265
El area es: 62.831853
Los datos de la figura Cuadrado son:
El perimetro es: 400.000000
El area es: 80.000000</pre>]]></content:encoded> <wfw:commentRss>http://snippets-tricks.org/introduccion-intefaces-java/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Práctica N° 7: Copo de nieve</title><link>http://snippets-tricks.org/practica-7-copo-de-nieve/</link> <comments>http://snippets-tricks.org/practica-7-copo-de-nieve/#comments</comments> <pubDate>Fri, 19 Feb 2010 02:31:58 +0000</pubDate> <dc:creator>Alberto</dc:creator> <category><![CDATA[Algoritmos]]></category> <category><![CDATA[Laboratorio]]></category><guid
isPermaLink="false">http://www.luisalberto.org/?p=2157</guid> <description><![CDATA[Próximamente&#8230;
]]></description> <content:encoded><![CDATA[<p>Próximamente&#8230;</p> ]]></content:encoded> <wfw:commentRss>http://snippets-tricks.org/practica-7-copo-de-nieve/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Modelo GtkListStore en C</title><link>http://snippets-tricks.org/modelo-gtkliststore-c/</link> <comments>http://snippets-tricks.org/modelo-gtkliststore-c/#comments</comments> <pubDate>Fri, 27 Nov 2009 04:22:37 +0000</pubDate> <dc:creator>Alberto</dc:creator> <category><![CDATA[C/C++]]></category> <category><![CDATA[Tutorial]]></category><guid
isPermaLink="false">http://www.luisalberto.org/?p=2154</guid> <description><![CDATA[GtkListStore es un modelo para el Widget GtkTreeView que permite almacenar los datos como un arreglo o tabla.
Para crear dicho control debemos crear GtkTreeView y asignarle el modelo de lista. Para crear nuestra lista necesitaremos declarar los siguientes Widgets, variables y un evento./* Declaraciones */
GtkWidget *treeview, *scroll;
GtkListStore *store;
GtkTreeIter iter;
guint i = 0;/* Declaramos el método [...]]]></description> <content:encoded><![CDATA[<p>GtkListStore es un modelo para el Widget GtkTreeView que permite almacenar los datos como un arreglo o tabla.</p><p>Para crear dicho control debemos crear GtkTreeView y asignarle el modelo de lista. Para crear nuestra lista necesitaremos declarar los siguientes Widgets, variables y un evento.<br
/> <span
id="more-2154"></span></p><pre class="brush: cpp; toolbar: false;">/* Declaraciones */
GtkWidget *treeview, *scroll;
GtkListStore *store;
GtkTreeIter iter;
guint i = 0;

/* Declaramos el método para crear las columnas */
static void setup_tree_view (GtkWidget*);</pre><p>Puesto que el Widget GtkListStore se basa en un TreeView debemos crear dicho control especificando las columnas que utilizaremos.</p><pre class="brush: cpp; toolbar: false;">/* Creamos el Widget */
treeview = gtk_tree_view_new();
setup_tree_view(treeview);</pre><p>Para crear una nueva lista utilizamos la función <code>gtk_list_store_new()</code> en donde especificamos la cantidad de columnas y los tipos de datos que almacenarán dichas columnas. En este caso utilizaremos dos columnas del tipo GString.</p><pre class="brush: cpp; toolbar: false;">/* Especificamos que tipos de datos almacenará el Widget */
store = gtk_list_store_new (COLUMNAS, G_TYPE_STRING, G_TYPE_STRING);</pre><p>La variable COLUMNAS la podemos sustituir por el número 2, en este ejemplo utilizamos la siguiente enumeración:</p><pre class="brush: cpp; toolbar: false;">enum {
	SOFTWARE = 0,
	LICENCIAS,
	COLUMNAS
};</pre><p>Puesto que el control que hemos creado en un GtkTreeView, debemos especificar que el control es un GtkListStore. Una vez que especificamos el modelo del Widget podemos agregar los datos con un ciclo. Los datos los tomaremos del arreglo <code>ListaItem lista[]</code>.</p><pre class="brush: cpp; toolbar: false;">/* Especificamos que el Widget es un GtkListStore */
gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (store));
g_object_unref (store);
scroll = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

/* Agregamos los datos */
while (i != 6) {
	gtk_list_store_append (store, &#038;iter);
	gtk_list_store_set (store, &#038;iter, SOFTWARE, lista[i].software, LICENCIAS, lista[i].licencias, -1);
	i++;
}</pre><p>Nuestro código completo queda de la siguiente manera:</p><pre class="brush: cpp">#include &lt;gtk/gtk.h&gt;

enum {
	SOFTWARE = 0,
	LICENCIAS,
	COLUMNAS
};

typedef struct {
	gchar *software;
	gchar *licencias;
} ListaItem;

const ListaItem lista[] = {
	{ "openSUSE", "Software libre" },
	{ "OpenOffice.org", "Software libre" },
	{ "RHLE 5", "Software libre" },
	{ "Microsoft Windows", "Privada" },
	{ "MacOS X", "Privada" },
	{ "Debian", "Software libre" }
};

/* Declaramos el método para crear las columnas */
static void setup_tree_view (GtkWidget*);

static void destroy (GtkWidget*, gpointer);
static gboolean destroy_event (GtkWidget*, GdkEvent*, gpointer);

int main (int argc, char *argv[]) {
	GtkWidget *ventana;

	/* Declaraciones */
	GtkWidget *treeview, *scroll;
	GtkListStore *store;
	GtkTreeIter iter;
	guint i = 0;

	gtk_init (&amp;argc, &amp;argv);

	ventana = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	gtk_widget_set_size_request (ventana, 400, 200);
	gtk_window_set_title (GTK_WINDOW (ventana), "GtkListStore");

	/* Creamos el Widget */
	treeview = gtk_tree_view_new();
	setup_tree_view(treeview);

	/* Especificamos que tipos de datos almacenará el Widget */
	store = gtk_list_store_new (COLUMNAS, G_TYPE_STRING, G_TYPE_STRING);

	/* Especificamos que el Widget es un GtkListStore */
	gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (store));
	g_object_unref (store);
	scroll = gtk_scrolled_window_new (NULL, NULL);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

	/* Agregamos los datos */
	while (i != 6) {
		gtk_list_store_append (store, &amp;iter);
		gtk_list_store_set (store, &amp;iter, SOFTWARE, lista[i].software, LICENCIAS, lista[i].licencias, -1);
		i++;
	}

	gtk_container_add (GTK_CONTAINER (scroll), treeview);
	gtk_container_add (GTK_CONTAINER (ventana), scroll);

	g_signal_connect (G_OBJECT (ventana), "destroy", G_CALLBACK (destroy), NULL);
	g_signal_connect (G_OBJECT (ventana), "destroy_event", G_CALLBACK (destroy_event), NULL);

	gtk_widget_show_all (ventana);
	gtk_main ();

	return 0;
}

/* Agregamos dos columnas: Software y Licencia */
static void setup_tree_view (GtkWidget *treeview) {
	GtkCellRenderer *renderer;
	GtkTreeViewColumn *columna;

	/* Columna 1 */
	renderer = gtk_cell_renderer_text_new();
	columna = gtk_tree_view_column_new_with_attributes("Software", renderer, "text", SOFTWARE, NULL);
	gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), columna);

	/* Columna 2 */
	renderer = gtk_cell_renderer_text_new();
	columna = gtk_tree_view_column_new_with_attributes("Licencia", renderer, "text", LICENCIAS, NULL);
	gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), columna);
}

static void destroy (GtkWidget *window, gpointer data) {
	gtk_main_quit ();
}

static gboolean destroy_event (GtkWidget *window, GdkEvent *event, gpointer data) {
	return FALSE;
}</pre><pre>
$ gcc -Wall -g Lista.c -o Lista `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0`
$ ./Lista</pre><p><img
src="http://netdna.snippets-tricks.org/wp-content/uploads/2009/11/GtkListStore.png" alt="GtkListStore" title="GtkListStore" width="447" height="267" class="aligncenter size-full wp-image-2155" /></p><p>Puedes encontrar más interfaces para utilizar este Widget en <a
href="http://library.gnome.org/devel/gtk/unstable/GtkListStore.html">GtkListStore &#8211; GTK+ Reference Manual</a>.</p> ]]></content:encoded> <wfw:commentRss>http://snippets-tricks.org/modelo-gtkliststore-c/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Mergesort</title><link>http://snippets-tricks.org/mergesort/</link> <comments>http://snippets-tricks.org/mergesort/#comments</comments> <pubDate>Wed, 11 Nov 2009 15:21:50 +0000</pubDate> <dc:creator>Alberto</dc:creator> <category><![CDATA[Algoritmos]]></category> <category><![CDATA[Tutorial]]></category><guid
isPermaLink="false">http://www.luisalberto.org/?p=2142</guid> <description><![CDATA[El algoritmo Mergesort (Ordenamiento por mezcla) es un algoritmo estable y óptimo basado en la técnica divide y vencerás.
Un merge es una operación que combina dos arreglos ordenados en un tercer arreglo ordenado. Por ejemplo, teniendo dos arreglos ordenados 1, 4, 6, 10 y 2, 3, 5, 9 los combinamos y obtenemos el tercer arreglo [...]]]></description> <content:encoded><![CDATA[<p>El algoritmo <em>Mergesort</em> (<em>Ordenamiento por mezcla</em>) es un algoritmo estable y óptimo basado en la técnica divide y vencerás.</p><p>Un <em>merge</em> es una operación que combina dos arreglos ordenados en un tercer arreglo ordenado. Por ejemplo, teniendo dos arreglos ordenados <em>1, 4, 6, 10</em> y <em>2, 3, 5, 9</em> los combinamos y obtenemos el tercer arreglo ordenado <em>1, 2, 3, 4, 5, 6, 9, 10</em>.</p><p>Esta combinación o mezcla es la clave del algoritmo Mergesort.<br
/> <span
id="more-2142"></span></p><h3>Análisis</h3><p>Veamos como se combinan dos secuencias ordenadas utilizando el siguiente arreglo.</p><p><img
src="http://netdna.snippets-tricks.org/wp-content/uploads/2009/11/Arreglo.png" alt="Arreglo" title="Arreglo" width="306" height="34" class="aligncenter size-full wp-image-2143" /></p><p>Comencemos dividiendo el arreglo a ordenar en dos arreglos ordenados como se muestra a continuación.</p><p><img
src="http://netdna.snippets-tricks.org/wp-content/uploads/2009/11/division-merge.png" alt="division-merge" title="division-merge" width="392" height="116" class="aligncenter size-full wp-image-2144" /></p><p>Vemos como los dos arreglos están ordenados, por lo que ahora los podemos combinar o mezclar.</p><p>Tomamos el primer elemento de los dos arreglos y los comparamos (10 y 5). Al ser menor 5 que 10 lo copiamos en el tercer arreglo.</p><p><img
src="http://netdna.snippets-tricks.org/wp-content/uploads/2009/11/mergesort-1.png" alt="mergesort-1" title="mergesort-1" width="392" height="134" class="aligncenter size-full wp-image-2145" /></p><p>Recorremos el segundo arreglo y ahora comparamos los valores 10 y 15. Copiamos el 10 por ser el menor.</p><p><img
src="http://netdna.snippets-tricks.org/wp-content/uploads/2009/11/mergesort-2.png" alt="mergesort-2" title="mergesort-2" width="392" height="130" class="aligncenter size-full wp-image-2146" /></p><p>Recorremos el primer arreglo y ahora comparamos los valores 23 y 15. Copiamos el 15 por ser menor.</p><p><img
src="http://netdna.snippets-tricks.org/wp-content/uploads/2009/11/mergesort-3.png" alt="mergesort-3" title="mergesort-3" width="392" height="130" class="aligncenter size-full wp-image-2147" /></p><p>Nuevamente recorremos el segundo arreglo y comparamos los valores 23 y 55. Copiamos el 23 por ser el menor.</p><p><img
src="http://netdna.snippets-tricks.org/wp-content/uploads/2009/11/mergesort-4.png" alt="mergesort-4" title="mergesort-4" width="392" height="132" class="aligncenter size-full wp-image-2148" /></p><p>Una vez más recorremos el primer arreglo y comparamos los valores 30 y 55. Nuevamente copiamos el menor.</p><p><img
src="http://netdna.snippets-tricks.org/wp-content/uploads/2009/11/mergesort-5.png" alt="mergesort-5" title="mergesort-5" width="392" height="132" class="aligncenter size-full wp-image-2149" /></p><p>Nuevamente recorremos el primer arreglo y comparamos 50 y 55. Bajamos el 50 por ser el menor.</p><p><img
src="http://netdna.snippets-tricks.org/wp-content/uploads/2009/11/mergesort-6.png" alt="mergesort-6" title="mergesort-6" width="392" height="138" class="aligncenter size-full wp-image-2150" /></p><p>Ya hemos copiado todos los elementos del primer arreglo, por lo que solo queda copiar los elementos restantes del segundo arreglo.</p><p><img
src="http://netdna.snippets-tricks.org/wp-content/uploads/2009/11/Mergesort-7.png" alt="Mergesort-7" title="Mergesort-7" width="388" height="182" class="aligncenter size-full wp-image-2151" /></p><p>Esta combinación o mezcla es la clave de este algoritmo. No obstante, las mitades deben ordenarse primero. Para lograr esto, el algoritmo se basa en la estrategia divide y vencerás, por lo que implementa una función recursiva hasta dividir todo el arreglo en un solo elemento.</p><p><img
src="http://netdna.snippets-tricks.org/wp-content/uploads/2009/11/mergesort.png" alt="mergesort" title="mergesort" width="490" height="602" class="aligncenter size-full wp-image-2152" /></p> ]]></content:encoded> <wfw:commentRss>http://snippets-tricks.org/mergesort/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Introducción a LINQ</title><link>http://snippets-tricks.org/introduccion-linq/</link> <comments>http://snippets-tricks.org/introduccion-linq/#comments</comments> <pubDate>Wed, 11 Nov 2009 00:08:52 +0000</pubDate> <dc:creator>Alberto</dc:creator> <category><![CDATA[Base de datos]]></category> <category><![CDATA[Tutorial]]></category><guid
isPermaLink="false">http://www.luisalberto.org/?p=2141</guid> <description><![CDATA[LINQ significa Language-INtegrated Query, Consulta integrada en los lenguajes. Esto quiere decir que es una extensión de C# y Visual Basic.
Antes de LINQ era necesario conocer tres herramientas: C#, SQL y el API de ADO .NET lo cual suele ser molesto. Con LINQ esta tarea se hace más sencilla.
Al programar con un lenguaje orientado a [...]]]></description> <content:encoded><![CDATA[<p>LINQ significa <em>Language-INtegrated Query</em>, Consulta integrada en los lenguajes. Esto quiere decir que es una extensión de C# y Visual Basic.</p><p>Antes de LINQ era necesario conocer tres herramientas: <em>C#, SQL y el API de ADO .NET</em> lo cual suele ser molesto. Con LINQ esta tarea se hace más sencilla.</p><p>Al programar con un lenguaje orientado a objetos es interesante hacer una consulta en la base de datos y cargar los resultados en objetos. LINQ soluciona el problema de mapeo relacional de objetos y simplifica la interacción entre objetos y las fuentes de datos.<br
/> <span
id="more-2141"></span></p><h3>Hola LINQ</h3><p>Veamos dos ejemplos básicos en C# con Mono-Project. En el primer ejemplo consultamos una lista de palabras en un objeto llamado <em>saludo</em> que muestra el tradicional mensaje <em>Hola Mundo!</em>. El segundo ejemplo mostramos como crear una consulta que selecciona las palabras con un máximo de cinco caracteres, las ordena de forma ascendente y las enlista en la consola.</p><p>Primeramente debemos importar la librería Ling de la siguiente manera:</p><pre class="brush: c-sharp">using System.Linq;</pre><h4>Ejemplo 1</h4><pre class="brush: c-sharp">using System;
using System.Linq;

namespace EjemploLinq
{
	class HolaLinq
	{
		[STAThread]
		public static void Main()
		{
			string[] palabras = {"Hola", "mundo", "!"};

			var saludo = from palabra in palabras select palabra;

			foreach (var palabra in saludo)
				Console.Write(palabra + " ");

			Console.WriteLine();
		}
	}
}</pre><pre>$ smcs HelloLinq.cs
$ mono HelloLinq.exe
Hola mundo !</pre><h4>Ejemplo 2</h4><pre class="brush: c-sharp">using System;
using System.Linq;

namespace EjemploLinq
{
	class HolaLinq2
	{
		[STAThread]
		public static void Main()
		{
			string[] palabras = {"programación", "linux", "unix", "mac os x",
						"concurrencia", "abstracción", "mono", "blog",
						"polmorfismo", "herencia", "código", "gnu"};

			var lista = from palabra in palabras
			where palabra.Length &lt;= 5
			orderby palabra ascending
			select palabra;

			foreach (var palabra in lista)
				Console.WriteLine(palabra);
		}
	}
}</pre><pre>$ smcs HelloLinq2.cs
$ mono HelloLinq2.exe
blog
gnu
linux
mono
unix</pre>]]></content:encoded> <wfw:commentRss>http://snippets-tricks.org/introduccion-linq/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Ordenación por Shell</title><link>http://snippets-tricks.org/ordenacion-shell/</link> <comments>http://snippets-tricks.org/ordenacion-shell/#comments</comments> <pubDate>Sun, 01 Nov 2009 02:12:23 +0000</pubDate> <dc:creator>Alberto</dc:creator> <category><![CDATA[Algoritmos]]></category> <category><![CDATA[Tutorial]]></category><guid
isPermaLink="false">http://www.luisalberto.org/?p=2127</guid> <description><![CDATA[Shell Sort ordena pequeños subconjuntos con el método de inserción desde un enfoque divide y vencerás.
Recomiendo dominar el método de Ordenación por Inserción.Análisis
Ordenemos el siguiente grupo de 16 elementos que se muestran a continuación.Los elementos de cada subconjunto se determinan poniendo un valor de intervalo entre los subíndices de cada grupo.
En este ejemplo utilizaremos un [...]]]></description> <content:encoded><![CDATA[<p><em>Shell Sort</em> ordena pequeños subconjuntos con el método de inserción desde un enfoque divide y vencerás.</p><p>Recomiendo dominar el método de <a
href="http://snippets-tricks.org/ordenacion-insercion/">Ordenación por Inserción</a>.<br
/> <span
id="more-2127"></span></p><h3>Análisis</h3><p>Ordenemos el siguiente grupo de 16 elementos que se muestran a continuación.</p><p><img
class="aligncenter size-full wp-image-2112" title="Arreglo" src="http://netdna.snippets-tricks.org/wp-content/uploads/2009/10/Arreglo2.png" alt="Arreglo" width="601" height="38" /></p><p>Los elementos de cada subconjunto se determinan poniendo un valor de intervalo entre los subíndices de cada grupo.</p><p>En este ejemplo utilizaremos un intervalo de 7 elementos.</p><p><img
class="aligncenter size-full wp-image-2113" title="Primer-Subconjunto" src="http://netdna.snippets-tricks.org/wp-content/uploads/2009/10/Primer-Subconjunto.png" alt="Primer-Subconjunto" width="613" height="170" /></p><p>Nuestro primer subconjunto cuenta con tres elementos (<em>95, 20 y 16</em>) que se ordenan con el método de inserción.</p><p>Ahora obtenemos los siguientes tres elementos del segundo subconjunto (<em>25, 54 y 80</em>). Nota que los tres elementos del primer subconjunto ya están ordenados.</p><p><img
class="aligncenter size-full wp-image-2115" title="Segundo-Subconjunto-Ordenado" src="http://netdna.snippets-tricks.org/wp-content/uploads/2009/10/Segundo-Subconjunto-Ordenado.png" alt="Segundo-Subconjunto-Ordenado" width="613" height="164" /></p><p>El segundo subconjunto esta ordenado por lo que no hay intercambio.</p><p>Ahora obtenemos el tercer subconjunto; a partir de el tercer subconjunto todos los subconjuntos tendrán dos elementos.</p><p><img
class="aligncenter size-full wp-image-2121" title="Tercer-Subconjunto-Ordenado" src="http://netdna.snippets-tricks.org/wp-content/uploads/2009/10/Tercer-Subconjunto-Ordenado.png" alt="Tercer-Subconjunto-Ordenado" width="611" height="320" /></p><p>Nuevamente los elementos del tercer subconjunto se ordenan con el método de inserción. Estas acciones se repiten con todos los subconjuntos y al final el conjunto queda de la siguiente manera:</p><p><img
class="aligncenter size-full wp-image-2123" title="Subconjunto-Semiordenado" src="http://netdna.snippets-tricks.org/wp-content/uploads/2009/10/Subconjunto-Semiordenado.png" alt="Subconjunto-Semiordenado" width="610" height="80" /></p><p>Ahora vamos a recorrer de nuevo todo el conjunto, pero usaremos un intervalo de 3. Solo habrá tres subconjuntos, el primero con seis valores (<em>16, 60, 68, 83, 63 y 80</em>), el segundo subconjunto tiene los valores () y el tercer subconjunto tiene ().</p><p><img
class="aligncenter size-full wp-image-2126" title="Primer-Subconjunto-3" src="http://netdna.snippets-tricks.org/wp-content/uploads/2009/10/Primer-Subconjunto-3.png" alt="Primer-Subconjunto-3" width="611" height="342" /></p><p>Al final obtenemos el siguiente conjunto semiordenado.</p><p><img
class="aligncenter size-full wp-image-2125" title="Subconjunto-Semiordenado-2" src="http://netdna.snippets-tricks.org/wp-content/uploads/2009/10/Subconjunto-Semiordenado-2.png" alt="Subconjunto-Semiordenado-2" width="610" height="79" /></p><p>Finalmente utilizamos un intervalos de 1; en otras palabras, utilizamos el ordenamiento por inserción en todo el conjunto.</p><p><img
class="aligncenter size-full wp-image-2128" title="Conjunto-Ordenado" src="http://netdna.snippets-tricks.org/wp-content/uploads/2009/10/Conjunto-Ordenado.png" alt="Conjunto-Ordenado" width="610" height="76" /></p><h3>Código de la función</h3><p>Nuestra función queda de la siguiente manera.</p><pre class="brush: cpp">
void shell(int array[], int size)
{
	int i, j, intervalo, temp;

	intervalo = size/2;

	while (intervalo &gt; 0) {
		for (i=intervalo; i &lt; size; i++) {
			j = i;
			temp = array[i];
			while ((j &gt;= intervalo) &amp;&amp; (array[j - intervalo] &gt; temp)) {
				array[j] = array[j - intervalo];
				j = j - intervalo;
			}
			array[j] = temp;
		}

	intervalo /= 2;
	}
}
</pre><h3>Código completo</h3><p>Ahora probemos la función con un arreglo.</p><pre class="brush: cpp">#include &lt;iostream&gt;

using namespace std;

void shell(int array[], int size)
{
	int i, j, intervalo, temp;

	intervalo = size/2;

	while (intervalo &gt; 0) {
		for (i=intervalo; i &lt; size; i++) {
			j = i;
			temp = array[i];
			while ((j &gt;= intervalo) &amp;&amp; (array[j - intervalo] &gt; temp)) {
				array[j] = array[j - intervalo];
				j = j - intervalo;
			}
			array[j] = temp;
		}

	intervalo /= 2;
	}
}

int main (int argc, char *argv[])
{
	int numeros[] = {95, 25, 83, 97, 71, 18, 68, 20, 54, 40, 60, 27, 63, 96, 16, 80};

	/* Imprimimos el arreglo original */
	for (int i = 0; i &lt; 16; ++i) {
		cout &lt;&lt; numeros[i] &lt;&lt; " ";
	}

	cout &lt;&lt; endl;

	shell(numeros, 16);

	/* Imprimimos el arreglo ordenado */
	for (int i = 0; i &lt; 16; ++i){
		cout &lt;&lt; numeros[i] &lt;&lt; " ";
	}

	cout &lt;&lt; endl;
}
</pre><pre>
$ g++ -o ShellSort ShellSort.cpp
$ ./ShellSort
95 25 83 97 71 18 68 20 54 40 60 27 63 96 16 80
16 18 20 25 27 40 54 60 63 68 71 80 83 95 96 97</pre>]]></content:encoded> <wfw:commentRss>http://snippets-tricks.org/ordenacion-shell/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Errores de programación</title><link>http://snippets-tricks.org/errores-programacion/</link> <comments>http://snippets-tricks.org/errores-programacion/#comments</comments> <pubDate>Fri, 16 Oct 2009 02:46:02 +0000</pubDate> <dc:creator>Alberto</dc:creator> <category><![CDATA[Programación]]></category> <category><![CDATA[Tutorial]]></category><guid
isPermaLink="false">http://www.luisalberto.org/?p=2111</guid> <description><![CDATA[A la hora de programar es común encontrarse con errores en el código y en software, incluso después de ser publicados.
Para evitar esto, es necesario hacer diferentes pruebas, pero no creo que importe cuantas de ellas se hagan, en algún momento el sistema necesitará revisiones.
Entre los errores de programación encontraremos: Errores de sintaxis, Errores de [...]]]></description> <content:encoded><![CDATA[<p>A la hora de programar es común encontrarse con errores en el código y en software, incluso después de ser publicados.</p><p>Para evitar esto, es necesario hacer diferentes pruebas, pero no creo que importe cuantas de ellas se hagan, en algún momento el sistema necesitará revisiones.</p><p>Entre los errores de programación encontraremos: <em>Errores de sintaxis</em>, <em>Errores de ejecución</em> y <em>Errores lógicos</em>.<br
/> <span
id="more-2111"></span></p><h3>Errores de sintaxis</h3><p>Los <em>errores de sintaxis</em> son los primeros errores con los que nos encontraremos, ya que se presentan cuando no se usa correctamente la gramática del lenguaje de programación.</p><p>Un ejemplo claro es el omitir el cierre del bloque de código con <em>&#8216;}&#8217;</em> en el caso de los lenguajes de programación que ocupan las laves.</p><p>Pero existe la ventaja de que todos los compiladores actuales dan un aviso de error en el momento de invocarlos y no permitirán la compilación hasta que se corrijan todos los errores de sintaxis.</p><p>Entre los errores más comunes encontramos:</p><ul><li>No declarar e iniciar una variable.</li><li>Repetir la declaración de alguna variable.</li><li>Omitir las llaves que engloban los bloques de código.</li><li>No devolver algún valor a las funciones (NO procedimientos).</li><li>Escribir mal el nombre de alguna variable, función o procedimientos.</li></ul><h3>Errores en tiempo de ejecución</h3><p>Los <em>errores en tiempo de ejecución</em> se presentan cuando el programa esta en marcha. Estos errores provocan que el sistema operativo o la biblioteca que se utilizo para su desarrollo envíe un mensaje de error y detenga su ejecución.</p><p>Para evitar estos errores se deben programar excepciones. Las excepciones capturan el error y permiten ejecutar otras instrucciones alternas para que el programa siga su ejecución.</p><p>Los errores más comunes son:</p><ul><li>División entre cero.</li><li>Índice de arreglos fuera de los límites.</li></ul><h3>Errores lógicos</h3><p>Los <em>errores lógicos</em> se presentan cuando el analista ha cometido un error en el diseño de alguna función o cuando ejecuta un algoritmo de forma incorrecta.</p><p>Estos errores se hacen visibles al finalizar la ejecución del programa puesto que los resultados son incorrectos. Por lo tanto, si el programador no conoce el resultado correcto será difícil de encontrar.</p><p>Para encontrarlos y corregirlos es necesario tener casos de prueba para comparar los resultados.</p> ]]></content:encoded> <wfw:commentRss>http://snippets-tricks.org/errores-programacion/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Introducción a la Minería de datos</title><link>http://snippets-tricks.org/introduccion-mineria-datos/</link> <comments>http://snippets-tricks.org/introduccion-mineria-datos/#comments</comments> <pubDate>Tue, 13 Oct 2009 02:45:57 +0000</pubDate> <dc:creator>Alberto</dc:creator> <category><![CDATA[Base de datos]]></category> <category><![CDATA[Tutorial]]></category><guid
isPermaLink="false">http://www.luisalberto.org/?p=2107</guid> <description><![CDATA[La minería de datos es el proceso de análisis para hallar estructuras de datos útiles para intentar descubrir patrones.
En otras palabras, la minería de datos busca el conocimiento en las bases de datos.Aplicaciones de la minería de datos
La información encontrada tiene muchas aplicaciones. Un ejemplo claro es el PageRank de Google. Podemos encontrar algunas aplicaciones [...]]]></description> <content:encoded><![CDATA[<p>La minería de datos es el proceso de análisis para hallar estructuras de datos útiles para intentar descubrir patrones.</p><p>En otras palabras, la minería de datos busca el conocimiento en las bases de datos.<br
/> <span
id="more-2107"></span></p><h3>Aplicaciones de la minería de datos</h3><p>La información encontrada tiene muchas aplicaciones. Un ejemplo claro es el PageRank de Google. Podemos encontrar algunas aplicaciones en <a
href="http://es.wikipedia.org/wiki/Miner%C3%ADa_de_datos#Ejemplos_de_uso_de_la_miner.C3.ADa_de_datos">Wikipedia</a>.</p><h4>Google PageRank</h4><p>¿Recuerdas como eran los buscadores antes de Google?. Para encontrar la información que requeríamos era necesario navegar entre las páginas de un directorio; si no sabíamos como buscar un libro en la biblioteca entonces no sabíamos buscar en Internet.</p><div
id="attachment_2108" class="wp-caption aligncenter" style="width: 438px"><img
src="http://netdna.snippets-tricks.org/wp-content/uploads/2009/10/yahoo-1995.png" alt="Página principal de Yahoo! en 1995, ¿La recuerdas?" title="yahoo-1995" width="428" height="411" class="size-full wp-image-2108" /><p
class="wp-caption-text">Página principal de Yahoo! en 1995, ¿La recuerdas?</p></div><p>Los chicos de Google (Larry Page y Sergey Brin), en la Universidad de Stanford se dedicaron a descargar páginas web y almacenarlas en una base de datos. En poco tiempo se dieron cuenta de que necesitaban una gran computadora ya que la cantidad de paginas almacenadas era enorme.</p><p>Una vez que tuvieron esa gran base de datos pusieron en práctica la minería de datos y encontraron un patrón. Con dicho patrón de datos se dieron cuenta de que hay cierto numero de sitios web que enlazan a un sitio web.</p><p>En la siguiente figura podemos ver como existen muchos sitios web que enlazan al sitio web <em>B</em>.</p><div
id="attachment_2109" class="wp-caption aligncenter" style="width: 410px"><img
src="http://netdna.snippets-tricks.org/wp-content/uploads/2009/10/pagerank.png" alt="Imagen obtenida en Wikipedia" title="pagerank" width="400" height="323" class="size-full wp-image-2109" /><p
class="wp-caption-text">Imagen obtenida en {link:http://es.wikipedia.org/wiki/PageRank}Wikipedia{/link}</p></div><p>Ellos analizaron esa información y esas páginas que recibían muchos enlaces y se dieron cuenta de que dichas páginas contenían la información que el usuario buscaba. Y en base a esto diseñaron el algoritmo para generar el valor que actualmente se le conoce como PageRank.</p><p>Una vez programado el algoritmo lo pusieron a prueba y se dieron cuenta de que mostraba resultados relevantes.</p><p>Y esto fue gracias a la minería de datos.</p> ]]></content:encoded> <wfw:commentRss>http://snippets-tricks.org/introduccion-mineria-datos/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Práctica N° 6: Valor Máximo, Mínimo y Media</title><link>http://snippets-tricks.org/practica-6-maximo-minimo-media/</link> <comments>http://snippets-tricks.org/practica-6-maximo-minimo-media/#comments</comments> <pubDate>Mon, 12 Oct 2009 20:27:14 +0000</pubDate> <dc:creator>Alberto</dc:creator> <category><![CDATA[Algoritmos]]></category> <category><![CDATA[Laboratorio]]></category><guid
isPermaLink="false">http://www.luisalberto.org/?p=2104</guid> <description><![CDATA[Elaborar tres funciones en C++ para buscar el valor máximo, mínimo y la media de un conjunto de números enteros y positivos.
Teniendo un conjunto de números ordenados, sabemos que la media es el valor que deja el mismo número de datos antes y después que él.Análisis
Considerando el siguiente conjunto de números enteros y positivos:
Determinamos que [...]]]></description> <content:encoded><![CDATA[<p>Elaborar tres funciones en C++ para buscar el valor máximo, mínimo y la media de un conjunto de números enteros y positivos.</p><p>Teniendo un conjunto de números ordenados, sabemos que la media es el valor que deja el mismo número de datos antes y después que él.<br
/> <span
id="more-2104"></span></p><h3>Análisis</h3><p>Considerando el siguiente conjunto de números enteros y positivos:</p> <img
src='http://s.wordpress.com/latex.php?latex=33%2C%20703%2C%204%2C%2011%2C%202%2C%208%2C%2020%2C%2010&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='33, 703, 4, 11, 2, 8, 20, 10' title='33, 703, 4, 11, 2, 8, 20, 10' class='latex' /><p>Determinamos que el valor máximo es <em>703</em>; el valor mínimo es <em>2</em> y la media es <em>10</em>.</p><h3>Solución</h3><h4>Máximo</h4><p>Para obtener el valor máximo del conjunto, es necesario recorrer todo el arreglo y comparar sus elementos y asignar el valor más grande a la variable <em>m</em>.</p><pre class="brush: cpp">int maximo (int conjunto[], int size) {
	int m = 0;

	for (int i = 1; i &lt; size; i++) {
		if (conjunto[i] &gt; conjunto[m]) {
			m = i;
		}
	}

	return conjunto[m];
}</pre><h4>Mínimo</h4><p>Para determinar el valor mínimo solo tenemos que cambiar el signo <em>&gt;</em> por <em>&lt;</em>.</p><pre class="brush: cpp">int minimo(int conjunto[], int size) {
	int m = 0;

	for (int i = 1; i &lt; size; i++) {
		if (conjunto[i] &lt; conjunto[m])
			m = i;
	}

	return conjunto[m];
}</pre><h4>Media</h4><p>La mediana es el valor de la variable que deja el mismo número de datos antes y después que él estando los datos ordenados.</p><pre class="brush: cpp">int media (int conjunto[], int size) {
	int i = 0;
	int j = 0;
	int m = 0;
	int count = 0;

	for (; (j &lt; size) &amp;&amp; (count != size/2); j++) {
		count = 0;
		m = j;

		for (i = 0; i &lt; size; i++) {
			if (conjunto[i] &gt; conjunto[m])
				count++;
		}
	}

	return conjunto[m];
}</pre><h3>Código completo</h3><pre class="brush: cpp">#include &lt;iostream&gt;

using namespace std;

int minimo(int conjunto[], int size) {
	int m = 0;

	for (int i = 1; i &lt; size; i++) {
		if (conjunto[i] &lt; conjunto[m])
			m = i;
	}

	return conjunto[m];
}

int maximo (int conjunto[], int size) {
	int m = 0;

	for (int i = 1; i &lt; size; i++) {
		if (conjunto[i] &gt; conjunto[m]) {
			m = i;
		}
	}

	return conjunto[m];
}

int media (int conjunto[], int size) {
	int i = 0;
	int j = 0;
	int m = 0;
	int count = 0;

	for (; (j &lt; size) &amp;&amp; (count != size/2); j++) {
		count = 0;
		m = j;

		for (i = 0; i &lt; size; i++) {
			if (conjunto[i] &gt; conjunto[m])
				count++;
		}
	}

	return conjunto[m];
}

int main (int argc, char *argv[])
{
	int conjunto[] = {33,703,4,11,2,8,20,10};

	cout &lt;&lt; minimo(conjunto, 8) &lt;&lt; endl;
	cout &lt;&lt; maximo(conjunto, 8) &lt;&lt; endl;
	cout &lt;&lt; media(conjunto, 8) &lt;&lt; endl;
}</pre><pre>
$ g++ -o Conjunto Conjunto.cpp
$ ./Conjunto
2
703
10
</pre>]]></content:encoded> <wfw:commentRss>http://snippets-tricks.org/practica-6-maximo-minimo-media/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> </channel> </rss>
<!-- This site's performance optimized by W3 Total Cache. Dramatically improve the speed and reliability of your blog!

Learn more about our WordPress Plugins: http://www.w3-edge.com/wordpress-plugins/

Minified using disk
Page Caching using disk (user agent is rejected)
Database Caching 10/13 queries in 0.011 seconds using memcached
Content Delivery Network via netdna.snippets-tricks.org

Served from: plus.snippets-tricks.org @ 2010-03-10 17:05:08 -->