jueves, 27 de septiembre de 2012

Android: Nombres código de los Sistemas Operativos



Quizás muchos estén familiarizados ya con los nombres tan llamativos que se le designan a las versiones de los distintos sistemas operativos de Android. Pero si son tan despistados como quien escribe en este blog, tal vez no habrán notado el patrón que siguen estos particulares nombres código.

Para los que sí ponen atención, sabrán que las distintas versiones de Android son nombradas a partir de nombres de bocadillos dulces: Cupcake, Donut, Éclair, Froyo, Gingerbread, Honeycomb, Ice Cream Sandwich, Jelly Bean. Para los aún más observadores, ya se dieron cuenta que cada uno de los postres lleva   un orden alfabético que comienza a partir de la letra C.

Android 1.5 - Cupcake
Android 1.6 - Donut
Android 2.0 - Éclair
Android 2.1 - Éclair
Android 2.2 - Froyo
Android 2.3 - Gingerbread
Android 3.0 - Honeycomb
Android 4.0 - Ice Cream Sandwich
Android 4.1 - Jelly Bean

En cuanto a por qué comienza con la letra C, y dónde están los snacks con A y B, muchos podrían pensar que se debe a la típica denominación en el mundo del software como Alfa y Beta. Pero parece que antes de Cupcake, simplemente las versiones tenían nombre aburridos con códigos alfa numéricos y por tanto comenzaron a utilizar nombres código más fáciles de recordar como se acostumbra en los proyectos tecnológicos.

lunes, 24 de septiembre de 2012

POO: Pilares de la programación orientada a objetos



En un libro aprendí un tip bastante útil para recordar los pilares de la programación orientada a objetos. Solo hay que recordar el acrónimo: PIE. En las entrevistas es muy típico que se pregunte alguno de los principios de la programación orientada a objetos. Si se pregunta de manera general, se puede dar una buena impresión explicando cada uno de los pilares de manera elocuente.

Polymorphism (Poliformismo): la habilidad de una variable de un tipo específico de ser usada para referenciar objetos de diferentes tipos, y automáticamente llamar el método que es específico al tipo del objeto que la variable referencia. El beneficio del poliformismo es que resulta fácil agregar nuevas clases de objetos derivados sin quebrar el código invocador. En cortas palabras, cuando se invoca un método de un objeto sin saber su tipo específico, y sucede lo correcto, a eso llamamos poliformismo. Ejemplo:

public void printArea(Figure figure) {
   System.out.println(figure.getArea());
}

Figure figure = new Square(); // Square extends from Figure
printArea(figure); // Should print axa (a=side of a square);

Inheritance (Herencia): Este debería ser el principio más fácil de explicar. Consiste en incluir el comportamiento (métodos) y estado (variables) de una clase base, en una clase derivada. El beneficio principal de la herencia es que provee un mecanismo formal para la reutilización de código.

Encapsulation (Encapsulación): Se refiere a mantener todos los miembros relacionados (variables y métodos) juntos en un objeto. Los objetos deben ocultar la funcionalidad que es interna del mundo exterior. Esto se realiza al declarar ciertos métodos y variables como privadas en la clase. La buena encapsulación mejora la modularidad del código al prevenir que los objetos interactuen entre sí de maneras insospechadas, lo cual hace más fácil futuros desarrollos y refactorizaciones más sencillas.

jueves, 20 de septiembre de 2012

Resaltador de sintaxis para el blog actualizado

Acaba de actualizar mi resaltador de sintaxis ya que estaba bastante obsoleto. Sigo usando el mismo resaltador, solo que ahora uso la versión más actual aprovechando el hosting de los scripts que provee el autor Alex Gorbatchev.

Estas son las líneas que agregué en el HTML de la plantilla de Blogger (incluye un arreglo de CSS para Chrome):
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeFadeToGrey.css' rel='stylesheet' type='text/css'/>
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shLegacy.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPhp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'/>

<style type='text/css'>
.syntaxhighlighter table td.gutter .line {
 padding: 0 5px  !important;
}
</style>

<script language='javascript'>
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.all();
dp.SyntaxHighlighter.HighlightAll('code');
</script>
</body>
</html>

miércoles, 19 de septiembre de 2012

CakePHP: Plugin para subir imágenes

Al fin pude descifrar una manera de subir imágenes en CakePHP 2.0. Probé este plugin de Jose Gonzalez y me funcionó adecuadamente. Puedo subir imágenes que se guardan en una estructura de carpetas fácilmente consultable por el identificador del modelo que se guarda en la base de datos. A parte genera los thumbnails en los tamaños que uno le defina.

Estos fueron los pasos que seguí:

1. Bajar el plugin.Se puede descargar el zip o bajar el código del repositorio de GitHub.

2. Se copia el código en la carpeta /app/Plugin/Upload (dejar la carpeta renombrada con Upload u otro nombre más amigable).

3. Se edita el "bootstrap.php" (/app/Config/) agregando la línea para habilitar el plugin:
CakePlugin::load('Upload');

4. En la base de datos, en la tabla donde se guarda la referencia a la foto, agregamos dos columnas: una para el identificador de la foto, y otra para el identificador del directorio:

CREATE TABLE  `mi_db`.`anuncios` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `titulo` varchar(45) NOT NULL,
  `id_foto` varchar(15) DEFAULT NULL,
  `dir` varchar(250) DEFAULT NULL,
)

5. En el modelo se configura las opciones para la subida de la imagen:

class Anuncio extends AppModel {
     
    public $actsAs = array(
        'Upload.Upload' => array(
            'id_foto' => array(
                'fields' => array(
                    'dir' => 'dir'
                ),                
                'thumbnailSizes' => array(
      'big' = '200x200',
                    'small' =>'120x120',
                    'thumb' =>'80x80'
                ),
                'thumbnailMethod'=> 'php'
            )
        )
    );
}

Observese que se configura los nombre de las columnas que configuramos en la tabla de nuestra base de datos, los tamaños de los thumbnails, y el método para crear los thumbnails (aquí uso php pues es una extensión que viene ya instalado por defecto en la mayoría de los ambientes de desarrollo tipo WAMP).

 6. Agrego el código de la vista:

<?php
 echo $this->Form->create('Anuncio', array('type' => 'file'));
 echo $this->Form->input('id_foto', array('type' => 'file', 'label' => 'Foto'));
 echo $this->Form->input('dir', array('type' => 'hidden'));
 echo $this->Form->end('Guardar Anuncio');
?>

7. ¡Listo! Las imágenes son guardadas dentro de 'webroot/files' (la ruta se puede configurar).


viernes, 14 de septiembre de 2012

Carga selectiva de JavaScript acorde con el Navegador

Interesante problema para resolver. Una funcionalidad de una página especifica no funciona apropiadamente en Chrome al parecer por la versión 1.7 de JQuery. La solución más sencilla es actualizar el sitio con la versión 1.8. Sin embargo por razones de tiempo y presupuesto, cambiar la versión de JQuery involucra probar el sitio de nuevo para validar que ninguna otra funcionalidad con dependencias de JQuery no se vieron afectadas.

La solución planteada entonces es cargar la versión 1.8 solamente en esa página, únicamente cuando el usuario usa el navegador Chrome. Para lograr esto hice un experimento primero (valga la nota de que deben haber soluciones más elegantes a esta) de colocar ambas versiones de JQuery en el HEAD para validar cuál versión de JQuery se utiliza si las dos están cargadas en la página. Algo así como determinar cuál es el orden de precedencia cuando hay funciones repetidas en dos scripts. Al parecer se invoca la última versión que se declara en el código.

Validado este experimento, programé un pequeño código, que con la ayuda de Yepnope, inyecto la versión 1.8 de JQuery cuando el navegador es Chrome.


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
 <script src="yepnope.1.5.4-min.js" type="text/javascript"></script>
 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js" type="text/javascript"></script>
</head>
<body>
<script type="text/javascript"> 
 $(document).ready(function() { 
  $.browser.chrome = /chrome/.test(navigator.userAgent.toLowerCase()); 

  if($.browser.chrome){
   yepnope.injectJs("http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js", function () {
    alert ("JQuery Version: " + $().jquery);
   });   
  } else {
   alert ("JQuery Version: " + $().jquery);
  }
 });  
</script>
</body>
</html>

Corremos el script en FireFox:


Corremos el Script en Chrome: