El Acueducto de Segovia

jueves, 9 de agosto de 2007

Segovia es una ciudad bulliciosa, como en cualquier otra, coches, niños, y paseantes llenan sus calles de vida y caos. Filas de japoneses cargados con sus cámaras y ropas estrafalarias nos hacen recordar que también somos extraños en aquel lugar. Sus antiguos restaurantes despiden un exquisito olor a carne recién hecha que llama nuestra atención, más tarde tendremos que visitarlos.

Mientras caminamos, vamos buscamos en el cielo una señal que nos indique donde se encuentra el edificio que estamos buscando. Poco a poco, al recorrer la calle, aparece ante nosotros el enorme acueducto. Una mole piedra cargada de energía que da la sensación de haber sido colocada allí sin tener el cuenta el resto de edificio. Como si fuera un ‘collage’, da la sensación de no encajar con lo que le rodea. Pero transmite al observador una gran fuerza al contemplarlo

Dice la leyenda que los constructores del acueducto no fueron los romanos, sino la pereza de una joven aguadora, harta de arrastrar el cántaro por las empinadas calles de la ciudad, llegó a un pacto con el diablo: el se quedaría con el alma de la mujer si, antes de que cantara el gallo, el agua llegaba hasta la puerta de su casa. Cuando cayó la noche, una gran tormenta se cernió sobre la ciudad. Sólo la muchacha sabía que no era una simple tormenta, sino el mismo diablo cumpliendo lo que ella le había pedido. Sin embargo, se arrepintió y rezó hasta la extenuación para evitar el cumplimiento del pacto. De pronto, el
gallo cantó y el Maligno se dio cuenta de que, por una sola piedra sin colocar, había perdido el alma.

La muchacha confesó su culpa ante los segovianos que, tras rociar con agua bendita los arcos para eliminar el rastro de azufre, aceptaron felices el nuevo perfil de la ciudad. Convencidos de que había sido un milagro que la muchacha escapara de las garras del diablo, se ordenó colocar una imagen de la virgen y de San Esteban en las hornacinas del acueducto.

Aun así, se dice que en las piedras todavía quedan las marcas de los dedos del maligno como testigo de su obra.

[Fuente: Wikipedia]

Numero de campos con valor null en una tabla

viernes, 18 de mayo de 2007

Me surgió el problema de que tenia que contar el numero de campos con valores null en una tabla y se me ocurrió este pequeño truco:


selec
(isnull(cast(campo1 as int) * 0 ,1)) +
(isnull(cast(campo2 as int) * 0 ,1)) +
(isnull(cast(campo3 as int) * 0 ,1)) +
(isnull(cast(campo4 as int) * 0 ,1)) as numeroDeNulls
from miTabla


Esto se pude hacer si los campos son datetime o numéricos, en el caso de cadenas hay que cambiarlos a:

(isnull(len(ltrim(rtrim(campo1)))) * 0 ,1)


Que ademas nos cuenta como nula la cadena vacía ;)

Eternity II, el juego de los 2M$

martes, 8 de mayo de 2007

En el mes de Julio sale a la venta sale un nuevo juego, Eternity II, que puede hacerte ganar mucho dinero o perder el tiempo.

Esta compuesto por un tablero de 16x16 cuadrados de lado y 256 fichas. Cada una de ellas tiene cuadro lados de colores en los que hay dibujada una figura. No se sebe el numero de colores ni de figuras aunque se estima que cada ficha es diferente. Para solucionarlo hay que colocar las 256 fichas en el tablero de manera que las fichas adyacentes contengan en los lados que quedan pegados la misma figura y color. Las fichas pueden rotarse y solo contienen dibujo por una de sus caras.

Existen 56 fichas con un lado gris, cuya posición en el tablero esta restringida a los bordes y 4 fichas con 2 lados grises q forman las esquinas.

Al parecer la solución es única (que me permito dudarlo) y habrá un total de 3 pistas, 2 fichas de las que nos indicaran su posición tras resolver los puzzles de 6x6 y 6x12 y una que ya viene dada.

Podéis encontrar mas información en la pagina web oficial y en algunas otras relacionadas [web oficial] [noticia en microsiervos] [solucion de eternity I]

La aproximación más sencilla para resolver el puzzle parece a simple vista utilizando un ordenador, aunque generar todas las posibles combinaciones de fichas en el tablero podría llevar años con un supercomputador. Así que como primera aproximación al algoritmo de resolución propongo los siguientes pasos:


Generar los posibles laterales del puzzle utilizando un algoritmo de vuelta atrás (backtracking) cuyo esquema general seria el siguiente:


PRODEDURE ResuelveLateral(tablero)
REPEAT
SeleccionarNuevaFichaGiro
IF Valida THEN
AnotarFichaGiro
IF NOT LateralCompleto THEN
ResuelveLateral(tablero_siguiente)
CancelarAnotacion
ELSE
AlmacenarSolucion
END
END
UNTIL (ultimaFichaGiro)
END resuelveLateral


Basado en los ejemplos del libro de la asignatura Análisis y Diseño de Algoritmos (una de mis favoritas): "Técnicas de diseño de algoritmos, Rosa Guerequeta García y Antonio Vallecillo Moreno, Universidad de Málaga"

Una vez generados todos los posibles laterales del puzzle tratar de resolver un cuadrado de pequeñas dimensiones (8x8) formado por la única ficha conocida y todos los posibles laterales, para un cuadrado de 8x8 (que hemos generado previamente).

El algoritmo de resolución de este cuadrado sigue el esquema del anterior pero seria un poco mas complejo.

Una vez calculados todos los posibles cuadrados volveríamos a realizar el algoritmo para el resto de cuadrados (cuadrantes del puzzle), partiendo como base de todas las posibilidades ya generadas.

La división del problema (cuadrado de 16x16) en problemas mas pequeños (cuadrados de 8x8) nos permitiría una resolución distribuida del problema, pudiendo utilizar varios miles ordenadores para resolver el problema, algo parecido al programa SETI@HOME. Aunque con tanto dinero de por medio, habría mas problemas que soluciones.

Paginacion con cakePHP 1.2

lunes, 19 de marzo de 2007

Aunque salio hace ya algun tiempo, a principios de febrero, acabo de empezar a probar cakePHP 1.2, la nueva versión de este framework que por fin incluye algunas de las funcionalidades mas demandas. Las novedades son:



  • Nuevos validadores

  • FormHelper mejorado y extendido

  • EmailComponent

  • SecurityComponent: Ahora con soporte para HTTP_AUTH a través de la variable $requireLogin.

  • Nuevo formato CTP que sustituye al thtml

  • Paginación

  • Extensiones Url

  • Model Behaviors

  • Datasources

  • i18N y l10N: Localizacion e Internacionalización


Podéis encontrar una definición un poco mas detallada en quarkblog


De todas estas las que mas me han interesado han sido la paginación (la echaba en falta después de trabajar con .net) y la internacionalización. Deseoso de probarlas busque documentación al respecto y no he encontrado nada, o prácticamente nada en Español y muy escasos documentos en Ingles.


Asi que aquí dejo un pequeño tutorial sobre paginación en cakePHP. Lo primero de todo es descargar esta versión desde cakeforge y configurar la base de datos. (Supongo que se sabe como instalar y configurar cakePHP, por si acaso:[1] [2] [3])


También crearemos una tabla de ejemplo e insertaremos algunos datos:


CREATE TABLE `posts` (
`id` int(5) NOT NULL auto_increment,
`title` varchar(255) collate latin1_general_ci NOT NULL default '',
`content` text collate latin1_general_ci NOT NULL,
`created` datetime default NULL,
`modified` datetime default NULL,
PRIMARY KEY (`id`)
);

INSERT INTO `posts` VALUES (1, 'Titulo del post 1 ',  'Contenido del post 1', '2007-03-18 23:07:58', '2007-03-18 23:07:58');
INSERT INTO `posts` VALUES (2, 'Titulo del post 2', 'Contenido del post 2', ' 2007-03-18 23:06:57', '2007-03-18 23:06:57');
INSERT INTO `posts` VALUES (3, 'Titulo del post 3', 'Contenido del post 3', '2007-03-18 23:08:19', '2007-03-18 23:08:19');
INSERT INTO `posts` VALUES (4, 'Titulo del post 4 ', 'Contenido del post 4', '2007-03-18 23:07:58', '2007-03-18 23:07:58');

Creamos el modelo y el controlador, usando scaffolding para no complicarnos mucho.


/app/models/post.php


            class Post  extends AppModel
{
var $name = 'Post';
}

/app/controllers/post_controller.php


            class  PostsController extends AppController
{
var $name = 'Posts';
var $scaffold;

var $helpers = array('Html','Paginator'); // estos los usaremos mas adelante.
}

Una vez hecho esto podemos observar en nuestro equipo que http://localhost/tutorial/post/ ya incluye la paginación. Lo único que haremos será reescribir el método ‘index’ con las mismas funcionalidades para aprender como realizar esta.


Añadimos al fichero ‘post_controller.php’ las siguientes lineas:


            function  index()
{
$this->set('data', $this->paginate());
}

¿Hay una manera mas sencilla de paginar los registros? $this->paginate() realiza la misma funcion que findAll() pero paginando los registros.


Y creamos la vista ‘posts/index.ctp’ que se encargara de mostrar la información.


<h2>Listado de Posts</h2>
<p><?php echo $paginator->counter(array('format' => 'Pagina %page% de %pages%, mostrando %current% registros de %count%')); ?></p>
<p><?php echo 'Ordenado por:'. $paginator-> sortKey() . ' ' . $paginator-> sortDir(); ?></p>
<table class="scaffold" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th><?php echo $paginator->sort('Id','id'); ?></th>
<th><?php echo $paginator->sort('Titulo','title'); ?></th>
<th>Contenido</th>
<th>Acciones</th>
</tr>
</thead>
<tbody>
<!--<?php print_r($data); ?>-->
<?php
$i = 0;
if(is_array($data)) {
foreach ($data as $row) {

$id = $row['Post']['id'];
$title = $row['Post']['title'];
$content = $row['Post']['content'];

if($i++ % 2 == 0) {
echo '<tr>';
} else {
echo '<tr class="altrow">';
}
?>
<td>
<?php echo $html->link($id, array('action' => 'view', $id));?>
</td>
<td>
<?php echo $html->link($title, array('action' => 'view', $id));?>
</td>
<td>
<?php echo $html->link($content, array('action' => 'view', $id));?>
</td>
<td>
<?php echo $html->link('Ver', array('action' => 'view', $id));?>
<?php echo $html->link('Editar', array('action' => 'edit', $id));?>
<?php echo $html->link('Borrar', array('action' => 'delete', $id),null,
sprintf("¿Estas seguro de querer borrar el post: '%s'?", $title));?>
</td>
<?php } ?>
</tr>
<?php } ?>
</tbody>
</table>
<div class="paging">
<?php echo $paginator->prev('<< Anterior', array(), null, array('class'=>'disabled'));?>
|
<?php echo $paginator->next('Siguiente >>', array(), null, array('class'=>'disabled'));?>
</div>
<div class="actions">
<ul>
<li>
<?php echo $html->link('Nuevo Post', array('action' => 'add')); ?>
</li>
</ul>
</div>

Esta vista esta basada en cake\libs\view\templates\scaffolds\index.thtml que es la que usa cakePHP por defecto si definimos la variable $scaffold.

Lo mas interesante es el uso de las siguientes funciones:




$paginator->sort(texto_a_mostrar,campo)

Crea un enlace gracias al cual podemos ordenar automaticamente los datos

$paginator->counter(array('format' => 'Pagina %page% de %pages%, mostrando %current% registros de %count%'))

Permite definir frases mostrando una serie de variables que se detellan a continuacion:


%page% => Pagina actual

%pages% => Total de paginas

current% => Registros mostrados

%count% => Total de registros

%start% => Primer registro de la pagina

%end% => Ultimo registro de la pagina

$paginator->prev('<< Anterior', array(), null, array('class'=>'disabled'))

$paginator->next('Siguiente >>', array(), null, array('class'=>'disabled'))

Devuelven un enlace a la pagina siguiente y anterior respectivamente.

$paginator->sortKey()

$paginator->sortDir()

Devuelven el campo por el que se esta ordenando y la direccion.


Como hemos incluido pocos registros, no podemos ver nuestra paginación funcionando aunque si la ordenación por columnas. Vamos a limitar el numero de registros por pagina para poder ver los resultdos paginados. Para ello incluimos la linea:

var $paginate = array('limit' =>  2, 'order' => array('Post.created' => 'desc'));


Con ella definimos el número de registros por pagina y la ordenación inicial que queremos en nuestros datos.


¡¡¡Ya podemos ver nuestra paginación funcionando!!!

cakePHP: Aplicaciones 'bipolares' usando "beforeRender()"

viernes, 2 de marzo de 2007

Hoy me siento orgulloso de mi mismo, por fin tengo algo que escribir aquí.

Llevo unos días trabajando con PHP para un proyecto de la facultad, y después de trabajar con .net para aplicaciones web volver a un lenguaje de script se me antojaba un poco difícil. Al menos con he encontrado un framework sencillo de utilizar y aunque le faltan muchas características por implementar hay que tener en cuenta que esta todavía en desarrollo. Acaban de sacar la versión 1.2alfa. Este framework es cakePHP, mas info aquí, aquí y aquí.

Buscando información para documentarme he encontrado este blog coderbattery con algunos posts interesantes. No me considero un entendido en cakePHP, mas bien un aprendiz, pero me aventuro a mejorar una de las soluciones que proponen para ‘aplicaciones web bipolares’. El problema esta muy bien explicado en post y por lo tanto os remito a el [Aplicaciones “bipolares” con CakePHP].

La solución propuesta pasa por modificar appController. Incluyendo el siguiente código que modifica el layout por defecto dependiendo del dominio desde el que estamos accediendo:


class AppController extends Controller {
/* Constructor que determina el dominio
y en base a eso usa el layout correspondiente */
function __construct() {
parent::__construct();

// Determinar layout por defecto
if(ereg('dominio1',$_SERVER['SERVER_NAME'])) {
// Estamos en el primer dominio
$this->layout = 'dominio1_layout';
} else {
// Estamos en el segundo dominio
$this->layout = 'dominio2_layout';
}
}
...
}

Pero se presenta el problema que en aquellos controladores que no utilicen el layout por defecto hemos de incluir el siguiente código:

class LoginController extends AppController {
// Constructor para evitar el layout default
function __construct() {
parent::__construct();

if(ereg('dominio1',$_SERVER['SERVER_NAME'])) {
$this->layout = 'dominio1_login';
} else {
$this->layout = 'dominio2_login';
}
}
...
}


Esto provoca la repetición de código complicando las cosas si decidimos cambiar de dominio o incluir alguno mas pues nos veremos obligados a modificar bastantes ficheros si nuestra aplicación es compleja. Buscando un poco he encontrado la función beforeRender() de la clase Controller que se ejecuta justo antes de aplicar la el layout. Por lo tanto mi propuesta es incluir el siguiente código en el AppController:


class AppController extends Controller {
/* Determina el dominio y en base a eso usa el layout correspondiente */
function beforeRender(){
// Determinar layout por defecto
if(ereg('localhost',$_SERVER['SERVER_NAME'])) {
// Estamos en el primer dominio
$this->layout = 'dominio1_'.$this->layout;
} else {
// Estamos en el segundo dominio
$this->layout = 'dominio2_'.$this->layout;
}
}
...
}


Con esto nos ahorramos tener que incluir el código en cada controlador que no utilice el layout por defecto. Por supuesto también tiene inconvenientes y es que tendremos que crear, al menos en mi caso, los layout ‘dominio1_ajax.thtml’ y ‘dominio2_ajax.thtml’ y es probable que también alguno mas.

Supervivencia

lunes, 26 de febrero de 2007

Es lo que nunca entiendo de la gente. Se asombran tanto cuando uno mata a otro, pero esta en nuestra naturaleza. ¿Crees que descendemos de tres tipos en una cueva compartiendo su búfalo? No. Descendemos del cuarto que tomo un palo y dijo:
"Si los muelo a palos, tendré mas carne para mi"
Nuestro ancestro es ese. Eso es supervivencia.


Sheriff Tom Underlay, Invasion

El niño esta dando sus primeros pasos...

domingo, 25 de febrero de 2007

Bueno algún día tenia que suceder, era inevitable, la tentacion de tener un blog era demasiado grande como para sortearla durante mucho tiempo. Como dijo Oscar Wilde:

"Puedo resistirlo todo menos la tentación "

Ahora empiezan los problemas... ¿sobre que escribo?