viernes, 24 de febrero de 2012

TDD Test Driven Development

El Test Driven Development es una tecnica de desarrollado que se ha aplicado desde hace varios años atras, a teniado mucho exito en Estados Unidos y el Reino Unido pero no ha teniado mucho exito ni mucha difusión en los países hispano-parlantes por la falta de material en Español.

La TDD o Desarrollo basado en pruebas es una técnica que pertenece a las metodologías ágiles de desarrollo de software (Agile). Originalmente formaba parte de la programación extrema (eXtreme Programming), pero ahora es una técnica independiente.

Se trata de la repetición de varios pasos:
  • En primer lugar, el programador escribe el auto-test que comprueba la funcionalidad agregada. La prueba en este punto no debería funcionar.
  • Luego viene la aplicación de la funcionalidad. En este punto, un código escrito previamente debe pasar las pruebas exitosamente.
  • En el último paso, el programador hace la refactorización del código escrito para cumplir con los estándaresesperados.

La técnica fue creada por Kent Beck. También se puede utilizar para mejorar el código existente.

La técnica de programación para el desarrollo basado en pruebas se distingue por el hecho de que el programador inicia por primera vez por escrito las pruebas de funcionalidad que aún no se ha escrito. En las primeras pruebas no puede ni siquiera compilar, porque no puede ser más elementos de código (métodos, clases) que se utilizan en los ensayos.

Al principio comienza con un caso que no pasa la prueba - asegura que la prueba se garantiza a los errores y la captura se puede.

Las pruebas deben ser: simple,implementar la funcionalidad y tiener código estructurado (refactorización)

Fases del Compilador

Un compilador típicamente opera en fases, cada una lleva a cabo una tarea sobre el programa fuente. Las primeras tres fases suelen agruparse en una sola fase llamada fase de análisis y las últimas tres en una llamada fase de síntesis. La fase de análisis y el modulo de manejo de errores se describen posteriormente en este mismo capítulo. La fase de síntesis no es relevante en el contexto de un lenguaje multibase de datos, ya que este sigue un enfoque diferente que el de los lenguajes tradicionales, por esta razón solo se menciona.

Muchas herramientas de software que manipulan programas fuente realizan primero algún tipo de análisis, entre estas se encuentran los editores de estructuras, impresoras estéticas, verificadores estáticos y los interpretes.

Estructura de un Compilador


Cualquier compilador debe realizar dos tareas principales: análisis del programa a compilar y síntesis de un programa en lenguaje maquina que, cuando se ejecute, realizara correctamente las actividades descritas en el programa fuente. Para el estudio de un compilador, es necesario dividir su trabajo en fases. Cada fase representa una transformación al código fuente para obtener el código objeto. La siguiente figura representa los componentes en que se divide un compilador. Las tres primeras fases realizan la tarea de análisis, y las demás la síntesis. En cada una de las fases se utiliza un administrador de la tabla de símbolos y un manejador de errores.

Análisis Léxico

En la fase de análisis léxico se leen los caracteres del programa fuente y se agrupan en cadenas que representan los componentes léxicos. Cada componente léxico es una secuencia lógicamente coherente de caracteres relativa a un identificador, una palabra reservada, un operador o un carácter de puntuación. A la secuencia de caracteres que representa un componente léxico se le llama lexema (o con su nombre en inglés token). En el caso de los identificadores creados por el programador no solo se genera un componente léxico, sino que se genera otro lexema en la tabla de símbolos.

Análisis Sintáctico

En esta fase, los componentes léxicos se agrupan en frases gramaticales que el compilador utiliza para sintetizar la salida. Análisis Semántico. La fase de análisis semántico se intenta detectar instrucciones que tengan la estructura sintáctica correcta, pero que no tengan significado para la operación implicada. Análisis Semántico: Este análisis es más difícil de formalizar, determina el tipo de los resultados intermedios, comprobar que los argumentos que tienen un operador pertenecen al conjunto de operadores posible, y si son compatibles entre sí.


Generación de código intermedio


Algunos compiladores generan una representación intermedia explícita del programa fuente, una vez que se han realizado las fases de análisis. Se puede considerar esta operación intermedia como un subprograma para una máquina abstracta. Esta representación intermedia debe tener dos propiedades importantes: debe ser fácil de producir y fácil de traducir al programa objeto.


Optimización de código


En esta fase se trata de mejorar el código intermedio, de modo que resulte un código de máquina más rápido de ejecutar.


Generación de código


Esta constituye la fase final de un compilador. En ella se genera el código objeto que por lo general consiste en código en lenguaje máquina (código relocalizable) o código en lenguaje ensamblador.
Administrador de la tabla de símbolos: Una tabla de símbolos es una estructura de datos que contiene un registro por cada identificador. El registro incluye los campos para los atributos del identificador. El administrador de la tabla de símbolos se encarga de manejar los accesos a la tabla de símbolos, en cada una de las etapas de compilación de un programa.


Manejador de errores


En cada fase del proceso de compilación es posibles encontrar errores. Es conveniente que el tratamiento de los errores se haga de manera centralizada a través de un manejador de errores. De esta forma podrán controlarse más eficientemente los errores encontrados en cada una de las fases de la compilación de un programa.

Decompiladores





Un decompilador es un programa de ordenador que realiza la operación inversa a un compilador. Esto es, traducir código o información de bajo nivel de abstracción (sólo diseñado para ser leído por un ordenador, ej código máquina) a un lenguaje o medio de mayor nivel de abstracción (usualmente diseñado para ser leído por un humano, ej cualquier lenguaje de programación de alto nivel).


El término "decompilar" es más comúnmente aplicado a programas cuya función es la de traducir un ejecutable (la salida de un compilador) a código fuente en un lenguaje de alto nivel, que, cuando compile, volverá a producir un ejecutable cuyo comportamiento es el mismo que el del ejecutable original. En comparación, un desensamblador traduce un ejecutable a lenguaje ensamblador (y este código puede volver a ser ensamblado en un programa ejecutable). Decompilar es el acto de utilizar un decompilador, aunque si es usado como nombre, puede referirse a la salida de un decompilador.

Puede ser usado para recuperar código fuente, y es muy útil en casos de seguridad del ordenador, interoperatividad y corrección de errores.1 El éxito de la decompilación depende de la cantidad de información presente en el código que está siendo decompilado y en la sofisticación del análisis realizado sobre él.

Los formatos de bytecode utilizados por muchas máquinas virtuales (como la Java Virtual Machine o el lenguaje .NET (.NET Framework Common Language Runtime)) en ocasiones incluyen metadatos en el alto nivel que hacen que la decompilación se más flexible. Los lenguajes máquina normalmente tienen mucha menos metadata, y son por lo tanto mucho más difíciles de compilar. Algunos compiladores y herramientas de post-compilación producen código ofuscado (esto quiere decir que intentan producir una salida que es muy difícil de decompilar). Esto hace que sea más difícil revertir el código del ejecutable.

Los decompiladores pueden ser pensados como un conjunto de fases, en las que cada una de ellas contribuye de una forma específica en el proceso de decompilación.

lunes, 13 de febrero de 2012

Árboles sintácticos

Tradicionalmente, se conoce como “árbol” (en informática) a una estructura de datos ampliamente usada, que consta de un conjunto de nodos conectados, la cual, lleva su nombra porque su forma imita la de la copa de un árbol, solo que en posición invertida.

Sin embargo, un Árbol Sintáctico tiene una idea que, aunque conserve la misma esencia, va por un camino diferente. Para comprenderla primero hay que aclarar los siguientes términos.

  • Semántica: Estudio del significado de los signos lingüísticos y de sus combinaciones. Es decir, para este tema el significado o “traducción” de los signos validos para el código, expresiones, operadores, etc.  
  • Léxico: Conjunto de palabras de una lengua, de una región, una actividad, etc. Es decir, las “palabras” conocidas o disponibles que corresponden para el contexto del programa o del código, según el lenguaje con el que se este trabajando y el entorno de desarrollo utilizado. El léxico engloba las palabras, su validez, su función, etc. 
  • Sintaxis: Se refiere al ‘ordenamiento correcto de las oraciones’. En informática, es la forma correcta en que deben estar dispuestos los símbolos que componen una instrucción, estos se rigen por un reducido conjunto de reglas gramaticales. Este conjunto de reglas se denomina la sintaxis del lenguaje de programación. Por esta razón, también se habla de reglas sintácticas como sinónimo de reglas gramaticales. 
 
 
Árboles Sintácticos


Es una clase especial de árbol, se le denomina Árbol Sintáctico es una forma condensada de un árbol de análisis sintáctico, útil para representar instrucciones de lenguajes. Un árbol sintáctico permite demostrar que una secuencia de caracteres es una determinada categoría sintáctica. Llevan su nombre en base a la función que cumple, donde cada nodo representa una operación y los hijos de un nodo son los argumentos de la operación.

Un árbol sintáctico puede cumplir tres funciones diferentes:
  •  Comprobar el orden en que llegan los tokens (componente léxico es una cadena de caracteres)
  • Construir una representación del programa fuente.
  • Si es sintácticamente correcto generar el error

Un Árbol Sintáctico bien realizado se caracteriza por ser una representación abstracta que va desde las sub-categorías hasta la categoría general, por constar de operadores en nodos no terminales y operandos en nodos terminales.


Dibujar un Árbol Sintáctico


Para construir un árbol sintáctico se construyen sub-arboles para las sub-expresiones creando un nodo para cada operador y para cada operando. Los hijos de un nodo de un operador son las raíces de los nodos que representan las sub-expresiones que constituyen los operandos de dicho operador.

Un árbol es un tipo de estructura que permite visualizar una oración, expresión, sentencia, etc. Por esa razón, debe ser lo más claro y representativo posible. Debe mostrar todas las relaciones relevantes en la oración sin confusión.
  • Primero, hay que asegurarse de que las palabras están en sucesión lineal de izquierda a derecha, y en el mismo orden en que aparecen en la oración. Hay que evitar escribir una palabra encima de la otra. Además, conviene subrayar las palabras, para que contrasten claramente con los nudos categoriales del árbol.
  • La idea es que se pueda leer la oración de izquierda a derecha sin tener que volver los ojos hacia la izquierda en ningún punto





 








Traductores, Compiladores e Interpretes

En los lenguajes de programación existen dos tipos de traductores, compilador e interprete ambos cumplen una misma función mediante métodos diferentes.
 
Compiladores

Los compiladores analizan el programa fuente y lo traducen generando un programa equivalente e independiente escrito en otro lenguaje (por ejemplo, en el lenguaje de la máquina), que puede ejecutarse tantas veces como se quiera. Su acción equivale a la de un traductor humano, que toma un libro y produce otro equivalente escrito en otra lengua.


Interpretes

Un intérprete es un software que recibe un programa en lenguaje de alto nivel, lo analiza y lo ejecuta. Para analizar el programa completo, va traduciendo sentencias de código y ejecutándolas si están bien, así hasta completar el programa origen. Los intérpretes informáticos, al contrario que los compiladores, no generan un fichero ejecutable u otro programa equivalente en otro lenguaje, por lo que cada vez que se ejecuta el programa original debe pasar por la fase de análisis.

 
Compiladores Vs. Interpretes


Ventajas del intérprete frente al compilador:
  • El programa se puede ejecutar de inmediato, sin esperar a ser compilado.
  • Puede ser interrumpido con facilidad.
  • Puede ser rápidamente modificado y ejecutado nuevamente.
  • Resultan muy apropiados durante la fase de desarrollo de un programa, ya que la compilación no permite la ejecución paso a paso del programa y con ello impide la edición seguimiento y depuración del programa.

Desventajas del intérprete frente al compilador:  
  • La ejecución es más lenta, pues cada intrucción debe ser traducida a código máquina tantas veces como sea ejecutada.
  •  No son adecuados en la fase de explotación del programa ya que el proceso de interpretación se ha de repetir cada vez que se ejecuta el programa, mientras que con la compilación, una vez obtenido el programa en leguaje máquina éste puede ser ejecutado sin necesidad de compilarlo de nuevo.


Son lenguajes interpretados:

  • PHP
  • ASP (hasta la versión 3)
  • HTML
  • JavaScript
  • Haskell
  • Prolog








domingo, 12 de febrero de 2012

Introducción y Conceptos Básicos

Lenguajes de Programación

Un lenguaje de programación es un tipo de lenguaje artificial diseñado para expresar instrucciones para ser desarrolladas por un ordenador. Los lenguajes de programación están conformados por conjuntos de palabras clave, simbolos y reglas sintácticas y semánticas que definen su estructura y el significado de los elementos y expresiones respectiamente.

Diferencia entre un lenguaje de programación y otros lenguajes

Un lenguaje informático es un lenguaje asociado con ordenadores, sin embargo, no tiene por qué ser un lenguaje de programación. Si bien para la mayoría de los casos son lenguajes artificiales, no significa que todos sean iguales.
El lenguaje de marcas más extendido es el HTML. Los lenguajes de marcado suelen confundirse con lenguajes de programación. Sin embargo, no son lo mismo, ya que el lenguaje de marcado no tiene funciones aritméticas o variables, como sí poseen los lenguajes de programación
Por otra parte también hay desigualdad hacia los lenguajes de especificación, los cuales, a diferencia de los lenguajes de programación, que son lenguajes interpretables o traducibles por una computadora hacia una representación ejecutable, los lenguajes de especificación no son por lo general utilizados para implementar el sistema, sino para especificarlo, conceptualizarlo o incluso validarlo, aunque también suelen ser legibles para un programa de computadora, que puede asistir en el proceso de validación.



Tipos de Lenguaje de Programación

Los lenguajes de programación pueden ser clasificados de varias maneras según la cualidad que se clasifica de ellos, sin embargo, lo más usual es su clasificación según su nivel de abstracción. Por ende, se encuentran los lenguajes de bajo nivel y los lenguajes de alto nivel.

1.- Lenguajes de bajo nivel:


Los lenguajes denominados "de bajo nivel", son aquellos constituidos por instrucciones en lenguaje máquina o próximos a él. Tales lenguajes permiten crear programas muy rápidos y eficientes, pero en contrapartida, estos lenguajes suelen ser difíciles de aprender, programar y depurar. Un hecho importante es, que los programas escritos en un bajo nivel, son prácticamente específicos para cada procesador, lo que implica, que si se quiere ejecutar el programa en otra máquina de arquitectura diferente, es necesario volver a escribir el programa desde el principio.

2.- Lenguajes de alto nivel:


En los lenguajes de alto nivel son lenguajes con mayor nivel de absracción, las instrucciones son independientes de la máquina, son más fáciles de aprender porque están formados por elementos de lenguajes naturales (del inglés), que posteriormente se traduce a código máquina para su ejecución. Por ejemplo, en BASIC, comandos como "IF CONTADOR = 10 THEN STOP" son usados para ordenar a la computadora, que pare si CONTADOR es igual a 10. Pero aunque las computadoras parecieran comprender el lenguaje natural, lo hacen de una manera bastante rígida y sistemática, lo cual podría parecer un poco frustrante e inspira la búsqueda de lenguajes más cercanos aún al natural.


Sistemas Operativos


El sistema operativo, en su principio más básico, es un sistema de programas, es decir, es un conjunto de programas relacionados entre sí, de manera de que logran tanto funcionar como relacionarse entre ellos, con varias finalidades, primeramente servir de puente (a través de la interfaz gráfica) para la comunicación y relación entre el usuario, las aplicaciones y los dispositivos y/o componentes de hardware. Y en segundo lugar, logran gestionar los procesos básicos de un sistema informático, la administración y gestión de los recursos del ordenador, supervisión del almacenamiento de los programas y coordinación de las diversas tareas; todo sin interrumpir la normal ejecución del resto de las operaciones.
Los sistemas operativos se encuentran en la mayoría de los dispositivos electrónicos que utilizan microprocesadores para funcionar, como los son los teléfonos celulares, reproductores de DVD, computadoras, tarjetas de video, etc.

Tipos de Sistemas Operativos

En la actualidad hay diversas formas de clasificar a los sistemas operativos existentes, suele clasificarse según la administración de los usuarios, la administración de las tareas y el manejo de recursos. Sin embargo, estas son clasificaciones técnicas y aunque exista el interés en ellas, los usuarios más comunes para los sistemas operativos son los llamados usuarios finales. El usuario final es la persona o el grupo de personas designadas a manipular directamente el producto informático adquirido, para este caso el sistema operativo. Sin embargo, aunque hay muchos usuarios finales que se familiarizan con la utilización del producto, no implica que necesariamente deban o quieran afianzar conocimiento acerca de cómo funciona el producto. Usualmente, para los usuarios finales y para los adquisidores existen los Sistemas Operativos pagos y los gratuitos, en otras palabras, los Sistemas Operativos Propietario y el Libre
  • Sistema Operativo Propietario: También conocido como “privativo”. Es aquel software informático que requiere de una licencia paga para su utilización. Además de que priva al usuario, imponiéndole limitaciones para su uso, modificación y redistribución. Ejemplos de este tipo de sistema operativo es el Macintosh de la compañía Apple, y el Windows de la compañía de Microsoft
  • Sistema Operativo Libre: Son sistemas operativos que pueden ser adquiridos de forma gratuita al igual que todas las aplicaciones destinadas al mismo, además de que da al usuario la libertad para usarlo, modificarlo y redistribuirlo a sus gustos y/o necesidades. Tal es el caso del GNU/Linux y de toda su variedad de sistemas operativos, como por ejemplo el Debian, Ubuntu y Canaima.