miércoles, 8 de junio de 2011

jCombo - Combos Anidados con jQuery PHP y MySQL

¿Que es un combo anidado?

Un combo anidado son listas desplegables de opciones en donde una depende de la otra en forma de cascada, lo que quiere decir que al seleccionar un elemento de una lista, la otra lista se debe modificar inmediatamente. Normalmente encontramos estos combos en los formularios donde tenemos que seleccionar un pais, luego una region y finalmente una ciudad o provincia. Y todo esto sin tener que volver a cargar la página gracias a AJAX.

¿Y como se implementa?

Para implementarlo se deben hacer llamadas a través de un objeto ajax en el lado del cliente, recibir la peticion, procesarla y convertirla en un elemento "SELECT" dentro de nuestro formulario, sin embargo aqui les dejo la manera simple de hacerlo, solo tienen que utilizar jquery dentro de su formulario, incluyen el plugin y realizan las llamadas de la siguiente manera:

$("select[name='country']").jCombo("getCountries.php");

o

$('#ciudades').jCombo("getEstados.php?id=", {

parent: "#estados", // select del cual dependemos

initial_text: "-- Favor Seleccione --", // texto inicial

selected_value: "5" // valor por defecto para seleccionar

});


Para ver a mas detalle acerca de su uso, la documentación necesaria y descarga del plugin deben revisar este sitio:
http://www.prodiven.com/jcombo

martes, 15 de marzo de 2011

Tips en Apache para mejorar tu servidor web

Algunos tips para configurar Apache y mejorar el rendimiento. Lo que todo desarrollador debe saber.

1. Prevenir el Hotlinking

¿Estás cansado de que la gente utilice tu ancho de banda poniendo las imágenes albergadas en tu servidor en su sitio web? Añade el siguiente código al final de tu archivo .htaccess para prevenir el hotlinking:


1. Options +FollowSymlinks
2. #Protect against hotlinking
3. RewriteEngine On
4. RewriteCond %{HTTP_REFERER} !^$
5. RewriteCond %{HTTP_REFERER} !^http://(www.)?nombrededominio.com/ [nc]
6. RewriteRule .*.(gif|jpg|png)$ http://nombrededominio.com/img/no_robar_ancho_de_banda.gif[nc]

2. Bloquea todas las peticiones del user-agent

Es posible bloquear a todos los user-agents indeseados que pueden ser potencialmente dañinos o quizá simplemente para mantener la carga del servidor lo más baja posible.


1. #Block bad bots
2. SetEnvIfNoCase user-Agent ^FrontPage [NC,OR]
3. SetEnvIfNoCase user-Agent ^Java.* [NC,OR]
4. SetEnvIfNoCase user-Agent ^Microsoft.URL [NC,OR]
5. SetEnvIfNoCase user-Agent ^MSFrontPage [NC,OR]
6. SetEnvIfNoCase user-Agent ^Offline.Explorer [NC,OR]
7. SetEnvIfNoCase user-Agent ^[Ww]eb[Bb]andit [NC,OR]
8. SetEnvIfNoCase user-Agent ^Zeus [NC]
9.
10. Order Allow,Deny
11. Allow from all
12. Deny from env=bad_bot

3. Redirecciona a todos, excepto a ciertas IPs

Si por alguna razón deseas denegar el acceso a todos los usuarios o sólo permitir a un cierto grupo de direcciones IP para que tengan acceso a tu sitio, añade el siguiente código a tu archivo .htaccess:


1. ErrorDocument 403 http://www.nombrededominio.com
2. Order deny,allow
3. Deny from all
4. Allow from 124.34.48.165
5. Allow from 102.54.68.123

4. Redirecciones 301 amigables con SEO

Si has transferido nombres de dominio o deseas redireccionar a una página específica sin que afecte a los resultados de los motores de búsqueda como Google, utiliza el siguiente código:


1. Redirect 301 /d/file.html http://www.nombrededominio.com/r/file.html

5. Crea una página personalizada para cada tipo de error

Si te cansaste del diseño por defecto de las páginas de error 401, 403, 404, 500, etc. puedes fácilmente crear la tuya propia y referirte hacía ella de esta forma:


1. ErrorDocument 401 /error/401.php
2. ErrorDocument 403 /error/403.php
3. ErrorDocument 404 /error/404.php
4. ErrorDocument 500 /error/500.php


6. Crea una lista de IPs prohibidas

¿Te cansaste de obtener siempre los mismos comentarios de ciertos usuarios una y otra vez? Simplemente prohíbe el acceso a determinadas IPs, añadiendo el siguiente código:


1. allow from all
2. deny from 145.186.14.122
3. deny from 124.15

7. Setea una dirección de e-mail por defecto para el administrador de servidor

Con el siguiente código puedes especificar la dirección de correo electrónico por defecto para el administrador de servidor:


1. ServerSignature EMail
2. SetEnv SERVER_ADMIN default@dominio.com

8. Deshabilita la ventana de aviso de descarga

Usualmente al descargar algo de un sitio web, saltará una ventana que pregunta si deseas abrir el archivo o guardarlo en tu PC. Para prevenir esto, utiliza el siguiente código:


1. AddType application/octet-stream .pdf
2. AddType application/octet-stream .zip
3. AddType application/octet-stream .mov

9. Protege un archivo específico

El código que sigue te permite denegar el acceso a cualquier archivo que desees, mostrando una página de error 403 cuando alguien intenta acceder al mismo:


1. #Protect the .htaccess File
2.
3. order allow,deny
4. deny from all


10. Comprime componentes con mod_deflate

Como alternativa a la compresión de archivos mediante Gzip, puedes implementar mod_deflate (que se supone es más rápido). Coloca el siguiente código en la parte superior de tu archivo .htaccess:


1. SetOutputFilter DEFLATE

11. Agrega headers de expiración a los archivos

El siguiente código muestra cómo agregar fechas de expiración en las cabeceras de los archivos:


1. Header set Expires "Wed, 21 May 2010 20:00:00 GMT"

12. Seteando la página por defecto

Puedes hacer que la página a mostrar ni bien un usuario llegue a tu sitio no sea la archiconocida "index". Aquí seteamos "about.html" como página de inicio:


1. #Serve Alternate Default Index Page
2. DirectoryIndex about.html


13. Proteje tus archivos y directorios con una contraseña


1. #proteger un archivo con contraseña
2.
3. AuthType Basic
4. AuthName "Prompt"
5. AuthUserFile /home/path/.htpasswd
6. Require valid-user
7.
8.
# proteger un directorio con contraseña
9. resides
10. AuthType basic
11. AuthName "This directory is protected"
12. AuthUserFile /home/path/.htpasswd
13. AuthGroupFile /dev/null
14. Require valid-user

14. Hacer una redirección 301 de un dominio viejo a uno nuevo

Incluyendo este snippet en el .htaccess de tu viejo dominio, conseguirás redigir a otro nuevo (sin ser penalizado por Google por duplicar contenido, dado que el 301 es un aviso de "redirección permanente"):


1. # Redirigir de un dominio viejo a uno nuevo
2. RewriteEngine On
3. RewriteRule ^(.*)$ http://www.nuevodominio.com/$1 [R=301,L]

15. Forzar el cacheo

El siguiente snippet no va a incrementar directamente la velocidad de carga de tu sitio en general, pero sí va a cargar más rápido cuando el mismo usuario vuelva a visitarlo al enviar un status 304 cuando se pidan elementos que no han sido modificados. Puedes cambiar la frecuencia de cacheo al cambiar el número de segundos (en este ejemplo se da una vez al día):


1. FileETag MTime Size
2. ExpiresActive on
3. ExpiresDefault "access plus 86400 seconds"

16. Comprimir componentes al activar Gzip

Esto hace que sea más rápida la carga de tu sitio:


1. AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/javascript text/css application/x-javascript
2. BrowserMatch ^Mozilla/4 gzip-only-text/html
3. BrowserMatch ^Mozilla/4.0[678] no-gzip
4.
5. BrowserMatch bMSIE !no-gzip !gzip-only-text/html

17. Quitar palabras o strings de una URL

En este ejemplo, quitaremos "category" de nuestras URL, es decir: http://tudominio.com/category/blue -> http://tudominio.com/blue

Agrega este código al final de tu .htaccess:


1. RewriteRule ^category/(.+)$ http://www.tudominio.com/$1 [R=301,L]

18. Deshabilitar la navegación por los directorios de tu sitio


1. Options All -Indexes

19. Redirigir los Feeds de WordPress a FeedBurner


1. #Redirect wordpress content feeds to feedburner
2.
3. RewriteEngine on
4. RewriteCond %{HTTP_USER_AGENT} !FeedBurner [NC]
5. RewriteCond %{HTTP_USER_AGENT} !FeedValidator [NC]
6. RewriteRule ^feed/?([_0-9a-z-]+)?/?$ http://feeds.feedburner.com/tufeed [R=302,NC,L]

20. Remover la extensión del archivo de una URL

Para que sea más amigable al usuario y a los buscadores, por ejemplo "http://www.tudominio.com/autos.html" -> "http://www.tudominio.com/autos"


1. RewriteRule ^(([^/]+/)*[^.]+)$ /$1.php [L]

21. Quitar el "www" del dominio


1. #remove www from URI
2. RewriteEngine On
3. RewriteCond %{HTTP_HOST} ^www\.dominio\.com$ [NC]
4. RewriteRule ^(.*)$ http://dominio.com/$1 [L,R=301]

miércoles, 12 de enero de 2011

Lo mejor del Iphone 5


Como es usual Apple tomó la decisión de agregar fascinantes caracteristicas en la nueva generación del IPhone. Ha adquirido a la compañia Polar Rose, conocida por su tecnología de reconocimiento facial FaceLib, el cual predomina sobre otros productos similares.

Con una detección total del rostro y seguimiento de caras en un video, las soluciones Polar Rose podrian cambiar la manera de interactuar con el iPhone. ahora que el iPhone 4 tiene una camara frontal, el bloqueo por contraseña terminará siendo una antiguedad.

Imagina que levantes tu iPhone y automaticamente te aparece la pantalla de inicio. El truco es que tu iPhone no hará esto para nadie mas. Si el software en el iPhone reconoce tu rostro, reemplazara la contraseña. Algunas nuevas patentes reveladas de Apple indican que el iPhone podrá reconocer la forma de tu mano, que podria reemplazar también la contraseña de cuatro digitos.

Otros usos interesantes de esta tecnología incluyen etiquetado automático de personas en fotos y reconocimiento a través de la libreta de contactos. Se podrian utilizar varios algoritmos que analicen y organicen las fotos automaticamente por tipo o grupos de personas.

iPhoto actualmente reconoce rostros en fotos para propósitos de etiquetado. Es posible que Apple esté tratando de mejorar y expandir esta funcionalidad. Polar Rose eliminó su servicio de etiquetado para Facebook y Flickr recientemente, enfocando su interés en compañias grandes que requieran su tecnología. Sin embargo Apple no ha confirmado su adquisición de Polar Rose.

martes, 11 de enero de 2011

8 queens (problema de las 8 reinas php)

Aqui les dejo un problema de backtracking para aquellos entusiastas de la programación, se trata de un problema clásico que consiste en ordenar 8 reinas en un tablero de ajedrez de manera que no coincidan lineal o diagonalmente. El algoritmo busca todas las soluciones posibles y se puede parametrizar para diferentes tipos de tablero. Debe ser probado con un N<=25 para no elevear drásticamente el coste computacional.

<>
<>
<>
< ?php

/*************************************************************************
*
* This algorithm solves the 8 queens problem using backtracking.
* Please try with N<=25 * * * *************************************************************************/ class Queens { var $size; var $arr; var $sol; function Queens($n = 8) { $this->size = $n;
$this->arr = array();
$this->sol = 0;
// Inicialiate array;
for($i=0; $i<$n; $i++) { $this->arr[$i] = 0;
}
}

function isSolution($n) {
for ($i = 0; $i < $n; $i++) { if ($this->arr[$i] == $this->arr[$n] ||
($this->arr[$i] - $this->arr[$n]) == ($n - $i) ||
($this->arr[$n] - $this->arr[$i]) == ($n - $i)) return false;
}
return true;
}

function PrintQueens() {
echo("solution #".(++$this->sol)."\n");
for ($i = 0; $i < $this->size; $i++) {
for ($j = 0; $j < $this->size; $j++) {
if ($this->arr[$i] == $j) echo("& ");
else echo(". ");
}
echo("\n");
}
echo("\n");
}


// backtracking Algorithm
function run($n = 0) {
if ($n == $this->size) $this->PrintQueens();
else {
for ($i = 0; $i < $this->size; $i++) {
$this->arr[$n] = $i;
if ($this->isSolution($n)) $this->run($n+1);
}
}
}

}

$myprogram = new Queens(8);
$myprogram->run();

? >
< /pre>
< /body>
< /html>

lunes, 16 de agosto de 2010

Windows Live Mail Offline Instaler

Microsoft no ha ido al CES a anunciar hardware sino principalmente software, y dos han sido las novedades principales que Steve Ballmer ha desvelado en su presentación. Una de ellas es que Windows Live Essentials ya está disponible en su versión final para descarga. Aqui les dejo la versión completa del instalador offline.

Los programas que puedes descargar incluyen:

Todo en un solo sitio
Obtén varias cuentas de correo electrónico en un solo programa: Hotmail, Gmail, Yahoo!*, etc. Y ahora Windows Live Mail también tiene un calendario. Mail combina la facilidad de uso de Outlook Express con la velocidad de Windows Live.


Exprésate en un blog
Writer te facilita el compartir fotos y vídeos en prácticamente en todos los servicios de blog: Windows Live, Wordpress, Blogger, Live Journal, TypePad, etc.


De tu cámara a Internet
Con Galería fotográfica, es muy sencillo llevar tus fotos y vídeos de la cámara al equipo. Busca tus fotos favoritas y compártelas con tus amigos y familiares. Puedes mejorar el aspecto de tus fotos e incluso crear asombrosas panorámicas.


¡Silencio, cámara y acción!
Crea películas y presentaciones a partir de tus fotos y vídeos, y compártelas con tus amigos y familiares.*



Ayuda a proteger a tus hijos en línea
Con Protección familiar, tú decides la experiencia de tus hijos en Internet. Limita las búsquedas, supervisa y bloquea o permite sitios web y decide con quién se pueden comunicar tus hijos en Windows Live Spaces, Messenger o Hotmail.*



Permanece conectado a Windows Live
Con Windows Live Toolbar, siempre obtendrás acceso rápido a Windows Live y Bing desde cualquier lugar de Internet en el que te encuentres.

enlace de descarga:

http://wl.dlservice.microsoft.com/download/D/8/A/D8A4AE91-3CA6-4F37-8988-1C0D91E4A7A7/es/wlsetup-all.exe

martes, 20 de julio de 2010

Combos Anidados con JQuery

Hay muchas maneras de crear combos anidados a través de javascript (ajax), aunque muchas veces necesitamos hacerlo de manera eficiente. Aqui propongo una manera donde los combos se cargan rápidamente a través de un servicio Json. El ejemplo tipico es elegir un Estado geográfico y que al seleccionarlo aparezcan las Ciudades asociadas a este Estado.

Lo primero que hacemos es crear el servicio del lado del servidor, donde el código quedaría mas o menos asi:

archivo: "./servicios/json.getCiudades.php"

// Conectarse a la base de datos

$option='[';
if($_GET['id'] && is_numeric($_GET['id'])) {
$result=mysql_query("select id_ciudad,nombre_ciudad from ciudades where id_estado='".$_GET['id']."'");
if($result && mysql_num_rows($result)>0) {
$error = false;
while ($row = mysql_fetch_array($result))
{
$option.= '{ "valor": "'.$row[0].'", "texto": "'.$row[1].'"}, ';
}
$option = substr( $option , 0, -2);
}
mysql_close();
}
$option=$option.']';
header('Content-Type: text/html; charset=ISO-8859-1');
echo($option);


Tambien podriamos utilziar una función de PHP llamada json_encode() para convertir un objeto directamente al formato JSON, sin embargo las primeras versiones de PHP no disponen nativamente de esta función. La razón de utilizar JSON es que puede ser convertido directamente en un objeto de javascript a través de una evaluación directa en el código.

Del lado del cliente, crearemos dos combos llamados ciudad y estado, de esta manera:


< html>...
< body>...
< form>...
< select name="estado" id="estado>< /select>
< select name="ciudad" id="estado>< /select>
< /form>
< /body>
< /html>


Luego incrustamos un bloque JQUERY para poder generar las ciudades dependientes del Estado seleccionado. Lo podriamos insertar directamente despues de la etiqueta body o donde sea mas cómodo. El código quedaría de esta manera:


< script type="text/javascript">
$(function() {
$("select#estado").change(function(){
$.ajax({
url: "./servicios/json.getCiudades.php?id=" + $(this).val(),
type: "GET",
dataType: "json",
error: function() {
alert("hay un error en el servicio de datos");
return false;
},
success: function(j) {
var opciones = '';
for (var i = 0; i < j.length; i++)
opciones += '';
$("#ciudad").html(opciones);
}
});
});

});
< /script>


Y listo!, con este código estamos invocando al script en PHP que trae las ciudades según el código de estado y las renderizamos directamente del lado del cliente dentro del combo ciudades. Observarán que la formación del combo de ciudades es casi instantáneo.

jueves, 1 de julio de 2010

Numeros primos en Java

Los números primos a lo largo del tiempo ha sido una de las ramas más complejas de la matemática. Poseen muchas aplicaciones prácticas debido a sus propiedades de números verdaderamente "únicos", asi como es el caso de la criptografía asimétrica por ejemplo. Pero uno de los problemas que ha tenido la humanidad desde sus inicios es determinar una función eficiente que genere estos números con un bajo costo computacional. Aqui escribo 5 versiones de funciones para cálcular números primos, en orden de rapidez y con un algoritmo que se encarga de medir el tiempo de ejecucion para numeros relativamente grandes.


public class Main {
private static long tiempomin=0;
private static int ganador = -1;

public static class Cronometro {
long t0;
public Cronometro() {
t0 = System.currentTimeMillis();
}
public long Parar() {
return (System.currentTimeMillis()-t0);
}
}

public static boolean esPrimo1(long n) {
if(n < 2) return false;
if(n < 4) return true;
for (long i = 2; i <= n; i++) if (n%i == 0) return false;
return true;
}

public static boolean esPrimo2(long n) {
if(n < 2) return false;
if(n < 4) return true;
for (long i = 2; i <= (long) Math.sqrt(n); i++) if (n%i == 0) return false;
return true;
}

public static boolean esPrimo3(long n) {
if(n< 2) return false;
if(n< 4) return true;
for (long i = 2; i*i <= n; i++) if (n%i == 0) return false;
return true;
}

public static boolean esPrimo4(long n) {
long nPrueba;
long nLimite;
if(n%2==0) return false;
nPrueba = 3;
nLimite = n;
while(nLimite > nPrueba) {
if(n%nPrueba==0) return false;
nLimite = n/nPrueba;
nPrueba += 2;
}
return true;
}

public static void Invocar(int nFuncion, long max) {
long enc=0;
if(ganador< 0) System.out.println("Se inicia el conteo para n=" + max + "...");
Cronometro reloj = new Cronometro();
long t2=0;
switch(nFuncion) {
case 1: for(long i=0; i <= max; i++) if(esPrimo1(i)) enc++; break;
case 2: for(long i=0; i <= max; i++) if(esPrimo2(i)) enc++; break;
case 3: for(long i=0; i <= max; i++) if(esPrimo3(i)) enc++; break;
case 4: for(long i=0; i <= max; i++) if(esPrimo4(i)) enc++; break;
}
t2 = reloj.Parar();
if(tiempomin==0 || t2< tiempomin) { tiempomin = t2; ganador = nFuncion; }
System.out.println("esPrimo" + nFuncion + "(1..n) " + t2 + " ms (" + enc + " numeros primos encontrados)");
}

public static void main(String[] args) {
int nfunciones = 4;
long maximo = 6000000;
for(int i=2; i <= nfunciones; i++) Invocar(i,maximo);
System.out.println("La funcion ganadora es esPrimo" + ganador + "() con " + tiempomin + " ms!!");
}

}