martes, 17 de abril de 2012

¿Metodología Ágil o Formal en tu Empresa?


Las Pequeñas y Medianas Empresas (PyMES) dedicadas al desarrollo de software o que cuentan con un área o unidad de negocio dedicadas a ello, están generando una parte significativa del software utilizado en el mundo. Sin embargo, carecen de una metodología de desarrollo de software son adaptados; y en casos extremos, ni siquiera son utilizados.

¿Cómo elegir la metodología de desarrollo de software “adecuada a utilizar” en proyectos de producción de software?

 Gráfica 1. Modelo propuesto por Barry Boehm y Richard Turner.


El modelo propuesto por Barry Boehm y Richard Turner es un modelo de fácil comprensión capaz de evaluar cuantificar e identificar 5 variables críticas a la hora de decidir si el desarrollo de un sistema se aventura por metodologías ágiles o robustas.

Personal. El por ciento del personal con capacidad, experiencia y posibilidades para enfrentar tareas es un aspecto de mucha importancia en un proyecto de producción de software, de esto depende mucho la posibilidad que tiene el grupo de desarrolladores de poder implantar o desarrollar un tipo de metodología u otra. Esta variable tiene su mayor importancia a la hora de adoptar métodos ágiles que requieren de un personal con niveles de experiencia medios-altos, capaces de comprender y adaptar los métodos y las técnicas empleadas.

Criticidad. La criticidad del sistema resultada determinante cuando se habla de proyectos cuya falla puede traer pérdidas de vidas humanas, daño al medio ambiente y grandes pérdidas económicas, por lo que se hace necesario emplear métodos robustos capaces de mantener un rigor de requisitos y diseño adecuados para procesos de pruebas, verificación y validación.

Cultura. El por ciento del personal con capacidad para enfrentarse a entornos caóticos resulta importante a la hora de adoptar métodos ágiles los cuales se basan fundamentalmente en el talento de las personas, un ambiente laboral con un control excesivamente normalizado y jerarquizado resultaría incómodo para llevar a cabo este tipo de práctica.

Tamaño La cantidad de personas de un proyecto resulta importante en dependencia de qué método ágil o robusto se vaya a poner en práctica. Para métodos ágiles donde es muy significativa una buena comunicación entre todos los integrantes del grupo de desarrollo esta resulta imposible con un número alto de personal en el proyecto.

Dinamismo. El por ciento de cambios de requerimientos que pueden ocurrir en un mes tiene gran peso en los métodos ágiles preparados para enfrentar este tipo de situación, resultaría muy incómodo enfrentar grandes cambios de requerimientos con métodos robustos que tienen grandes volúmenes de documentación y una verificación y validación de procesos continua.

Tiempo. El tiempo de respuesta requerido por el cliente para obtener su producto resulta determinante a la hora de escoger una metodología, para proyectos que se necesiten terminar en un periodo de tiempo breve resultaría tedioso seleccionar un método robusto estos se ajustan más a sistemas a largo plazo con un gran número de requerimientos.

¿Por qué adicionar la variable Tiempo de respuesta requerido por el cliente al Modelo de Barry Boehm y Richard Turner ?

En la actualidad el tiempo de respuesta requerido por el cliente es un factor muy importante a tener en cuenta a la hora de desarrollar un software y seleccionar una metodología de desarrollo. Resulta determinante cumplir con el tiempo que requiere el cliente, de lo contrario esto podría traer consigo consecuencias desfavorables para el proyecto en cuanto a su costo su tiempo de desarrollo, errores en la aplicación entre otros. La relación entre los beneficios y la cantidad de tiempo necesario para poner el producto o servicios en el mercado tiene gran significado, cuanto menor sea el tiempo o plazo para llegar al mercado mayor serán los beneficios. Esto posibilita que se pueda alcanzar a diferentes tipos de usuarios y consumidores. A medida que transcurre el tiempo se incrementan los costos, se desmotiva el personal, aumenta la presión y existen mayores posibilidades de perder personal involucrado en el desarrollo.adecuada a sus necesidades y sus recursos, ya que las metodologías existentes y sus marcos de trabajo difícilmente.

                                       Gráfica 2. Delimita el área ágil.


                                                        Gráfica 3. Delimita el área formal.


martes, 10 de abril de 2012

Mensajes de "Warning" en PHP


 Como su nombre lo indica un "Warning" es una advertencia  del sistema indicándonos que "algo" estamos haciendo mal los programadores. 



Algunos Warnings en PHP son los siguientes:

  1. Warning: Cannot modify header information - headers already sent by (output started at ...
Causas:

  1. En el script PHP existen espacios o caracteres extraños antes o después del código PHP.
  2. La configuración de PHP en el servidor tiene activa (en On) la directiva display_errors
  3. session_start() debe ser ejecutado antes de cualquier salida HTML porque envía headers HTTP al navegador. 
  4. Cuando hay un include, require, antes de la función.
  5. Enviar "algo" antes del header. Ej: un espacio, una coma..." 
  6. Redireccionar con header luego de haber mostrado "algo" por pantalla.
  7. Falta el (./) y el (;) : header("Location: ./pagina.php");

Soluciones:

  1. Revisar que no existan espacios, saltos de línea o caracteres antes de:
<?php
    //Y que no existan también después de:
?>
     2. Al apagar (poner en Off) la directiva display_errors, el error puede desaparecer. Se puede modificar en el archivo .htaccess o php.ini. En .htaccess:

     php_value display_errors "Off"
     3.  Añadir los include, require en las primeras lineas del código.
     4. La función header en PHP debe enviarse en la cabecera de la respuesta http, por tanto debe ser lo primero que se envíe al navegador.El  header hay que colocarlo en la primera linea del archivo, antes que cualquier tipo de salida (ya sea html, texto o espacios en blanco.
     5. Colocar el siguiente código
      
        //al inicio
<?
   ob_start();
?>
        //al final 
<?
    ob_end_flush();
?>
La función ob_start() sirve para indicarle a PHP que se ha de iniciar el buffering de la salida, es decir, que debe empezar a guardar la salida en un buffer interno, en vez de enviarla al cliente.

La función ob_end_flush() sirve para indicar a PHP que se desea realizar el volcado de todo el bufer en la salida, con lo que se enviará al cliente que ha solicitado la página.

Nota 1: Es posible desactivar el PHP Notice y PHP Warning:

Con el parámetro de configuración error_reporting podemos definir que tipo de errores quedemos almacenar en el log.

En el caso que lo tengamos a E_ALL, veremos como se van guardando en el log "PHP Notice", que algunas veces conocemos pero que quizás no resultan de interés. Podemos desactivarlos de la siguiente manera:


error_reporting = E_ALL & ~E_NOTICE //restando a los E_ALL las E_NOTICE
De la misma manera podemos eliminar los "PHP Warning"

error_reporting = E_ALL & ~E_NOTICE & ~E_WARNING

Trabajo con Fechas PHP, MYSQL

Cuando los programadores tenemos que realizar una página web donde se trabaja con Fechas, siempre nos enfrentamos a problemas de formato, ya sea por la forma en que MySQL almacena los tipo "DATE", o la forma en que se quiere mostrar la fecha al usuario.

Casualmente hoy, me ha dado un error que he logrado solucionar, lo comento por si les pasa ya tengan la solución.

Primero, hacerles un breve resumen de la situación:

 Como todos saben MYSQL almacena lor registros de tipo DATE en formato "YYYY-MM-DD" (Año-Mes-Dia), por ejemplo, (2012-04-10): Fechas ISO 8601. 

Imaginemos que queremos realizar una consulta para extraer de la tabla "tusuario" la fecha de nacimiento de todos los usuarios de la tabla:

SELECT tusuario.fechaNacimiento FROM tusuario.

Si esta consulta la escribimos dentro de un fichero PHP:

require_once(conexionBD.php"); //para llamar al archivo que ejecuta la conexión a la BD.
$sql="SELECT tusuario.fechaNacimiento FROM tusuario";
$consulta=mysql_query($sql, $conexion) or die (mysql_error()); //crea conexión
 if(mysql_num_rows($consulta)>0){
      while($fila=mysql_fetch_array($consulta)){
             echo $fila[fechaNacimiento];
      }
}
 En pantalla se mostrará la fecha en formato "YYYY-MM-DD"; ahora bien, si el usuario final desea que le fecha se muestre en formato "DD/MM/YYYY" en muchos sitios se recomienda utilizar la siguiente función

echo (date(("d/m/Y"),strtotime( $fila[fechaNacimiento])));
VER: strtotime

Sin embargo, cuando utilicé dicha función, me devolvía la fecha "01/01/1970" para todos los casos, por tanto comencé a buscar opciones e hice lo siguiente:

 list($anno, $mes, $dia) = explode('-', $fila[fechaProximaLlamada]);
echo "$dia/$mes/$anno";
 Y de esa forma salieron las fechas con el formato adecuado.

Por el contrario, si queremos almacenar la fecha en nuestra BD y se ecnuentra en formato DD/MM/YYYY lo que tenemos que hacer para cambiarla es lo siguiente:

$fechaNacimiento=$_GET["fechaNacimiento"]; //En caso de que se reciba por GET o por POST
 $partes=explode("/", $fechaNacimiento);
 $fecha=$partes[2]."-".$partes[1]."-".$partes[0]; //para que la fecha se guarde en la BD como YYYY-MM-DD 

jueves, 5 de abril de 2012

Relaciones entre tablas PHPMyAdmin

PHPMyAdmin nos permite crear relaciones entre tablas. Para ello, abrir una tabla y seleccionar la pestaña "Estructura". En esa ventana aparecerá la opción "Vista de Relaciones".

Antes de comenzar asegúrese de estar usando el Motor de almacenamiento INNODB (que es el que soporta las relaciones), para ello la pestaña "Operaciones" les muestra en "Opciones de la tabla" el dato anteriormente mencionado.

Volviendo a la vista de relaciones, podrá seleccionar la llave foránea correspondiente, permitiendo hacer cambios en cascada al agregar o eliminar registros en nuestra base de datos asi como conservar integridad de la información almacenada en ella.

La integridad de datos es importante ya que no permite tener incoherencia en la información o falta de ella, permitiendo que todos los datos estén relacionados en nuestra Base de datos.

Por lo general, cuando se selecciona el índice destino para la relación y las acciones correspondientes de "ON DELETE" y "ON UPDATE" se selecciona la opción "CASCADE" que permite actualizar los valores. Lo que significa que si una fila en la tabla padre es eliminada, entonces se eliminarán las filas de la tabla hijo cuya clave foránea sea igual al valor de la clave referenciada en la tabla padre.

También se encuentran las opciones siguientes:

  • SET NULL: Actualiza los valores relacionados a "null". Requiere que el campo indicado en FOREIGN KEY permita valores nulos. Si está definido con flag NOT NULL daría un mensaje de error. 
  • NO ACTION: no realiza ninguna acción.
  • RESTRICT: restringe o impide que se ejecuten acciones.

Un error frecuente que suele aparecer es "#1452 - Cannot add or update a child row: a foreign key constraint fails"

La respuesta la suele tener la "integridad referencial" (Por ejemplo, Si cargas la tabla B, pero en esa tabla un campo es FK de la tabla A, hasta que la tabla A no tenga en su PK el valor correspondiente que usarás en B, no puedes cargar la tabla B).

La integridad referencial ha de establecerse siempre entre dos tablas. Una de ellas ha de comportarse como tabla principal o tabla padre y la otra sería la tabla vinculada o tabla hijo. Siendo necesario que::
  •  La tabla padre tenga un índice primario (PRIMARY KEY)
  • La tabla hijo tenga un índice (no es necesario que sea ni único ni primario) asociado a campos de tipo idéntico a los que se usen para índice de la tabla principal.

El error #1452 de MySQL ocurrirá si se intenta añadir un registro a la tabla hijo sin que exista el campo en la tabla padre. Por tanto, tenemos que añadir primero el registro en la tabla padre y luego en la tabla hijo.  
Es importante señalar que en la columna que se estableció como índice podemos insertar duplicados ya que no establecimos la condición de índice PRIMARIO ó UNICO.

Del tema "integridad referencial" hablaré más adelante.

Vista Indexada


Mejorar el rendimiento de una vista.

Si al ejecutar una vista demora en devolver los resultados, una solución podría ser hacerla indexada, para que guarde la información y no tenga que unir todas las tablas que componen la vista cada vez.

Los índices se utilizan para buscar las filas con valores de columna específica rápidamente. Sin un índice, MySQL debe comenzar con el primer registro y luego leer a través de toda la tabla para buscar las filas correspondientes, y si la tabla es muy grande este proceso se demorará más.

Si la tabla tiene un índice para las columnas que se trate, MySQL puede determinar rápidamente la posición de buscar en el medio del archivo de datos sin tener que mirar todos los datos. Por tanto, los índices aumentan la velocidad de la consulta y si no están bien configurados o no se tienen, puede traer como consecuencia el bloqueo de MYSQL, que la Web vaya lenta o incluso que el servidor se bloque o se caiga.

En caso de que la consulta SQL continúe lenta y no se pueda solucionar mediante una vista indexada, habría que pensar en hacer Triggers.

Los índices se crearían en los campos que se utilizan para unir tablas (por ejemplo, si en una tabla se usa el idUsuario para unirlo con la otra que también tiene idUsuario, se crearían dos índices, ambos con idUsuario, para que la BD pueda unir las tablas más rápidamente). Esto sólo es necesario en caso de que no sean campos de clave primaria, ya que éstos se indexan automáticamente. Creo que se ganaría bastante si en las uniones se están usando campos que no son clave primaria...

Se puede probar a crear los índices de las tablas de una vista, porque eso se haría rápido (si por ejemplo una vista une 5 tablas, sería crear 5 índices o pocos más) y es fácil de comprobar si va bien o no. Y si no funciona o no optimiza lo suficiente, pues hay que intentar lo otro.

Problemas encontrados:

  • En SQL SERVER 2005, por ejemplo, si hay tablas que se unen con OUTER JOIN no es posible tenerlo en vistas indexadas ya que las filas pueden desaparecer de forma lógica de una vista indizada basada en OUTER JOIN cuando inserte datos en una tabla de base. Esto hace que las vistas OUTER JOIN que son relativamente complejas de implementar se actualicen de forma incremental y el rendimiento de la implementación sería más lento que para las vistas basadas en (INNER) JOIN estándar.
  • Hay ocasiones que si en vez de utilizar OUTER JOIN utilizamos INNER JOIN nos devolve menos registros de los que necesitamos.
  • Otro problema es la dependencia de vistas con otras vistas. Es decir, si tengo una vista definida sobre otra vista. SQL Server no permite indizar la vista del nivel superior. En este artículo (http://www.microsoft.com/latam/technet/productos/servers/sql/2005/impprfiv.mspx) dicen que hay que expandir la definición de la vista anidada a mano en la vista del nivel superior y luego crear un índice, indizando la vista interna o no.