viernes, 4 de septiembre de 2015

Maricela Ocaña 
Programación Paralela y Distribuida 

Cinco ejemplos de programación con hilos con Python

   Los hilos permiten a nuestras aplicaciones ejecutar múltiples operaciones de forma concurrente en el mismo espacio de proceso. El módulo utilizado para ello es el módulo threading.

THREADS EN PYTHON

   El trabajo con threads se lleva a cabo en Python mediante el módulo thread. Este módulo es opcional y dependiente de la plataforma, y puede ser necesario, aunque no es común, recompilar el intérprete para añadir el soporte de threads.

   Además de thread, también contamos con el módulo threading que se apoya en el primero para proporcionarnos una API de más alto nivel, más completa, y orientada a objetos. El módulo threading se basa ligeramente en el modelo de threads de Java.

   El módulo threading contiene una clase Thread que debemos extender para crear nuestros propios hilos de ejecución. El método run contendrá el código que queremos que ejecute el thread. Si queremos especificar nuestro propio constructor, este deberá llamar athreading.Thread.__init__(self) para inicializar el objeto correctamente.


  1. import threading  
  2.   
  3. class MiThread(threading.Thread):  
  4.       def __init__(self, num):  
  5.           threading.Thread.__init__(self)  
  6.           self.num = num  
  7.   
  8.       def run(self):  
  9.           print "Soy el hilo", self.num  
   Para que el thread comience a ejecutar su código basta con crear una instancia de la clase que acabamos de definir y llamar a su método start. El código del hilo principal y el del que acabamos de crear se ejecutarán de forma concurrente.

  1. print "Soy el hilo principal"  
  2.   
  3. for i in range(0, 10):  
  4.     t = MiThread(i)  
  5.     t.start()  
  6.     t.join()  
   El método join se utiliza para que el hilo que ejecuta la llamada se bloquee hasta que finalice el thread sobre el que se llama. En este caso se utiliza para que el hilo principal no termine su ejecución antes que los hijos, lo cual podría resultar en algunas plataformas en la terminación de los hijos antes de finalizar su ejecución. El método join puede tomar como parámetro un número en coma flotante indicando el número máximo de segundos a esperar.

   Si se intenta llamar al método start para una instancia que ya se está ejecutando, obtendremos una excepción.

   La forma recomendada de crear nuevos hilos de ejecución consiste en extender la claseThread, como hemos visto, aunque también es posible crear una instancia de Threaddirectamente, e indicar como parámetros del constructor una clase ejecutable (una clase con el método especial __call__) o una función a ejecutar, y los argumentos en una tupla (parámetro args) o un diccionario (parámetro kwargs).

  1. import threading  
  2.   
  3. def imprime(num):  
  4.     print "Soy el hilo", num  
  5.   
  6. print "Soy el hilo principal"  
  7.   
  8. for i in range(0, 10):  
  9.     t = threading.Thread(target=imprime, args=(i, ))  
  10.     t.start()  
   Además de los parámetros target, args y kwargs también podemos pasar al constructor un parámetro de tipo cadena name con el nombre que queremos que tome el thread (el thread tendrá un nombre predeterminado aunque no lo especifiquemos); un parámetro de tipo booleano verbose para indicar al módulo que imprima mensajes sobre el estado de los threads para la depuración y un parámetro group, que por ahora no admite ningún valor pero que en el futuro se utilizará para crear grupos de threads y poder trabajar a nivel de grupos.

   Para comprobar si un thread sigue ejecutándose, se puede utilizar el método isAlive.    También podemos asignar un nombre al hilo y consultar su nombre con los métodossetName y getName.

 Mediante la función threading.enumerate obtendremos una lista de los objetos Thread que se están ejecutando, incluyendo el hilo principal (podemos comparar el objeto Thread con la variable main_thread para comprobar si se trata del hilo principal) y conthreading.activeCount podemos consultar el número de threads ejecutándose.

   Los objetos Thread también cuentan con un método setDaemon que toma un valor booleano indicando si se trata de un demonio. La utilidad de esto es que si solo quedan threads de tipo demonio ejecutándose, la aplicación terminará automáticamente, terminando estos threads de forma segura.

   Por último tenemos en el módulo threading una clase Timer que hereda de Thread y cuya utilidad es la de ejecutar el código de su método run después de un periodo de tiempo indicado como parámetro en su constructor. También incluye un método cancel mediante el que cancelar la ejecución antes de que termine el periodo de espera.

Otro ejemplo.

   En python, los threads  se realizan a través del módulo threading (basado en el módulo más prehistórico thread), y consiste en ir expandiendo la clase para añadir threads.

   La forma más sencilla de utilizar un hilo es crear una instancia con una función objetivo y llamar a start () para dejar que empiece a trabajar.

  threading import

 trabajador def ():
     "" "función de trabajador hilo" ""
     print 'trabajador'
     regreso

 hilos = []
 for i in range (5):
     t = roscado. Tema (target = trabajador)
     hilos. append (t)
     t. start ()

   La salida es de cinco líneas con "Trabajador" en cada uno:

  $ Python threading_simple.py

 Obrero
 Obrero
 Obrero
 Obrero
 Obrero

   Es útil para poder generar un hilo y pasarlo argumentos para decirle lo que hacer. En este ejemplo se pasa un número, que el hilo luego imprime.
  
threading import

 trabajador def (num):
     "" "función de trabajador hilo" ""
     'Trabajador:% s' print% num
     regreso

 hilos = []
 for i in range (5):
     t = roscado. Thread (target = trabajador, args = (i,))
     hilos. append (t)


     t. start ()

   El argumento entero ahora se incluye en el mensaje impreso por cada hilo:

  $ Python -u threading_simpleargs.py

 Trabajador: 0
 Trabajador: 1
 Trabajador: 2
 Trabajador: 3
 Trabajador: 4

   Verifica mas ejemplos en en los siguientes links:
  • https://pythonr2.wordpress.com/tag/ejemplos-de-threads/
  • http://victorpando.blogspot.mx/2008/12/programacin-de-threads-con-python.html 

martes, 1 de septiembre de 2015

Maricela Ocaña
Programacion Paralela y Distribuida


Cinco programas fáciles de entender con POO y Python


Objeto y Clase

    Un objeto es una entidad que agrupa un estado y una funcionalidad relacionadas. El estado del objeto se define a través de variables llamadas atributos, mientras que la funcionalidad se modela a través de funciones a las que se les conoce con el nombre de métodos del objeto.
    Una clase, por otro lado, no es más que una plantilla genérica a partir de la cuál instanciar los objetos; plantilla que es la que define qué atributos y métodos tendrán los objetos de esa clase.

    En Python las clases se definen mediante la palabra clave class seguida del nombre de la clase, dos puntos (:) y a continuación, indentado, el cuerpo de la clase.




Herencia múltiple

    Una clase puede heredar de varias clases a la vez; basta con enumerar las clases de las que se hereda separándolas por comas. En el caso de que alguna de las clases padre tuviera métodos con el mismo nombre y número de parámetros las clases sobrescribirían la implementación de los métodos de las clases más a su derecha en la definición.


Encapsulación

    La encapsulación se refiere a impedir el acceso a determinados métodos y atributos de los objetos estableciendo así qué puede utilizarse desde fuera de la clase.

    En Python no existen los modificadores de acceso, y lo que se suele hacer es que el acceso a una variable o función viene determinado por su nombre: si el nombre comienza con dos guiones bajos (y no termina también con dos guiones bajos) se trata de una variable o función privada, en caso contrario es pública.

    En el siguiente ejemplo sólo se imprimirá la cadena correspondiente al
método publico(), mientras que al intentar llamar al método __privado() Python lanzará una excepción de que no existe (existe, pero no lo podemos ver porque es privado).


Encapsulación y empleo de Getters y Setters

    En ocasiones también puede suceder que queramos permitir el acceso a algún atributo de nuestro objeto, pero que este se produzca de forma controlada. Para esto podemos escribir métodos cuyo único cometido sea este, métodos que normalmente, por convención, tienen nombres como getVariable y setVariable; de ahí que se conozcan también con el nombre de getters y setters.

Ahora un ejercicio más completo utilizando clases, instancias y método constructor.

#Maricela Ocaña Martínez
#Objetivo: POO con Python
#Fecha: 29/Ago/2015

# -*- coding: utf-8 -*-
class ModeloDePresupuesto:
    # Datos comerciales
    titulo = "PRESUPUESTO"
    encabezado_nombre = "Eugenia Bahit"
    encabezado_web = "www.eugeniabahit.com.ar"
    encabezado_email = "mail@mail.com"

    # Datos impositivos
    alicuota_iva = 21

    # Propiedades relativas al formato
    divline = "="*80

    # Setear los datos del cliente
    def set_cliente(self):
        self.empresa = raw_input('\tEmpresa: ')
        self.cliente = raw_input('\tNombre del cliente: ')

    # Setear los datos básicos del presupuesto
    def set_datos_basicos(self):
        self.fecha = raw_input('\tFecha: ')
        self.servicio = raw_input('\tDescripción del servicio: ')
        importe = raw_input('\tImporte bruto: $')
        self.importe = float(importe)
        self.vencimiento = raw_input('\tFecha de caducidad: ')

    # Calcular IVA
    def calcular_iva(self):
        self.monto_iva = self.importe*self.alicuota_iva/100

    # Calcula el monto total del presupuesto
    def calcular_neto(self):
        self.neto = self.importe+self.monto_iva

    # Armar el presupuesto
    def armar_presupuesto(self):
        """
            Esta función se encarga de armar todo el presupuesto
        """
        txt = '\n'+self.divline+'\n'
        txt += '\t'+self.encabezado_nombre+'\n'
        txt += '\tWeb Site: '+self.encabezado_web+' | '
        txt += 'E-mail: '+self.encabezado_email+'\n'
        txt += self.divline+'\n'
        txt += '\t'+self.titulo+'\n'
        txt += self.divline+'\n\n'
        txt += '\tFecha: '+self.fecha+'\n'
        txt += '\tEmpresa: '+self.empresa+'\n'
        txt += '\tCliente: '+self.cliente+'\n'
        txt += self.divline+'\n\n'
        txt += '\tDetalle del servicio:\n'
        txt += '\t'+self.servicio+'\n\n'
        txt += '\tImporte: $%0.2f | IVA: $%0.2f\n' % (
                                  self.importe, self.monto_iva)
        txt += '-'*80
        txt += '\n\tMONTO TOTAL: $%0.2f\n' % (self.neto)
        txt += self.divline+'\n'
        print txt
  
    # Método constructor
    def __init__(self):
        print self.divline
        print "\tGENERACION DEL PRESUPUESTO"
        print self.divline
        self.set_cliente()
        self.set_datos_basicos()
        self.calcular_iva()
        self.calcular_neto()
        self.armar_presupuesto()

# Instanciar clase

presupuesto = ModeloDePresupuesto()

    Para más dudas consulta el Tutorial de Python 'Python para todos' y 'Maestros del Web'.

miércoles, 26 de agosto de 2015

Programación Paralela y Distribuida

Maricela Ocaña

Procesamiento Pipeline, Ley de Amdahl y Ley de 
Gustafson

Procesamiento Pipeline

En computación, se le llama pipeline a una serie de elementos de procesamiento de datos ordenados de tal modo que la salida de cada uno es la entrada del siguiente, como quien dice una cadena de montaje pero en vez de orientada a la manufactura, orientada al procesamiento de datos e instrucciones.

Ciclo de vida de una instrucción

La acción básica de cualquier microprocesador, en tanto se mueve a través de la corriente de instrucciones, se puede descomponer en una serie de cuatro pasos simples, que cada instrucción en la corriente de código debe atravesar para ser ejecutada:
         1. Fetch: "traer" la instrucción que se va a ejecutar, de la dirección almacenada en el contador de programa.
         2. Store: "almacenar" la instrucción en el registro de instrucciones y "descifrarla", incrementando la dirección en el contador de programa.
         3. Execute: "Ejecutar" la instrucción almacenada en el registro de instrucciones. Si la instrucción no es una instrucción de rama sino una instrucción aritmética, este proceso la envía a la ALU apropiada (ALU: Arithmetic Logic Unit en español: Unidad Aritmético-Lógica), donde el microprocesador: a. "Lee" el contenido de los registros de entrada. b. "Agrega" el contenido de los registros de entrada.
         4. Write: "Escribir" los resultados de esa instrucción de la ALU nuevamente dentro del registro de destinación.

    En un procesador moderno, los cuatro pasos arriba descritos son repetidos una y otra vez hasta que el programa termine de ejecutarse. Éstas son, en hecho, las cuatro etapas en un "pipe" clásico del RISC.
    El pipelining hace su truco con la optimización total de los recursos existentes.
    Los diseñadores de microprocesadores siempre están buscando formas de incrementar el número de instrucciones que un CPU puede completar en un período de tiempo dado. Cuando recordamos que un programa es una secuencia ordenada de instrucciones, se hace claro que incrementar el número de instrucciones ejecutadas por unidad de tiempo es una forma de disminuir el tiempo total de ejecución de un programa. Incrementar la tasa de proceso de instrucciones de nuestro procesador (esto es, el numero de instrucciones completadas por unidad de tiempo) nos permite correr programas más rápidos.
    Haciendo "pipelining" al procesador, podemos poner a trabajar más de ese hardware en cada nanosegundo, incrementando de esa manera la eficiencia del procesador y su performance en la ejecución de programas.

Ley de Amdahl

    La mejora obtenida en el rendimiento de un sistema debido a la alteración de uno de sus componentes está limitada por la fracción de tiempo que se utiliza dicho componente.

¿Cuál es la aceleración A (speedup) del sistema completo después de acelerar k veces un componente?
Casos particulares de la ley
aSi f = 0 Þ A = 1: no hay ninguna mejora en el sistema.
bSi f = 1 Þ A = k : el sistema mejora igual que el componente.

 Casos particulares de la ley
        Si f = 0 Þ A = 1: no hay ninguna mejora en el sistema.
        Si f = 1 Þ A = k : el sistema mejora igual que el componente.







Ley de Gustafson

    La ley de Gustafson establece que cualquier problema suficientemente grande puede ser eficientemente paralelizado. La ley de Gustafson está muy ligada a la Ley de Amdahl, Gustafson enunció por primera vez la ley que lleva su nombre en 1988.


 donde P es el número de procesadores
 S es el speedup
la parte no paralelizable del proceso.

    La ley de Gustafson propone que los programadores establezcan el tamaño de los problemas para utilizar el equipamiento disponible en su solución en un tiempo práctico. Por consiguiente, si existe equipamiento más rápido disponible, mayores problemas se pondrán resolver en el mismo tiempo.


    La ley redefine la eficiencia como una necesidad para minimizar la parte secuencial de un programa, incluso si esto incrementa la cantidad total de cálculos.

Para más información puedes consultar “Cómo funcionan los pipelines de un CPU”.



martes, 25 de agosto de 2015

Maricela Ocaña
Programación Paralela y Distribuida


Programación Google App Engine con Python

Google App Engine nos permite publicar aplicaciones web en línea sin necesidad de preocuparnos por la parte de la infraestructura y con un enfoque 100% en la construcción de nuestra aplicación y en la posibilidad de correrla directamente sobre la infraestructura de Google, es decir, la que Google usa para sus propios productos esto garantiza un mejor rendimiento de la aplicación.

Para el almacenamiento de datos tendremos dos posibilidades en casi cualquier lenguaje en el que estemos desarrollando: Cloud Datastore y Cloud SQL. 

Cloud Datastore es una base de datos NoSQL ideada como la opción de almacenamiento principal a la hora de que corremos aplicaciones en App Engine.

Cloud SQL es una base de datos MySQL que corre en la nube de Google y tiene todas las características de cualquier base MySQL, entre otras.

Características
GAE soporta de manera oficial los lenguajes de programación Python y Java de manera estable y en modo de beta testing en lenguaje de programación Go creado por ellos mismos. Al soportar Java, es posible además utilizar cualquier lenguaje JVM o lo que es lo mismo, cualquier lenguaje que pueda ejecutarse sobre una máquina virtual de Java, aunque eso sí, con serias limitaciones. Entre dichos lenguajes se encuentran:
  • Groovy
  • JRuby
  • Scala
  • 4PHP
  • Clojure
  • Perl

Pero sin duda Python es el lenguaje mejor soportado y con mayor robustez por parte del App Engine.
Para utilizar Google App Engine como tu propia  red de entrega de contenidos (CDN) personal necesitas instalar algunas cosas en tu computadora y editar unos archivos de configuración. Todo este trabajo se realiza una sola vez y luego lo que necesitas es correr un simple programa para subir los archivos a Google.
Los scripts que tienes que descargar solo están disponibles para Windows únicamente si cuentas con otro sistema operativo deberás crearlos para que realicen las mismas funciones, el scrip que tienes que descargar es el siguiente:
deploy_digitalistic_cdn.bat 
Si ya cuentas con lo anterior sigue los siguientes pasos.
  1. Necesitas descargar e instalar Python en tu computadora. Si estas corriendo Mac o Linux, es muy probable que ya cuentes con Python instalado, así que puedes saltar este paso. Es recomendable descargar la Python 2.5 en adelante debido a que con las versiones 3 presenta algunos problemas.
  2. Descarga el SDK del motor de Google APP desde http://code.google.com/appengine/downloads.html e instalo. Durante la instalación del SDK va a revisar que tengas instalado Python o no, así que si tienes algún problema con la instalación de Python lo sabrás en este paso. El Google App Engine SDK es necesario para escribir y subir aplicaciones a Google. Solo utiliza las opciones ya establecidas cuando instales el SDK.
  3. Regístrate para el Google App Engine en appengine.google.com. Para esto crear una cuenta de Google.
  4. Una vez que hayas ingresado al servicio, crear una aplicación, así que pulsa el botón de “Create an application” y dale a la aplicación un nombre .Este nombre tiene que ser único dentro de todas las aplicaciones de usuarios, así que puedes tardar un rato en encontrar un nombre único. Guarda la nueva aplicación. Luego de que hayas creado esta primera aplicación, necesitas especificar tu número de teléfono. Google te enviará un mensaje de texto SMS con un código para ingresar al sitio. Esto confirma que eres el dueño de la cuenta de Google App Engine.
  5. Descarga el archivo http://nombredeaplicacion.appspot.com/files/digitalisticcdn.zip  (alojado en mi CDN privado!) y descomprímelo en tu disco duro. Si quieres puedes cambiarle el nombre del directorio de “nombre de aplicación” al nombre que quieras, por ejemplo el de tu propia aplicación. No importa realmente y solo te facilita el mantener un registro para el futuro.
  6. Utiliza un editor de texto para editar el archivo app.yaml que se encuentra en el directorio de “nombre de aplicación”. Cambia “application: nombre de aplicación” a “application:el identificador de tu aplicación” y guarda el archivo. Esto le dirá a Google App Engine que aplicación debe utilizar para cargar archivos.
  7. Ahora es tiempo de agregar todas las imágenes, hojas de estilo, archivos, vídeos, etc. que quieras subir a Googleen los folders de “nombre de aplicación”. Incluye las imágenes en el folder /images, etc. Puedes crear cualquier número de subfolders dentro de imágenes, archivos, hojas de estilo, etc. Puedes agregar más archivos en cualquier momento, así que si sólo quieres configurar la aplicación para que funcione puedes saltar este pasó. Ya existe una imagen en el folder de /images para que puedas comprobar que está funcionando como debería.
  8. Descarga http:/nombredeaplicación.appspot.com/files/deploy_digitalistic_cdn.bat y edítalo con un editor de texto. Este archivo debe apuntar a tu instalación de Python, tu instalación de Google App Engine y tu directorio “nombre de aplicación”. Si has instalado Google App Engine SDK en el directorio original y Python en C:/Program Files/ entonces no tienes que preocuparte por esta configuración. Solo cambia la última parte del archivo para apuntarlo a tu directorio de “nombre de aplicación”. Ten en cuenta que todas las rutas que tienen espacios tienen que estar encerradas entre comillas.
  9. Doble click en el archivo recientemente actualizado deploy_digitalist_cdn.bat para subir todos los archivos dentro del directorio “nombre de aplicación” hacia Google. La primera vez que hagas esto deberás especificar tu usuario y password de Google.
  10. Ahora ya tienes tu propio CDN privado! Ve a (“nombre de aplicación”).appspot.com/images/ninja.gif para ver si funciona.