Cada vez que aprendemos un nuevo lenguaje de programacion nos encontramos en la disyuntiva de optar por las librerias adecuadas para cada necesidad, una de estas necesidades es la seleccion de un conjunto de widgets para el desarrollo de la interfaz de usuario. En el caso especifico de Python las alternativas para cubrir esta necesidad son varias. En esta serie de apuntes comenzaremos a investigar y desarrollar breves tutoriales que mostrara algunas de estas librerias en suficiente profundidad como para conocer las prestaciones basicas de la misma. En esta primera entrega nos referiremos a la libreria de widgets wxPython, en entregas futuras abordaremos otras opciones como TKInter, QT, etc. Tambien se prentende presentar una metodologia basica de programacion de interfaces de usuarios graficas e introducir en las buenas practicas de programacion. Para ello crearemos una aplicacion sencilla donde se pueda aplicar los conocimientos adquiridos.

Objetivos:

  • Conocer las tecnicas basicas de programacion de GUIS
  • Comprender cada uno de los metodos y parametros usados por wxPython
  • Servir de base para el desarrollo de nuestras propias aplicaciones

Temas:

  • La creacion de un programa con interfaz de usuario grafica GUI
  • Creacion de widgets
  • Incorporacion de widgets en los contenedores
  • Vincular y manipular eventos
  • Manipular los valores de los widgets

El documento esta escrito de manera lineal y con la informacion estrictamente necesaria para comprender lo que se prentende enseñar, se explica paso a paso y de manera incremental la creacion de un pequeña aplicacion detallando los aspectos necesarios para la comprension sin abundar en detalles que puedan resultar confusos, luego el lector podra profundizar en los conceptos necesarios, para ello al final del documento se sugiere lectura relacionada.

Paso 1: Importacion del modulo

Lo primero que tenemos que hacer es importar el modulo, para poder hacerlo es importante no olvidarse que tenemos que tener instalado tanto el interprete de python como las librerias wxPython, en Debian la instalacion de ambos se hace con apt-get con los siguientes comandos:

Veamos ahora el codigo fuente de nuestro primer programa:

Vamos a usar para corroborar el correcto funcionamiento el manejo de excpciones de python mediante try y except, intenta importar el modulo, si la importacion no da errores continua, en caso de producirse un error lanza una excepcion y muestra un mensaje de error.

Paso 2: Creacion de una clase

Python es un lenguaje de programacion orientado a objetos, por lo tanto lo logico es que nuestra aplicacion sea una clase, en wxPython, heredamos de wx.Frame, que es la clase base para ventanas estándar.

 Paso 3: El constructor

Un GUI es una jerarquía de objetos, un botón puede estar contenido en un panel que figura en una solapa que es contenido en una ventana, etc.

Por lo tanto, cada elemento gráfico tiene un padre (su contenedor, por lo general). Por lo tanto tambien tiene un constructor padre (parent) como parámetro. Hacer un seguimiento de los padres es muy útil cuando tenemos que mostrar/ocultar un grupos de widgets, redibujar la pantalla o simplemente destruirlas cuando la aplicación termina. Asi, simpleapp_wx hereda de wx.Frame, por lo que tenemos que llamar al constructor wx.Frame (wx.Frame.__init__ ()).

El objeto wx.Frame tiene dos parámetros: id (identificador del widget) y title (el título de la ventana).

Paso 4: Mantener relacion con el padre

Es una buena costumbre, cuando se realiza la construcción de cualquier tipo de componente GUI, mantener una referencia a nuestra clase padre.

 Paso 5: Inicializacion de nuestro GUI

Usualmente es mejor tener la porción de código que crea todos los elementos GUI (botón, campos de texto …) separado de la lógica del programa. Es por eso que creamos el metodo initialize(). Vamos a crear todos los widgets (botones, campo de texto, etc) en este método.

En wxPython tenemos que usar self.Show(True) para forzar que la ventana se muestre en pantalla (de lo contrario permanecera oculta).

 Paso 6: Creación de la clase principal

Ya tenemos un clase completamente funcional y sintacticamente correcta, vamos a usarla!

Creamos una funcion main que se ejecuta cuando el programa se invoca desde la línea de comandos.

En wxPyhon, es obligatoria la instanciacion de un objeto wx.App () antes de la creación de los elementos del GUI. Por lo que hacemos app = wx.App (). Luego instanciamos nuestra clase (frame = simpleapp_wx ()). Asimismo, no le asignamos ningun padres (None), porque es el primer elemento GUI que vamos a construir. Usamos -1 a dejar a wxPython elegir un identificador (id) propio. Y damos nuestra ventana un título: «Mi aplicacion».

Paso 7: Entramos en el loop

Ahora, le tenemos que decir a nuestro programa que entre en un bucle esperando eventos, esto lo hacemos con mainloop ()

Esto significa que cada programa entra en un bucle “infinito”, ya veremos que no tanto, a la espera de eventos (ej. clic en un botón, pulsacion de una tecla, alguna accion con el raton, etc.) En wxPython el bucle principal recibirá estos eventos y los manejara en consecuencia. Esto se llama programacion event-driven o controlada por eventos (debido a que el programa no hará nada, sino esperar los eventos, y sólo reaccionara cuando se reciba uno de ellos).

Ya estamos en condiciones de ejecutar nuestro programa y ver el primer resultado, yo programo desde VIM, por lo que hago lo siguiente, :w para grabar, luego :!python % para ejecutar el interprete y pasarle como parametro el archivo que actualemente se encuentra en el buffer. Si usa otro editor grabe el programa y desde linea de comandos cambiele los permisos para hacerlo ejecutable por el dueño con:

Luego invoquelo de la siguiente manera:

Podremos ver nuestro programa en accion, por una parte es estimulante ver una ventana en modo grafico con todos los botones y el aspecto identico al resto de nuestras ventans, pero por otra parte es decepcionante ver la ventana vacia, por lo que en los proximos pasos iremos poblandola con widgets.

Paso 8: Diseño de interfaz

Hay varias manera de incrustar widgets en una ventana (o en otro contenedor): Añadir apilados horizontalmente, verticalmente, en una grilla, etc

Existen diferentes clases, llamadas gestores de diseño (layout managers), capaces de colocar los widgets en los contenedores de diferentes maneras. Algunos son más flexibles que otros. Cada contenedor (ventana, panel, solapa, diálogo …) puede tener su propio gestor de diseño.

Yo recomiendo el gestor de diseño grid (grilla). Se trata de una simple grilla donde se pueden incrustar los widgets, algo parecido a una tabla con filas y columnas donde se pueden ir incroporando nuestros elementos. Por ejemplo: Ponga un botón en la columna 2, fila 1. Ponga una casilla en la columna 5, fila 3. etc.

En wxPython, para crear el gestor de diseño del tipo grilla usamos grilla=wx.GridBagSizer() y luego le indicamos a nuestra ventana que lo use (self.SetSizerAndFit(grilla)).

Obtendremos una ventana minima que puede ser redimensionada.

Paso 9: Agregar un widget de entrada de texto

Los pasos para agregar un widget a un contenedor son dos, primero debemos definirlo para crearlo, luego lo agregamos a un gestor de diseño, vamos por partes entonces.

Crear del widget

El objeto que vamos a crear es una netrada de texto en wxPython esa clase se lla TextCtrl y lo hacemos asi (self.entrada=wx.TextCtrl()), pasamos como parametro self y el padre, porque nuestra ventana será el padre de este widget, es decir que aparecera dentro de nuestra ventana.

TextCtrl reciba dos parámetros ademas de self, -1 (para que wxPython asigne automáticamente un identificador), y el texto a mostrar (value=u”Enter text here.”).

Tenga en cuenta que mantenemos una referencia a este widget en nuestra clase: self.entrada =…, esto se debe a que tenemos que acceder a ella más adelante, desde otros métodos.

Agregar el widget

Ahora, lo agregaremos a nuestros gestor de diseño (GridBagSizer).

Llamamos al metodo .Add() de nuestra grilla, le pasamos el widget que acaba de crear (self.entrada) y sus coordenadas de ubicacion en la grilla (0,0) y (1,1) que es el espaciado alrededor del widget. En nuestro caso, el widget no se extienden a varias celdas, wx.EXPAND le dice al gestor de diseño (grilla) que debe ampliar la entrada de texto si su celda es redimencionada.

Tenemos una ventana con un solo campo de texto. Usted puede incluso ingresar en algún texto por teclado. Pero tenemos un problema, el campo de texto no cambia de tamaño cuando redimenciono la ventana. No se preocupe, hay una buena razón para esto, le dijimos al campo de entrada de texto que debia redimensionarse automáticamente si su columna o celda se expande, pero aún no le especificamos al gestor de diseño (grilla) que cuando la ventana se redimensiona tambien lo debe hacer la grilla. Ya veremos como hacerlo mas adelante.

Paso 10: Agregar un nuevo widget, un boton

Muy simple, ya vimos como hacerlo, crear el botón y añadirlo. Tenga en cuenta que en este caso, no mantenemos una referencia al botón (ya que vamos a leer ni alterar su valor en ningun momento).

Observe como ubicamos el nuevo widget, el boton, usando las coordenadas (0,1) sin espaciado. En este punto tenemos una ventana con un campo de texto y un botón.

Paso 11: Agregar otro widget, una etiqueta

Se trata de un StaticText en wxPython. Le pondremos coleres personalizados, usaremos un texto blanco sobre fondo azul, tenemos que llamar dos métodos para ello (SetForegroundColour y SetBackgroundColour), el texto estara alineado a la izquierda por defecto, ubicamos la etiqueta en nuestro gestor de diseño, la grilla, pero esta vez el nuevo widget se extienden a través de dos celdas (de modo que aparezca por debajo del campo de texto y del botón.), para ello se debe especificar un area de (1,2), es decir una celda verticalmente, y dos celdas horizontalmente. Finalmente para la expancion de la etiqueta usamos wx.EXPAND.

Ya tenemos tres widgets en nuestra aplicacion, todavia no hacen nada ni se ven bien cuando redimensionamos la ventana, pero seguiremos mejorando nuestro programa.

Paso 12: Habilitar redimensionamiento

Ahora le decimos a la gestor de diseño que tiene que cambiar el tamaño de sus columnas y filas cuando la ventana es redimensionada. Sólo la primera columna (0), para ello usaremos AddGrowableCol(), Tenga en cuenta que hay otros parámetros. Por ejemplo, algunas columna pueden crecer más que otras cuando se cambia el tamaño, eso se logra con el parámetro es de peso (En nuestro caso, simplemente se debe poner en 1).

Ahora intente cambiar el tamaño de la ventana. El campo de texto y la etiqueta azul ahora cambian de tamaño correctamente para adaptarse al tamaño de la ventana. Pero no se ve tan bien cuando redimensionamos la ventana verticalmente.

Paso 13: Agregar limitaciones

Vamos a añadir un contraint de modo que el usuario sólo pueda modificar el tamaño de la ventana horizontalmente. En consecuencia, para impedir el cambio de tamaño vertical de la ventana especificaremos el ancho y alto máximos y mínimos de la ventana, establecemos el alto mínimo y máximo de nuestra actual ventana (self.GetSize().y) a fin de que la ventana no se puede cambiar el tamaño verticalmente. Para ello dejamos en los valores -1 y -1 para el ancho (y) anchura de manera que la ventana puede ser libremente redimensionada horizontalmente (-1 significa “Sin límite”).

 

Paso 14: manejador de eventos y modificacion de atributos

Los manejadores de eventos (event handler) son métodos que se llaman cuando algo sucede en el GUI. Relacionamos en el manejador de eventos widgets especificos con eventos puntuales. De esta forma decimos que es lo que tiene que hacer la aplicacion ante cualquier evento que pueda ser capturado, por ejemplo, cuando se hace clic con raton sobre el boton o se presiona ENTER en el campo de texto.

Creamos un metodo SiCliqueaBoton(), método que se llama cuando se hace clic en el botón. Tambien creamos un metodo SiPulsamosEnter(), método que se llamará luego de presionar ENTER en el campo de texto. Observe que es necesario agregar en la entrada el parametro style=wx.TE_PROCESS_ENTER para que este sea capaz de procesar el pulsado de la tecla enter.

En cada uno de estos metodos modificamos a su vez la etiqueta usando el metodoGetValue() para tomar el valor actual del campo de texto y SetLabel() para establecer el nuevo valor de la etiqueta mas una leyenda discrecional con la accion realizada.

 Paso 15: Fijar foco

Como ultimo agregado, haremos que el cambo de entrada de texto obtenga el foco y se seleccione el texto contenido, para ello agregaremos tanto en el metodo initialize como en cada uno de los metodos llamados por lo eventos un par de lineas, self.entrada.SetFocus() y self.entrada.SetSelection(-1,-1). Veamos ahora nuestro programa terminado y lo ejecutemos para probarlo.

Conclusiones

Bueno, eso es todo, espero que les sirva, si encuentran errores por favor me avisan asi lo corrijo. El documento es de libre distribucion, solo me gustaria que se mantenga la autoria, pero, si no lo quiere hacer tambien esta bien, la unica motivacion es compartir conocimientos.

Si quieren profundizar en el uso de wxPython recomiendo los siguientes enlaces:

http://www.wxpython.org/onlinedocs.php

http://wiki.wxpython.org/

http://boa-constructor.sourceforge.net/

Todo indica que es el momento de comenzar a jugar con Django y las cosas que nos tiene preparado, dijimos que vamos a comenzar a trabajar en un entorno de tipo LAMP donde luego vamos a mostrar como desplegar una app completa de Django. Por el momento vamos por el principio.

Así comienza una serie de artículos de El Codigo K, recomendable.

Makefiles son una forma sencilla de organizar la compilación de código. Este tutorial es un muy simple ejemplo de lo que se puede hacer con “make”, pero pretende ser una guía de principiantes para que pueda crear rápida y fácilmente sus propios archivos make para pequeños proyectos.

Vamos a tomar el código de ejemplo del articulo anterior. Lo que representaría un típico programa principal, algo de código funcional en un archivo separado, y un archivo de inclusión, respectivamente.

 

 

Normalmente, se compilará esta colección de código ejecutando el siguiente comando:

Este comando compila los dos códigos fuente involucrados en la creación del binario ejecutable “main” el parámetro -I. le dice al compilador que los archivos de inclusión .hpp los tiene que buscar en el directorio actual “.”

Por desgracia, este enfoque de la compilación tiene dos problemas. En primer lugar, si se pierde el comando de compilación o se cambia de computadora tiene que volver a escribir desde cero el comando. En segundo lugar, si sólo está haciendo cambios a un archivo .cpp, recompilar todos los archivos de código fuente cada vez que necesita recompilar demanda mucho tiempo y es poco eficiente. Ambos problemas se puede solucionar mediante el uso de un archivo “Makefile” con las instrucciones necesarias para la generación del ejecutable.

El makefile más simple que se podría crear sería algo como:

 

Si pones estas regla en un fichero llamado Makefile o makefile  y ejecutas “make” en la línea de comandos se ejecutará el comando de compilación como esta escrito en el makefile.

Se pone luego del nombre del ejecutable que se generara el símbolo : seguido de los archivos de codigo fuente que son necesarios para su creación y en la linea siguiente el comando de compilación necesario. Es importante destacar que antes de la llamada al compilador en la segunda linea hay un “Tab

Con el fin de ser un poco más eficiente, vamos crear un nuevo archivos Makefile:

 

Ahora hemos definido algunas constantes CC y CFLAGS. Resulta que estos son constantes especiales que se usan para decirle a make como queremos compilar. En particular  CC es el macro que especifica el compilador que vamos a usar usar, y CFLAGS es la lista de las banderas a pasar al comando de compilación. Al poner los archivos de objetos – main.o y suma.o – en la lista de dependencias y en la regla, make sabe que debe compilar primero las versiones .cpp individualmente, y luego construir el ejecutable.

El uso de esta forma de makefile es suficiente para la mayoría de proyectos de pequeña escala. Sin embargo, hay una cosa que falta: la dependencia de los archivos de inclusión. Si se va a realizar un cambio en suma.hpp, por ejemplo, que make no vuelva a compilar los archivos .cpp. Con el fin de solucionar este problema, tenemos que decirle make que todos los archivos .cpp dependen de ciertos archivos .hpp. Podemos hacer esto escribiendo una regla simple y agregarlo al archivo MAKE.

 

Esta adición creamo primero la macro DEPS, que es el conjunto de archivos .hpp de los que  los archivos .cpp dependen. Entonces definimos una regla que se aplica a todos los archivos que terminan en el sufijo .o. La regla dice que el archivo .o depende de la versión .cpp del archivo y los archivos .hpp incluidos en la macro DEPS. La regla luego dice que para generar el archivo .o, make necesita compilar el archivo .cpp usando el compilador definido en la macro CC. La bandera -c dice que genere el archivo de objeto, -o $@ dice para ponga la salida de la compilación en el archivo con el nombre en el lado izquierdo de los :,  $< es el primer elemento de la lista de dependencias, y  la macro CFLAGS se define como lo hicimos anteriormente.

Bueno este es un simple tutorial con ejemplos de como usar la herramienta Make. Aun así apenas nos asomamos a ver todo el potencial que nos ofrece.

 

En nuestro articulo anterior Cómo organizar tu código fuente en C++  definíamos algunas pautas para organizar nuestro código en varios archivos a fin de mejorar su tratamiento. En este articulo vamos a ver como hacer esto con un ejemplo simple, tomemos para ello el siguiente ejemplo que suma dos números a través de una función:

Vamos a retirar la función suma a un nuevo archivo, para ello necesitamos crear en realidad dos nuevos archivos y modificar el original. Por una parte tendremos la implementación de la función suma en un nuevo archivo llamado en este caso suma.cpp:

Que simplemente contiene la implementación de la función suma, para poder incorporar esta implementación en otros códigos fuentes es preciso que creemos un nuevo archivo con la definición de la función, para hacerlo, creamos ahora un archivo llamado suma.hpp donde podemos observar que la h hace referencia a header.

Acá tenemos unicamente la definición de la función y un par de directivas de preprocesador, veamos de que se trata.

La primera parte se llama un guardia de cabecera o header guard en ingles, estas lineas impiden que un archivo de cabecera sea cargado mas de una vez mediante #include. Sirve para proyectos de software muy extensos especialmente.

La segunda parte es el contenido real del archivo .hpp, que debe ser las declaraciones de todas las funciones que queremos otros archivos puedan ver. Todos nuestros archivos de cabecera deben tener una extensión .hpp.

Finalmente el archivo principal main.cpp queda de la siguiente manera:

Observe que la segunda linea incluye las funciones definidas en suma.hpp que se implementan en suma.cpp. Ahora ya las podemos usar libremente y a discreción a lo largo de este código fuente.

Julio Cesar tenía la premisa de “Divide y Triunfaras”, y muy mal no le fue en sus conquistas. Vamos a ver como organizar nuestro código fuente dividiéndolo en fragmentos de código más fáciles y cómodos de manejar, vamos a aprender cómo hacerlo y bajo qué criterios.

Muchos programas simples se pueden escribir en un solo archivo fuente en C++, pero, cualquier proyecto serio va a necesitar dividir en varios archivos con el fin de ser más manejable.

Sin embargo, muchos programadores que recién comienzan no se dan cuenta de cuál es la importancia de esto, sobre todo porque algunos ya lo intentaron y se encontraron con tantos problemas que decidieron que no valía la pena el esfuerzo.

Este artículo intenta explicar por qué hacerlo y en un próximo artículo cómo hacerlo correctamente.

Voy a llamar a los archivos estándar de C ++ (por lo general con extensión .cpp) “archivos de codigo fuente”. Esto será para distinguirlos de los “archivos de cabecera” (por lo general con extensión .h o .hpp).

¿Por qué dividir el código en varios archivos?

La primera pregunta que algunos programadores novatos se hacen cuando ven un directorio lleno de archivos de código fuente es, “¿por qué no está todo en un solo archivo?”

La división de cualquier proyecto de tamaño razonable nos provee de algunas ventajas, las más significativas de las cuales son las siguientes:

  • Acelerar la compilación – la mayoría de los compiladores trabajan en un archivo a la vez. Así que si todos sus 10000 líneas de código se encuentra en un archivo, y cambian una línea, entonces usted tiene que recompilar 10000 líneas de código. Por otro lado, si sus 10000 líneas de código se distribuyen uniformemente a través de 10 archivos, a continuación, cambiar una línea única requerirá compilar solo 1.000 líneas de código. Las 9000 líneas en los otros 9 archivos no necesitarán volver a compilarse.
  • Aumentar organización – La división de su código a lo largo de líneas lógicas, será más fácil para usted (y los otros programadores del proyecto) para encontrar funciones, variables, declaraciones, etc.
  • Facilitar la reutilización de código – Si el código está cuidadosamente dividido en secciones que operan en gran medida de forma independiente el uno del otro, esto le permite utilizar ese código en otro proyecto, que le ahorra un montón de tiempo y trabajo en volver a escribir el código.
  • Compartir código entre los proyectos – El principio aquí es el mismo que con el tema reutilización. Al separar cuidadosamente código en determinados archivos, se hace posible que los múltiples proyectos que utilizan algunos de los mismos archivos de código sin duplicarlos. El beneficio de compartir un archivo de código entre los proyectos y no sólo utilizando la copia y pega es que cualquier corrección de errores realizados en ese archivo o archivos de un proyecto afectará el otro proyecto, por lo que ambos proyectos pueden estar seguros de utilizar la versión más reciente del código.
  • Dividir las responsabilidades de codificación entre los programadores – Para grandes proyectos, esta es quizás la principal razón para la separación de código en varios archivos. Sistemas de gestión de configuración y los sistemas de control de versiones como CVS o Git ayudarle con esto.

Ahora que ya estás convencido de que hay beneficios para la división de tu proyecto en varios archivos más pequeños. Así que, ¿cómo hacerlo? Aunque algunas de las decisiones que tomes serán razonablemente arbitrarias, hay algunas reglas básicas que debes seguir.

En primer lugar, mira cómo dividir el código en secciones. A menudo esto es mediante su división en subsistemas separados, o “módulos”, como el sonido, la música, gráficos, manejo de archivos, base de datos, etc.

Crea nuevos archivos con nombres significativos para saber de un vistazo qué tipo de código es el que contienen.

A veces es necesario que un módulo se divida en dos o más archivos, ya que podría tener sentido hacerlo por razones lógicas.

Una vez que haya dividirlo según este criterio los archivos de código fuente, el siguiente paso es considerar lo que va a entrar en los archivos de cabecera. Básicamente consiste en poner el código que suele estar en la parte superior del archivo de código fuente en un archivo de cabecera separado.

EL código que se pone  en un encabezado por lo general incluye algunos o todos de los siguientes:

  • definiciones de clases y struct
  • typedefs
  • prototipos de funciones
  • variables globales
  • constantes
  • macros #defined
  • directivas #pragma

Peligros potenciales

Las reglas dadas arriba son bastante generales y sólo sirven como punto de partida para la organización de su código. En casos sencillos, se puede seguir esas directrices. Sin embargo, hay algunos detalles más que se tienen que considerar.

En mi experiencia, hay cuatro errores básicos que las personas enfrentan cuando entran en el oscuro mundo de los archivos de cabecera definidos por el usuario.

  • Los archivos de código fuente ya no se compilan ya que no pueden encontrar las funciones o variables que necesitan.
  • Definiciones duplicadas en una clase o identificador se incluye dos veces en un archivo de origen.
  • Duplicar instancias de objetos dentro del código que compila bien. Este es un error que une, a menudo difícil de entender

Conclusión

Si se realiza correctamente, la organización de los archivos de esta manera puede acelerar su desarrollo sin perjudicar en absoluto o introducir algún problema adicional. A pesar de que parece que hay mucho que considerar cuando se hace así, con el tiempo se convierte en una práctica habitual.

Sólo recuerde estos puntos clave:

  • Divida el código siguiendo el criterio de identificar los modulos logicos
  • Use los archivos de .cpp para la implementación y los archivos .hpp para la interfaz

En la empresa estábamos trabajando sobre nuestros servidores de VOIP y nos dimos cuenta de que surgía la necesidad de poder conectar los teléfonos de la flota dentro de nuestra red (configurar SIP) y así poder hacer llamadas desde el exterior o simple llamas a internos utilizando datos, ya sea wi-fi o red móvil, buscando en internet no encontramos una página que nos explique bien la operatoria es por eso que preparamos este post.

Fuente: Synergo

Boost es un conjunto de librerias de software libre y revisión por pares preparadas para extender las capacidades del lenguaje de programación C++. Su licencia, de tipo BSD, permite que sea utilizada en cualquier tipo de proyectos, ya sean comerciales o no.

Su diseño e implementación permiten que sea utilizada en un amplio espectro de aplicaciones y plataformas. Abarca desde bibliotecas de propósito general hasta abstracciones del sistema operativo. Con el objetivo de alcanzar el mayor rendimiento y flexibilidad se hace un uso intensivo de plantillas. Boost ha representado una fuente de trabajo e investigación en programación genérica y metaprogramación en C++.

Varios fundadores de Boost pertenecen al Comité ISO de Estándares C++. La próxima versión estándar de C++ incorporará varias de estas bibliotecas.

Vamos a hablar un poco de vectores e iteradores en C++. Como derivado de C es comun que muchos desarrolladores a pesar de conocerlos les cueste adaptarse al uso de iteradores.

Contenedores, los vectores:

Un contenedor de la STL es una clase genérica que puede instanciarse para representar diversos tipos de objetos. Esta clase incluye ciertas operaciones (muy básicas) sobre los objetos de su tipo;  estas operaciones están representadas por funciones-miembro, incluyendo constructores y funciones-operador, que son a su vez funciones genéricas.

De su propio nombre (“Containers”) podemos deducir que su misión principal es funcionar como estructuras de datos, y en este sentido podemos decir que entre sus funcionalidades más destacadas se encuentran la gestión del espacio de almacenamiento necesario lo que de por si es una gran ventaja ya que el programador no tiene que preocuparse de asignar o liberar memoria para los objetos creados.

Veamos uso de los contenedores mediante un sencillo ejemplo, si tenemos que manejar un conjunto de enteros, puede utilizarse una matriz de enteros, pero ya hemos señalado que esta estructura nos obliga a conocer de antemano la cantidad de datos a almacenar (el tamaño de la matriz).

Una alternativa es utilizar como “contenedor” para nuestros enteros una clase genérica de la STL denominada vector.

Como se puede observa en la linea 8 definimos un vector de tipo int al que llamamos enteros.

Teniendo ya el objeto disponible vamos a usar uno de sus métodos o funciones miembro “push_back” para ir cargando el vector con valores del tipo que fue definido.

Luego mediante cout podemos acceder a los valores almacenados en el vector de la misma manera que lo haríamos en un array, es decir a travez de su indice.

¿Sencillo no? Y lo mejor de todo es que nos despreocupamos completamente de la dimensión de la colección y el manejo de memoria.

Iteradores:

Pero vamos un poco mas alla con C++, veamos como podemos usar un iterador para recorrer nuestro vector.

El concepto de iterador es fundamental para entender las clases de contenedores y algoritmos asociados inclusos en la Librería Estándar de Plantillas de C++.   En realidad los algoritmos son funciones globales que aceptan iteradores como argumentos, y a través de ellos puedan operar sobre los elementos del contenedor.

Un iterador es una especie de puntero que es utilizado por un algoritmo para recorrer los elementos almacenados en un contenedor. Dado que los distintos algoritmos necesitan recorrer los contenedores de diversas maneras para realizar diversas operaciones, y los contenedores deben ser accedidos de formas distintas, existen diferentes tipos de iteradores. Cada contenedor de la Librería Estándar puede generar un iterador con funcionalidad adecuada a la técnica de almacenamiento que utiliza. Es precisamente el tipo de iterador requerido como argumento, lo que distingue qué algoritmos STL pueden ser utilizados con cada clase de contenedor. Por ejemplo, si un contenedor solo dispone de iteradores de acceso secuencial, no pueden utilizarse con algoritmos que exijan iteradores de acceso aleatorio.

Pero vamos a un ejemplo que es la mejor forma de entenderlos:

Acá incorporamos un iterador, en la linea 9 declaramos un iterador a un vector de enteros.

Mas abajo podemos observar que en la linea 13 apuntamos con el iterador al primer elemento-ítem de nuestro vector.

Luego en la linea 14, 15 y 16 podemos ver como accedemos los enteros almacenados en el vector mediante los iteradores, observe que para acceder al valor se usa “*” como lo hacemos con punteros.

Pongamos atención ahora a la construcción de las lineas 17-19, este es el uso común y adecuado que se hace de los iteradores para recorrer una colección, en este caso mediante “for” que es en esencia un iterador.

Observemos que es este ultimo ejemplo hemos utilizado los métodos .begin() u .end() para denotar los limites de acción de for. También debemos notar que usamos el operador de  auto-incremento ++ para el iterador.

Bueno queridos lecoter espero que les haya gustado.

Resulta que Pi también desempeña un papel importante en un experimento llamado “el problema de la aguja de Buffon“, el cual buscar determinar la probabilidad de que objetos alargados  uniformes,  arrojados aleatoriamente aterricen en medio o atravesando una serie de líneas paralelas en el suelo.
Resulta que si la distancia entre las líneas es la misma que la longitud de los objetos lanzados, el número de veces que los objetos aterrizan atravesando las líneas (luego de un gran número de lanzamientos) se puede utilizar para calcular el valor de Pi. aguja de buffon
Se trata de lanzar una aguja sobre un papel en el que se han trazado rectas paralelas distanciadas entre sí de manera uniforme. Se puede demostrar que si la distancia entre las rectas es igual a la longitud de la aguja, la probabilidad de que cruce alguna de las líneas es  2/\pi.
Los científicos y los matemáticos aún no han descubierto la forma para calcular el valor exacto de Pi, ya que no se ha podido encontrar un material lo suficientemente delgado con el cual se obtengan cálculos exactos.