Noticias Weblogs Foros Wiki Código
Sponsors:

Meta-Info

¿Que es?

Planeta Código es un agregador de weblogs sobre programación y desarrollo en castellano. Si eres lector te permite seguirlos de modo cómodo en esta misma página o mediante el fichero de subscripción.

rss subscripción

Sponsors

Anunciarse aquí

PlanetaCódigo en inglés

Puedes utilizar las siguientes imagenes para enlazar PlanetaCodigo:
planetacodigo

planetacodigo

Si tienes un weblog de programación y quieres ser añadido aquí, envíame un email solicitándolo.

Idea: Juanjo Navarro

Diseño: Albin

Navegapolis

Presentación de Scrum + XP

Marzo 31st, 2007 - [Enlace local]

pptEl mes pasado José Manuel impartió en la Universidad Pontificia de Salamanca un curso de programación de videojuegos para móviles, que arrancó con una presentación de las metodologías ágiles Scrum y XP.
JM trabaja como ingeniero de software en unkasoft , empresa que emplea ambas metodologías, y tras el curso comenta en su blog :

Es divertido ver la cara de poker que pone alguien que acaba de estudiar "Ingeniería de Software II", cuando escuchan que las metodologías ágiles echan por tierra todas esas viejas ideas...

Pero recordad lo más importante: no os dejéis engañar, ni por los "clásicos", ni por los "ágiles". Cada proyecto debe buscar su propio equilibrio entre metodologías ágiles y clásicas (o formales). Habrá proyectos exitosos ágiles, y proyectos formales igual de exitosos, y eso no significa que unos sean unos inconscientes y otros unos carcas.


Esta es la presentación a la que desde Navegapolis contribuimos con el material que pudimos facilitarle.

Blogalaxia Tags: Presentación Scrum

» Leer más, comentarios, etc...

Buayacorp

La Universidad

Marzo 31st, 2007 - [Enlace local]

La Universidad debiera insistirnos en lo antiguo y en lo ajeno. Si insiste en lo propio y lo contemporáneo, la Universidad es inútil porque está ampliando una función que ya cumple la prensa — Jorge Luis Borges. (1899-1986) Escritor argentino.

» Leer más, comentarios, etc...

Buayacorp

Problemas de seguridad con Wordpress 2.x y el plugin pagebar

Marzo 31st, 2007 - [Enlace local]

Debido a unos cambios hechos en la función get_pagenum_link de las ramas 2.0 y 2.1 de Wordpress, varios blogs que usan el plugin pagebar son vulnerables a XSS.

Si alguno de ustedes usa el mencionado plugin y se muestra algún mensaje con la siguientes direcciones URL, entonces necesitan modificar ciertas cosas:

code:
http://tublog.com/index.php?"><script>alert(/XSS/)</script><&paged=2
http://tublog.com/index.php/"><script>alert(/XSS/)</script><&paged=2 
 

Para corregir el problema descrito en el plugin pagebar, tienen que escapar el valor devuelto por get_pagenum_link con las funciones attribute_escape o clean_url. Por si alguien desea, puede bajar la versión modificada o aplicar el parche que corrige estos problemas.

» Leer más, comentarios, etc...

Variable not found, 0:1

Restricción de tipos en generics (C#)

Marzo 31st, 2007 - [Enlace local]

Una particularidad interesante en la declaración de los generics en C# es la posibilidad de establecer limitaciones en los tipos utilizados como parámetros de las plantillas. Paradójico pero cierto, el propio lenguaje facilita la creación de clase genéricas que no lo sean tanto.

Para verle el sentido a esto, utilicemos el siguiente ejemplo, aparentemente correcto:


public class Seleccionador<Tipo>
{
public Tipo Mayor(Tipo x, Tipo y)
{
int result = ((IComparable)x).CompareTo(y);
if (result > 0)
return x;
else
return y;
}
}

Se trata de una clase genérica abierta, cuya única operación (Mayor(...)) permite obtener el objeto mayor de los dos que le pasemos como parámetros. El criterio comparativo lo pondrá la propia clase sobre la que se instancie la plantilla: los enteros serán según su valor, las cadenas según su orden alfabético, etc.

A continuación creamos dos instancias partiendo de la plantilla anterior, y concretando el generic a los tipos que nos hacen falta:

Seleccionador<int> selInt = new Seleccionador<int>();
Seleccionador<string> selStr = new Seleccionador<string>();

Estas dos instanciaciones son totalmente correctas, ¿verdad? Si después de ellas usamos el siguiente código:

Console.WriteLine(selInt.Mayor(3, 5));
Console.WriteLine(selStr.Mayor("X", "M"));

Obtendremos por consola un 5 y una X. Todo correcto, aparece, para cada llamada, la conversión a cadena del objeto mayor de los dos que le hayamos enviado como parámetros.

El problema aparece cuando instanciamos la clase genérica para un tipo que no implementa IComparable, que se utiliza en el método Mayor para determinar el objeto mayor de ambos. En este caso, se lanza una excepción en ejecución indicando que el cast hacia IComparable no puede ser realizado, abortando el proceso. Por ejemplo:

public class MiClase // No es comparable
{
}
[...]
Seleccionador<MiClase> sel = new Seleccionador<MiClase>();
MiClase x1 = new MiClase();
MiClase x2 = new MiClase();
Console.WriteLine(selString.Mayor(x1, x2)); // Excepción,
// no son
// comparables!


Una posible solución sería, antes del cast a IComparable en el método Mayor(), hacer una comprobación de tipos y realizar el cast sólo si es posible, pero, ¿y qué hacemos en caso contrario? ¿devolver un nulo? La pregunta no creo que tenga una respuesta sencilla, puesto que en cualquier caso, se estarían intentado comparar dos objetos que no pueden ser comparados.

La solución óptima, como casi siempre, es controlar en tiempo de compilación lo que podría ser una fuente de problemas en tiempo de ejecución. La especificación de C# 2.0 incluye la posibilidad de definir constraints o restricciones en la declaración de la clase genérica, limitando los tipos con los que el generic podrá ser instanciado. Y, además, de forma bastante simple, nada más que añadir en la declaración de la clase Seleccionador la siguiente cláusula where:


public class Seleccionador
where Tipo: IComparable // !Sólo comparables!
{
public Tipo Mayor(Tipo x, Tipo y)
[...]

Justo a partir de ese momento, el intento de instanciar el Seleccionador utilizando MiClase o cualquier otro tipo que no implemente IComparable, generará un error en tiempo de compilación.

» Leer más, comentarios, etc...

MadeInFlex

Qué viene con Moxie?

Marzo 31st, 2007 - [Enlace local]


Que se está trabajando en la nueva versión de Flex no es ninguna novedad. De hecho, ya hay diferentes artículos que esbozan algunas de las caracterísitcas que va a tener la tercera versión de Flex ( aka Moxie ).

Quizás, la entrada que ofrece información más actualizada sea ésta:

Brief on Moxie

En resumen, podemos ver que se está trabajando intensivamente en:

  • Características para dotar de más expresividad a nuestros diseños
  • Mejor integración con el Creative Suite
  • Mejor integración con Apollo
  • Un profiler para estudiar el rendimiento y uso de memoria de nuestra aplicación Flex
  • Mejora en la integración y uso de módulos
  • Mejora en la velocidad de compilación incremental
  • Wizards para ayudar a migrar a desarrolladores Web hacia Flex
  • Seguiremos informando de cualquier detalle que vaya surgiendo entorno a Moxie.

    » Leer más, comentarios, etc...

    Ingenieria de Software / Software Engineering

    UML : Estados y Superestados

    Marzo 31st, 2007 - [Enlace local]



    Muy bien explicado en el blog de Tyner Blain el uso de estados y superestados el cual es explicado a travès de un ejemplo de ordenes de compra. Aqui el artìculo.

    » Leer más, comentarios, etc...

    BLOG - 3wstudio.com.ar

    Clases dinámicas en Flash

    Marzo 31st, 2007 - [Enlace local]

    En el post anterior vimos que la clase Array es una clase dinámica. ¿Pero que significa eso?

     

    Una clase en actionscript puede ser dinámica o no dinámica. Una clase dinámica permite que se le creen métodos y atributos en tiempo de ejecución (cuando se corre la aplicación). Las clases no dinámicas no lo permiten.

     

    Para indicar que una clase es dinámica debemos utilizar el modificador dynamic

    dynamic class miClase{
    }
     

     

    Las clases heredadas de clases dinámicas también son dinámicas, salvo las heredadas de la clase MovieClip que no lo son (aunque las podemos definir manualmente como dinámicas).

     

    En flash por ejemplo las clases Array y MoviClip son clase dinámicas. Otras como la clase Math no lo son.

     

    Profundicemos un poquito en las clases de Flash.... 

    Las clases Array, MovieClip, TextField, Sound, Number, Color, XML, entre otras son las clases de nivel superior (primitivas) que provee el flash. Una clase primitiva es una clase que se la puede utilizar sin necesidad de incluirla (por medio de include o #include) y vendrian a ser los tipos de datos que maneja el flash de forma nativa (asi como el int, float o char lo son para el C/C++ ).

     

    Estas clases provienen de la aplicación de flash del estándar internacional ECMAScript (ECMA-262) edición 3. El estándar ECMAScript es algo asi como una norma para definir la sintaxis que debe tener un lenguaje. Si mal no recuerdo Javascript utiliza el mismo estándar y Java utiliza uno similar.

     

    No se puede dejar de mensionar que en flash también podemos encontrar los paquetes de clases display, external, filters, geom entre otras. La diferencia de éstas con respecto a las de nivel superior es que hay que incluirlas en la aplicación por medio de include.

     

    Je, podemos ver que esto de las clases y la OOP es todo un mundo lleno de sorpresas. Ya de a poco se va  ir armando un manual de OOP tanto de teoria como de practica sobre AS 2.0/3.0, PHP 4/5, JS (y mootools). 

     

    Saludos!

    » Leer más, comentarios, etc...

    Buayacorp

    Ejercicio de fin de Semana: Evitar SQL Injection con PHP

    Marzo 31st, 2007 - [Enlace local]

    A través de tweako (visto hace algunos minutos en menéame) llegué a un artículo -en inglés- que explica como protegerse de ataques de Inyección de SQL con PHP. En el mencionado artículo, en la última parte aparecen las siguientes dos porciones de código:

    php:
    <?php
     
    # Ok, so I'm going to oversecure a query to the database that selects an article 
    # by using the given article ID. 
    # Here is the code.
     
    //Database connection is present
    //Make sure that the id is actually given
     
    if (isset($_GET['id']))
    {
    	$id = $_GET['id'];
    }
    else
    {
    	die('Please provide an article ID');
    }
     
    //Make sure that its an integer
    if (is_integer($id))
    {
    	die('Please enter a valid article ID');
    }
     
    //Validate that its in between the ranges 1 and 10,000
    if ($id < 1 || $id > 10000)
    {
    	die('Please enter a valid artile ID');
    }
     
    //Construct the query
    $SQL = "SELECT * FROM posts WHERE postID = '".$id."'";
     
    echo $SQL; // Línea agregada
     
    ?>
    php:
    <?php
     
    # This next one will validate a username before its entered into the database.
     
    //Database connection is present
    //Make sure that the id is actually given
    if (isset($_GET['username']))
    {
    	$username = $_GET['username'];
    }
    else
    {
    	die('Please provide a username');
    }
    //Get the length of the username
    $length = strlen($username);
    //Validate the length
    if ($length < 3 || $length > 20) // parte modificada
    {
    	die('Please enter a username between 3 and 20 characters long');
    }
    //Make sure that its safe to enter the database.
    $username = mysql_real_escape_string($username);
    //Construct the query
    $SQL = "SELECT * FROM username WHERE username = '".$username."'";
    //Show the username
    echo 'Username: '.stripslashes($username);
    //Send the query and close the connection to the database
     
    ?>

    Los códigos mostrados ¿son correctos? si no es así, ¿qué errores tiene?.

    » Leer más, comentarios, etc...

    BLOG - 3wstudio.com.ar

    Extendiendo las posibilidades de Array

    Marzo 31st, 2007 - [Enlace local]

    Todo lenguaje orientado a objetos (OOP) moderadamente avanzado tiene gran cantidad de metodos para recorrer colecciones e incluso por lo general tienen más de un tipo de colección. En su defecto otros lenguajes  no OOP o semi OOP (por ejemplo PHP ) proveen una gran libreria de funciones para trabajar con vectores y matrices.

     

    En flash el único tipo de "collection" que podemos encotrar son los "Array". Los "Array" (en flash) son bolsas sin un límite en donde podemos colocar elementos de cualquer tipo y repetirlos el numero de veces que querramos.

     

    Lamentablemente Flash en AS2.0 no provee una API muy amplia para el manejo de arrays como lo pueden dar el smalltalk o java. Unicamente podemos agregar/eliminar elementos, ordernar bajo diferentes criterios o por funciones de callback y alguna que otra cosa mas.

     

    Para no extrañar los metodos como map, filter, select, do, occurrenceOf, etc tan útiles de otros lenguajes, extendí dinámicamente la clase primitiva Array y así poder utilizarlos.

     

    Veamos unos ejemplos de como utilizar esto

    #include "extendsArray.as"
    var vec:Array = new Array(2,35,6,4,5,6);
    
    trace(vec.filter(function(a){
                        if (a>10){
                            return true;
                        } else {
                            return false;
                        }
                        }, new Boolean(0)));
    
    vec.map(function(a){
                   return a+1;
                   }, true);
                   
    trace(vec);

     

    No solo se pueden utilizar numeros y cadenas en las posicione de los vectores para utilizar estas funciones, sino tambien pueden tener MovieClips, XMLNodes (bastantes útiles), Obejct, intancias de clases propias y cualquier otra cosa que querramos, incluso otros arrays. 

     

    En este caso, desidí aprovechar la propiedad dinámica de la clase Array para crearle nuevas funciones y no crear una nueva clase heredada de Array. Creo que de esta manera se gana en portabilidad y en fasilidad.

     

    El código de las funciones es:

     

    extendsArray.as

     /*
    Function map
    Efecuta una funcion callback en cada posicion del vector y el resultado se asigna a la posicion
    
    Definicion
    Array.map(func:Function, [bool:Boolean])
    
    func: es la funcion a ejecutar
    bool (opcional): si es true indica q se debe modificar el array original. Si es false nose modifica.
    
    La funcion callback debe recibir 1 parametro y devolver el resultado de la transformacion.
    
    Devuelve:
    Una nueva matriz modificada.
    */
    Array.prototype.map = function(func:Function):Array{
        
        var cant:Number = this.length;
        var i:Number = 0;
        var aux:Array = new Array();
        var mod:Boolean = (arguments[1] == undefined || (typeof(arguments[1]) != "boolean" && !(arguments[1] instanceof Boolean)))?false:arguments[1];
    
        for(i=0; i<cant; i++){
            aux[i] = func(this[i]);
            if(mod==true) { this[i] = aux[i];}
        }
        
        return aux;
    }
    
    /*
    Function filter
    Filtra elementos de una matriz por medio de una funcion callback
    
    Definicion
    Array.filtar = function(func:Funcion, [bool:Boolean])
    
    func: funcion callback para filtrar.
    bool (opcional): Si es true indica que se debe modificar el array de origen. Si es false no se lo modifica.
    
    La funcion de callback debe recibir un parametro y devolder como resultado true o false. Si es true el elemento se lo debe eliminar de la matriz. Si es true se lo deja.
    
    Devuelve
    El array modificado.
    */
    Array.prototype.filter = function(func:Function):Array {
        var cont:Number = 0;
        var i:Number = 0;
        var aux:Array = new Array();
        var mod:Boolean = (arguments[1] == undefined || (typeof(arguments[1]) != "boolean" && !(arguments[1] instanceof Boolean)))?false:arguments[1];
        
        for(i=0; i<this.length; i++){
            if (func(this[i]) == true){
                if(mod == true){ this.splice(i--, 1);}
            } else  {
                aux[cont++] = this[i];
            }
        }
        
        return aux;
    }
    
    /*
    Funcion run
    Ejecuta una funcion recibiendo como parametro cada elemento de la matriz.
    
    Definicion
    Array.run = function(func:Function);
    
    func: funcion callback debe recibir un parametro y no devolver nada.
    
    */
    Array.prototype.run = function(func:Function):Void{
        var cant = this.length;
        var i:Number;
        
        for(i=0; i<cant; i++){
            func(this[i]);
        }
        return;
    }
    
    /*
    Function detect
    Devuelve el primer elemento que coincida con una funcion callback
    
    Definicion
    Array.detect = function(func:Funcion, [obj:Object]);
    
    func: funcion callback
    obj (opcional): valor por default que devuelve detect si no encuentra ninguna coincidencia
    
    La funcion callback debe recibir un parametro y devolver true si coincide con la busqueda y false en caso contrario.
    
    Devuelve
    El primer objeto que coincide con la busqueda
    */
    Array.prototype.detect = function(func:Function):Object{
        var cant:Number = this.length;
        var i:Number;
        
        for(i=0; i<cant; i++){
            if (func(this[i])){ break;}
        }
        
        return (i<cant)?this[i]:(arguments[1] != undefined)?arguments[i]:undefined;
    }
    
    /*
    function select
    Selecciona elementos de la matriz q coincidan con una funcion
    
    Definicion
    Array.select = function(func:Funcion)
    
    func: funcion de comparacion
    
    La funcion de comparacion debe recibir un parametro y devolver true si coincide con la busqueda y false en caso contrario.
    
    Devuelve
    Un nuevo Array con los elementos seleccionados. O un Array vacio si no se encotraron coincidencias
    */
    Array.prototype.select = function(func:Function):Array{
        var cont:Number = 0;
        var i:Number = 0;
        var aux:Array = new Array();
        var cant:Number = this.length;
        
        for(i=0; i<cant; i++){
            if (func(this[i]) == true){aux[cont++] = this[i];}
        }
        
        return aux;
    }
    /*
    function reject
    Selecciona elementos de la matriz q no coincidan con una funcion
    
    Definicion
    Array.select = function(func:Funcion)
    
    func: funcion de comparacion
    
    La funcion de comparacion debe recibir un parametro y devolver true si coincide con la busqueda y false en caso contrario.
    
    Devuelve
    Un nuevo Array con los elementos que con coinciden con la busqueda de la funcion. O un Array vacio si no se encotraron coincidencias
    */
    Array.prototype.reject = function(func:Function):Array{
        var cont:Number = 0;
        var i:Number = 0;
        var aux:Array = new Array();
        var cant:Number = this.length;
        
        for(i=0; i<cant; i++){
            if (func(this[i]) == false){aux[cont++] = this[i];}
        }
        
        return aux;
    }
    
    /*
    Funcion includes
    Indica si un elemento esta en la matriz o no
    
    Definicion
    Array.includes = function(obj:Object);
    
    obj: elemento a buscar
    
    Devuelve
    Devuelve true si encontro el elemento, false en caso contrario.
    */
    Array.prototype.includes = function(obj:Object){
        var i:Number = 0;
        var cant:Number = this.length;
        
        for(i=0; i<cant; i++){
            if (this[i] == obj) {return true;}
        }
        
        return false;
    }
    
    /*
    Function occrurrencesOf
    Indica la cantidad de ocurrencias de un elemento dentro de una matriz
    
    Defincion
    Array.occurrencesOf = function(obj:Object);
    
    obj: elemento a comparar
    
    Devuelve
    La cantidad de veces que el elemento obj esta dentro de una matriz
    */
    Array.prototype.occurrencesOf = function(obj:Object){
        var i:Number = 0;
        var cant:Number = this.length;
        var cont:Number = 0;
        
        for(i=0; i<cant; i++){
            if (this[i] == obj) {cont++;}
        }
        
        return cont;
    }
    /*
    Function at
    Devuelve el primer elemento que coincida con la clave y el valor
    */
    Array.prototype.at = function(clave:String, valor:Object):Object{
        var i:Number = 0;
        var cant:Number = this.length;
        
        for(i=0; i<cant; i++){
            if (this[i][clave] == valor) {return this[i];}
        }
        
        return undefined;
    }
    
    /*
    Function at
    Elimina los elementos que coincidan con la clave y el valor
    */
    Array.prototype.removeAt = function(clave:String, valor:Object):Void{
        var i:Number = 0;
        var cant:Number = this.length;
        
        for(i=0; i<cant; i++){
            if (this[i][clave] == valor) {this.splice(i--, 1);}
        }
        
        return;
    }
    
    /*
    Function keyAt
    Devuelve todos los elementos q contengan la clave (propiedad de un Object)
    */
    Array.prototype.keyAt = function(clave:String):Object{
        var i:Number = 0;
        var cant:Number = this.length;
        var cont:Number = 0;
        var aux:Array = new Array();
        
        for(i=0; i<cant; i++){
            if (this[i][clave] != undefined) {aux[cont++] = this[i];}
        }
        
        return aux;
    }

     

    Lo que tienen que hacer con esto, es meter este código en un archivo .as y luego con #include meterlo dentro del archivo flash y ya queda listo para utilzarlo en cualquier lado del proyecto.

     

    Espero que les sirva para sus proyectos...

    » Leer más, comentarios, etc...

    Ricardo's Blog

    Captura de GNOME Live Messenger

    Marzo 30th, 2007 - [Enlace local]

    Buenas noches, les presento algunas capturas de GNOME Live Messenger..

    glivemsgrLogin glivemsgrLogin2 glivemsgrConversation

    Hacen falta algunos detalles de algunos botones que quizá lo mejor se implementarlos con System.Drawing como la mayor parte del resto de la interfaz, para que quede mejor integrada, ya que algunos botones podrían hacer la interfaz no-homogenea, les debo aun la ventana de lista de contactos porque estoy trabajando en ella, y algunos otros elementos como el dialogo de configuración, aunque este último lo escribiré mas adelante..

    Los aspectos fundamentales de esta interfaz es que..

    Se uso widgets de GTK, pero sobre ellos se usó System.Drawing para modelar y adecuar su apariencia para adecuarla a la apariencia que tiene Live Messenger..

    Ahora, quisiera aclarar porque he decidido escribir la aplicación completa desde cero sin usar alguna biblioteca existente..

    1. Porque esto inició como un juego, de hecho sigue siendo un juego para mí..
    2. Por que posiblemente sea mi proyecto de tesis (y eso no le quita la calidad de juego) de la licenciatura..
    3. Porque es divertido estudiar protocolos en general (asi que no les sorprenda si pronto escribo una app tipo firewall :) ) ..
    4. Y la mas importante porque quiero que este proyecto sea diferente.. ..y eso será mas adelante cuando vean porque..

    Saludos y seguire adelante, desafortunadamente, no se para cuando tendré internet en mi casa, asi que la fusión de la interfáz con el modelo de mi aplicación tardará un poco porque tendré acceso limitado a internet..

    Pero no se preocupen, la terminaré..

    Bueno, cuidense y estamos en contacto.. ..sugerencias y comentarios haganlos a este post o escribanme a ricki@dana-ide.org

    Bye

    » Leer más, comentarios, etc...

    RiCKi's Blog

    Captura de GNOME Live Messenger

    Marzo 30th, 2007 - [Enlace local]

    Buenas noches, les presento algunas capturas de GNOME Live Messenger..

    glivemsgrLogin glivemsgrLogin2 glivemsgrConversation

    Hacen falta algunos detalles de algunos botones que quizá lo mejor se implementarlos con System.Drawing como la mayor parte del resto de la interfaz, para que quede mejor integrada, ya que algunos botones podrían hacer la interfaz no-homogenea, les debo aun la ventana de lista de contactos porque estoy trabajando en ella, y algunos otros elementos como el dialogo de configuración, aunque este último lo escribiré mas adelante..

    Los aspectos fundamentales de esta interfaz es que..

    Se uso widgets de GTK, pero sobre ellos se usó System.Drawing para modelar y adecuar su apariencia para adecuarla a la apariencia que tiene Live Messenger..

    Ahora, quisiera aclarar porque he decidido escribir la aplicación completa desde cero sin usar alguna biblioteca existente..

    1. Porque esto inició como un juego, de hecho sigue siendo un juego para mí..
    2. Por que posiblemente sea mi proyecto de tesis (y eso no le quita la calidad de juego) de la licenciatura..
    3. Porque es divertido estudiar protocolos en general (asi que no les sorprenda si pronto escribo una app tipo firewall :) ) ..
    4. Y la mas importante porque quiero que este proyecto sea diferente.. ..y eso será mas adelante cuando vean porque..

    Saludos y seguire adelante, desafortunadamente, no se para cuando tendré internet en mi casa, asi que la fusión de la interfáz con el modelo de mi aplicación tardará un poco porque tendré acceso limitado a internet..

    Pero no se preocupen, la terminaré..

    Bueno, cuidense y estamos en contacto.. ..sugerencias y comentarios haganlos a este post o escribanme a ricki@dana-ide.org

    Bye

    » Leer más, comentarios, etc...

    Buayacorp

    Diario El Comercio estrena “nueva� Web

    Marzo 30th, 2007 - [Enlace local]

    El Comercio, es uno de los diarios más leídos de Perú y al parecer acaba de estrenar una "nueva" versión de su sitio Web. Giovanni Lamarca hace el siguiente resumen de las novedades:

    1. Tiene radio! Por fin un medio multimedia. Ya Terra había incluido la señal de Canal N (y RPP texto), pero esto es distinto. Esto es un periódico que suena e incluye video. Dejo el tema del YouTube para otro post. :)

    2. Lo más importante arriba y claro Y lo más importante es que yo escoja qué quiero leer. Si la web, si la edición impresa, si los clasificados. :)

    3 Publicidad entrometida (literalmente) No son los odiosos pop ups que se abren sin que uno les pregunte y aunque se estila usarla como divisor (separa la cabecera de las notas horarias), me resulta un poco grande. Depende del tenor del aviso para tener un elemento que alegre o, en todo caso, desentone. Sobre gustos y colores… :(

    4 Tags! Por fin sabremos qué palabras o temas son los que más se leen en el diario. La nubecita de palabras (algunas más grandes que otras) indican, por su tamaño, los items o criterios de busqueda o cantidad de apariciones de determinado tema en la edición web. ;)

    5 Blogs! Válgame Dios! Y con posibilidad para comentarios! Merece tomarse una res en el Queirolo!

    6 Incertidumbre Finalmente, un espacio para ser llenado con interactivos que, desde mi punto de vista, costará encontrarles un común denominador. Foros, mail de contactos, juegos, información de mercado, guías, ediciones anteriores, RSS… mmm Lo bueno es que queda pampa. Harta pampa

    Saldo positivo y muchas felicitaciones!!!

    Sinceramente no comparto el fanatismo de Giovanni por un trabajo que, en mi opinión, deja mucho que desear; estos son sólo algunos de los puntos en contra que veo:

    La versión anterior me parece que al menos era un poco más sobria y más usable que esta nueva versión (imagen capturada con Firefox)

    » Leer más, comentarios, etc...

    Ingenieria de Software / Software Engineering

    Análisis del valor ganado / Earned Value

    Marzo 30th, 2007 - [Enlace local]

    He leìdo varios artìculos acerca del valor ganado pero pocos tan claros como el que se presenta en Baccou Boneville Consultants el cual me ha parecido claro y digerible, aprovecho para recomendar el sitio de Bacou Boneville el cual presenta artìculos de varios temas correspondientes al desarrollo de software.

    » Leer más, comentarios, etc...

    Infectogroovalistic

    Curso de introduccion a PHP

    Marzo 30th, 2007 - [Enlace local]

    En el trabajo estamos armando algunos cursos de desarrollo web y estos son los apuntes del curso de introducción a PHP que hicimos. Si alguno está iniciándose o hizo el curso, le puede venir bien.

    Bajar PDF

    » Leer más, comentarios, etc...

    avemundi

    más iconos y un programa

    Marzo 29th, 2007 - [Enlace local]

    Una de las cosas que debe tener cualquier programador es una carpeta llena de iconos para sus programas. Como ya dije uso los de iconexperience. Hace como un par de meses pasé por su sitio buscando iconos para una nueva...

    » Leer más, comentarios, etc...

    Navegapolis

    Idoneidad de Ruby On Rails para desarrollos web ágiles

    Marzo 29th, 2007 - [Enlace local]

    charlaAl menos eso es lo que afirma Gegg Pollack , fundador del grupo de usuarios de Ruby de Orlando en la charla que dio el pasado día 15.

    Afirma que él odia el desarrollo predictivo, con ciclo de vida secuencial y requisitos cerrados al comienzo del proyecto. Que Ruby On Rails es una plataforma pefecta para proyectos web con ciclos de construcción ágiles (desarrollo iterativo e incremental), que es libre y que resulta muy cómoda para los programadores.

    Blogalaxia Tags: ruby+on+rails

    » Leer más, comentarios, etc...

    Navegapolis

    ScrumMaster: El traje nuevo del emperador

    Marzo 29th, 2007 - [Enlace local]

    certificado"Certified Scrum Master" suena bien. Suena muy bien. Tiene "Certified" y tiene "Master", y con estos términos tan pomposos, uno supone que se debe tratar de una certificación de conocimiento o  reconocimiento profesional; y este es un engaño que cada vez despista a más personas.

    Decir que el emperador está desnudo quizá no es muy inteligente, porque uno no gana simpatías ni de los emperadores que han pagado un buen dinero por un traje inexistente, ni de los sastres que hacen tantos trajes y entregan tan poca tela; pero alabar el traje que no se termina de ver no es profesionalmente honesto.

    » Leer más, comentarios, etc...

    Spejman's Blog

    Algoritmos genéticos para Ruby (gga4r) release 0.9

    Marzo 29th, 2007 - [Enlace local]

    Algoritmos genéticos para Ruby (gga4r) es una librería para ejecutar algoritmos genéticos fácilmente.

    En 3 pasos ya puedes trabajar con gga4r:

    1. Escoger la clase a evolucionar y definirle los métodos fitness, combine y mutate.

    2. Con un array de instancias de la clase anterior (población inicial) crear un objeto de tipo GeneticAlgorithm.

    3. Llamar a la función evolve de la clase GeneticAlgorithm tantas veces como quieras.


    Más documentación y ejemplos en:

    » Leer más, comentarios, etc...

    Buayacorp

    ¿Las certificaciones sirven para algo?

    Marzo 29th, 2007 - [Enlace local]

    En mi lectura diaria, encontré una entrada en la que se comenta que SANS creó un instituto de seguridad (Software Security Institute), en el cual se tomará un examen que determina si los candidatos conocen sobre técnicas de seguridad para escribir código seguro (por el momento los lenguages que se mencionan son C/C++, Java/J2EE y próximamente Perl, PHP, .NET y ASP.NET).

    Como curioso que soy :) me puse a resolver una prueba gratuita de Java/J2EE -hice esto porque actualmente no existen pruebas para .NET o PHP-, entre las que se incluían algunas preguntas generales y otras específicas con respecto a técnicas de seguridad usando este lenguaje. Esta es la calificación que obtuve:

    SANS Software Security Institute Test Results

    Ustedes se preguntarán que hay de malo con esta calificación, pues el pequeño detalle es que yo en este momento conozco muy poco de Java y jamás desarrollé una aplicación con J2EE.

    Aunque los conceptos de seguridad se pueden aplicar en varios lenguajes, esto dista mucho de los objetivos que SANS -o cualquier empresa que se dedica a certificar gente- desea lograr... si alguien llegara a contratarme basándose solamente en este resultado, es obvio que sería un desastre para el trabajo que me asignen los primeros meses.

    No es por desmerecer a las personas que tienen certificaciones -y saben de lo que hablan, pero en mi humilde opinión, éstas solo sirven para adornar el curriculum vitae y casi siempre para convencer a empleadores que sólo se fijan en estas cosas.

    » Leer más, comentarios, etc...

    Navegapolis

    Nueva revisión de Spec#

    Marzo 28th, 2007 - [Enlace local]

    VS logoEn el área de descargas de Microsoft Research está disponible una revisión de Spec# para Visual Studio 2005. Según la página del proyecto, Spec# intenta ofrecer una forma de desarrollar y mantener software de alta calidad, con eficiencia de costes.

    Blogalaxia Tags: Spec# Visual+Studio .NET

    » Leer más, comentarios, etc...

    BLOG - 3wstudio.com.ar

    Rotar imagenes en flash (version 2 -OOP-)

    Marzo 28th, 2007 - [Enlace local]

    Hace unos dias vimos un codigo con el cual podíamos rotar imágenes por medio de fades, ahora vamos a aplicar lo que aprendimos en ese momento para construir una clase y asi aumentar la portabilidad del código.

     

    La idea de la clase es poder manipular el conjunto de imágenes de forma dinámica, poder agregar/sacar elementos en tiempo de ejecución, cambiar el tipo de transición, el tiempo de espera, etc.

     

    Veamos la forma básica para utilizar la clase

    import CarruselEfect; 
      
     var ce:CarruselEfect = new CarruselEfect(); 
     ce.load([a1, a2, a3, a4],2000,true);

     

    En donde primero importamos e instanciamos la clase, luego llamamos al metodo load para cargar las imágenes. En su primer parámetro enviamos un array con referencias a los movieclip con las imágenes (una imágen en cada movieclip), en el segundo indicamos el tiempo de espera en el cambio de imágen (en milisegundo), y finalmente con el tercer parámetro indicamos si se comienza ahora el efecto o no.

     

    Si quisieramos por ejemplo modificar en tiempo de ejecucion (talvez con un boton) el comportamiento del efecto lo tendriamos que hacer de esta forma 

     

    bt.onPress = function(){
       ce.stop();
    } 

     

    Con ese mensaje detenemos el efecto. Otros mensajes/métodos que podemos utilizar son

    ce.start(); //iniciamos el efecto (si en load hubieramos puesto false en el 3er parámetro)
    ce.continueEfect(); //para continuar con el efecto si lo detuvimos previamente
    ce.remItem(mc); //elimina un elemento del efecto (puede ser en tiempo de ejecucion) 
    
    ce.addItem(mc); //agrega un elemento al efecto (puede ser en tiempo de ejecucion) 
    ce.changeTimeInterval(tiempo); //cambia el tiempo que tarda en cambiar de imágen
    ce.changeTimeEfect(tiempo); //cambia el tiempo que dura el efecto de transicion
    ce.changeEfect(funcion); //cambia el efecto de transicion (debe ser alguno del paquete mx.transitions)

     

    Otra cosa que pueden hacer es capturar el evento que lanza la clase al intercambiar una imagen. El evento se llama onChange y es el único que la clase lanza.  Para capturarlo se hace lo siguiente.

    
    import CarruselEfect; 
      
     var obj:Object = {} 
     obj.onChange = function(o:Object){ 
        trace("cambio=> Anterior: "+o.oldMc+" // Nuevo: "+o.newMc) 
     } 
      
     var ce:CarruselEfect = new CarruselEfect(); 
     ce.load([a1, a2, a3, a4],2000,true); 
     ce.addEventListener("onChange",obj) 
    
    
     

     

    Bien, aca les dejo el código de la clase para que lo puedan usar y mejorar

     

    
    import mx.events.EventDispatcher; 
     import mx.transitions.Tween; 
     import mx.utils.Delegate; 
      
     /* 
     * Script:CarruselEfect.as 
     * Clase que maneja transiciones de imagenes
    
     *
       * Author: Andres Lozada Mosto 
     *  
     * Class: CarruselEfect 
     */ 
     class CarruselEfect{ 
        public var addEventListener : Function; 
        public var removeEventListener : Function; 
        public var dispatchEvent : Function 
         
        private var elems:Array; 
        private var id:Number; 
        private var tiempo:Number; 
        private var actual:Number; 
        private var anterior:Number; 
        private var tween1:Tween; 
        private var tween2:Tween; 
        private var comenzo:Boolean; 
        private var tiempoEfecto:Number; 
        private var func:Function 
         
        /* 
        * Metodo constructor
         */
       public function CarruselEfect(){
            this.elems = new Array();
            this.actual = 0; 
           this.tiempo = 1000; 
           this.anterior = 0; 
           this.comenzo = false; 
           this.tiempoEfecto = 25; 
           this.func = mx.transitions.easing.None.easeNone; 
            
           EventDispatcher.initialize (this); 
        } 
         
        /******************* 
        * API pública 
        *******************/ 
        //inicia el efecto 
        public function load(vec:Array, tiempo:Number, bool:Boolean){ 
           this.elems = this.elems.concat(vec); 
           this.tiempo = (tiempo > 0)?tiempo:this.tiempo; 
           this.ocultar(); 
           if (bool) { 
              this.efectoMc(this); 
              this. comenzo = true; 
           } 
        } 
         
        //comienza el efecto 
        public function start():Void{ 
           if(!this.comenzo){ 
              this.efectoMc(this); 
              this.comenzo = true; 
           } 
        } 
         
        //detiene el efecto 
        public function stop():Void{ 
           if(this.comenzo){ 
              clearInterval(this.id); 
              this.comenzo = false; 
              delete this.tween1.onMotionFinished; 
           } 
        } 
         
        //continua el efecto 
        public function continueEfect():Void{ 
           if(!this.comenzo){ 
              this.efectoMc(this); 
              this.comenzo = true; 
           } 
        } 
         
        //saca un elemento  
        public function remItem(item:MovieClip):Void{
            var i:Number = 0; 
           var vec:Array = new Array();
           for(i=0; i<this.elems.length; i++){
               if(this.elems[i] !== item){ 
                 vec.push(this.elems[i]);
               }
            }
                    this.actual--;
            this.elems = vec; 
        } 
         
        //agrega un elemento 
        public function addItem(item:MovieClip):Void{ 
           this.elems.push(item); 
        } 
         
        //cambia el tiempo de retardo en el cambio de foto 
        public function changeTimeInterval(valor:Number):Void { 
           this.tiempo = valor; 
        } 
         
        //cambia el tiempo que dura la transicion 
        public function changeTimeEfect(valor:Number):Void{ 
           this.tiempoEfecto = valor; 
        } 
         
        //cambia el efecto de cambio 
        public function changeEfect(func:Function){ 
           this.func = func; 
        } 
         
        /*************************** 
        * API PRIVADA 
        * *************************/ 
        private function efectoMc(clase:CarruselEfect):Void{ 
           clase.tween1 = new Tween(clase.elems[this.actual], "_alpha", clase.func,0, 100, this.tiempoEfecto, false); 
           clase.tween1.onMotionFinished = Delegate.create(clase,asignarEvento); 
        } 
         
        private function ocultar():Void{ 
           var i:Number; 
           for(i=0; i<this.elems.length; i++){ 
              this.elems[i]._alpha = 0; 
           } 
        } 
         
        private function asignarEvento(){ 
           this.id = setInterval(Delegate.create(this, evento), this.tiempo,this);  
        } 
         
        [onChange] 
        static private function evento(clase:CarruselEfect){ 
           clearInterval(clase.id); 
           clase.anterior = clase.actual; 
           clase.actual = (clase.actual >= clase.elems.length-1)?0:clase.actual+1; 
           clase.tween2 = clase.tween1; 
           delete clase.tween2.onMotionFinished; 
           clase.efectoMc(clase); 
           clase.tween2.yoyo(); 
           clase.dispatchEvent ({type : 'onChange', oldMc:clase.elems[clase.anterior], newMc:clase.elems[clase.actual]}); 
        } 
         
     } 
    
    
     

     

    Para cualquier consulta pueden preguntar acá.

    » Leer más, comentarios, etc...

    Spejman's Blog

    Estreno template! Hemingway modificado

    Marzo 28th, 2007 - [Enlace local]

    Como podéis ver, estreno template para el blog. El estilo anterior desaprovechaba mucho el espacio y no se leía muy bien.

    He partido del template Hemingway y lo he modificado para añadir una cabezera y un par de cosillas más. Poco a poco iré añadiendo algún link más y algo que permita ver las últimas entradas de mi nuevo Thumblog: Spejman Thumblog!

    Espero que os guste y sobretodo que sea más cómodo de leer!

    Ya sabéis, acepto todo tipo de críticas ;)

    » Leer más, comentarios, etc...

    Buayacorp

    ¿Qué hace difícil a la seguridad?

    Marzo 28th, 2007 - [Enlace local]

    Michael Howard:

    I’ve been asked this question numerous times, often in the guise of a question like, "why can't you guys simply fix the security problem?" or "reliability and scalability problems are understood and solvable, why can't you do the same with security?" or my favorite variant, "what the heck keeps you interested in security when it seems you're fighting a 'no-win' battle?"

    ...

    So what is it that makes security hard?

    It’s simple:

    This security stuff is an ongoing arms race and chess game, and each side is constantly trying to outwit the other. We raise the bar, and the attackers then spend time trying to defeat that bar. So we raise the bar again, and so on. With reliability and scalability, we can understand the "adversary" and that’s that. The "enemy" won’t adapt to defeat you!

    Cuánta razón tiene al decir que esta es una constante batalla entre los que intentan desarrollar software seguro y aquellos que talvez con más tiempo, dinero de por medio u otras motivaciones se dedican a encontrar vulnerabilidades.

    Por tanto, es nuestra responsabilidad como desarrolladores, estar pendiente de aquellos aspectos de seguridad que se pueden presentar en nuestras aplicaciones, caso contrario estaremos en desventaja y probablemente ya hayamos perdido esta lucha sin cuartel :)

    » Leer más, comentarios, etc...

    xailer.info (esp)

    Correo SMTP con Blat y Xailer

    Marzo 28th, 2007 - [Enlace local]

    En estas últimas semanas se ha preguntado varias veces en los foros si es posible utilizar Blat para enviar correo desde Xailer, así que me he decidido a pulir y publicar una pequeña librería que empezé en el mes de enero a partir de un trabajo inicial de José Luis Capel

    Esta librería incluye una jerarquía de 3 clases para el envío de correo SMTP:

    La clase TBlat es una clase abstracta que maneja la carga y descarga de la DLL y la configuración de los datos para el envío, etc. Sólo sirve como base para las otras y NO se utiliza directamente.

    Las clases descendientes son las que hacen realmente el envío del correo, la primera lo hace a través de servidores SMTP y la segunda lo hace con el servicio SMTP de GMail.

    Para explicar su funcionamiento, nada mejor que un sencillo ejemplo:

    1. WITH OBJECT TBlatMail():New()
    2.    :cServer := "ServidorSMTP.com"
    3.    :cAddress := "yomismo@mail.com"
    4.    :Create()
    5.  
    6.    IF :nLastError == 0
    7.       :cSubject := "Probando Blat desde Xailer"
    8.       :cBody := "Cuerpo del mensaje"
    9.       /*:lHtml := .T.*/
    10.       :Send()
    11.    ENDIF
    12.  
    13.    :Destroy()
    14. END

    Desde aquí puede descargarse el proyecto con los fuentes para generar la librería.

    » Leer más, comentarios, etc...

    MadeInFlex

    Componente Sticky ToolTip

    Marzo 28th, 2007 - [Enlace local]

    Este componente tooltip, a diferencia del que viene con el framework de Flex sigue al puntero del ratón a medida que éste se mueve por la superficie del componente que lo lanzó. Está todavía en fase de desarrollo pero es totalmente funcional.
    Componente Sticky ToolTip

    » Leer más, comentarios, etc...